Improve efficiency of kernel console

This commit is contained in:
Jeremy Soller 2016-09-01 14:39:45 -06:00
parent 04f6e7b558
commit 0ccfd2125a
7 changed files with 98 additions and 52 deletions

View file

@ -13,7 +13,7 @@ extern crate linked_list_allocator;
extern crate lazy_static;
pub const HEAP_START: usize = 0xffff_ff00_0000_0000; // Put at end of memory, below the recursive page mapping
pub const HEAP_SIZE: usize = 16 * 1024 * 1024; // 16 MB
pub const HEAP_SIZE: usize = 64 * 1024 * 1024; // 128 MB
lazy_static! {
static ref HEAP: Mutex<Heap> = Mutex::new(unsafe {

View file

@ -5,7 +5,7 @@ version = "0.1.0"
[dependencies]
bitflags = "*"
hole_list_allocator = { path = "../../alloc/hole_list_allocator"}
ransid = "*"
ransid = { git = "https://github.com/redox-os/ransid.git", branch = "new_api" }
spin = "*"
[dependencies.x86]

View file

@ -1,7 +1,7 @@
use core::fmt::{self, Write};
use spin::Mutex;
use device::display::DISPLAY;
use device::display;
use device::serial::COM1;
pub static CONSOLE: Mutex<Console> = Mutex::new(Console::new());
@ -16,8 +16,13 @@ impl 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());
if let Some(ref mut console) = *display::CONSOLE.lock() {
if let Some(ref mut display) = *display::DISPLAY.lock() {
console.write(s.as_bytes(), |event| {
display.event(event);
});
}
Ok(())
} else {
COM1.lock().write_str(s)

View file

@ -1,11 +1,46 @@
use core::{cmp, slice};
use ransid::Console;
use ransid::{Console, Event};
use spin::Mutex;
use externs::memset;
use memory::Frame;
use paging::{ActivePageTable, PhysicalAddress, entry};
#[cfg(target_arch = "x86_64")]
#[allow(unused_assignments)]
#[inline(always)]
unsafe fn fast_copy64(dst: *mut u64, src: *const u64, len: usize) {
asm!("cld
rep movsq"
:
: "{rdi}"(dst as usize), "{rsi}"(src as usize), "{rcx}"(len)
: "cc", "memory"
: "intel", "volatile");
}
#[cfg(target_arch = "x86_64")]
#[allow(unused_assignments)]
#[inline(always)]
unsafe fn fast_set(dst: *mut u32, src: u32, len: usize) {
asm!("cld
rep stosd"
:
: "{rdi}"(dst as usize), "{eax}"(src), "{rcx}"(len)
: "cc", "memory"
: "intel", "volatile");
}
#[cfg(target_arch = "x86_64")]
#[allow(unused_assignments)]
#[inline(always)]
unsafe fn fast_set64(dst: *mut u64, src: u64, len: usize) {
asm!("cld
rep stosq"
:
: "{rdi}"(dst as usize), "{rax}"(src), "{rcx}"(len)
: "cc", "memory"
: "intel", "volatile");
}
/// The info of the VBE mode
#[derive(Copy, Clone, Default, Debug)]
#[repr(packed)]
@ -44,7 +79,10 @@ pub struct VBEModeInfo {
offscreenmemsize: u16,
}
pub static DISPLAY: Mutex<Option<Display>> = Mutex::new(None);
pub static CONSOLE: Mutex<Option<Console>> = Mutex::new(None);
pub static DISPLAY: Mutex<Option<Display<'static>>> = Mutex::new(None);
static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font");
pub unsafe fn init(active_table: &mut ActivePageTable) {
@ -54,20 +92,21 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
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 onscreen = 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));
let start_frame = Frame::containing_address(PhysicalAddress::new(onscreen));
let end_frame = Frame::containing_address(PhysicalAddress::new(onscreen + 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);
fast_set64(onscreen as *mut u64, 0, size/2);
*DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(start as *mut u32, size)));
*CONSOLE.lock() = Some(Console::new(width/8, height/16));
*DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(onscreen as *mut u32, size)));
}
}
@ -92,20 +131,18 @@ pub unsafe fn init_ap(active_table: &mut ActivePageTable) {
}
/// A display
pub struct Display {
pub struct Display<'a> {
pub width: usize,
pub height: usize,
pub data: &'static mut [u32],
console: Console,
pub data: &'a mut [u32],
}
impl Display {
fn new(width: usize, height: usize, data: &'static mut [u32]) -> Self {
impl<'a> Display<'a> {
fn new<'data>(width: usize, height: usize, data: &'data mut [u32]) -> Display<'data> {
Display {
width: width,
height: height,
data: data,
console: Console::new(width/8, height/16)
}
}
@ -114,14 +151,15 @@ impl Display {
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;
let mut start_x = cmp::min(self.width - 1, x);
let mut len = cmp::min(self.width, x + w) - start_x;
let width = self.width;
let data_ptr = self.data.as_mut_ptr();
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;
unsafe {
fast_set(data_ptr.offset(offset as isize), color, len);
}
}
}
@ -147,35 +185,34 @@ impl Display {
}
}
pub fn write(&mut self, bytes: &[u8]) {
self.console.write(bytes);
if self.console.redraw {
self.console.redraw = false;
/// Scroll display
pub fn scroll(&mut self, rows: usize, color: u32) {
let data = (color as u64) << 32 | color as u64;
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);
let width = self.width/2;
let height = self.height;
if rows > 0 && rows < height {
let off1 = rows * width;
let off2 = height * width - off1;
unsafe {
let data_ptr = self.data.as_mut_ptr() as *mut u64;
fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2);
fast_set64(data_ptr.offset(off2 as isize), data, off1);
}
}
}
/// Handle ransid event
pub fn event(&mut self, event: Event) {
match event {
Event::Char { x, y, c, color, .. } => {
self.char(x * 8, y * 16, c, color.data);
},
Event::Rect { x, y, w, h, color } => {
self.rect(x * 8, y * 16, w * 8, h * 16, color.data);
},
Event::Scroll { rows, color } => {
self.scroll(rows * 16, color.data);
}
}
}

View file

@ -12,6 +12,7 @@
#![no_std]
extern crate hole_list_allocator as allocator;
#[macro_use]
extern crate bitflags;
extern crate ransid;

View file

@ -127,7 +127,7 @@ pub unsafe extern fn kstart() -> ! {
device::init(&mut active_table);
// Read ACPI tables, starts APs
acpi::init(&mut active_table);
// acpi::init(&mut active_table);
BSP_READY.store(true, Ordering::SeqCst);
}

View file

@ -133,6 +133,7 @@ pub extern fn kmain() {
let pid = syscall::getpid();
println!("BSP: {:?}", pid);
/*
if let Ok(_context_lock) = context::contexts_mut().spawn(context_test) {
print!("Spawned context\n");
}
@ -141,6 +142,8 @@ pub extern fn kmain() {
unsafe { context::switch(); }
print!("Main halt\n");
*/
loop {
unsafe { interrupt::enable_and_halt(); }
}