Draw on VESA for console using ransid
This commit is contained in:
		
							parent
							
								
									53c71d9183
								
							
						
					
					
						commit
						d7d61f82af
					
				
					 10 changed files with 87 additions and 52 deletions
				
			
		|  | @ -9,7 +9,6 @@ crate-type = ["staticlib"] | |||
| 
 | ||||
| [dependencies] | ||||
| bitflags = "*" | ||||
| ransid = "*" | ||||
| spin = "*" | ||||
| 
 | ||||
| [dependencies.goblin] | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ version = "0.1.0" | |||
| [dependencies] | ||||
| bitflags = "*" | ||||
| hole_list_allocator = { path = "../../alloc/hole_list_allocator"} | ||||
| ransid = "*" | ||||
| spin = "*" | ||||
| 
 | ||||
| [dependencies.x86] | ||||
|  |  | |||
							
								
								
									
										26
									
								
								arch/x86_64/src/console.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/x86_64/src/console.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| use core::fmt::{self, Write}; | ||||
| use spin::Mutex; | ||||
| 
 | ||||
| use device::display::DISPLAY; | ||||
| use device::serial::COM1; | ||||
| 
 | ||||
| pub static CONSOLE: Mutex<Console> = 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) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +1,8 @@ | |||
| use core::{cmp, slice}; | ||||
| use ransid::Console; | ||||
| use spin::Mutex; | ||||
| 
 | ||||
| use externs::memset; | ||||
| use memory::Frame; | ||||
| use paging::{ActivePageTable, PhysicalAddress, entry}; | ||||
| 
 | ||||
|  | @ -63,11 +65,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) { | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         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);
 | ||||
|         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))); | ||||
|     } | ||||
|  | @ -98,6 +96,7 @@ pub struct Display { | |||
|     pub width: usize, | ||||
|     pub height: usize, | ||||
|     pub data: &'static mut [u32], | ||||
|     console: Console, | ||||
| } | ||||
| 
 | ||||
| impl Display { | ||||
|  | @ -106,11 +105,12 @@ impl Display { | |||
|             width: width, | ||||
|             height: height, | ||||
|             data: data, | ||||
|             console: Console::new(width/8, height/16) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Draw a rectangle
 | ||||
|     pub fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) { | ||||
|     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); | ||||
| 
 | ||||
|  | @ -127,7 +127,7 @@ impl Display { | |||
|     } | ||||
| 
 | ||||
|     /// Draw a character
 | ||||
|     pub fn char(&mut self, x: usize, y: usize, character: char, color: u32) { | ||||
|     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; | ||||
| 
 | ||||
|  | @ -146,4 +146,37 @@ impl Display { | |||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -104,11 +104,3 @@ impl Write for SerialPort { | |||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct SerialConsole; | ||||
| 
 | ||||
| impl Write for SerialConsole { | ||||
|     fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { | ||||
|         COM1.lock().write_str(s) | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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::device::serial::SerialConsole, $($arg)*); | ||||
|         let _ = write!($crate::console::CONSOLE.lock(), $($arg)*); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
|  | @ -119,6 +121,9 @@ macro_rules! interrupt_error { | |||
| /// ACPI table parsing
 | ||||
| pub mod acpi; | ||||
| 
 | ||||
| /// Console handling
 | ||||
| pub mod console; | ||||
| 
 | ||||
| /// Context switching
 | ||||
| pub mod context; | ||||
| 
 | ||||
|  |  | |||
|  | @ -92,17 +92,11 @@ pub unsafe extern fn kstart() -> ! { | |||
|             assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE); | ||||
|         } | ||||
| 
 | ||||
|         // Initialize devices
 | ||||
|         device::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); | ||||
|     } | ||||
| 
 | ||||
|  | @ -165,9 +165,6 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { | |||
|             assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE); | ||||
|         } | ||||
| 
 | ||||
|         // Init devices for AP
 | ||||
|         device::init_ap(&mut active_table); | ||||
| 
 | ||||
|         // Map heap
 | ||||
|         { | ||||
|             let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START)); | ||||
|  | @ -187,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); | ||||
|  | @ -195,9 +195,5 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { | |||
|         interrupt::pause(); | ||||
|     } | ||||
| 
 | ||||
|     if let Some(ref mut display) = *device::display::DISPLAY.lock() { | ||||
|         display.char(0, ap_number * 16, (ap_number as u8 + b'0') as char, 0xFF00); | ||||
|     } | ||||
| 
 | ||||
|     kmain_ap(ap_number); | ||||
| } | ||||
|  |  | |||
|  | @ -1,15 +0,0 @@ | |||
| use ransid::Console; | ||||
| use spin::{Once, Mutex, MutexGuard}; | ||||
| 
 | ||||
| /// Console
 | ||||
| static CONSOLE: Once<Mutex<Console>> = Once::new(); | ||||
| 
 | ||||
| /// Initialize console, called if needed
 | ||||
| fn init_console() -> Mutex<Console> { | ||||
|     Mutex::new(Console::new(0, 0)) | ||||
| } | ||||
| 
 | ||||
| /// Get the global console
 | ||||
| pub fn console() -> MutexGuard<'static, Console> { | ||||
|     CONSOLE.call_once(init_console).lock() | ||||
| } | ||||
|  | @ -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) | ||||
|     } | ||||
|  |  | |||
|  | @ -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,7 +130,8 @@ 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) { | ||||
|         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() } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller