Make display::TextDisplay::get_size be failable and implement a better power on test method
This commit is contained in:
parent
fc11d393ff
commit
6d3c77056c
8 changed files with 83 additions and 58 deletions
|
@ -69,15 +69,23 @@ impl crate::display::TextDisplay for FramebufferInfo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(&self) -> (u32, u32) { (self.width, self.height) }
|
fn get_size(&self) -> Result<(u32, u32), crate::Error<'static>> {
|
||||||
|
Ok((self.width, self.height))
|
||||||
|
}
|
||||||
|
|
||||||
fn scroll(&self) {
|
fn scroll(&self) {
|
||||||
let mut addr = self.address as usize;
|
let mut addr = self.address as usize;
|
||||||
addr += self.pitch as usize;
|
addr += self.pitch as usize;
|
||||||
unsafe { core::ptr::copy(addr as *const u8, self.address as usize as *mut u8, (self.pitch*(self.height-1)) as usize); }
|
unsafe {
|
||||||
|
core::ptr::copy(
|
||||||
|
addr as *const u8,
|
||||||
|
self.address as usize as *mut u8,
|
||||||
|
(self.pitch * (self.height - 1)) as usize,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for x in 0..self.width {
|
for x in 0..self.width {
|
||||||
self.write_char((x, self.height-1), b' ', crate::display::COLOR_DEFAULT);
|
self.write_char((x, self.height - 1), b' ', crate::display::COLOR_DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,20 +26,21 @@ pub trait TextDisplay: core::fmt::Write {
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Result<(), crate::Error<'static>>;
|
) -> Result<(), crate::Error<'static>>;
|
||||||
/// Gets the size of the screen.
|
/// Gets the size of the screen.
|
||||||
fn get_size(&self) -> (u32, u32);
|
fn get_size(&self) -> Result<(u32, u32), crate::Error<'static>>;
|
||||||
/// Scroll the screen up one character. Clear the bottom row.
|
/// Scroll the screen up one character. Clear the bottom row.
|
||||||
fn scroll(&self);
|
fn scroll(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dyn TextDisplay + '_ {
|
impl dyn TextDisplay + '_ {
|
||||||
/// Clears the screen.
|
/// Clears the screen.
|
||||||
pub fn clear_screen(&self, color: Color) {
|
pub fn clear_screen(&self, color: Color) -> Result<(), crate::Error<'static>> {
|
||||||
let (width, height) = self.get_size();
|
let (width, height) = self.get_size()?;
|
||||||
for x in 0..width {
|
for x in 0..width {
|
||||||
for y in 0..height {
|
for y in 0..height {
|
||||||
self.write_char((x, y), b' ', color).unwrap();
|
self.write_char((x, y), b' ', color).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a &str to the screen.
|
/// Writes a &str to the screen.
|
||||||
|
@ -49,7 +50,7 @@ impl dyn TextDisplay + '_ {
|
||||||
str: &str,
|
str: &str,
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Result<(u32, u32), crate::Error<'static>> {
|
) -> Result<(u32, u32), crate::Error<'static>> {
|
||||||
let (width, height) = self.get_size();
|
let (width, height) = self.get_size()?;
|
||||||
let (mut x, mut y) = pos;
|
let (mut x, mut y) = pos;
|
||||||
for char in str.as_bytes() {
|
for char in str.as_bytes() {
|
||||||
if y >= height {
|
if y >= height {
|
||||||
|
@ -76,7 +77,7 @@ impl dyn TextDisplay + '_ {
|
||||||
str: &[u8],
|
str: &[u8],
|
||||||
color: Color,
|
color: Color,
|
||||||
) -> Result<(u32, u32), crate::Error<'static>> {
|
) -> Result<(u32, u32), crate::Error<'static>> {
|
||||||
let (width, _) = self.get_size();
|
let (width, _) = self.get_size()?;
|
||||||
let (mut x, mut y) = pos;
|
let (mut x, mut y) = pos;
|
||||||
for char in str {
|
for char in str {
|
||||||
self.write_char((x, y), *char, color)?;
|
self.write_char((x, y), *char, color)?;
|
||||||
|
@ -98,7 +99,9 @@ impl dyn TextDisplay + '_ {
|
||||||
pub struct NoneTextDisplay {}
|
pub struct NoneTextDisplay {}
|
||||||
|
|
||||||
impl TextDisplay for NoneTextDisplay {
|
impl TextDisplay for NoneTextDisplay {
|
||||||
fn get_size(&self) -> (u32, u32) { (1, 1) }
|
fn get_size(&self) -> Result<(u32, u32), crate::Error<'static>> {
|
||||||
|
Ok((1,1))
|
||||||
|
}
|
||||||
fn write_char(&self, _: (u32, u32), _: u8, _: Color) -> Result<(), crate::Error<'static>> {
|
fn write_char(&self, _: (u32, u32), _: u8, _: Color) -> Result<(), crate::Error<'static>> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,11 @@
|
||||||
#![allow(unexpected_cfgs)]
|
#![allow(unexpected_cfgs)]
|
||||||
#![allow(static_mut_refs)]
|
#![allow(static_mut_refs)]
|
||||||
|
|
||||||
use core::alloc::{Allocator, Layout};
|
|
||||||
|
|
||||||
use crate::display::{COLOR_DEFAULT, NoneTextDisplay};
|
use crate::display::{COLOR_DEFAULT, NoneTextDisplay};
|
||||||
use crate::output::*;
|
use crate::output::*;
|
||||||
|
|
||||||
use aphrodite_proc_macros::*;
|
use aphrodite_proc_macros::*;
|
||||||
|
|
||||||
const MEM_TEST_SIZES: [usize; 8] = [1, 2, 4, 8, 16, 32, 64, 128];
|
|
||||||
|
|
||||||
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files
|
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files
|
||||||
/// eventually call this.
|
/// eventually call this.
|
||||||
#[kernel_item(IndepBootEntry)]
|
#[kernel_item(IndepBootEntry)]
|
||||||
|
@ -24,7 +20,6 @@ fn indep_boot_entry(
|
||||||
crate::arch::Architecture::ExampleDummy,
|
crate::arch::Architecture::ExampleDummy,
|
||||||
"Somehow the kernel successfully booted into IndepBootEntry with a dummy architecture"
|
"Somehow the kernel successfully booted into IndepBootEntry with a dummy architecture"
|
||||||
);
|
);
|
||||||
crate::arch::output::sdebugsln("IndepBootEntry called");
|
|
||||||
|
|
||||||
let display = display.unwrap_or(&NoneTextDisplay {});
|
let display = display.unwrap_or(&NoneTextDisplay {});
|
||||||
|
|
||||||
|
@ -33,48 +28,8 @@ fn indep_boot_entry(
|
||||||
|
|
||||||
let mem_map = BI.memory_map.unwrap();
|
let mem_map = BI.memory_map.unwrap();
|
||||||
crate::mem::MemMapAllocInit(mem_map).unwrap();
|
crate::mem::MemMapAllocInit(mem_map).unwrap();
|
||||||
let allocator = crate::mem::MemMapAlloc().unwrap();
|
|
||||||
|
|
||||||
tdebugsln("Testing allocator...", display).unwrap();
|
crate::power_on_tests::run(display);
|
||||||
|
|
||||||
for size in MEM_TEST_SIZES {
|
|
||||||
tdebugs("Number of allocations: ", display).unwrap();
|
|
||||||
tdebugbnpln(
|
|
||||||
&crate::u64_as_u8_slice(allocator.number_of_allocations()),
|
|
||||||
display,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
tdebugs("Allocating ", display).unwrap();
|
|
||||||
tdebugbnp(&crate::usize_as_u8_slice(size), display).unwrap();
|
|
||||||
tdebugsnpln(" byte(s) of memory...", display).unwrap();
|
|
||||||
|
|
||||||
let allocation = allocator.allocate(Layout::from_size_align(size, 1).unwrap());
|
|
||||||
if let Err(_) = allocation {
|
|
||||||
terrors("Failed to allocate: ", display).unwrap();
|
|
||||||
unsafe { crate::mem::LAST_MEMMAP_ERR.unwrap_err().display_np(display) }
|
|
||||||
panic!("Allocation failure");
|
|
||||||
} else if let Ok(ptr) = allocation {
|
|
||||||
tdebugs("Successfully allocated! Address is ", display).unwrap();
|
|
||||||
tdebugbnp(&crate::usize_as_u8_slice(ptr.addr().get()), display).unwrap();
|
|
||||||
tdebugsnpln(".", display).unwrap();
|
|
||||||
tdebugsln("", display).unwrap();
|
|
||||||
tdebugsln("Deallocating memory...", display).unwrap();
|
|
||||||
unsafe {
|
|
||||||
allocator.deallocate(
|
|
||||||
ptr.as_non_null_ptr(),
|
|
||||||
Layout::from_size_align(size, 1).unwrap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if let Err(err) = unsafe { crate::mem::LAST_MEMMAP_ERR } {
|
|
||||||
terrors("Failed to deallocate: ", display).unwrap();
|
|
||||||
err.display_np(display);
|
|
||||||
panic!("Deallocation failure");
|
|
||||||
} else {
|
|
||||||
tdebugsln("Successfully deallocated!", display).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tdebugsln("", display).unwrap();
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ static mut ALLOCATOR_MEMMAP: MaybeUninit<MemoryMap> = MaybeUninit::uninit();
|
||||||
static mut ALLOCATOR_INITALIZED: bool = false;
|
static mut ALLOCATOR_INITALIZED: bool = false;
|
||||||
|
|
||||||
#[kernel_item(MemMapAlloc)]
|
#[kernel_item(MemMapAlloc)]
|
||||||
fn get_allocator() -> Option<&'static MemoryMapAlloc<'static>> {
|
pub fn get_allocator() -> Option<&'static MemoryMapAlloc<'static>> {
|
||||||
if unsafe { ALLOCATOR_INITALIZED } {
|
if unsafe { ALLOCATOR_INITALIZED } {
|
||||||
#[allow(static_mut_refs)]
|
#[allow(static_mut_refs)]
|
||||||
return Some(unsafe { ALLOCATOR.assume_init_ref() });
|
return Some(unsafe { ALLOCATOR.assume_init_ref() });
|
||||||
|
|
|
@ -38,6 +38,8 @@ pub mod psfont;
|
||||||
mod traits;
|
mod traits;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
pub(crate) mod power_on_tests;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub(crate) mod cfg;
|
pub(crate) mod cfg;
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ macro_rules! message_funcs {
|
||||||
|
|
||||||
/// Outputs a message u8 to the terminal.
|
/// Outputs a message u8 to the terminal.
|
||||||
pub fn [< t $func_name u >](s: u8, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
pub fn [< t $func_name u >](s: u8, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||||
let (width, _) = info.get_size();
|
let (width, _) = info.get_size()?;
|
||||||
unsafe {
|
unsafe {
|
||||||
if cfg!($level = "false") {
|
if cfg!($level = "false") {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -127,7 +127,7 @@ macro_rules! message_funcs {
|
||||||
|
|
||||||
/// Outputs a message u8 to the terminal without a prefix.
|
/// Outputs a message u8 to the terminal without a prefix.
|
||||||
pub fn [< t $func_name unp >](s: u8, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
pub fn [< t $func_name unp >](s: u8, info: &dyn crate::display::TextDisplay) -> Result<(), crate::Error<'static>> {
|
||||||
let (width, _) = info.get_size();
|
let (width, _) = info.get_size()?;
|
||||||
unsafe {
|
unsafe {
|
||||||
if cfg!($level = "false") {
|
if cfg!($level = "false") {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
50
kernel/src/kernel/power_on_tests/memmapalloc.rs
Normal file
50
kernel/src/kernel/power_on_tests/memmapalloc.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use crate::{display::TextDisplay, output::*};
|
||||||
|
|
||||||
|
use core::alloc::{Allocator, Layout};
|
||||||
|
|
||||||
|
const MEM_TEST_SIZES: [usize; 8] = [1, 2, 4, 8, 16, 32, 64, 128];
|
||||||
|
|
||||||
|
pub fn run(display: &dyn TextDisplay) {
|
||||||
|
let allocator = crate::mem::get_allocator().unwrap();
|
||||||
|
tdebugsln("Testing allocator...", display).unwrap();
|
||||||
|
|
||||||
|
for size in MEM_TEST_SIZES {
|
||||||
|
tdebugs("Number of allocations: ", display).unwrap();
|
||||||
|
tdebugbnpln(
|
||||||
|
&crate::u64_as_u8_slice(allocator.number_of_allocations()),
|
||||||
|
display,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
tdebugs("Allocating ", display).unwrap();
|
||||||
|
tdebugbnp(&crate::usize_as_u8_slice(size), display).unwrap();
|
||||||
|
tdebugsnpln(" byte(s) of memory...", display).unwrap();
|
||||||
|
|
||||||
|
let allocation = allocator.allocate(Layout::from_size_align(size, 1).unwrap());
|
||||||
|
if let Err(_) = allocation {
|
||||||
|
terrors("Failed to allocate: ", display).unwrap();
|
||||||
|
unsafe { crate::mem::LAST_MEMMAP_ERR.unwrap_err().display_np(display) }
|
||||||
|
panic!("Allocator test failure");
|
||||||
|
} else if let Ok(ptr) = allocation {
|
||||||
|
tdebugs("Successfully allocated! Address is ", display).unwrap();
|
||||||
|
tdebugbnp(&crate::usize_as_u8_slice(ptr.addr().get()), display).unwrap();
|
||||||
|
tdebugsnpln(".", display).unwrap();
|
||||||
|
tdebugsln("", display).unwrap();
|
||||||
|
tdebugsln("Deallocating memory...", display).unwrap();
|
||||||
|
unsafe {
|
||||||
|
allocator.deallocate(
|
||||||
|
ptr.as_non_null_ptr(),
|
||||||
|
Layout::from_size_align(size, 1).unwrap(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if let Err(err) = unsafe { crate::mem::LAST_MEMMAP_ERR } {
|
||||||
|
terrors("Failed to deallocate: ", display).unwrap();
|
||||||
|
err.display_np(display);
|
||||||
|
panic!("Deallocation failure");
|
||||||
|
} else {
|
||||||
|
tdebugsln("Successfully deallocated!", display).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tdebugsln("", display).unwrap();
|
||||||
|
}
|
||||||
|
}
|
7
kernel/src/kernel/power_on_tests/mod.rs
Normal file
7
kernel/src/kernel/power_on_tests/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
use crate::display::TextDisplay;
|
||||||
|
|
||||||
|
mod memmapalloc;
|
||||||
|
|
||||||
|
pub fn run(display: &dyn TextDisplay) {
|
||||||
|
memmapalloc::run(display);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue