diff --git a/Cargo.toml b/Cargo.toml index 661a78f6f..9817d48f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ crate-type = ["staticlib"] [dependencies] bitflags = "*" -ransid = "*" spin = "*" [dependencies.goblin] diff --git a/arch/x86_64/Cargo.toml b/arch/x86_64/Cargo.toml index a845fa7f0..c9f00e0d5 100644 --- a/arch/x86_64/Cargo.toml +++ b/arch/x86_64/Cargo.toml @@ -5,8 +5,9 @@ version = "0.1.0" [dependencies] bitflags = "*" hole_list_allocator = { path = "../../alloc/hole_list_allocator"} +ransid = "*" spin = "*" [dependencies.x86] -default-features = false version = "0.7.1" +default-features = false diff --git a/arch/x86_64/src/console.rs b/arch/x86_64/src/console.rs new file mode 100644 index 000000000..62bd79e73 --- /dev/null +++ b/arch/x86_64/src/console.rs @@ -0,0 +1,26 @@ +use core::fmt::{self, Write}; +use spin::Mutex; + +use device::display::DISPLAY; +use device::serial::COM1; + +pub static CONSOLE: Mutex = Mutex::new(Console::new()); + +pub struct Console; + +impl Console { + const fn new() -> Self { + Console + } +} + +impl Write for Console { + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + if let Some(ref mut display) = *DISPLAY.lock() { + display.write(s.as_bytes()); + Ok(()) + } else { + COM1.lock().write_str(s) + } + } +} diff --git a/arch/x86_64/src/context.rs b/arch/x86_64/src/context.rs index 694ead4a5..ef95e058a 100644 --- a/arch/x86_64/src/context.rs +++ b/arch/x86_64/src/context.rs @@ -1,4 +1,3 @@ -use core::mem; use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; /// This must be used by the kernel to ensure that context switches are done atomically @@ -52,8 +51,6 @@ impl Context { #[inline(never)] #[naked] pub unsafe fn switch_to(&mut self, next: &mut Context) { - asm!("xchg bx, bx" : : : "memory" : "intel", "volatile"); - /* asm!("fxsave [$0]" : : "r"(self.fx) : "memory" : "intel", "volatile"); self.loadable = true; diff --git a/arch/x86_64/src/device/display.rs b/arch/x86_64/src/device/display.rs new file mode 100644 index 000000000..2ce458cb1 --- /dev/null +++ b/arch/x86_64/src/device/display.rs @@ -0,0 +1,182 @@ +use core::{cmp, slice}; +use ransid::Console; +use spin::Mutex; + +use externs::memset; +use memory::Frame; +use paging::{ActivePageTable, PhysicalAddress, entry}; + +/// The info of the VBE mode +#[derive(Copy, Clone, Default, Debug)] +#[repr(packed)] +pub struct VBEModeInfo { + attributes: u16, + win_a: u8, + win_b: u8, + granularity: u16, + winsize: u16, + segment_a: u16, + segment_b: u16, + winfuncptr: u32, + bytesperscanline: u16, + pub xresolution: u16, + pub yresolution: u16, + xcharsize: u8, + ycharsize: u8, + numberofplanes: u8, + bitsperpixel: u8, + numberofbanks: u8, + memorymodel: u8, + banksize: u8, + numberofimagepages: u8, + unused: u8, + redmasksize: u8, + redfieldposition: u8, + greenmasksize: u8, + greenfieldposition: u8, + bluemasksize: u8, + bluefieldposition: u8, + rsvdmasksize: u8, + rsvdfieldposition: u8, + directcolormodeinfo: u8, + physbaseptr: u32, + offscreenmemoryoffset: u32, + offscreenmemsize: u16, +} + +pub static DISPLAY: Mutex> = Mutex::new(None); +static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font"); + +pub unsafe fn init(active_table: &mut ActivePageTable) { + active_table.identity_map(Frame::containing_address(PhysicalAddress::new(0x5200)), entry::PRESENT | entry::NO_EXECUTE); + + let mode_info = &*(0x5200 as *const VBEModeInfo); + if mode_info.physbaseptr > 0 { + let width = mode_info.xresolution as usize; + let height = mode_info.yresolution as usize; + let start = mode_info.physbaseptr as usize; + let size = width * height; + + { + let start_frame = Frame::containing_address(PhysicalAddress::new(start)); + let end_frame = Frame::containing_address(PhysicalAddress::new(start + size * 4 - 1)); + for frame in Frame::range_inclusive(start_frame, end_frame) { + active_table.identity_map(frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE); + } + } + + memset(start as *mut u8, 0, size * 4); + + *DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(start as *mut u32, size))); + } +} + +pub unsafe fn init_ap(active_table: &mut ActivePageTable) { + active_table.identity_map(Frame::containing_address(PhysicalAddress::new(0x5200)), entry::PRESENT | entry::NO_EXECUTE); + + let mode_info = &*(0x5200 as *const VBEModeInfo); + if mode_info.physbaseptr > 0 { + let width = mode_info.xresolution as usize; + let height = mode_info.yresolution as usize; + let start = mode_info.physbaseptr as usize; + let size = width * height; + + { + let start_frame = Frame::containing_address(PhysicalAddress::new(start)); + let end_frame = Frame::containing_address(PhysicalAddress::new(start + size * 4 - 1)); + for frame in Frame::range_inclusive(start_frame, end_frame) { + active_table.identity_map(frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE); + } + } + } +} + +/// A display +pub struct Display { + pub width: usize, + pub height: usize, + pub data: &'static mut [u32], + console: Console, +} + +impl Display { + fn new(width: usize, height: usize, data: &'static mut [u32]) -> Self { + Display { + width: width, + height: height, + data: data, + console: Console::new(width/8, height/16) + } + } + + /// Draw a rectangle + fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) { + let start_y = cmp::min(self.height - 1, y); + let end_y = cmp::min(self.height, y + h); + + let start_x = cmp::min(self.width - 1, x); + let len = cmp::min(self.width, x + w) - start_x; + + for y in start_y..end_y { + let offset = y * self.width + start_x; + let row = &mut self.data[offset..offset + len]; + for pixel in row.iter_mut() { + *pixel = color; + } + } + } + + /// Draw a character + fn char(&mut self, x: usize, y: usize, character: char, color: u32) { + if x + 8 <= self.width && y + 16 <= self.height { + let mut offset = y * self.width + x; + + let font_i = 16 * (character as usize); + if font_i + 16 <= FONT.len() { + for row in 0..16 { + let row_data = FONT[font_i + row]; + for col in 0..8 { + if (row_data >> (7 - col)) & 1 == 1 { + self.data[offset + col] = color; + } + } + + offset += self.width; + } + } + } + } + + pub fn write(&mut self, bytes: &[u8]) { + self.console.write(bytes); + if self.console.redraw { + self.console.redraw = false; + + for y in 0..self.console.h { + if self.console.changed[y] { + self.console.changed[y] = false; + + for x in 0..self.console.w { + let block = self.console.display[y * self.console.w + x]; + + let (bg, fg) = if self.console.cursor && self.console.y == y && self.console.x == x { + (block.fg.data, block.bg.data) + }else{ + (block.bg.data, block.fg.data) + }; + + self.rect(x * 8, y * 16, 8, 16, bg); + + if block.c != ' ' { + self.char(x * 8, y * 16, block.c, fg); + } + + if block.underlined { + self.rect(x * 8, y * 16 + 14, 8, 1, fg); + } + } + } + } + } + } +} diff --git a/arch/x86_64/src/device/mod.rs b/arch/x86_64/src/device/mod.rs new file mode 100644 index 000000000..9ca32d7a7 --- /dev/null +++ b/arch/x86_64/src/device/mod.rs @@ -0,0 +1,15 @@ +use paging::ActivePageTable; + +pub mod display; +pub mod ps2; +pub mod serial; + +pub unsafe fn init(active_table: &mut ActivePageTable){ + serial::init(); + ps2::init(); + display::init(active_table); +} + +pub unsafe fn init_ap(active_table: &mut ActivePageTable) { + display::init_ap(active_table); +} diff --git a/arch/x86_64/src/device/ps2.rs b/arch/x86_64/src/device/ps2.rs new file mode 100644 index 000000000..38a4f71d5 --- /dev/null +++ b/arch/x86_64/src/device/ps2.rs @@ -0,0 +1,304 @@ +use core::cmp; +use spin::Mutex; + +use io::{Io, Pio, ReadOnly, WriteOnly}; + +pub static PS2: Mutex = Mutex::new(Ps2::new()); + +pub unsafe fn init() { + PS2.lock().init(); +} + +bitflags! { + flags StatusFlags: u8 { + const OUTPUT_FULL = 1, + const INPUT_FULL = 1 << 1, + const SYSTEM = 1 << 2, + const COMMAND = 1 << 3, + // Chipset specific + const KEYBOARD_LOCK = 1 << 4, + // Chipset specific + const SECOND_OUTPUT_FULL = 1 << 5, + const TIME_OUT = 1 << 6, + const PARITY = 1 << 7 + } +} + +bitflags! { + flags ConfigFlags: u8 { + const FIRST_INTERRUPT = 1, + const SECOND_INTERRUPT = 1 << 1, + const POST_PASSED = 1 << 2, + // 1 << 3 should be zero + const CONFIG_RESERVED_3 = 1 << 3, + const FIRST_DISABLED = 1 << 4, + const SECOND_DISABLED = 1 << 5, + const FIRST_TRANSLATE = 1 << 6, + // 1 << 7 should be zero + const CONFIG_RESERVED_7 = 1 << 7, + } +} + +#[repr(u8)] +#[allow(dead_code)] +enum Command { + ReadConfig = 0x20, + WriteConfig = 0x60, + DisableSecond = 0xA7, + EnableSecond = 0xA8, + TestSecond = 0xA9, + TestController = 0xAA, + TestFirst = 0xAB, + Diagnostic = 0xAC, + DisableFirst = 0xAD, + EnableFirst = 0xAE, + WriteSecond = 0xD4 +} + +#[repr(u8)] +#[allow(dead_code)] +enum KeyboardCommand { + EnableReporting = 0xF4, + SetDefaults = 0xF6, + Reset = 0xFF +} + +#[repr(u8)] +#[allow(dead_code)] +enum MouseCommand { + GetDeviceId = 0xF2, + EnableReporting = 0xF4, + SetDefaults = 0xF6, + Reset = 0xFF +} + +#[repr(u8)] +enum MouseCommandData { + SetSampleRate = 0xF3, +} + +bitflags! { + flags MousePacketFlags: u8 { + const LEFT_BUTTON = 1, + const RIGHT_BUTTON = 1 << 1, + const MIDDLE_BUTTON = 1 << 2, + const ALWAYS_ON = 1 << 3, + const X_SIGN = 1 << 4, + const Y_SIGN = 1 << 5, + const X_OVERFLOW = 1 << 6, + const Y_OVERFLOW = 1 << 7 + } +} + +pub struct Ps2 { + data: Pio, + status: ReadOnly>, + command: WriteOnly>, + mouse: [u8; 4], + mouse_i: usize, + mouse_extra: bool, + mouse_x: usize, + mouse_y: usize +} + +impl Ps2 { + const fn new() -> Ps2 { + Ps2 { + data: Pio::new(0x60), + status: ReadOnly::new(Pio::new(0x64)), + command: WriteOnly::new(Pio::new(0x64)), + mouse: [0; 4], + mouse_i: 0, + mouse_extra: false, + mouse_x: 0, + mouse_y: 0 + } + } + + fn status(&mut self) -> StatusFlags { + StatusFlags::from_bits_truncate(self.status.read()) + } + + fn wait_write(&mut self) { + while self.status().contains(INPUT_FULL) {} + } + + fn wait_read(&mut self) { + while ! self.status().contains(OUTPUT_FULL) {} + } + + fn flush_read(&mut self) { + while self.status().contains(OUTPUT_FULL) { + print!("FLUSH: {:X}\n", self.data.read()); + } + } + + fn command(&mut self, command: Command) { + self.wait_write(); + self.command.write(command as u8); + } + + fn read(&mut self) -> u8 { + self.wait_read(); + self.data.read() + } + + fn write(&mut self, data: u8) { + self.wait_write(); + self.data.write(data); + } + + fn config(&mut self) -> ConfigFlags { + self.command(Command::ReadConfig); + ConfigFlags::from_bits_truncate(self.read()) + } + + fn set_config(&mut self, config: ConfigFlags) { + self.command(Command::WriteConfig); + self.write(config.bits()); + } + + fn keyboard_command(&mut self, command: KeyboardCommand) -> u8 { + self.write(command as u8); + self.read() + } + + fn mouse_command(&mut self, command: MouseCommand) -> u8 { + self.command(Command::WriteSecond); + self.write(command as u8); + self.read() + } + + fn mouse_command_data(&mut self, command: MouseCommandData, data: u8) -> u8 { + self.command(Command::WriteSecond); + self.write(command as u8); + self.read(); + self.command(Command::WriteSecond); + self.write(data as u8); + self.read() + } + + fn init(&mut self) { + // Disable devices + self.command(Command::DisableFirst); + self.command(Command::DisableSecond); + + // Clear remaining data + self.flush_read(); + + // Disable clocks, disable interrupts, and disable translate + { + let mut config = self.config(); + config.insert(FIRST_DISABLED); + config.insert(SECOND_DISABLED); + config.remove(FIRST_TRANSLATE); + config.remove(FIRST_INTERRUPT); + config.remove(SECOND_INTERRUPT); + self.set_config(config); + } + + // Perform the self test + self.command(Command::TestController); + let self_test = self.read(); + if self_test != 0x55 { + // TODO: Do reset on failure + print!("PS/2 Self Test Failure: {:X}\n", self_test); + return; + } + + // Enable devices + self.command(Command::EnableFirst); + self.command(Command::EnableSecond); + + // Reset and enable scanning on keyboard + // TODO: Check for ack + print!("KEYBOARD RESET {:X}\n", self.keyboard_command(KeyboardCommand::Reset)); + print!("KEYBOARD RESET RESULT {:X} == 0xAA\n", self.read()); + self.flush_read(); + + // Reset and enable scanning on mouse + // TODO: Check for ack + print!("MOUSE RESET {:X}\n", self.mouse_command(MouseCommand::Reset)); + print!("MOUSE RESET RESULT {:X} == 0xAA\n", self.read()); + print!("MOUSE RESET ID {:X} == 0x00\n", self.read()); + self.flush_read(); + + // Enable extra packet on mouse + print!("SAMPLE 200 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 200)); + print!("SAMPLE 100 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 100)); + print!("SAMPLE 80 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 80)); + print!("GET ID {:X}\n", self.mouse_command(MouseCommand::GetDeviceId)); + let mouse_id = self.read(); + print!("MOUSE ID: {:X} == 0x03\n", mouse_id); + self.mouse_extra = mouse_id == 3; + + // Enable extra buttons, TODO + /* + if self.mouse_extra { + print!("SAMPLE 200 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 200)); + print!("SAMPLE 200 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 200)); + print!("SAMPLE 80 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 80)); + print!("GET ID {:X}\n", self.mouse_command(MouseCommand::GetDeviceId)); + let mouse_id = self.read(); + print!("MOUSE ID: {:X} == 0x04\n", mouse_id); + } + */ + + // Set sample rate to maximum + print!("SAMPLE 200 {:X}\n", self.mouse_command_data(MouseCommandData::SetSampleRate, 200)); + + // Enable data reporting + print!("KEYBOARD ENABLE {:X}\n", self.keyboard_command(KeyboardCommand::EnableReporting)); + print!("MOUSE ENABLE {:X}\n", self.mouse_command(MouseCommand::EnableReporting)); + + // Enable clocks and interrupts + { + let mut config = self.config(); + config.remove(FIRST_DISABLED); + config.remove(SECOND_DISABLED); + config.insert(FIRST_INTERRUPT); + config.insert(SECOND_INTERRUPT); + self.set_config(config); + } + } + + pub fn on_keyboard(&mut self) { + let data = self.data.read(); + print!("KEY {:X}\n", data); + } + + pub fn on_mouse(&mut self) { + self.mouse[self.mouse_i] = self.data.read(); + self.mouse_i += 1; + if self.mouse_i >= self.mouse.len() || (!self.mouse_extra && self.mouse_i >= 3) { + self.mouse_i = 0; + + let flags = MousePacketFlags::from_bits_truncate(self.mouse[0]); + + let mut dx = self.mouse[1] as isize; + if flags.contains(X_SIGN) { + dx -= 0x100; + } + + let mut dy = self.mouse[2] as isize; + if flags.contains(Y_SIGN) { + dy -= 0x100; + } + + let _extra = if self.mouse_extra { + self.mouse[3] + } else { + 0 + }; + + //print!("MOUSE {:?}, {}, {}, {}\n", flags, dx, dy, extra); + + if let Some(ref mut display) = *super::display::DISPLAY.lock() { + self.mouse_x = cmp::max(0, cmp::min(display.width as isize - 1, self.mouse_x as isize + dx)) as usize; + self.mouse_y = cmp::max(0, cmp::min(display.height as isize - 1, self.mouse_y as isize - dy)) as usize; + let offset = self.mouse_y * display.width + self.mouse_x; + display.data[offset as usize] = 0xFF0000; + } + } + } +} diff --git a/arch/x86_64/src/device/serial.rs b/arch/x86_64/src/device/serial.rs new file mode 100644 index 000000000..872fad15e --- /dev/null +++ b/arch/x86_64/src/device/serial.rs @@ -0,0 +1,106 @@ +use core::fmt::{self, Write}; +use spin::Mutex; + +use io::{Io, Pio, ReadOnly}; + +pub static COM1: Mutex = Mutex::new(SerialPort::new(0x3F8)); +pub static COM2: Mutex = Mutex::new(SerialPort::new(0x2F8)); + +pub unsafe fn init() { + COM1.lock().init(); + COM2.lock().init(); +} + +bitflags! { + /// Interrupt enable flags + flags IntEnFlags: u8 { + const RECEIVED = 1, + const SENT = 1 << 1, + const ERRORED = 1 << 2, + const STATUS_CHANGE = 1 << 3, + // 4 to 7 are unused + } +} + +bitflags! { + /// Line status flags + flags LineStsFlags: u8 { + const INPUT_FULL = 1, + // 1 to 4 unknown + const OUTPUT_EMPTY = 1 << 5, + // 6 and 7 unknown + } +} + +#[allow(dead_code)] +pub struct SerialPort { + /// Data register, read to receive, write to send + data: Pio, + /// Interrupt enable + int_en: Pio, + /// FIFO control + fifo_ctrl: Pio, + /// Line control + line_ctrl: Pio, + /// Modem control + modem_ctrl: Pio, + /// Line status + line_sts: ReadOnly>, + /// Modem status + modem_sts: ReadOnly>, +} + +impl SerialPort { + const fn new(base: u16) -> SerialPort { + SerialPort { + data: Pio::new(base), + int_en: Pio::new(base + 1), + fifo_ctrl: Pio::new(base + 2), + line_ctrl: Pio::new(base + 3), + modem_ctrl: Pio::new(base + 4), + line_sts: ReadOnly::new(Pio::new(base + 5)), + modem_sts: ReadOnly::new(Pio::new(base + 6)) + } + } + + fn line_sts(&self) -> LineStsFlags { + LineStsFlags::from_bits_truncate(self.line_sts.read()) + } + + fn write(&mut self, data: u8) { + while ! self.line_sts().contains(OUTPUT_EMPTY) {} + self.data.write(data) + } + + fn init(&mut self) { + //TODO: Cleanup + self.int_en.write(0x00); + self.line_ctrl.write(0x80); + self.data.write(0x03); + self.int_en.write(0x00); + self.line_ctrl.write(0x03); + self.fifo_ctrl.write(0xC7); + self.modem_ctrl.write(0x0B); + self.int_en.write(0x01); + } + + pub fn on_receive(&mut self) { + let data = self.data.read(); + let _ = write!(self, "SERIAL {:X}\n", data); + } +} + +impl Write for SerialPort { + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + for byte in s.bytes() { + self.write(byte); + + if byte == 8 { + self.write(b' '); + self.write(8); + } + } + + Ok(()) + } +} diff --git a/arch/x86_64/src/display.rs b/arch/x86_64/src/display.rs deleted file mode 100644 index cb6acf80c..000000000 --- a/arch/x86_64/src/display.rs +++ /dev/null @@ -1,91 +0,0 @@ -use core::slice; -use spin::Mutex; - -use externs::memset; -use memory::Frame; -use paging::{ActivePageTable, PhysicalAddress, entry}; - -/// The info of the VBE mode -#[derive(Copy, Clone, Default, Debug)] -#[repr(packed)] -pub struct VBEModeInfo { - attributes: u16, - win_a: u8, - win_b: u8, - granularity: u16, - winsize: u16, - segment_a: u16, - segment_b: u16, - winfuncptr: u32, - bytesperscanline: u16, - pub xresolution: u16, - pub yresolution: u16, - xcharsize: u8, - ycharsize: u8, - numberofplanes: u8, - bitsperpixel: u8, - numberofbanks: u8, - memorymodel: u8, - banksize: u8, - numberofimagepages: u8, - unused: u8, - redmasksize: u8, - redfieldposition: u8, - greenmasksize: u8, - greenfieldposition: u8, - bluemasksize: u8, - bluefieldposition: u8, - rsvdmasksize: u8, - rsvdfieldposition: u8, - directcolormodeinfo: u8, - physbaseptr: u32, - offscreenmemoryoffset: u32, - offscreenmemsize: u16, -} - -pub static DISPLAY: Mutex> = Mutex::new(None); - -pub unsafe fn init(active_table: &mut ActivePageTable) { - active_table.identity_map(Frame::containing_address(PhysicalAddress::new(0x5200)), entry::PRESENT | entry::NO_EXECUTE); - - let mode_info = &*(0x5200 as *const VBEModeInfo); - if mode_info.physbaseptr > 0 { - let width = mode_info.xresolution as usize; - let height = mode_info.yresolution as usize; - let start = mode_info.physbaseptr as usize; - let size = width * height; - - { - let start_frame = Frame::containing_address(PhysicalAddress::new(start)); - let end_frame = Frame::containing_address(PhysicalAddress::new(start + size * 4 - 1)); - for frame in Frame::range_inclusive(start_frame, end_frame) { - active_table.identity_map(frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE); - } - } - - for i in 0..size { - let c = ((i * 256)/size) as u32 & 0xFF; - *(start as *mut u32).offset(i as isize) = (c << 16) | (c << 8) | c; - } - //memset(start as *mut u8, 0, size * 4); - - *DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(start as *mut u32, size))); - } -} - -/// A display -pub struct Display { - pub width: usize, - pub height: usize, - pub data: &'static mut [u32], -} - -impl Display { - fn new(width: usize, height: usize, data: &'static mut [u32]) -> Self { - Display { - width: width, - height: height, - data: data, - } - } -} diff --git a/arch/x86_64/src/idt.rs b/arch/x86_64/src/idt.rs index d412b4ba5..75f54f127 100644 --- a/arch/x86_64/src/idt.rs +++ b/arch/x86_64/src/idt.rs @@ -1,7 +1,7 @@ use core::mem; use x86::dtables::{self, DescriptorTablePointer}; -use interrupt::halt; +use interrupt::*; pub static mut IDTR: DescriptorTablePointer = DescriptorTablePointer { limit: 0, @@ -14,69 +14,56 @@ pub unsafe fn init() { IDTR.limit = (IDT.len() * mem::size_of::() - 1) as u16; IDTR.base = IDT.as_ptr() as u64; - for entry in IDT[0..32].iter_mut() { - entry.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT); - entry.set_offset(8, exception as usize); - } - IDT[13].set_offset(8, protection_fault as usize); - IDT[14].set_offset(8, page_fault as usize); - for entry in IDT[32..].iter_mut() { - entry.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT); - entry.set_offset(8, blank as usize); - } - IDT[0x80].set_offset(8, syscall as usize); + // Set up exceptions + IDT[0].set_func(exception::divide_by_zero); + IDT[1].set_func(exception::debug); + IDT[2].set_func(exception::non_maskable); + IDT[3].set_func(exception::breakpoint); + IDT[4].set_func(exception::overflow); + IDT[5].set_func(exception::bound_range); + IDT[6].set_func(exception::invalid_opcode); + IDT[7].set_func(exception::device_not_available); + IDT[8].set_func(exception::double_fault); + // 9 no longer available + IDT[10].set_func(exception::invalid_tss); + IDT[11].set_func(exception::segment_not_present); + IDT[12].set_func(exception::stack_segment); + IDT[13].set_func(exception::protection); + IDT[14].set_func(exception::page); + // 15 reserved + IDT[16].set_func(exception::fpu); + IDT[17].set_func(exception::alignment_check); + IDT[18].set_func(exception::machine_check); + IDT[19].set_func(exception::simd); + IDT[20].set_func(exception::virtualization); + // 21 through 29 reserved + IDT[30].set_func(exception::security); + // 31 reserved + + // Set up IRQs + IDT[32].set_func(irq::pit); + IDT[33].set_func(irq::keyboard); + IDT[34].set_func(irq::cascade); + IDT[35].set_func(irq::com2); + IDT[36].set_func(irq::com1); + IDT[37].set_func(irq::lpt2); + IDT[38].set_func(irq::floppy); + IDT[39].set_func(irq::lpt1); + IDT[40].set_func(irq::rtc); + IDT[41].set_func(irq::pci1); + IDT[42].set_func(irq::pci2); + IDT[43].set_func(irq::pci3); + IDT[44].set_func(irq::mouse); + IDT[45].set_func(irq::fpu); + IDT[46].set_func(irq::ata1); + IDT[47].set_func(irq::ata2); + + // Set syscall function + IDT[0x80].set_func(syscall::syscall); dtables::lidt(&IDTR); } -interrupt!(blank, { - -}); - -interrupt!(exception, { - println!("EXCEPTION"); - loop { - halt(); - } -}); - -interrupt_error!(protection_fault, { - println!("PROTECTION FAULT"); - loop { - halt(); - } -}); - -interrupt_error!(page_fault, { - println!("PAGE FAULT"); - loop { - halt(); - } -}); - -#[naked] -pub unsafe extern fn syscall() { - extern { - fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize; - } - - let a; - let b; - let c; - let d; - let e; - let f; - asm!("" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f) - : : : "intel", "volatile"); - - let a = syscall(a, b, c, d, e, f); - - asm!("" : : "{rax}"(a) : : "intel", "volatile"); - - // Pop scratch registers, error code, and return - asm!("iretq" : : : : "intel", "volatile"); -} - bitflags! { pub flags IdtFlags: u8 { const IDT_PRESENT = 1 << 7, @@ -142,4 +129,10 @@ impl IdtEntry { self.offsetm = (base >> 16) as u16; self.offseth = (base >> 32) as u32; } + + // A function to set the offset more easily + pub fn set_func(&mut self, func: unsafe extern fn()) { + self.set_flags(IDT_PRESENT | IDT_RING_0 | IDT_INTERRUPT); + self.set_offset(8, func as usize); + } } diff --git a/arch/x86_64/src/interrupt.rs b/arch/x86_64/src/interrupt.rs deleted file mode 100644 index d6d3cf839..000000000 --- a/arch/x86_64/src/interrupt.rs +++ /dev/null @@ -1,118 +0,0 @@ -//! Interrupt instructions - -/// Clear interrupts -#[inline(always)] -pub unsafe fn disable() { - asm!("cli" : : : : "intel", "volatile"); -} - -/// Set interrupts -#[inline(always)] -pub unsafe fn enable() { - asm!("sti" : : : : "intel", "volatile"); -} - -/// Set interrupts and halt -#[inline(always)] -pub unsafe fn enable_and_halt() { - asm!("sti - hlt" - : : : : "intel", "volatile"); -} - -/// Halt instruction -#[inline(always)] -pub unsafe fn halt() { - asm!("hlt" : : : : "intel", "volatile"); -} - -/// Pause instruction -/// Safe because it is similar to a NOP, and has no memory effects -#[inline(always)] -pub fn pause() { - unsafe { asm!("pause" : : : : "intel", "volatile"); } -} - -/// Get a stack trace -//TODO: Check for stack being mapped before dereferencing -#[inline(never)] -pub unsafe fn stack_trace() { - let mut rbp: usize; - asm!("xchg bx, bx" : "={rbp}"(rbp) : : : "intel", "volatile"); - - println!("TRACE: {:>016X}", rbp); - //Maximum 64 frames - for _frame in 0..64 { - let rip = *(rbp as *const usize).offset(1); - println!(" {:>016X}: {:>016X}", rbp, rip); - if rip == 0 { - break; - } - rbp = *(rbp as *const usize); - } -} - -/// x86 External Interrupts (1-16). -pub static EXCEPTIONS: [Descriptor; 21] = [ - Descriptor::new("Division error", Kind::Fault), - Descriptor::new("Debug trap", Kind::Trap), - Descriptor::new("Unmaskable interrupt", Kind::Unmaskable), - Descriptor::new("Breakpoint", Kind::Trap), - Descriptor::new("Overflow", Kind::Trap), - Descriptor::new("Out of bound", Kind::Fault), - Descriptor::new("Invalid opcode", Kind::Fault), - Descriptor::new("Device unavailable", Kind::Fault), - Descriptor::new("Double fault", Kind::Fault), - Descriptor::new("Coprocessor segment overrun", Kind::Fault), - Descriptor::new("Invalid TSS", Kind::Fault), - Descriptor::new("Segment not present", Kind::Fault), - Descriptor::new("Stack-segment fault", Kind::Fault), - Descriptor::new("General protection", Kind::Fault), - Descriptor::new("Page fault", Kind::Fault), - Descriptor::new("Reserved", Kind::Reserved), - Descriptor::new("x87 FPU", Kind::Fault), - Descriptor::new("Unaligned memory access", Kind::Fault), - Descriptor::new("Machine check", Kind::Abort), - Descriptor::new("SIMD floating-point", Kind::Fault), - Descriptor::new("Virtualization violation", Kind::Fault), -]; - -/// An interrupt description. -#[derive(Debug, Copy, Clone)] -pub struct Descriptor { - /// The description of this interrupt. - pub desc: &'static str, - /// The interrupt type. - pub kind: Kind, -} - -impl Descriptor { - /// Create a new interrupt description. - pub const fn new(desc: &'static str, kind: Kind) -> Descriptor { - Descriptor { - desc: desc, - kind: kind, - } - } -} - -/// The interrupt kind. -#[derive(Debug, Copy, Clone)] -pub enum Kind { - /// A fault. - /// - /// This can have multiple sources, but is often a result of a program error of some sort. - Fault, - /// A trap. - /// - /// These are often for debugging purposes. - Trap, - /// A deliberate abort. - Abort, - /// An unmaskable interrupt. - /// - /// This is a forced interrupt which need to be handled immediately. - Unmaskable, - /// Reserved or deprecated. - Reserved, -} diff --git a/arch/x86_64/src/interrupt/exception.rs b/arch/x86_64/src/interrupt/exception.rs new file mode 100644 index 000000000..18fc47c52 --- /dev/null +++ b/arch/x86_64/src/interrupt/exception.rs @@ -0,0 +1,97 @@ +use super::halt; + +interrupt!(divide_by_zero, { + print!("Divide by zero fault\n"); + loop { halt(); } +}); + +interrupt!(debug, { + print!("Debug trap\n"); +}); + +interrupt!(non_maskable, { + print!("Non-maskable interrupt\n"); +}); + +interrupt!(breakpoint, { + print!("Breakpoint trap\n"); +}); + +interrupt!(overflow, { + print!("Overflow trap\n"); +}); + +interrupt!(bound_range, { + print!("Bound range exceeded fault\n"); + loop { halt(); } +}); + +interrupt!(invalid_opcode, { + print!("Invalid opcode fault\n"); + loop { halt(); } +}); + +interrupt!(device_not_available, { + print!("Device not available fault\n"); + loop { halt(); } +}); + +interrupt_error!(double_fault, { + print!("Double fault\n"); + loop { halt(); } +}); + +interrupt_error!(invalid_tss, { + print!("Invalid TSS fault\n"); + loop { halt(); } +}); + +interrupt_error!(segment_not_present, { + print!("Segment not present fault\n"); + loop { halt(); } +}); + +interrupt_error!(stack_segment, { + print!("Stack segment fault\n"); + loop { halt(); } +}); + +interrupt_error!(protection, { + print!("Protection fault\n"); + loop { halt(); } +}); + +interrupt_error!(page, { + print!("Page fault\n"); + loop { halt(); } +}); + +interrupt!(fpu, { + print!("FPU floating point fault\n"); + loop { halt(); } +}); + +interrupt_error!(alignment_check, { + print!("Alignment check fault\n"); + loop { halt(); } +}); + +interrupt!(machine_check, { + print!("Machine check fault\n"); + loop { halt(); } +}); + +interrupt!(simd, { + print!("SIMD floating point fault\n"); + loop { halt(); } +}); + +interrupt!(virtualization, { + print!("Virtualization fault\n"); + loop { halt(); } +}); + +interrupt_error!(security, { + print!("Security exception\n"); + loop { halt(); } +}); diff --git a/arch/x86_64/src/interrupt/irq.rs b/arch/x86_64/src/interrupt/irq.rs new file mode 100644 index 000000000..acec106b4 --- /dev/null +++ b/arch/x86_64/src/interrupt/irq.rs @@ -0,0 +1,99 @@ +use x86::io; + +use device::ps2::PS2; +use device::serial::{COM1, COM2}; + +#[inline(always)] +unsafe fn master_ack() { + io::outb(0x20, 0x20); +} + +#[inline(always)] +unsafe fn slave_ack() { + io::outb(0xA0, 0x20); + master_ack(); +} + +interrupt!(pit, { + io::outb(0x43, 0); + let low = io::inb(0x40); + let high = io::inb(0x40); + let count = (high as u16) << 8 | (low as u16); + let _missed = 5370 - count; + master_ack(); +}); + +interrupt!(keyboard, { + PS2.lock().on_keyboard(); + master_ack(); +}); + +interrupt!(cascade, { + print!("CASCADE\n"); + master_ack(); +}); + +interrupt!(com2, { + COM2.lock().on_receive(); + master_ack(); +}); + +interrupt!(com1, { + COM1.lock().on_receive(); + master_ack(); +}); + +interrupt!(lpt2, { + print!("LPT2\n"); + master_ack(); +}); + +interrupt!(floppy, { + print!("FLOPPY\n"); + master_ack(); +}); + +interrupt!(lpt1, { + print!("LPT1\n"); + master_ack(); +}); + +interrupt!(rtc, { + print!("RTC\n"); + slave_ack(); +}); + +interrupt!(pci1, { + print!("PCI1\n"); + slave_ack(); +}); + +interrupt!(pci2, { + print!("PCI2\n"); + slave_ack(); +}); + +interrupt!(pci3, { + print!("PCI3\n"); + slave_ack(); +}); + +interrupt!(mouse, { + PS2.lock().on_mouse(); + slave_ack(); +}); + +interrupt!(fpu, { + print!("FPU\n"); + slave_ack(); +}); + +interrupt!(ata1, { + print!("ATA1\n"); + slave_ack(); +}); + +interrupt!(ata2, { + print!("ATA2\n"); + slave_ack(); +}); diff --git a/arch/x86_64/src/interrupt/mod.rs b/arch/x86_64/src/interrupt/mod.rs new file mode 100644 index 000000000..bde817811 --- /dev/null +++ b/arch/x86_64/src/interrupt/mod.rs @@ -0,0 +1,57 @@ +//! Interrupt instructions + +pub mod exception; +pub mod irq; +pub mod syscall; + +/// Clear interrupts +#[inline(always)] +pub unsafe fn disable() { + asm!("cli" : : : : "intel", "volatile"); +} + +/// Set interrupts +#[inline(always)] +pub unsafe fn enable() { + asm!("sti" : : : : "intel", "volatile"); +} + +/// Set interrupts and halt +#[inline(always)] +pub unsafe fn enable_and_halt() { + asm!("sti + hlt" + : : : : "intel", "volatile"); +} + +/// Halt instruction +#[inline(always)] +pub unsafe fn halt() { + asm!("hlt" : : : : "intel", "volatile"); +} + +/// Pause instruction +/// Safe because it is similar to a NOP, and has no memory effects +#[inline(always)] +pub fn pause() { + unsafe { asm!("pause" : : : : "intel", "volatile"); } +} + +/// Get a stack trace +//TODO: Check for stack being mapped before dereferencing +#[inline(never)] +pub unsafe fn stack_trace() { + let mut rbp: usize; + asm!("xchg bx, bx" : "={rbp}"(rbp) : : : "intel", "volatile"); + + println!("TRACE: {:>016X}", rbp); + //Maximum 64 frames + for _frame in 0..64 { + let rip = *(rbp as *const usize).offset(1); + println!(" {:>016X}: {:>016X}", rbp, rip); + if rip == 0 { + break; + } + rbp = *(rbp as *const usize); + } +} diff --git a/arch/x86_64/src/interrupt/syscall.rs b/arch/x86_64/src/interrupt/syscall.rs new file mode 100644 index 000000000..45eae6a7e --- /dev/null +++ b/arch/x86_64/src/interrupt/syscall.rs @@ -0,0 +1,22 @@ +#[naked] +pub unsafe extern fn syscall() { + extern { + fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize; + } + + let a; + let b; + let c; + let d; + let e; + let f; + asm!("" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f) + : : : "intel", "volatile"); + + let a = syscall(a, b, c, d, e, f); + + asm!("" : : "{rax}"(a) : : "intel", "volatile"); + + // Pop scratch registers, error code, and return + asm!("iretq" : : : : "intel", "volatile"); +} diff --git a/arch/x86_64/src/io/io.rs b/arch/x86_64/src/io/io.rs index a2d5fc614..fb866b581 100644 --- a/arch/x86_64/src/io/io.rs +++ b/arch/x86_64/src/io/io.rs @@ -7,10 +7,12 @@ pub trait Io { fn read(&self) -> Self::Value; fn write(&mut self, value: Self::Value); + #[inline(always)] fn readf(&self, flags: Self::Value) -> bool { (self.read() & flags) as Self::Value == flags } + #[inline(always)] fn writef(&mut self, flags: Self::Value, value: bool) { let tmp: Self::Value = match value { true => self.read() | flags, @@ -25,16 +27,18 @@ pub struct ReadOnly { } impl ReadOnly { - pub fn new(inner: I) -> ReadOnly { + pub const fn new(inner: I) -> ReadOnly { ReadOnly { inner: inner } } + #[inline(always)] pub fn read(&self) -> I::Value { self.inner.read() } + #[inline(always)] pub fn readf(&self, flags: I::Value) -> bool { self.inner.readf(flags) } @@ -45,16 +49,18 @@ pub struct WriteOnly { } impl WriteOnly { - pub fn new(inner: I) -> WriteOnly { + pub const fn new(inner: I) -> WriteOnly { WriteOnly { inner: inner } } + #[inline(always)] pub fn write(&mut self, value: I::Value) { self.inner.write(value) } + #[inline(always)] pub fn writef(&mut self, flags: I::Value, value: bool) { self.inner.writef(flags, value) } diff --git a/arch/x86_64/src/io/pio.rs b/arch/x86_64/src/io/pio.rs index 52febcb59..562c1c1e1 100644 --- a/arch/x86_64/src/io/pio.rs +++ b/arch/x86_64/src/io/pio.rs @@ -1,4 +1,5 @@ use core::marker::PhantomData; +use x86::io; use super::io::Io; @@ -24,19 +25,15 @@ impl Io for Pio { type Value = u8; /// Read + #[inline(always)] fn read(&self) -> u8 { - let value: u8; - unsafe { - asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - value + unsafe { io::inb(self.port) } } /// Write + #[inline(always)] fn write(&mut self, value: u8) { - unsafe { - asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); - } + unsafe { io::outb(self.port, value) } } } @@ -45,19 +42,15 @@ impl Io for Pio { type Value = u16; /// Read + #[inline(always)] fn read(&self) -> u16 { - let value: u16; - unsafe { - asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - value + unsafe { io::inw(self.port) } } /// Write + #[inline(always)] fn write(&mut self, value: u16) { - unsafe { - asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); - } + unsafe { io::outw(self.port, value) } } } @@ -66,18 +59,14 @@ impl Io for Pio { type Value = u32; /// Read + #[inline(always)] fn read(&self) -> u32 { - let value: u32; - unsafe { - asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); - } - value + unsafe { io::inl(self.port) } } /// Write + #[inline(always)] fn write(&mut self, value: u32) { - unsafe { - asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); - } + unsafe { io::outl(self.port, value) } } } diff --git a/arch/x86_64/src/lib.rs b/arch/x86_64/src/lib.rs index 8faf3e72a..ca9d99599 100644 --- a/arch/x86_64/src/lib.rs +++ b/arch/x86_64/src/lib.rs @@ -4,6 +4,7 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(core_intrinsics)] +#![feature(drop_types_in_const)] #![feature(lang_items)] #![feature(naked_functions)] #![feature(thread_local)] @@ -13,6 +14,7 @@ extern crate hole_list_allocator as allocator; #[macro_use] extern crate bitflags; +extern crate ransid; extern crate spin; extern crate x86; @@ -21,7 +23,7 @@ extern crate x86; macro_rules! print { ($($arg:tt)*) => ({ use core::fmt::Write; - let _ = write!($crate::serial::SerialConsole, $($arg)*); + let _ = write!($crate::console::CONSOLE.lock(), $($arg)*); }); } @@ -44,8 +46,7 @@ macro_rules! interrupt { } // Push scratch registers - asm!("xchg bx, bx - push rax + asm!("push rax push rcx push rdx push rdi @@ -86,8 +87,7 @@ macro_rules! interrupt_error { } // Push scratch registers - asm!("xchg bx, bx - push rax + asm!("push rax push rcx push rdx push rdi @@ -121,11 +121,14 @@ macro_rules! interrupt_error { /// ACPI table parsing pub mod acpi; +/// Console handling +pub mod console; + /// Context switching pub mod context; -/// Display handling -pub mod display; +/// Devices +pub mod device; /// Memcpy, memmove, etc. pub mod externs; @@ -151,8 +154,5 @@ pub mod paging; /// Panic pub mod panic; -/// Serial driver and print! support -pub mod serial; - /// Initialization and start function pub mod start; diff --git a/arch/x86_64/src/serial.rs b/arch/x86_64/src/serial.rs deleted file mode 100644 index 22030846f..000000000 --- a/arch/x86_64/src/serial.rs +++ /dev/null @@ -1,45 +0,0 @@ -use core::fmt; -use spin::Mutex; - -use super::io::{Io, Pio}; - -static SERIAL_PORT: Mutex = Mutex::new(SerialPort::new()); - -struct SerialPort { - status: Pio, - data: Pio -} - -impl SerialPort { - pub const fn new() -> SerialPort { - SerialPort { - status: Pio::new(0x3F8 + 5), - data: Pio::new(0x3F8) - } - } - - pub fn write(&mut self, bytes: &[u8]) { - for byte in bytes.iter() { - while !self.status.readf(0x20) {} - self.data.write(*byte); - - if *byte == 8 { - while !self.status.readf(0x20) {} - self.data.write(0x20); - - while !self.status.readf(0x20) {} - self.data.write(8); - } - } - } -} - -pub struct SerialConsole; - -impl fmt::Write for SerialConsole { - fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - SERIAL_PORT.lock().write(s.as_bytes()); - - Ok(()) - } -} diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs index 8009e37dd..94b648772 100644 --- a/arch/x86_64/src/start.rs +++ b/arch/x86_64/src/start.rs @@ -7,7 +7,7 @@ use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE use acpi; use allocator::{HEAP_START, HEAP_SIZE}; -use display; +use device; use externs::memset; use gdt; use idt; @@ -92,17 +92,11 @@ pub unsafe extern fn kstart() -> ! { assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE); } - // Initialize display - display::init(&mut active_table); - // Reset AP variables AP_COUNT.store(0, Ordering::SeqCst); BSP_READY.store(false, Ordering::SeqCst); HEAP_FRAME.store(0, Ordering::SeqCst); - // Read ACPI tables, starts APs - acpi::init(&mut active_table); - // Map heap { let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START)); @@ -129,6 +123,12 @@ pub unsafe extern fn kstart() -> ! { } } + // Initialize devices + device::init(&mut active_table); + + // Read ACPI tables, starts APs + acpi::init(&mut active_table); + BSP_READY.store(true, Ordering::SeqCst); } @@ -184,6 +184,9 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { entry.set(frame, entry::PRESENT | entry::WRITABLE); } } + + // Init devices for AP + device::init_ap(&mut active_table); } let ap_number = AP_COUNT.fetch_add(1, Ordering::SeqCst); diff --git a/kernel/console.rs b/kernel/console.rs deleted file mode 100644 index d2dfeca98..000000000 --- a/kernel/console.rs +++ /dev/null @@ -1,15 +0,0 @@ -use ransid::Console; -use spin::{Once, Mutex, MutexGuard}; - -/// Console -static CONSOLE: Once> = Once::new(); - -/// Initialize console, called if needed -fn init_console() -> Mutex { - Mutex::new(Console::new(0, 0)) -} - -/// Get the global console -pub fn console() -> MutexGuard<'static, Console> { - CONSOLE.call_once(init_console).lock() -} diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index f563c051c..a706b2fc2 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -80,7 +80,7 @@ impl ContextList { } context.arch.set_stack(stack.as_ptr() as usize + offset); context.kstack = Some(stack); - print!("{}", format!("{}: {:X}\n", context.id, func as usize)); + println!("{}: {:X}", context.id, func as usize); } Ok(context_lock) } @@ -151,13 +151,11 @@ pub unsafe fn switch() { return; } - unsafe { - (&mut *from_ptr).running = false; - (&mut *to_ptr).running = true; - CONTEXT_ID.store((&mut *to_ptr).id, Ordering::SeqCst); - - (&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch); - } + (&mut *from_ptr).running = false; + (&mut *to_ptr).running = true; + CONTEXT_ID.store((&mut *to_ptr).id, Ordering::SeqCst); + + (&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch); } /// A context, which identifies either a process or a thread diff --git a/kernel/lib.rs b/kernel/lib.rs index cc0326571..8291035b8 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -97,12 +97,8 @@ extern crate collections; #[macro_use] extern crate bitflags; extern crate goblin; -extern crate ransid; extern crate spin; -/// Console -pub mod console; - /// Context management pub mod context; @@ -134,9 +130,10 @@ pub extern fn context_test() { pub extern fn kmain() { context::init(); - print!("{}", format!("BSP: {:?}\n", syscall::getpid())); + let pid = syscall::getpid(); + println!("BSP: {:?}", pid); - if let Ok(context_lock) = context::contexts_mut().spawn(context_test) { + if let Ok(_context_lock) = context::contexts_mut().spawn(context_test) { print!("Spawned context\n"); } @@ -153,7 +150,8 @@ pub extern fn kmain() { pub extern fn kmain_ap(id: usize) { context::init(); - print!("{}", format!("AP {}: {:?}\n", id, syscall::getpid())); + let pid = syscall::getpid(); + println!("AP {}: {:?}", id, pid); loop { unsafe { interrupt::enable_and_halt() } diff --git a/res/unifont.font b/res/unifont.font new file mode 100644 index 000000000..01173fc6c Binary files /dev/null and b/res/unifont.font differ