Interrupts are working again, new fontplate
This commit is contained in:
BIN
assets/cozette.otb
Normal file
BIN
assets/cozette.otb
Normal file
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 7.0 KiB |
42
assets/fontplate.py
Executable file
42
assets/fontplate.py
Executable file
@@ -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")
|
||||
@@ -34,7 +34,7 @@ fn to_format(img: ImageBuffer<Luma<u8>, Vec<u8>>, width: usize, height: usize) -
|
||||
output
|
||||
}
|
||||
|
||||
fn path_to_image(path: &str) -> (Vec<u8>, String, usize, usize) {
|
||||
fn path_to_image(path: &str) -> (Vec<u8>, 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<u8>, 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<proc_macro2::TokenStream>,
|
||||
),
|
||||
syn::Error,
|
||||
> {
|
||||
) -> Result<(u8, u8, usize, Vec<proc_macro2::TokenStream>), syn::Error> {
|
||||
// parse the input into a comma separated list of arguments
|
||||
let parsed_args = syn::parse::<ParsedArgs>(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::<Vec<_>>();
|
||||
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),*]
|
||||
|
||||
@@ -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"};
|
||||
|
||||
@@ -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
|
||||
|
||||
12
src/main.rs
12
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();
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user