summaryrefslogtreecommitdiffstats
path: root/rsnix/src/interrupts.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/interrupts.rs')
-rw-r--r--rsnix/src/interrupts.rs146
1 files changed, 144 insertions, 2 deletions
diff --git a/rsnix/src/interrupts.rs b/rsnix/src/interrupts.rs
index 7ea0b07..be252df 100644
--- a/rsnix/src/interrupts.rs
+++ b/rsnix/src/interrupts.rs
@@ -269,6 +269,56 @@ core::arch::global_asm!(
269 " push 0xFF", 269 " push 0xFF",
270 " jmp isr_common", 270 " jmp isr_common",
271 "", 271 "",
272 // Exception stubs for the remaining vectors 0-31 so every fault gets
273 // a diagnosable dump instead of converging to a cryptic double fault.
274 // Vectors that push their own error code (10, 11, 12, 13, 17, 18 — 8
275 // and 14 have dedicated stubs above) skip the fake push-0.
276 ".macro ISR_NOERR vec",
277 " .globl isr_stub_x_\\vec",
278 " .p2align 4",
279 "isr_stub_x_\\vec:",
280 " push 0",
281 " push \\vec",
282 " jmp isr_common",
283 ".endm",
284 ".macro ISR_ERR vec",
285 " .globl isr_stub_x_\\vec",
286 " .p2align 4",
287 "isr_stub_x_\\vec:",
288 " push \\vec",
289 " jmp isr_common",
290 ".endm",
291 "ISR_NOERR 0",
292 "ISR_NOERR 1",
293 "ISR_NOERR 2",
294 "ISR_NOERR 3",
295 "ISR_NOERR 4",
296 "ISR_NOERR 5",
297 "ISR_NOERR 6",
298 "ISR_NOERR 7",
299 "ISR_NOERR 9",
300 "ISR_ERR 10",
301 "ISR_ERR 11",
302 "ISR_ERR 12",
303 "ISR_ERR 13",
304 "ISR_NOERR 15",
305 "ISR_NOERR 16",
306 "ISR_ERR 17",
307 "ISR_ERR 18",
308 "ISR_NOERR 19",
309 "ISR_NOERR 20",
310 "ISR_NOERR 21",
311 "ISR_NOERR 22",
312 "ISR_NOERR 23",
313 "ISR_NOERR 24",
314 "ISR_NOERR 25",
315 "ISR_NOERR 26",
316 "ISR_NOERR 27",
317 "ISR_NOERR 28",
318 "ISR_NOERR 29",
319 "ISR_NOERR 30",
320 "ISR_NOERR 31",
321 "",
272 // Common handler — save all registers, call into Rust (which returns 322 // Common handler — save all registers, call into Rust (which returns
273 // the next task's frame pointer in rax), switch rsp, restore, iretq. 323 // the next task's frame pointer in rax), switch rsp, restore, iretq.
274 "isr_common:", 324 "isr_common:",
@@ -381,8 +431,9 @@ unsafe extern "C" fn isr_dispatch(frame: &IntFrame) -> usize {
381 fp 431 fp
382 } 432 }
383 8 => { 433 8 => {
384 crate::serial_println!("double fault — halting"); 434 // Double fault — dump the frame (we're on the IST stack
385 halt() 435 // so this is safe) and halt.
436 crate::sched::fault_dump("double fault", 0, frame)
386 } 437 }
387 14 => { 438 14 => {
388 let cr2: u64; 439 let cr2: u64;
@@ -391,6 +442,11 @@ unsafe extern "C" fn isr_dispatch(frame: &IntFrame) -> usize {
391 crate::sched::page_fault(cr2, fp) 442 crate::sched::page_fault(cr2, fp)
392 } 443 }
393 0x60 => crate::sched::on_yield(fp), 444 0x60 => crate::sched::on_yield(fp),
445 v if v < 32 => {
446 // Any other CPU exception: full dump (screen + serial),
447 // then halt the shell or abort the faulting background task.
448 crate::sched::fault_dump("exception", 0, frame)
449 }
394 _ => fp, 450 _ => fp,
395 } 451 }
396 }; 452 };
@@ -418,6 +474,47 @@ pub fn read_mouse_byte() -> Option<u8> {
418/// sub-tick fraction. 474/// sub-tick fraction.
419pub static TICKS: AtomicU64 = AtomicU64::new(0); 475pub static TICKS: AtomicU64 = AtomicU64::new(0);
420 476
477/// Address of the stub for CPU exception vector `vec` (0-31), or 0 for
478/// vectors without a stub. 8 (double fault) and 14 (page fault) use
479/// dedicated stubs that run on IST stacks.
480fn exc_stub_addr(vec: u8) -> u64 {
481 match vec {
482 8 => isr_stub_08 as *const () as u64,
483 14 => isr_stub_14 as *const () as u64,
484 0 => isr_stub_x_0 as *const () as u64,
485 1 => isr_stub_x_1 as *const () as u64,
486 2 => isr_stub_x_2 as *const () as u64,
487 3 => isr_stub_x_3 as *const () as u64,
488 4 => isr_stub_x_4 as *const () as u64,
489 5 => isr_stub_x_5 as *const () as u64,
490 6 => isr_stub_x_6 as *const () as u64,
491 7 => isr_stub_x_7 as *const () as u64,
492 9 => isr_stub_x_9 as *const () as u64,
493 10 => isr_stub_x_10 as *const () as u64,
494 11 => isr_stub_x_11 as *const () as u64,
495 12 => isr_stub_x_12 as *const () as u64,
496 13 => isr_stub_x_13 as *const () as u64,
497 15 => isr_stub_x_15 as *const () as u64,
498 16 => isr_stub_x_16 as *const () as u64,
499 17 => isr_stub_x_17 as *const () as u64,
500 18 => isr_stub_x_18 as *const () as u64,
501 19 => isr_stub_x_19 as *const () as u64,
502 20 => isr_stub_x_20 as *const () as u64,
503 21 => isr_stub_x_21 as *const () as u64,
504 22 => isr_stub_x_22 as *const () as u64,
505 23 => isr_stub_x_23 as *const () as u64,
506 24 => isr_stub_x_24 as *const () as u64,
507 25 => isr_stub_x_25 as *const () as u64,
508 26 => isr_stub_x_26 as *const () as u64,
509 27 => isr_stub_x_27 as *const () as u64,
510 28 => isr_stub_x_28 as *const () as u64,
511 29 => isr_stub_x_29 as *const () as u64,
512 30 => isr_stub_x_30 as *const () as u64,
513 31 => isr_stub_x_31 as *const () as u64,
514 _ => 0,
515 }
516}
517
421/// Initialise the IDT, remap the PIC, set up the PIT, and enable interrupts. 518/// Initialise the IDT, remap the PIC, set up the PIT, and enable interrupts.
422pub fn init() { 519pub fn init() {
423 unsafe { 520 unsafe {
@@ -435,6 +532,20 @@ pub fn init() {
435 idt_set_entry(idt_ptr, vec, spurious, cs, 0x0Eu8, 0); 532 idt_set_entry(idt_ptr, vec, spurious, cs, 0x0Eu8, 0);
436 } 533 }
437 534
535 // Wire up every CPU exception vector (0-31) so any fault produces
536 // a diagnosable dump instead of converging to a double fault.
537 for vec in 0..=31u8 {
538 let a = exc_stub_addr(vec);
539 if a != 0 {
540 let ist = match vec {
541 8 => 2u8,
542 14 => 1u8,
543 _ => 0u8,
544 };
545 idt_set_entry(idt_ptr, vec, a, cs, 0x0Eu8, ist);
546 }
547 }
548
438 // Override vectors for interrupt we actually handle. 549 // Override vectors for interrupt we actually handle.
439 idt_set_entry(idt_ptr, 32, isr_stub_32 as *const () as u64, cs, 0x0Eu8, 0); 550 idt_set_entry(idt_ptr, 32, isr_stub_32 as *const () as u64, cs, 0x0Eu8, 0);
440 idt_set_entry(idt_ptr, 33, isr_stub_33 as *const () as u64, cs, 0x0Eu8, 0); 551 idt_set_entry(idt_ptr, 33, isr_stub_33 as *const () as u64, cs, 0x0Eu8, 0);
@@ -513,4 +624,35 @@ unsafe extern "C" {
513 fn isr_stub_44(); 624 fn isr_stub_44();
514 fn isr_stub_60(); 625 fn isr_stub_60();
515 fn isr_stub_spurious(); 626 fn isr_stub_spurious();
627 // Macro-generated exception stubs (isr_stub_x_<vec>).
628 fn isr_stub_x_0();
629 fn isr_stub_x_1();
630 fn isr_stub_x_2();
631 fn isr_stub_x_3();
632 fn isr_stub_x_4();
633 fn isr_stub_x_5();
634 fn isr_stub_x_6();
635 fn isr_stub_x_7();
636 fn isr_stub_x_9();
637 fn isr_stub_x_10();
638 fn isr_stub_x_11();
639 fn isr_stub_x_12();
640 fn isr_stub_x_13();
641 fn isr_stub_x_15();
642 fn isr_stub_x_16();
643 fn isr_stub_x_17();
644 fn isr_stub_x_18();
645 fn isr_stub_x_19();
646 fn isr_stub_x_20();
647 fn isr_stub_x_21();
648 fn isr_stub_x_22();
649 fn isr_stub_x_23();
650 fn isr_stub_x_24();
651 fn isr_stub_x_25();
652 fn isr_stub_x_26();
653 fn isr_stub_x_27();
654 fn isr_stub_x_28();
655 fn isr_stub_x_29();
656 fn isr_stub_x_30();
657 fn isr_stub_x_31();
516} 658}