serial_driver/src/main.rs
2024-10-04 12:36:26 -05:00

106 lines
2.7 KiB
Rust

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<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
}