diff options
Diffstat (limited to 'rsnix/src/interrupts.rs')
| -rw-r--r-- | rsnix/src/interrupts.rs | 146 |
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. |
| 419 | pub static TICKS: AtomicU64 = AtomicU64::new(0); | 475 | pub 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. | ||
| 480 | fn 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. |
| 422 | pub fn init() { | 519 | pub 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 | } |
