106 lines
2.7 KiB
Rust
106 lines
2.7 KiB
Rust
use std::os::mikros::{ipc, syscalls, Errno, FileOpenMode};
|
|
|
|
use parking_lot::Mutex;
|
|
use uart::{
|
|
Baud, Data, DataBits, FifoSize, InterruptEnable, LineControl, LineStatus, ModemControl,
|
|
ParityMode, Uart, UartAddress,
|
|
};
|
|
|
|
struct DevServ;
|
|
|
|
impl dev_driver_rpc::Server for DevServ {
|
|
fn open(&self, _path: &std::path::Path, _mode: FileOpenMode) -> Result<u64, Errno> {
|
|
Ok(0)
|
|
}
|
|
}
|
|
|
|
struct UartWrp(Uart<Data>);
|
|
|
|
impl std::ops::DerefMut for UartWrp {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.0
|
|
}
|
|
}
|
|
|
|
impl std::ops::Deref for UartWrp {
|
|
type Target = Uart<Data>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
unsafe impl Send for UartWrp {}
|
|
unsafe impl Sync for UartWrp {}
|
|
|
|
struct FileServ(Mutex<UartWrp>);
|
|
|
|
impl file_rpc::Server for FileServ {
|
|
fn read(
|
|
&self,
|
|
_fd: u64,
|
|
_len: usize,
|
|
) -> std::result::Result<std::borrow::Cow<'_, [u8]>, Errno> {
|
|
Err(Errno::ENOSYS)
|
|
}
|
|
|
|
fn write(&self, _fd: u64, data: &[u8]) -> Result<(), Errno> {
|
|
let mut uart = self.0.lock();
|
|
for &byte in data {
|
|
while !uart.read_line_status().contains(LineStatus::TRANSMIT_EMPTY) {}
|
|
uart.write_data(byte);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn close(&self, _fd: u64) -> Result<(), Errno> { Ok(()) }
|
|
|
|
fn size(&self, _fd: u64) -> Result<u64, Errno> {
|
|
Err(Errno::ENOSYS)
|
|
}
|
|
|
|
fn dup(&self, fd: u64) -> Result<u64, Errno> {
|
|
Ok(fd)
|
|
}
|
|
|
|
fn seek(&self, _fd: u64, _pos: file_rpc::SeekFrom) -> Result<u64, Errno> { Err(Errno::ESPIPE) }
|
|
}
|
|
|
|
fn main() {
|
|
let uart = unsafe { init_uart(uart::COM1) };
|
|
dev_driver_rpc::register_server(Box::new(DevServ));
|
|
file_rpc::register_server(Box::new(FileServ(Mutex::new(UartWrp(uart)))));
|
|
let devfs_pid;
|
|
loop {
|
|
if let Some(pid) = syscalls::try_get_registered(1) {
|
|
devfs_pid = pid;
|
|
break;
|
|
}
|
|
}
|
|
devfs_rpc::Client::new(devfs_pid)
|
|
.register_dev("ttyS0")
|
|
.unwrap();
|
|
loop {
|
|
ipc::process_messages()
|
|
}
|
|
}
|
|
|
|
/// Sets up the given UART for 115200 baud 8N1, no interrupts
|
|
unsafe fn init_uart(address: UartAddress) -> Uart<Data> {
|
|
let mut uart = unsafe { Uart::new(address) }.configure_mode();
|
|
uart.set_baud(Baud::B115200);
|
|
let mut uart = uart.data_mode();
|
|
let line_control = LineControl {
|
|
bits: DataBits::Eight,
|
|
parity: ParityMode::None,
|
|
extra_stop: false,
|
|
break_signal: false,
|
|
};
|
|
uart.write_line_control(line_control);
|
|
uart.enable_fifo(true, true, false, FifoSize::Fourteen);
|
|
// UART library misspelled modem here
|
|
uart.write_model_control(ModemControl::TERMINAL_READY | ModemControl::REQUEST_TO_SEND);
|
|
uart.write_interrupt_enable(InterruptEnable::empty());
|
|
uart
|
|
}
|