optimize cpu (4h 12m)
This commit is contained in:
parent
59a7f07012
commit
dbb0f83d6f
5 changed files with 66 additions and 19 deletions
|
@ -4,6 +4,7 @@ use lazy_static::lazy_static;
|
|||
use crate::gdt;
|
||||
use pic8259::ChainedPics;
|
||||
use spin;
|
||||
use crate::print;
|
||||
|
||||
lazy_static! {
|
||||
static ref IDT: InterruptDescriptorTable = {
|
||||
|
@ -11,8 +12,10 @@ lazy_static! {
|
|||
idt.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
unsafe {
|
||||
idt.double_fault.set_handler_fn(double_fault_handler)
|
||||
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); // new
|
||||
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
}
|
||||
idt[InterruptIndex::Timer.as_usize()]
|
||||
.set_handler_fn(timer_interrupt_handler);
|
||||
|
||||
idt
|
||||
};
|
||||
|
@ -45,3 +48,30 @@ pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
|||
|
||||
pub static PICS: spin::Mutex<ChainedPics> =
|
||||
spin::Mutex::new(unsafe {ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum InterruptIndex {
|
||||
Timer = PIC_1_OFFSET,
|
||||
}
|
||||
|
||||
impl InterruptIndex {
|
||||
fn as_u8(self) -> u8 {
|
||||
self as u8
|
||||
}
|
||||
|
||||
fn as_usize(self) -> usize {
|
||||
usize::from(self.as_u8())
|
||||
}
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(
|
||||
_stack_frame: InterruptStackFrame)
|
||||
{
|
||||
print!(".");
|
||||
|
||||
unsafe {
|
||||
PICS.lock()
|
||||
.notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
}
|
||||
}
|
10
src/lib.rs
10
src/lib.rs
|
@ -48,7 +48,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! {
|
|||
serial_println!("[failed]\n");
|
||||
serial_println!("Error: {}\n", info);
|
||||
exit_qemu(QemuExitCode::Failed);
|
||||
loop {}
|
||||
hlt_loop();
|
||||
}
|
||||
|
||||
/// Entry point for `cargo test`
|
||||
|
@ -57,7 +57,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! {
|
|||
pub extern "C" fn _start() -> ! {
|
||||
init();
|
||||
test_main();
|
||||
loop {}
|
||||
hlt_loop();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -80,4 +80,10 @@ pub fn exit_qemu(exit_code: QemuExitCode) {
|
|||
let mut port = Port::new(0xf4);
|
||||
port.write(exit_code as u32);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hlt_loop() -> ! {
|
||||
loop {
|
||||
x86_64::instructions::hlt();
|
||||
}
|
||||
}
|
12
src/main.rs
12
src/main.rs
|
@ -10,19 +10,13 @@ use donald::println;
|
|||
#[no_mangle]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
println!("Hello World{}", "!");
|
||||
println!("It did not crash!");
|
||||
donald::init();
|
||||
|
||||
fn stack_overflow() {
|
||||
stack_overflow();
|
||||
}
|
||||
|
||||
stack_overflow();
|
||||
|
||||
#[cfg(test)]
|
||||
test_main();
|
||||
|
||||
loop {}
|
||||
println!("It did not crash!");
|
||||
donald::hlt_loop();
|
||||
}
|
||||
|
||||
/// This function is called on panic.
|
||||
|
@ -30,7 +24,7 @@ pub extern "C" fn _start() -> ! {
|
|||
#[panic_handler]
|
||||
fn panic(info: &PanicInfo) -> ! {
|
||||
println!("{}", info);
|
||||
loop {}
|
||||
donald::hlt_loop();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -14,7 +14,14 @@ lazy_static! {
|
|||
#[doc(hidden)]
|
||||
pub fn _print(args: ::core::fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
SERIAL1.lock().write_fmt(args).expect("Printing to serial failed");
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
SERIAL1
|
||||
.lock()
|
||||
.write_fmt(args)
|
||||
.expect("Printing to serial failed");
|
||||
});
|
||||
}
|
||||
|
||||
/// Prints to the host through the serial interface.
|
||||
|
|
|
@ -140,7 +140,11 @@ macro_rules! println {
|
|||
#[doc(hidden)]
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
WRITER.lock().write_fmt(args).unwrap();
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
WRITER.lock().write_fmt(args).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
#[test_case]
|
||||
|
@ -157,10 +161,16 @@ fn test_println_many() {
|
|||
|
||||
#[test_case]
|
||||
fn test_println_output() {
|
||||
use core::fmt::Write;
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
let s = "Some test string that fits on a single line";
|
||||
println!("{}", s);
|
||||
for (i, c) in s.chars().enumerate() {
|
||||
let screen_char = WRITER.lock().buffer.chars[BUFFER_HEIGHT - 2][i].read();
|
||||
assert_eq!(char::from(screen_char.ascii_character), c);
|
||||
}
|
||||
interrupts::without_interrupts(|| {
|
||||
let mut writer = WRITER.lock();
|
||||
writeln!(writer, "\n{}", s).expect("writeln failed");
|
||||
for (i, c) in s.chars().enumerate() {
|
||||
let screen_char = writer.buffer.chars[BUFFER_HEIGHT - 2][i].read();
|
||||
assert_eq!(char::from(screen_char.ascii_character), c);
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue