diff --git a/assets/cozette.otb b/assets/cozette.otb new file mode 100644 index 0000000..1ad13b9 Binary files /dev/null and b/assets/cozette.otb differ diff --git a/assets/fontplate.png b/assets/fontplate.png index 7120f47..b66dcba 100644 Binary files a/assets/fontplate.png and b/assets/fontplate.png differ diff --git a/assets/fontplate.py b/assets/fontplate.py new file mode 100755 index 0000000..a7b5f1e --- /dev/null +++ b/assets/fontplate.py @@ -0,0 +1,42 @@ +#!/bin/python + +from fontTools.ttLib import TTFont +from PIL import Image, ImageDraw, ImageFont + +COLUMNS, ROWS = 32, 42 +CHAR_WIDTH, CHAR_HEIGHT = 6, 13 + +font_path = "assets/cozette.otb" +canvas = Image.new("1", (COLUMNS * CHAR_WIDTH, ROWS * CHAR_HEIGHT), color=0) + +try: + font = ImageFont.truetype(font_path, 13) + ttfont = TTFont(font_path) + cmap = ttfont.getBestCmap() + if cmap is None: + raise Exception() +except Exception: + print("The font can't be loaded") + exit() + +ranges = [ + range(ROWS * COLUMNS), +] + +for range in ranges: + for i in range: + pos = i + x = (pos % COLUMNS) * CHAR_WIDTH + y = (pos // COLUMNS) * CHAR_HEIGHT + + char_to_draw = chr(i) + if i < 32 or i not in cmap: + char_to_draw = chr(0xFFFD) + + cell = Image.new("1", (CHAR_WIDTH, CHAR_HEIGHT), color=0) + cell_draw = ImageDraw.Draw(cell) + + cell_draw.text((0, 0), char_to_draw, font=font, fill=1) + canvas.paste(cell, (x, y)) + +canvas.save("assets/fontplate.png") diff --git a/crates/kernel-macros/src/image.rs b/crates/kernel-macros/src/image.rs index c4a6391..8dfc80b 100644 --- a/crates/kernel-macros/src/image.rs +++ b/crates/kernel-macros/src/image.rs @@ -34,7 +34,7 @@ fn to_format(img: ImageBuffer, Vec>, width: usize, height: usize) - output } -fn path_to_image(path: &str) -> (Vec, String, usize, usize) { +fn path_to_image(path: &str) -> (Vec, usize, usize) { let img = match image::open(path) { Ok(img) => img.to_luma8(), Err(e) => panic!("failed to open image {}: {}", path, e), @@ -45,14 +45,7 @@ fn path_to_image(path: &str) -> (Vec, String, usize, usize) { let bytes = to_format(img, width, height); - let path = path - .split('/') - .next_back() - .expect("failed to get last part of path"); - let split: Vec<_> = path.split('.').collect(); - let name = remove_non_alphanumeric(&split[0..split.len() - 1].join(".")).to_uppercase(); - - (bytes, name, width, height) + (bytes, width, height) } struct ParsedArgs { @@ -69,20 +62,11 @@ impl Parse for ParsedArgs { pub fn parse_image( input: TokenStream, -) -> Result< - ( - u8, - u8, - proc_macro2::Ident, - usize, - Vec, - ), - syn::Error, -> { +) -> Result<(u8, u8, usize, Vec), syn::Error> { // parse the input into a comma separated list of arguments let parsed_args = syn::parse::(input)?; // let parsed_args = parse_macro_input!(input as ParsedArgs); - let (bytes, name, width, height) = path_to_image(&parsed_args.path); + let (bytes, width, height) = path_to_image(&parsed_args.path); let width = width as u8; let height = height as u8; @@ -90,14 +74,12 @@ pub fn parse_image( let byte_array = bytes.as_slice(); let byte_count = byte_array.len(); - let name_ident = syn::Ident::new(&name, Span::call_site().into()); - let byte_tokens = bytes.iter().map(|b| quote! { #b }).collect::>(); - Ok((width, height, name_ident, byte_count, byte_tokens)) + Ok((width, height, byte_count, byte_tokens)) } pub fn include_bitmap_image_impl(input: TokenStream) -> TokenStream { - let (_, _, _, _, byte_tokens) = parse_image(input).unwrap(); + let (_, _, _, byte_tokens) = parse_image(input).unwrap(); let output = quote! { [#(#byte_tokens),*] diff --git a/src/draw.rs b/src/draw.rs index f0e709f..b3160a3 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -39,12 +39,6 @@ pub trait Draw { /// /// Uses the embedded font plate to render glyphs into the framebuffer. unsafe fn draw_char_bg(&mut self, x: u16, y: u16, c: char, color: Color, bg_color: Color) { - let c = if (c as u8 > b'~') || ((c as u8) < b' ') { - b'/' - b' ' - } else { - c as u8 - b' ' - }; - // Get char position within font plate let char_x = (c as usize % 32) * FONT_WIDTH; let char_y = (c as usize / 32) * FONT_HEIGHT; @@ -119,6 +113,6 @@ pub trait Draw { pub const FONT_WIDTH: usize = 6; pub const FONT_HEIGHT: usize = 13; pub const FONTPLATE_WIDTH: usize = 32 * FONT_WIDTH; -pub const FONTPLATE_HEIGHT: usize = 3 * FONT_HEIGHT; +pub const FONTPLATE_HEIGHT: usize = 42 * FONT_HEIGHT; pub const FONTPLATE_SIZE: usize = FONTPLATE_WIDTH * FONTPLATE_HEIGHT / 8; pub static FONTPLATE: [u8; FONTPLATE_SIZE] = include_bitmap_image! {"assets/fontplate.png"}; diff --git a/src/interrupt.rs b/src/interrupt.rs index f80fbb0..e1e08b4 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -385,17 +385,6 @@ unsafe extern "C" fn _supervisor_mode_trap() { csrr t0, sepc sd t0, 248(sp) csrr t0, sstatus - // Move SIE bit to SPIE. Restore_context, in the sret instruction, will do the inverse operation - // Isolate SIE bit (1) - andi t1, t0, 0x2 - // li t1, 0x2 - // Shift to bit 5 (SPIE) - slli t1, t1, 4 - // Clear bit 1 and 5 - li t2, ~0x22 - and t0, t0, t2 - // Add the SPIE bit - or t0, t0, t1 sd t0, 256(sp) mv a0, sp diff --git a/src/main.rs b/src/main.rs index a72cbf5..c51e8d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -115,7 +115,7 @@ pub static mut KBD_DRIVER: VirtioPciDriver = unsafe { } _ => {} } - // println!("event: {:#?}", event); + println!("event: {:#?}", event); } } else { // println!("key pressed, {:#?}", event); @@ -171,12 +171,12 @@ pub extern "C" fn supervisor_mode_entry() { info!("Hello World !"); // unsafe { Vga.draw_string(10, 10, "Hello World !", Color::WHITE, Color::BLACK) }; - // SCHEDULER.lock().create_process(Box::new(test), "proc1"); - // SCHEDULER.lock().create_process(Box::new(proc2), "proc2"); + SCHEDULER.lock().create_process(Box::new(test), "proc1"); + SCHEDULER.lock().create_process(Box::new(proc2), "proc2"); - // SCHEDULER - // .lock() - // .create_process_from_file("/usr/bin/test_pic"); + SCHEDULER + .lock() + .create_process_from_file("/usr/bin/test_pic"); enable_supervisor_interrupt(); diff --git a/src/process.rs b/src/process.rs index 4066c64..485a68f 100644 --- a/src/process.rs +++ b/src/process.rs @@ -16,6 +16,7 @@ use shared::syscall::exit; use crate::{ println, + riscv::SStatus, scheduler::{ACTIVE_PID, SCHEDULER, Scheduler}, time::elapsed_time_since_startup, tty::TTY0, @@ -25,15 +26,6 @@ use crate::{ /// Size of the stack allocated to each process (in 64-bit words). const STACK_SIZE: usize = 4096; -/// MSTATUS bit to enable supervisor mode interrupts. -const MSTATUS_SIE: u64 = 1 << 1; - -/// MSTATUS bit to enable supervisor mode interrupts. -const MSTATUS_SPIE: u64 = 1 << 5; - -/// MSTATUS bit to set previous privilege mode to supervisor. -const MSTATUS_SPP: u64 = 1 << 1; - /// Represents the state of a process in the system. #[derive(Debug, PartialEq, Eq)] pub enum ProcessState { @@ -317,7 +309,7 @@ impl Scheduler { process.ctx.mepc = process_launcher as *const _; // Configure mstatus for supervisor mode with interrupts enabled - process.ctx.mstatus = MSTATUS_SPP | MSTATUS_SPIE; + process.ctx.mstatus = SStatus::SPIE; // Initialize stack pointer at the top of the stack process.ctx.sp = &raw const process.stack[STACK_SIZE - 1]; diff --git a/src/riscv.rs b/src/riscv.rs index 4e36463..8adb5df 100644 --- a/src/riscv.rs +++ b/src/riscv.rs @@ -22,8 +22,9 @@ impl MStatus { pub const MPIE: usize = 1 << 7; } impl SStatus { - pub const SIE: usize = 1 << 1; - pub const SPIE: usize = 1 << 5; + pub const SPP: u64 = 1 << 8; + pub const SIE: u64 = 1 << 1; + pub const SPIE: u64 = 1 << 5; } /// Return the current machine interrupt enable state. @@ -32,7 +33,7 @@ pub fn get_interrupt_state() -> bool { } /// Return whether supervisor interrupts are currently enabled. pub fn get_supervisor_interrupt_state() -> bool { - (read_csr!(sstatus) & SStatus::SIE as u64) != 0 + (read_csr!(sstatus) & SStatus::SIE) != 0 } /// Enable machine-level interrupts. pub fn enable_interrupt() { diff --git a/src/time.rs b/src/time.rs index eade1e7..9dc13f2 100644 --- a/src/time.rs +++ b/src/time.rs @@ -26,7 +26,7 @@ const CLINT_TIMER: *const u64 = 0x0200_bff8 as *const u64; /// The hardware timer frequency (Hz). const TIMER_FREQUENCY: u64 = 10_000_000; // 10 MHz /// The frequency at which timer interrupts should occur (Hz). -const INTERRUPT_FREQUENCY: u64 = 200; // 20 Hz +const INTERRUPT_FREQUENCY: u64 = 100; // 100 Hz /// Stores the instant when the kernel started. static START_TIME: AtomicU64 = AtomicU64::new(0);