From 234fb64999f6beacc2102ffc72f8fd8438f24481 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 24 Aug 2016 20:10:55 -0600 Subject: [PATCH] Add display --- Makefile | 3 +- arch/x86_64/src/display.rs | 91 ++++++++++++++++++++++++++++++++++++++ arch/x86_64/src/lib.rs | 3 ++ arch/x86_64/src/start.rs | 4 ++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 arch/x86_64/src/display.rs diff --git a/Makefile b/Makefile index e01020b..0e0057c 100644 --- a/Makefile +++ b/Makefile @@ -11,9 +11,10 @@ ifeq ($(UNAME),Darwin) endif QEMUFLAGS+=-smp 4 -machine q35 -QEMUFLAGS+=-serial mon:stdio -nographic +QEMUFLAGS+=-serial mon:stdio QEMUFLAGS+=-d guest_errors #,int,pcall +#-nographic #-device intel-iommu diff --git a/arch/x86_64/src/display.rs b/arch/x86_64/src/display.rs new file mode 100644 index 0000000..cb6acf8 --- /dev/null +++ b/arch/x86_64/src/display.rs @@ -0,0 +1,91 @@ +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/lib.rs b/arch/x86_64/src/lib.rs index 2bb0cb9..8faf3e7 100644 --- a/arch/x86_64/src/lib.rs +++ b/arch/x86_64/src/lib.rs @@ -124,6 +124,9 @@ pub mod acpi; /// Context switching pub mod context; +/// Display handling +pub mod display; + /// Memcpy, memmove, etc. pub mod externs; diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs index bb35b84..1b80e93 100644 --- a/arch/x86_64/src/start.rs +++ b/arch/x86_64/src/start.rs @@ -7,6 +7,7 @@ use core::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, AtomicUsize, ATOMIC_USIZE use acpi; use allocator::{HEAP_START, HEAP_SIZE}; +use display; use externs::memset; use gdt; use idt; @@ -90,6 +91,9 @@ 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);