Improve efficiency of kernel console
This commit is contained in:
parent
04f6e7b558
commit
0ccfd2125a
|
@ -13,7 +13,7 @@ extern crate linked_list_allocator;
|
||||||
extern crate lazy_static;
|
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_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! {
|
lazy_static! {
|
||||||
static ref HEAP: Mutex<Heap> = Mutex::new(unsafe {
|
static ref HEAP: Mutex<Heap> = Mutex::new(unsafe {
|
||||||
|
|
|
@ -5,7 +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 = "*"
|
ransid = { git = "https://github.com/redox-os/ransid.git", branch = "new_api" }
|
||||||
spin = "*"
|
spin = "*"
|
||||||
|
|
||||||
[dependencies.x86]
|
[dependencies.x86]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::fmt::{self, Write};
|
use core::fmt::{self, Write};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
use device::display::DISPLAY;
|
use device::display;
|
||||||
use device::serial::COM1;
|
use device::serial::COM1;
|
||||||
|
|
||||||
pub static CONSOLE: Mutex<Console> = Mutex::new(Console::new());
|
pub static CONSOLE: Mutex<Console> = Mutex::new(Console::new());
|
||||||
|
@ -16,8 +16,13 @@ impl Console {
|
||||||
|
|
||||||
impl Write for Console {
|
impl Write for Console {
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||||
if let Some(ref mut display) = *DISPLAY.lock() {
|
if let Some(ref mut console) = *display::CONSOLE.lock() {
|
||||||
display.write(s.as_bytes());
|
if let Some(ref mut display) = *display::DISPLAY.lock() {
|
||||||
|
console.write(s.as_bytes(), |event| {
|
||||||
|
display.event(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
COM1.lock().write_str(s)
|
COM1.lock().write_str(s)
|
||||||
|
|
|
@ -1,11 +1,46 @@
|
||||||
use core::{cmp, slice};
|
use core::{cmp, slice};
|
||||||
use ransid::Console;
|
use ransid::{Console, Event};
|
||||||
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};
|
||||||
|
|
||||||
|
#[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
|
/// The info of the VBE mode
|
||||||
#[derive(Copy, Clone, Default, Debug)]
|
#[derive(Copy, Clone, Default, Debug)]
|
||||||
#[repr(packed)]
|
#[repr(packed)]
|
||||||
|
@ -44,7 +79,10 @@ pub struct VBEModeInfo {
|
||||||
offscreenmemsize: u16,
|
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");
|
static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font");
|
||||||
|
|
||||||
pub unsafe fn init(active_table: &mut ActivePageTable) {
|
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 {
|
if mode_info.physbaseptr > 0 {
|
||||||
let width = mode_info.xresolution as usize;
|
let width = mode_info.xresolution as usize;
|
||||||
let height = mode_info.yresolution 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 size = width * height;
|
||||||
|
|
||||||
{
|
{
|
||||||
let start_frame = Frame::containing_address(PhysicalAddress::new(start));
|
let start_frame = Frame::containing_address(PhysicalAddress::new(onscreen));
|
||||||
let end_frame = Frame::containing_address(PhysicalAddress::new(start + size * 4 - 1));
|
let end_frame = Frame::containing_address(PhysicalAddress::new(onscreen + size * 4 - 1));
|
||||||
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
||||||
active_table.identity_map(frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
|
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
|
/// A display
|
||||||
pub struct Display {
|
pub struct Display<'a> {
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
pub data: &'static mut [u32],
|
pub data: &'a mut [u32],
|
||||||
console: Console,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
impl<'a> Display<'a> {
|
||||||
fn new(width: usize, height: usize, data: &'static mut [u32]) -> Self {
|
fn new<'data>(width: usize, height: usize, data: &'data mut [u32]) -> Display<'data> {
|
||||||
Display {
|
Display {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
data: data,
|
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 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);
|
||||||
|
|
||||||
let start_x = cmp::min(self.width - 1, x);
|
let mut start_x = cmp::min(self.width - 1, x);
|
||||||
let len = cmp::min(self.width, x + w) - start_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 {
|
for y in start_y..end_y {
|
||||||
let offset = y * self.width + start_x;
|
let offset = y * self.width + start_x;
|
||||||
let row = &mut self.data[offset..offset + len];
|
unsafe {
|
||||||
for pixel in row.iter_mut() {
|
fast_set(data_ptr.offset(offset as isize), color, len);
|
||||||
*pixel = color;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,35 +185,34 @@ impl Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(&mut self, bytes: &[u8]) {
|
/// Scroll display
|
||||||
self.console.write(bytes);
|
pub fn scroll(&mut self, rows: usize, color: u32) {
|
||||||
if self.console.redraw {
|
let data = (color as u64) << 32 | color as u64;
|
||||||
self.console.redraw = false;
|
|
||||||
|
|
||||||
for y in 0..self.console.h {
|
let width = self.width/2;
|
||||||
if self.console.changed[y] {
|
let height = self.height;
|
||||||
self.console.changed[y] = false;
|
if rows > 0 && rows < height {
|
||||||
|
let off1 = rows * width;
|
||||||
for x in 0..self.console.w {
|
let off2 = height * width - off1;
|
||||||
let block = self.console.display[y * self.console.w + x];
|
unsafe {
|
||||||
|
let data_ptr = self.data.as_mut_ptr() as *mut u64;
|
||||||
let (bg, fg) = if self.console.cursor && self.console.y == y && self.console.x == x {
|
fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2);
|
||||||
(block.fg.data, block.bg.data)
|
fast_set64(data_ptr.offset(off2 as isize), data, off1);
|
||||||
}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 {
|
/// Handle ransid event
|
||||||
self.rect(x * 8, y * 16 + 14, 8, 1, fg);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
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 ransid;
|
||||||
|
|
|
@ -127,7 +127,7 @@ pub unsafe extern fn kstart() -> ! {
|
||||||
device::init(&mut active_table);
|
device::init(&mut active_table);
|
||||||
|
|
||||||
// Read ACPI tables, starts APs
|
// Read ACPI tables, starts APs
|
||||||
acpi::init(&mut active_table);
|
// acpi::init(&mut active_table);
|
||||||
|
|
||||||
BSP_READY.store(true, Ordering::SeqCst);
|
BSP_READY.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,7 @@ pub extern fn kmain() {
|
||||||
let pid = syscall::getpid();
|
let pid = syscall::getpid();
|
||||||
println!("BSP: {:?}", pid);
|
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");
|
||||||
}
|
}
|
||||||
|
@ -141,6 +142,8 @@ pub extern fn kmain() {
|
||||||
unsafe { context::switch(); }
|
unsafe { context::switch(); }
|
||||||
|
|
||||||
print!("Main halt\n");
|
print!("Main halt\n");
|
||||||
|
*/
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
unsafe { interrupt::enable_and_halt(); }
|
unsafe { interrupt::enable_and_halt(); }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue