blob: 9570cdb8b2c0f30f4105a6ff7a4ce681fc512230 [file] [log] [blame]
use alloc::string::String;
use core::cell::Cell;
use core::fmt;
use core::result::Result;
use core::slice;
use syscalls;
const DRIVER_NUMBER: usize = 1;
mod command_nr {
pub const WRITE: usize = 1;
}
mod subscribe_nr {
pub const SET_ALARM: usize = 1;
}
mod allow_nr {
pub const SHARE_BUFFER: usize = 1;
}
pub struct Console;
impl Console {
pub fn new() -> Console {
Console
}
pub fn write(&mut self, text: String) {
self.write_bytes(text.as_bytes());
}
// TODO: Use this method after relocation is fixed
pub(crate) fn write_bytes(&mut self, text: &[u8]) {
let num_bytes = text.len();
let result = syscalls::allow(DRIVER_NUMBER, allow_nr::SHARE_BUFFER, unsafe {
slice::from_raw_parts_mut(text.as_ptr() as *mut _, num_bytes)
});
if result.is_err() {
return;
}
let is_written = Cell::new(false);
let mut is_written_alarm = |_, _, _| is_written.set(true);
let subscription = syscalls::subscribe(
DRIVER_NUMBER,
subscribe_nr::SET_ALARM,
&mut is_written_alarm,
);
if subscription.is_err() {
return;
}
let result_code =
unsafe { syscalls::command(DRIVER_NUMBER, command_nr::WRITE, num_bytes, 0) };
if result_code < 0 {
return;
}
syscalls::yieldk_for(|| is_written.get());
}
}
impl fmt::Write for Console {
fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
self.write(String::from(string));
Ok(())
}
}