use std::os::mikros::{ipc, syscalls, Errno}; 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) -> Result { Ok(0) } } struct UartWrp(Uart); 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; fn deref(&self) -> &Self::Target { &self.0 } } unsafe impl Send for UartWrp {} unsafe impl Sync for UartWrp {} struct FileServ(Mutex); impl file_rpc::Server for FileServ { fn read( &self, _fd: u64, _len: usize, ) -> std::result::Result, 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 { Err(Errno::ENOSYS) } fn dup(&self, fd: u64) -> Result { Ok(fd) } fn seek(&self, _fd: u64, _pos: file_rpc::SeekFrom) -> Result { 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 { 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 }