From 0e7f27d25dca35cc6c6323dd93479336f4d36ffd Mon Sep 17 00:00:00 2001 From: Matt Taylor Date: Tue, 16 Jul 2019 08:20:53 +0100 Subject: [PATCH] Use volatile accesses in VGA code and make font dependency optional (#67) --- Cargo.toml | 3 ++- src/printer/mod.rs | 3 +++ src/printer/vga_320x200.rs | 25 ++++++++++++------------- src/printer/vga_text_80x25.rs | 24 ++++++++++++------------ 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d4dd8227..f7fe9fef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,13 +18,14 @@ fixedvec = "0.2.3" version = "0.2.4" default-features = false features = ["unicode"] +optional = true [build-dependencies] llvm-tools = "0.1" [features] default = [] -vga_320x200 = [] +vga_320x200 = ["font8x8"] recursive_page_table = [] map_physical_memory = [] diff --git a/src/printer/mod.rs b/src/printer/mod.rs index b4ecd7b3..726bb765 100644 --- a/src/printer/mod.rs +++ b/src/printer/mod.rs @@ -4,5 +4,8 @@ pub use self::vga_text_80x25::*; #[cfg(feature = "vga_320x200")] pub use self::vga_320x200::*; +#[cfg(feature = "vga_320x200")] mod vga_320x200; + +#[cfg(not(feature = "vga_320x200"))] mod vga_text_80x25; diff --git a/src/printer/vga_320x200.rs b/src/printer/vga_320x200.rs index 22b35fce..fb1e36af 100644 --- a/src/printer/vga_320x200.rs +++ b/src/printer/vga_320x200.rs @@ -1,30 +1,28 @@ use core::fmt::{Result, Write}; -use core::slice; use core::sync::atomic::{AtomicUsize, Ordering}; const VGA_BUFFER: *mut u8 = 0xa0000 as *mut _; const SCREEN_WIDTH: usize = 320; const SCREEN_HEIGHT: usize = 200; -pub static X_POS: AtomicUsize = AtomicUsize::new(1); // must not be 0 so that we don't have a .bss section -pub static Y_POS: AtomicUsize = AtomicUsize::new(1); // must not be 0 so that we don't have a .bss section +// must not be 0 so that we don't have a .bss section +pub static X_POS: AtomicUsize = AtomicUsize::new(1); +pub static Y_POS: AtomicUsize = AtomicUsize::new(1); pub struct Printer; impl Printer { pub fn clear_screen(&mut self) { - let vga_buffer = Self::vga_buffer(); - for byte in vga_buffer { - *byte = 0x00; + for i in 0..(SCREEN_WIDTH * SCREEN_HEIGHT) { + unsafe { + VGA_BUFFER.offset(i as isize).write_volatile(0); + } } + X_POS.store(0, Ordering::SeqCst); Y_POS.store(0, Ordering::SeqCst); } - fn vga_buffer() -> &'static mut [u8] { - unsafe { slice::from_raw_parts_mut(VGA_BUFFER, SCREEN_WIDTH * SCREEN_HEIGHT) } - } - fn newline(&mut self) { let y_pos = Y_POS.fetch_add(8, Ordering::SeqCst); X_POS.store(0, Ordering::SeqCst); @@ -41,8 +39,6 @@ impl Printer { return; } - let vga_buffer = Self::vga_buffer(); - let x_pos = X_POS.fetch_add(8, Ordering::SeqCst); let y_pos = Y_POS.load(Ordering::SeqCst); @@ -57,7 +53,10 @@ impl Printer { continue; } let color = 0xf; - vga_buffer[(y_pos + y) * SCREEN_WIDTH + x_pos + x] = color; + let idx = (y_pos + y) * SCREEN_WIDTH + x_pos + x; + unsafe { + VGA_BUFFER.offset(idx as isize).write_volatile(color); + } } } } diff --git a/src/printer/vga_text_80x25.rs b/src/printer/vga_text_80x25.rs index 1202054a..fd689987 100644 --- a/src/printer/vga_text_80x25.rs +++ b/src/printer/vga_text_80x25.rs @@ -1,35 +1,35 @@ use core::fmt::{Result, Write}; -use core::slice; use core::sync::atomic::{AtomicUsize, Ordering}; const VGA_BUFFER: *mut u8 = 0xb8000 as *mut _; const SCREEN_SIZE: usize = 80 * 25; +// must not be 0 so that we don't have a .bss section pub static CURRENT_OFFSET: AtomicUsize = AtomicUsize::new(160); pub struct Printer; impl Printer { pub fn clear_screen(&mut self) { - let vga_buffer = Self::vga_buffer(); - for byte in vga_buffer { - *byte = 0; + for i in 0..SCREEN_SIZE { + unsafe { + VGA_BUFFER.offset(i as isize).write_volatile(0); + } } - CURRENT_OFFSET.store(0, Ordering::Relaxed); - } - fn vga_buffer() -> &'static mut [u8] { - unsafe { slice::from_raw_parts_mut(VGA_BUFFER, SCREEN_SIZE * 2) } + CURRENT_OFFSET.store(0, Ordering::Relaxed); } } impl Write for Printer { fn write_str(&mut self, s: &str) -> Result { - let vga_buffer = Self::vga_buffer(); for byte in s.bytes() { - let index = CURRENT_OFFSET.fetch_add(2, Ordering::Relaxed); - vga_buffer[index] = byte; - vga_buffer[index + 1] = 0x4f; + let index = CURRENT_OFFSET.fetch_add(2, Ordering::Relaxed) as isize; + + unsafe { + VGA_BUFFER.offset(index).write_volatile(byte); + VGA_BUFFER.offset(index + 1).write_volatile(0x4f); + } } Ok(())