Draw on VESA for console using ransid
This commit is contained in:
parent
53c71d9183
commit
d7d61f82af
|
@ -9,7 +9,6 @@ crate-type = ["staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "*"
|
bitflags = "*"
|
||||||
ransid = "*"
|
|
||||||
spin = "*"
|
spin = "*"
|
||||||
|
|
||||||
[dependencies.goblin]
|
[dependencies.goblin]
|
||||||
|
|
|
@ -5,6 +5,7 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "*"
|
bitflags = "*"
|
||||||
hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
|
hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
|
||||||
|
ransid = "*"
|
||||||
spin = "*"
|
spin = "*"
|
||||||
|
|
||||||
[dependencies.x86]
|
[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 core::{cmp, slice};
|
||||||
|
use ransid::Console;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
|
use externs::memset;
|
||||||
use memory::Frame;
|
use memory::Frame;
|
||||||
use paging::{ActivePageTable, PhysicalAddress, entry};
|
use paging::{ActivePageTable, PhysicalAddress, entry};
|
||||||
|
|
||||||
|
@ -63,11 +65,7 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..size {
|
memset(start as *mut u8, 0, size * 4);
|
||||||
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)));
|
*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 width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
pub data: &'static mut [u32],
|
pub data: &'static mut [u32],
|
||||||
|
console: Console,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
|
@ -106,11 +105,12 @@ impl Display {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
data: data,
|
data: data,
|
||||||
|
console: Console::new(width/8, height/16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a rectangle
|
/// 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 start_y = cmp::min(self.height - 1, y);
|
||||||
let end_y = cmp::min(self.height, y + h);
|
let end_y = cmp::min(self.height, y + h);
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ impl Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a character
|
/// 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 {
|
if x + 8 <= self.width && y + 16 <= self.height {
|
||||||
let mut offset = y * self.width + x;
|
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(())
|
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(concat_idents)]
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
#![feature(drop_types_in_const)]
|
||||||
#![feature(lang_items)]
|
#![feature(lang_items)]
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(thread_local)]
|
#![feature(thread_local)]
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
extern crate hole_list_allocator as allocator;
|
extern crate hole_list_allocator as allocator;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
extern crate ransid;
|
||||||
extern crate spin;
|
extern crate spin;
|
||||||
extern crate x86;
|
extern crate x86;
|
||||||
|
|
||||||
|
@ -21,7 +23,7 @@ extern crate x86;
|
||||||
macro_rules! print {
|
macro_rules! print {
|
||||||
($($arg:tt)*) => ({
|
($($arg:tt)*) => ({
|
||||||
use core::fmt::Write;
|
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
|
/// ACPI table parsing
|
||||||
pub mod acpi;
|
pub mod acpi;
|
||||||
|
|
||||||
|
/// Console handling
|
||||||
|
pub mod console;
|
||||||
|
|
||||||
/// Context switching
|
/// Context switching
|
||||||
pub mod context;
|
pub mod context;
|
||||||
|
|
||||||
|
|
|
@ -92,17 +92,11 @@ pub unsafe extern fn kstart() -> ! {
|
||||||
assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE);
|
assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize devices
|
|
||||||
device::init(&mut active_table);
|
|
||||||
|
|
||||||
// Reset AP variables
|
// Reset AP variables
|
||||||
AP_COUNT.store(0, Ordering::SeqCst);
|
AP_COUNT.store(0, Ordering::SeqCst);
|
||||||
BSP_READY.store(false, Ordering::SeqCst);
|
BSP_READY.store(false, Ordering::SeqCst);
|
||||||
HEAP_FRAME.store(0, Ordering::SeqCst);
|
HEAP_FRAME.store(0, Ordering::SeqCst);
|
||||||
|
|
||||||
// Read ACPI tables, starts APs
|
|
||||||
acpi::init(&mut active_table);
|
|
||||||
|
|
||||||
// Map heap
|
// Map heap
|
||||||
{
|
{
|
||||||
let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START));
|
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);
|
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);
|
assert_eq!(TDATA_TEST_NONZERO, 0xFFFFFFFFFFFFFFFE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init devices for AP
|
|
||||||
device::init_ap(&mut active_table);
|
|
||||||
|
|
||||||
// Map heap
|
// Map heap
|
||||||
{
|
{
|
||||||
let heap_start_page = Page::containing_address(VirtualAddress::new(HEAP_START));
|
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);
|
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);
|
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();
|
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);
|
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.arch.set_stack(stack.as_ptr() as usize + offset);
|
||||||
context.kstack = Some(stack);
|
context.kstack = Some(stack);
|
||||||
print!("{}", format!("{}: {:X}\n", context.id, func as usize));
|
println!("{}: {:X}", context.id, func as usize);
|
||||||
}
|
}
|
||||||
Ok(context_lock)
|
Ok(context_lock)
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,12 +97,8 @@ extern crate collections;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
extern crate goblin;
|
extern crate goblin;
|
||||||
extern crate ransid;
|
|
||||||
extern crate spin;
|
extern crate spin;
|
||||||
|
|
||||||
/// Console
|
|
||||||
pub mod console;
|
|
||||||
|
|
||||||
/// Context management
|
/// Context management
|
||||||
pub mod context;
|
pub mod context;
|
||||||
|
|
||||||
|
@ -134,7 +130,8 @@ pub extern fn context_test() {
|
||||||
pub extern fn kmain() {
|
pub extern fn kmain() {
|
||||||
context::init();
|
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");
|
print!("Spawned context\n");
|
||||||
|
@ -153,7 +150,8 @@ pub extern fn kmain() {
|
||||||
pub extern fn kmain_ap(id: usize) {
|
pub extern fn kmain_ap(id: usize) {
|
||||||
context::init();
|
context::init();
|
||||||
|
|
||||||
print!("{}", format!("AP {}: {:?}\n", id, syscall::getpid()));
|
let pid = syscall::getpid();
|
||||||
|
println!("AP {}: {:?}", id, pid);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
unsafe { interrupt::enable_and_halt() }
|
unsafe { interrupt::enable_and_halt() }
|
||||||
|
|
Loading…
Reference in a new issue