aboutsummaryrefslogtreecommitdiff
path: root/bunny/src
diff options
context:
space:
mode:
Diffstat (limited to 'bunny/src')
-rw-r--r--bunny/src/interrupt.rs1213
-rw-r--r--bunny/src/inttraits.rs14
-rw-r--r--bunny/src/io.rs18
-rw-r--r--bunny/src/lapic.rs313
-rw-r--r--bunny/src/main.rs211
-rw-r--r--bunny/src/println.rs31
-rw-r--r--bunny/src/uefi.rs49
7 files changed, 1849 insertions, 0 deletions
diff --git a/bunny/src/interrupt.rs b/bunny/src/interrupt.rs
new file mode 100644
index 0000000..4ac8192
--- /dev/null
+++ b/bunny/src/interrupt.rs
@@ -0,0 +1,1213 @@
+use core::mem::size_of;
+
+use x86_64::structures::idt::{InterruptDescriptorTable, ExceptionStackFrame, PageFaultErrorCode};
+
+pub use x86_64::instructions::interrupts::{are_enabled, disable, enable, without_interrupts};
+
+pub const IRQ_APIC_LVT_ERROR: u8 = 0x20;
+
+static mut IDT: InterruptDescriptorTable = InterruptDescriptorTable::new();
+
+extern "x86-interrupt" fn handle_divzero(exc: &mut ExceptionStackFrame) {
+ println!("DIVISION BY ZERO: {:x?}", exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_seg_not_present(exc: &mut ExceptionStackFrame, code: u64) {
+ println!("SEGMENT NOT PRESENT 0x{:x}: {:x?}", code, exc);
+}
+
+extern "x86-interrupt" fn handle_ss_fault(exc: &mut ExceptionStackFrame, code: u64) {
+ println!("STACK SEGMENT FAULT 0x{:x}: {:x?}", code, exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_gp(exc: &mut ExceptionStackFrame, code: u64) {
+ println!("GENERAL PROTECTION FAULT 0x{:x}: {:x?}", code, exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_iopc(exc: &mut ExceptionStackFrame) {
+ println!("INVALID OPCODE @ 0x{:x}: {:x?}", exc.instruction_pointer.as_u64(), exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_pagefault(exc: &mut ExceptionStackFrame, code: PageFaultErrorCode) {
+ println!("PAGE FAULT {:?}: {:x?}", code, exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_inval_tss(exc: &mut ExceptionStackFrame, code: u64) {
+ println!("INVALID TSS 0x{:x}: {:x?}", code, exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_doublefault(exc: &mut ExceptionStackFrame, code: u64) {
+ println!("DOUBLE FAULT 0x{:x}: {:x?}", code, exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_mce(exc: &mut ExceptionStackFrame) {
+ println!("MACHINE CHECK EXCEPTION: {:x?}", exc);
+ loop {}
+}
+
+extern "x86-interrupt" fn handle_breakpoint(exc: &mut ExceptionStackFrame) {
+ println!("BREAKPOINT AT 0x{:x}: {:x?}", exc.instruction_pointer.as_u64(), exc);
+}
+
+extern "x86-interrupt" fn handle_apic_error(exc: &mut ExceptionStackFrame) {
+ println!("APIC ERROR AT 0x{:x}: {:x?}", exc.instruction_pointer.as_u64(), exc);
+}
+
+fn unhandled_irq(exc: &mut ExceptionStackFrame, num: u8) {
+ println!("UNHANDLED IRQ#{:02x}h: {:x?}", num, exc);
+}
+
+
+extern "x86-interrupt" fn unhandled_irq_20(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x20);
+}
+
+extern "x86-interrupt" fn unhandled_irq_21(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x21);
+}
+
+extern "x86-interrupt" fn unhandled_irq_22(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x22);
+}
+
+extern "x86-interrupt" fn unhandled_irq_23(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x23);
+}
+
+extern "x86-interrupt" fn unhandled_irq_24(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x24);
+}
+
+extern "x86-interrupt" fn unhandled_irq_25(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x25);
+}
+
+extern "x86-interrupt" fn unhandled_irq_26(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x26);
+}
+
+extern "x86-interrupt" fn unhandled_irq_27(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x27);
+}
+
+extern "x86-interrupt" fn unhandled_irq_28(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x28);
+}
+
+extern "x86-interrupt" fn unhandled_irq_29(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x29);
+}
+
+extern "x86-interrupt" fn unhandled_irq_2a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x2a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_2b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x2b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_2c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x2c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_2d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x2d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_2e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x2e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_2f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x2f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_30(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x30);
+}
+
+extern "x86-interrupt" fn unhandled_irq_31(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x31);
+}
+
+extern "x86-interrupt" fn unhandled_irq_32(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x32);
+}
+
+extern "x86-interrupt" fn unhandled_irq_33(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x33);
+}
+
+extern "x86-interrupt" fn unhandled_irq_34(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x34);
+}
+
+extern "x86-interrupt" fn unhandled_irq_35(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x35);
+}
+
+extern "x86-interrupt" fn unhandled_irq_36(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x36);
+}
+
+extern "x86-interrupt" fn unhandled_irq_37(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x37);
+}
+
+extern "x86-interrupt" fn unhandled_irq_38(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x38);
+}
+
+extern "x86-interrupt" fn unhandled_irq_39(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x39);
+}
+
+extern "x86-interrupt" fn unhandled_irq_3a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x3a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_3b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x3b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_3c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x3c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_3d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x3d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_3e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x3e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_3f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x3f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_40(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x40);
+}
+
+extern "x86-interrupt" fn unhandled_irq_41(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x41);
+}
+
+extern "x86-interrupt" fn unhandled_irq_42(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x42);
+}
+
+extern "x86-interrupt" fn unhandled_irq_43(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x43);
+}
+
+extern "x86-interrupt" fn unhandled_irq_44(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x44);
+}
+
+extern "x86-interrupt" fn unhandled_irq_45(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x45);
+}
+
+extern "x86-interrupt" fn unhandled_irq_46(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x46);
+}
+
+extern "x86-interrupt" fn unhandled_irq_47(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x47);
+}
+
+extern "x86-interrupt" fn unhandled_irq_48(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x48);
+}
+
+extern "x86-interrupt" fn unhandled_irq_49(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x49);
+}
+
+extern "x86-interrupt" fn unhandled_irq_4a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x4a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_4b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x4b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_4c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x4c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_4d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x4d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_4e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x4e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_4f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x4f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_50(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x50);
+}
+
+extern "x86-interrupt" fn unhandled_irq_51(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x51);
+}
+
+extern "x86-interrupt" fn unhandled_irq_52(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x52);
+}
+
+extern "x86-interrupt" fn unhandled_irq_53(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x53);
+}
+
+extern "x86-interrupt" fn unhandled_irq_54(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x54);
+}
+
+extern "x86-interrupt" fn unhandled_irq_55(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x55);
+}
+
+extern "x86-interrupt" fn unhandled_irq_56(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x56);
+}
+
+extern "x86-interrupt" fn unhandled_irq_57(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x57);
+}
+
+extern "x86-interrupt" fn unhandled_irq_58(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x58);
+}
+
+extern "x86-interrupt" fn unhandled_irq_59(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x59);
+}
+
+extern "x86-interrupt" fn unhandled_irq_5a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x5a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_5b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x5b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_5c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x5c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_5d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x5d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_5e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x5e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_5f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x5f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_60(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x60);
+}
+
+extern "x86-interrupt" fn unhandled_irq_61(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x61);
+}
+
+extern "x86-interrupt" fn unhandled_irq_62(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x62);
+}
+
+extern "x86-interrupt" fn unhandled_irq_63(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x63);
+}
+
+extern "x86-interrupt" fn unhandled_irq_64(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x64);
+}
+
+extern "x86-interrupt" fn unhandled_irq_65(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x65);
+}
+
+extern "x86-interrupt" fn unhandled_irq_66(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x66);
+}
+
+extern "x86-interrupt" fn unhandled_irq_67(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x67);
+}
+
+extern "x86-interrupt" fn unhandled_irq_68(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x68);
+}
+
+extern "x86-interrupt" fn unhandled_irq_69(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x69);
+}
+
+extern "x86-interrupt" fn unhandled_irq_6a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x6a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_6b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x6b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_6c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x6c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_6d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x6d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_6e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x6e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_6f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x6f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_70(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x70);
+}
+
+extern "x86-interrupt" fn unhandled_irq_71(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x71);
+}
+
+extern "x86-interrupt" fn unhandled_irq_72(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x72);
+}
+
+extern "x86-interrupt" fn unhandled_irq_73(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x73);
+}
+
+extern "x86-interrupt" fn unhandled_irq_74(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x74);
+}
+
+extern "x86-interrupt" fn unhandled_irq_75(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x75);
+}
+
+extern "x86-interrupt" fn unhandled_irq_76(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x76);
+}
+
+extern "x86-interrupt" fn unhandled_irq_77(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x77);
+}
+
+extern "x86-interrupt" fn unhandled_irq_78(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x78);
+}
+
+extern "x86-interrupt" fn unhandled_irq_79(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x79);
+}
+
+extern "x86-interrupt" fn unhandled_irq_7a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x7a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_7b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x7b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_7c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x7c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_7d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x7d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_7e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x7e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_7f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x7f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_80(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x80);
+}
+
+extern "x86-interrupt" fn unhandled_irq_81(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x81);
+}
+
+extern "x86-interrupt" fn unhandled_irq_82(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x82);
+}
+
+extern "x86-interrupt" fn unhandled_irq_83(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x83);
+}
+
+extern "x86-interrupt" fn unhandled_irq_84(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x84);
+}
+
+extern "x86-interrupt" fn unhandled_irq_85(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x85);
+}
+
+extern "x86-interrupt" fn unhandled_irq_86(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x86);
+}
+
+extern "x86-interrupt" fn unhandled_irq_87(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x87);
+}
+
+extern "x86-interrupt" fn unhandled_irq_88(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x88);
+}
+
+extern "x86-interrupt" fn unhandled_irq_89(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x89);
+}
+
+extern "x86-interrupt" fn unhandled_irq_8a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x8a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_8b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x8b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_8c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x8c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_8d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x8d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_8e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x8e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_8f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x8f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_90(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x90);
+}
+
+extern "x86-interrupt" fn unhandled_irq_91(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x91);
+}
+
+extern "x86-interrupt" fn unhandled_irq_92(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x92);
+}
+
+extern "x86-interrupt" fn unhandled_irq_93(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x93);
+}
+
+extern "x86-interrupt" fn unhandled_irq_94(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x94);
+}
+
+extern "x86-interrupt" fn unhandled_irq_95(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x95);
+}
+
+extern "x86-interrupt" fn unhandled_irq_96(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x96);
+}
+
+extern "x86-interrupt" fn unhandled_irq_97(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x97);
+}
+
+extern "x86-interrupt" fn unhandled_irq_98(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x98);
+}
+
+extern "x86-interrupt" fn unhandled_irq_99(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x99);
+}
+
+extern "x86-interrupt" fn unhandled_irq_9a(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x9a);
+}
+
+extern "x86-interrupt" fn unhandled_irq_9b(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x9b);
+}
+
+extern "x86-interrupt" fn unhandled_irq_9c(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x9c);
+}
+
+extern "x86-interrupt" fn unhandled_irq_9d(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x9d);
+}
+
+extern "x86-interrupt" fn unhandled_irq_9e(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x9e);
+}
+
+extern "x86-interrupt" fn unhandled_irq_9f(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0x9f);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a0(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa0);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a1(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa1);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a2(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa2);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a3(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa3);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a4(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa4);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a5(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa5);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a6(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa6);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a7(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa7);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a8(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa8);
+}
+
+extern "x86-interrupt" fn unhandled_irq_a9(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xa9);
+}
+
+extern "x86-interrupt" fn unhandled_irq_aa(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xaa);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ab(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xab);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ac(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xac);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ad(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xad);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ae(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xae);
+}
+
+extern "x86-interrupt" fn unhandled_irq_af(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xaf);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b0(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb0);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b1(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb1);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b2(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb2);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b3(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb3);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b4(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb4);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b5(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb5);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b6(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb6);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b7(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb7);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b8(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb8);
+}
+
+extern "x86-interrupt" fn unhandled_irq_b9(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xb9);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ba(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xba);
+}
+
+extern "x86-interrupt" fn unhandled_irq_bb(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xbb);
+}
+
+extern "x86-interrupt" fn unhandled_irq_bc(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xbc);
+}
+
+extern "x86-interrupt" fn unhandled_irq_bd(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xbd);
+}
+
+extern "x86-interrupt" fn unhandled_irq_be(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xbe);
+}
+
+extern "x86-interrupt" fn unhandled_irq_bf(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xbf);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c0(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc0);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c1(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc1);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c2(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc2);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c3(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc3);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c4(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc4);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c5(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc5);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c6(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc6);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c7(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc7);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c8(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc8);
+}
+
+extern "x86-interrupt" fn unhandled_irq_c9(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xc9);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ca(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xca);
+}
+
+extern "x86-interrupt" fn unhandled_irq_cb(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xcb);
+}
+
+extern "x86-interrupt" fn unhandled_irq_cc(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xcc);
+}
+
+extern "x86-interrupt" fn unhandled_irq_cd(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xcd);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ce(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xce);
+}
+
+extern "x86-interrupt" fn unhandled_irq_cf(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xcf);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d0(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd0);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d1(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd1);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d2(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd2);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d3(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd3);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d4(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd4);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d5(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd5);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d6(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd6);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d7(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd7);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d8(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd8);
+}
+
+extern "x86-interrupt" fn unhandled_irq_d9(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xd9);
+}
+
+extern "x86-interrupt" fn unhandled_irq_da(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xda);
+}
+
+extern "x86-interrupt" fn unhandled_irq_db(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xdb);
+}
+
+extern "x86-interrupt" fn unhandled_irq_dc(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xdc);
+}
+
+extern "x86-interrupt" fn unhandled_irq_dd(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xdd);
+}
+
+extern "x86-interrupt" fn unhandled_irq_de(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xde);
+}
+
+extern "x86-interrupt" fn unhandled_irq_df(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xdf);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e0(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe0);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e1(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe1);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e2(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe2);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e3(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe3);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e4(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe4);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e5(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe5);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e6(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe6);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e7(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe7);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e8(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe8);
+}
+
+extern "x86-interrupt" fn unhandled_irq_e9(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xe9);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ea(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xea);
+}
+
+extern "x86-interrupt" fn unhandled_irq_eb(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xeb);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ec(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xec);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ed(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xed);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ee(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xee);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ef(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xef);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f0(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf0);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f1(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf1);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f2(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf2);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f3(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf3);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f4(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf4);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f5(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf5);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f6(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf6);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f7(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf7);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f8(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf8);
+}
+
+extern "x86-interrupt" fn unhandled_irq_f9(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xf9);
+}
+
+extern "x86-interrupt" fn unhandled_irq_fa(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xfa);
+}
+
+extern "x86-interrupt" fn unhandled_irq_fb(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xfb);
+}
+
+extern "x86-interrupt" fn unhandled_irq_fc(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xfc);
+}
+
+extern "x86-interrupt" fn unhandled_irq_fd(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xfd);
+}
+
+extern "x86-interrupt" fn unhandled_irq_fe(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xfe);
+}
+
+extern "x86-interrupt" fn unhandled_irq_ff(exc: &mut ExceptionStackFrame) {
+ unhandled_irq(exc, 0xff);
+}
+
+
+pub fn descriptor() -> (u16, u64) {
+ ((size_of::<InterruptDescriptorTable>() - 1) as u16,
+ unsafe { &IDT } as *const _ as u64)
+
+}
+
+pub fn register_handlers() {
+ unsafe {
+ IDT[0x20].set_handler_fn(unhandled_irq_20);
+ IDT[0x21].set_handler_fn(unhandled_irq_21);
+ IDT[0x22].set_handler_fn(unhandled_irq_22);
+ IDT[0x23].set_handler_fn(unhandled_irq_23);
+ IDT[0x24].set_handler_fn(unhandled_irq_24);
+ IDT[0x25].set_handler_fn(unhandled_irq_25);
+ IDT[0x26].set_handler_fn(unhandled_irq_26);
+ IDT[0x27].set_handler_fn(unhandled_irq_27);
+ IDT[0x28].set_handler_fn(unhandled_irq_28);
+ IDT[0x29].set_handler_fn(unhandled_irq_29);
+ IDT[0x2a].set_handler_fn(unhandled_irq_2a);
+ IDT[0x2b].set_handler_fn(unhandled_irq_2b);
+ IDT[0x2c].set_handler_fn(unhandled_irq_2c);
+ IDT[0x2d].set_handler_fn(unhandled_irq_2d);
+ IDT[0x2e].set_handler_fn(unhandled_irq_2e);
+ IDT[0x2f].set_handler_fn(unhandled_irq_2f);
+ IDT[0x30].set_handler_fn(unhandled_irq_30);
+ IDT[0x31].set_handler_fn(unhandled_irq_31);
+ IDT[0x32].set_handler_fn(unhandled_irq_32);
+ IDT[0x33].set_handler_fn(unhandled_irq_33);
+ IDT[0x34].set_handler_fn(unhandled_irq_34);
+ IDT[0x35].set_handler_fn(unhandled_irq_35);
+ IDT[0x36].set_handler_fn(unhandled_irq_36);
+ IDT[0x37].set_handler_fn(unhandled_irq_37);
+ IDT[0x38].set_handler_fn(unhandled_irq_38);
+ IDT[0x39].set_handler_fn(unhandled_irq_39);
+ IDT[0x3a].set_handler_fn(unhandled_irq_3a);
+ IDT[0x3b].set_handler_fn(unhandled_irq_3b);
+ IDT[0x3c].set_handler_fn(unhandled_irq_3c);
+ IDT[0x3d].set_handler_fn(unhandled_irq_3d);
+ IDT[0x3e].set_handler_fn(unhandled_irq_3e);
+ IDT[0x3f].set_handler_fn(unhandled_irq_3f);
+ IDT[0x40].set_handler_fn(unhandled_irq_40);
+ IDT[0x41].set_handler_fn(unhandled_irq_41);
+ IDT[0x42].set_handler_fn(unhandled_irq_42);
+ IDT[0x43].set_handler_fn(unhandled_irq_43);
+ IDT[0x44].set_handler_fn(unhandled_irq_44);
+ IDT[0x45].set_handler_fn(unhandled_irq_45);
+ IDT[0x46].set_handler_fn(unhandled_irq_46);
+ IDT[0x47].set_handler_fn(unhandled_irq_47);
+ IDT[0x48].set_handler_fn(unhandled_irq_48);
+ IDT[0x49].set_handler_fn(unhandled_irq_49);
+ IDT[0x4a].set_handler_fn(unhandled_irq_4a);
+ IDT[0x4b].set_handler_fn(unhandled_irq_4b);
+ IDT[0x4c].set_handler_fn(unhandled_irq_4c);
+ IDT[0x4d].set_handler_fn(unhandled_irq_4d);
+ IDT[0x4e].set_handler_fn(unhandled_irq_4e);
+ IDT[0x4f].set_handler_fn(unhandled_irq_4f);
+ IDT[0x50].set_handler_fn(unhandled_irq_50);
+ IDT[0x51].set_handler_fn(unhandled_irq_51);
+ IDT[0x52].set_handler_fn(unhandled_irq_52);
+ IDT[0x53].set_handler_fn(unhandled_irq_53);
+ IDT[0x54].set_handler_fn(unhandled_irq_54);
+ IDT[0x55].set_handler_fn(unhandled_irq_55);
+ IDT[0x56].set_handler_fn(unhandled_irq_56);
+ IDT[0x57].set_handler_fn(unhandled_irq_57);
+ IDT[0x58].set_handler_fn(unhandled_irq_58);
+ IDT[0x59].set_handler_fn(unhandled_irq_59);
+ IDT[0x5a].set_handler_fn(unhandled_irq_5a);
+ IDT[0x5b].set_handler_fn(unhandled_irq_5b);
+ IDT[0x5c].set_handler_fn(unhandled_irq_5c);
+ IDT[0x5d].set_handler_fn(unhandled_irq_5d);
+ IDT[0x5e].set_handler_fn(unhandled_irq_5e);
+ IDT[0x5f].set_handler_fn(unhandled_irq_5f);
+ IDT[0x60].set_handler_fn(unhandled_irq_60);
+ IDT[0x61].set_handler_fn(unhandled_irq_61);
+ IDT[0x62].set_handler_fn(unhandled_irq_62);
+ IDT[0x63].set_handler_fn(unhandled_irq_63);
+ IDT[0x64].set_handler_fn(unhandled_irq_64);
+ IDT[0x65].set_handler_fn(unhandled_irq_65);
+ IDT[0x66].set_handler_fn(unhandled_irq_66);
+ IDT[0x67].set_handler_fn(unhandled_irq_67);
+ IDT[0x68].set_handler_fn(unhandled_irq_68);
+ IDT[0x69].set_handler_fn(unhandled_irq_69);
+ IDT[0x6a].set_handler_fn(unhandled_irq_6a);
+ IDT[0x6b].set_handler_fn(unhandled_irq_6b);
+ IDT[0x6c].set_handler_fn(unhandled_irq_6c);
+ IDT[0x6d].set_handler_fn(unhandled_irq_6d);
+ IDT[0x6e].set_handler_fn(unhandled_irq_6e);
+ IDT[0x6f].set_handler_fn(unhandled_irq_6f);
+ IDT[0x70].set_handler_fn(unhandled_irq_70);
+ IDT[0x71].set_handler_fn(unhandled_irq_71);
+ IDT[0x72].set_handler_fn(unhandled_irq_72);
+ IDT[0x73].set_handler_fn(unhandled_irq_73);
+ IDT[0x74].set_handler_fn(unhandled_irq_74);
+ IDT[0x75].set_handler_fn(unhandled_irq_75);
+ IDT[0x76].set_handler_fn(unhandled_irq_76);
+ IDT[0x77].set_handler_fn(unhandled_irq_77);
+ IDT[0x78].set_handler_fn(unhandled_irq_78);
+ IDT[0x79].set_handler_fn(unhandled_irq_79);
+ IDT[0x7a].set_handler_fn(unhandled_irq_7a);
+ IDT[0x7b].set_handler_fn(unhandled_irq_7b);
+ IDT[0x7c].set_handler_fn(unhandled_irq_7c);
+ IDT[0x7d].set_handler_fn(unhandled_irq_7d);
+ IDT[0x7e].set_handler_fn(unhandled_irq_7e);
+ IDT[0x7f].set_handler_fn(unhandled_irq_7f);
+ IDT[0x80].set_handler_fn(unhandled_irq_80);
+ IDT[0x81].set_handler_fn(unhandled_irq_81);
+ IDT[0x82].set_handler_fn(unhandled_irq_82);
+ IDT[0x83].set_handler_fn(unhandled_irq_83);
+ IDT[0x84].set_handler_fn(unhandled_irq_84);
+ IDT[0x85].set_handler_fn(unhandled_irq_85);
+ IDT[0x86].set_handler_fn(unhandled_irq_86);
+ IDT[0x87].set_handler_fn(unhandled_irq_87);
+ IDT[0x88].set_handler_fn(unhandled_irq_88);
+ IDT[0x89].set_handler_fn(unhandled_irq_89);
+ IDT[0x8a].set_handler_fn(unhandled_irq_8a);
+ IDT[0x8b].set_handler_fn(unhandled_irq_8b);
+ IDT[0x8c].set_handler_fn(unhandled_irq_8c);
+ IDT[0x8d].set_handler_fn(unhandled_irq_8d);
+ IDT[0x8e].set_handler_fn(unhandled_irq_8e);
+ IDT[0x8f].set_handler_fn(unhandled_irq_8f);
+ IDT[0x90].set_handler_fn(unhandled_irq_90);
+ IDT[0x91].set_handler_fn(unhandled_irq_91);
+ IDT[0x92].set_handler_fn(unhandled_irq_92);
+ IDT[0x93].set_handler_fn(unhandled_irq_93);
+ IDT[0x94].set_handler_fn(unhandled_irq_94);
+ IDT[0x95].set_handler_fn(unhandled_irq_95);
+ IDT[0x96].set_handler_fn(unhandled_irq_96);
+ IDT[0x97].set_handler_fn(unhandled_irq_97);
+ IDT[0x98].set_handler_fn(unhandled_irq_98);
+ IDT[0x99].set_handler_fn(unhandled_irq_99);
+ IDT[0x9a].set_handler_fn(unhandled_irq_9a);
+ IDT[0x9b].set_handler_fn(unhandled_irq_9b);
+ IDT[0x9c].set_handler_fn(unhandled_irq_9c);
+ IDT[0x9d].set_handler_fn(unhandled_irq_9d);
+ IDT[0x9e].set_handler_fn(unhandled_irq_9e);
+ IDT[0x9f].set_handler_fn(unhandled_irq_9f);
+ IDT[0xa0].set_handler_fn(unhandled_irq_a0);
+ IDT[0xa1].set_handler_fn(unhandled_irq_a1);
+ IDT[0xa2].set_handler_fn(unhandled_irq_a2);
+ IDT[0xa3].set_handler_fn(unhandled_irq_a3);
+ IDT[0xa4].set_handler_fn(unhandled_irq_a4);
+ IDT[0xa5].set_handler_fn(unhandled_irq_a5);
+ IDT[0xa6].set_handler_fn(unhandled_irq_a6);
+ IDT[0xa7].set_handler_fn(unhandled_irq_a7);
+ IDT[0xa8].set_handler_fn(unhandled_irq_a8);
+ IDT[0xa9].set_handler_fn(unhandled_irq_a9);
+ IDT[0xaa].set_handler_fn(unhandled_irq_aa);
+ IDT[0xab].set_handler_fn(unhandled_irq_ab);
+ IDT[0xac].set_handler_fn(unhandled_irq_ac);
+ IDT[0xad].set_handler_fn(unhandled_irq_ad);
+ IDT[0xae].set_handler_fn(unhandled_irq_ae);
+ IDT[0xaf].set_handler_fn(unhandled_irq_af);
+ IDT[0xb0].set_handler_fn(unhandled_irq_b0);
+ IDT[0xb1].set_handler_fn(unhandled_irq_b1);
+ IDT[0xb2].set_handler_fn(unhandled_irq_b2);
+ IDT[0xb3].set_handler_fn(unhandled_irq_b3);
+ IDT[0xb4].set_handler_fn(unhandled_irq_b4);
+ IDT[0xb5].set_handler_fn(unhandled_irq_b5);
+ IDT[0xb6].set_handler_fn(unhandled_irq_b6);
+ IDT[0xb7].set_handler_fn(unhandled_irq_b7);
+ IDT[0xb8].set_handler_fn(unhandled_irq_b8);
+ IDT[0xb9].set_handler_fn(unhandled_irq_b9);
+ IDT[0xba].set_handler_fn(unhandled_irq_ba);
+ IDT[0xbb].set_handler_fn(unhandled_irq_bb);
+ IDT[0xbc].set_handler_fn(unhandled_irq_bc);
+ IDT[0xbd].set_handler_fn(unhandled_irq_bd);
+ IDT[0xbe].set_handler_fn(unhandled_irq_be);
+ IDT[0xbf].set_handler_fn(unhandled_irq_bf);
+ IDT[0xc0].set_handler_fn(unhandled_irq_c0);
+ IDT[0xc1].set_handler_fn(unhandled_irq_c1);
+ IDT[0xc2].set_handler_fn(unhandled_irq_c2);
+ IDT[0xc3].set_handler_fn(unhandled_irq_c3);
+ IDT[0xc4].set_handler_fn(unhandled_irq_c4);
+ IDT[0xc5].set_handler_fn(unhandled_irq_c5);
+ IDT[0xc6].set_handler_fn(unhandled_irq_c6);
+ IDT[0xc7].set_handler_fn(unhandled_irq_c7);
+ IDT[0xc8].set_handler_fn(unhandled_irq_c8);
+ IDT[0xc9].set_handler_fn(unhandled_irq_c9);
+ IDT[0xca].set_handler_fn(unhandled_irq_ca);
+ IDT[0xcb].set_handler_fn(unhandled_irq_cb);
+ IDT[0xcc].set_handler_fn(unhandled_irq_cc);
+ IDT[0xcd].set_handler_fn(unhandled_irq_cd);
+ IDT[0xce].set_handler_fn(unhandled_irq_ce);
+ IDT[0xcf].set_handler_fn(unhandled_irq_cf);
+ IDT[0xd0].set_handler_fn(unhandled_irq_d0);
+ IDT[0xd1].set_handler_fn(unhandled_irq_d1);
+ IDT[0xd2].set_handler_fn(unhandled_irq_d2);
+ IDT[0xd3].set_handler_fn(unhandled_irq_d3);
+ IDT[0xd4].set_handler_fn(unhandled_irq_d4);
+ IDT[0xd5].set_handler_fn(unhandled_irq_d5);
+ IDT[0xd6].set_handler_fn(unhandled_irq_d6);
+ IDT[0xd7].set_handler_fn(unhandled_irq_d7);
+ IDT[0xd8].set_handler_fn(unhandled_irq_d8);
+ IDT[0xd9].set_handler_fn(unhandled_irq_d9);
+ IDT[0xda].set_handler_fn(unhandled_irq_da);
+ IDT[0xdb].set_handler_fn(unhandled_irq_db);
+ IDT[0xdc].set_handler_fn(unhandled_irq_dc);
+ IDT[0xdd].set_handler_fn(unhandled_irq_dd);
+ IDT[0xde].set_handler_fn(unhandled_irq_de);
+ IDT[0xdf].set_handler_fn(unhandled_irq_df);
+ IDT[0xe0].set_handler_fn(unhandled_irq_e0);
+ IDT[0xe1].set_handler_fn(unhandled_irq_e1);
+ IDT[0xe2].set_handler_fn(unhandled_irq_e2);
+ IDT[0xe3].set_handler_fn(unhandled_irq_e3);
+ IDT[0xe4].set_handler_fn(unhandled_irq_e4);
+ IDT[0xe5].set_handler_fn(unhandled_irq_e5);
+ IDT[0xe6].set_handler_fn(unhandled_irq_e6);
+ IDT[0xe7].set_handler_fn(unhandled_irq_e7);
+ IDT[0xe8].set_handler_fn(unhandled_irq_e8);
+ IDT[0xe9].set_handler_fn(unhandled_irq_e9);
+ IDT[0xea].set_handler_fn(unhandled_irq_ea);
+ IDT[0xeb].set_handler_fn(unhandled_irq_eb);
+ IDT[0xec].set_handler_fn(unhandled_irq_ec);
+ IDT[0xed].set_handler_fn(unhandled_irq_ed);
+ IDT[0xee].set_handler_fn(unhandled_irq_ee);
+ IDT[0xef].set_handler_fn(unhandled_irq_ef);
+ IDT[0xf0].set_handler_fn(unhandled_irq_f0);
+ IDT[0xf1].set_handler_fn(unhandled_irq_f1);
+ IDT[0xf2].set_handler_fn(unhandled_irq_f2);
+ IDT[0xf3].set_handler_fn(unhandled_irq_f3);
+ IDT[0xf4].set_handler_fn(unhandled_irq_f4);
+ IDT[0xf5].set_handler_fn(unhandled_irq_f5);
+ IDT[0xf6].set_handler_fn(unhandled_irq_f6);
+ IDT[0xf7].set_handler_fn(unhandled_irq_f7);
+ IDT[0xf8].set_handler_fn(unhandled_irq_f8);
+ IDT[0xf9].set_handler_fn(unhandled_irq_f9);
+ IDT[0xfa].set_handler_fn(unhandled_irq_fa);
+ IDT[0xfb].set_handler_fn(unhandled_irq_fb);
+ IDT[0xfc].set_handler_fn(unhandled_irq_fc);
+ IDT[0xfd].set_handler_fn(unhandled_irq_fd);
+ IDT[0xfe].set_handler_fn(unhandled_irq_fe);
+ IDT[0xff].set_handler_fn(unhandled_irq_ff);
+
+ IDT.divide_by_zero.set_handler_fn(handle_divzero);
+ IDT.invalid_tss.set_handler_fn(handle_inval_tss);
+ IDT.segment_not_present.set_handler_fn(handle_seg_not_present);
+ IDT.stack_segment_fault.set_handler_fn(handle_ss_fault);
+ IDT.general_protection_fault.set_handler_fn(handle_gp);
+ IDT.invalid_opcode.set_handler_fn(handle_iopc);
+ IDT.page_fault.set_handler_fn(handle_pagefault);
+ IDT.double_fault.set_handler_fn(handle_doublefault);
+ IDT.machine_check.set_handler_fn(handle_mce);
+ IDT.breakpoint.set_handler_fn(handle_breakpoint);
+
+ IDT[IRQ_APIC_LVT_ERROR as usize].set_handler_fn(handle_apic_error);
+
+ IDT.load();
+ }
+}
diff --git a/bunny/src/inttraits.rs b/bunny/src/inttraits.rs
new file mode 100644
index 0000000..5d402b3
--- /dev/null
+++ b/bunny/src/inttraits.rs
@@ -0,0 +1,14 @@
+use core::slice;
+use core::mem::size_of;
+
+pub trait AsBytes: Sized {
+ fn as_bytes(&self) -> &[u8] {
+ unsafe { slice::from_raw_parts(self as *const _ as *const u8, size_of::<Self>()) }
+ }
+}
+
+impl AsBytes for u128 {}
+impl AsBytes for u64 {}
+impl AsBytes for u32 {}
+impl AsBytes for u16 {}
+impl AsBytes for u8 {}
diff --git a/bunny/src/io.rs b/bunny/src/io.rs
new file mode 100644
index 0000000..2fae55a
--- /dev/null
+++ b/bunny/src/io.rs
@@ -0,0 +1,18 @@
+use x86_64::instructions::port::{Port, PortReadWrite};
+
+const PIC1 : u16 = 0x20;
+const PIC2 : u16 = 0xa0;
+#[allow(unused)]
+pub const PIC1_COMMAND : u16 = PIC1;
+pub const PIC1_DATA : u16 = PIC1;
+#[allow(unused)]
+pub const PIC2_COMMAND : u16 = PIC2 + 1;
+pub const PIC2_DATA : u16 = PIC2 + 1;
+
+pub const PIC_DISABLE : u8 = 0xff;
+
+#[inline(always)]
+pub unsafe fn out<T: PortReadWrite>(port: u16, value: T) {
+ let mut p = Port::new(port);
+ p.write(value)
+}
diff --git a/bunny/src/lapic.rs b/bunny/src/lapic.rs
new file mode 100644
index 0000000..86d7a43
--- /dev/null
+++ b/bunny/src/lapic.rs
@@ -0,0 +1,313 @@
+use interrupt::IRQ_APIC_LVT_ERROR;
+
+use x86_64::registers::model_specific::Msr;
+
+/*
+ * See: Intel SDM Table 10-1: Local APIC Register Address Map
+ */
+/*
+#[allow(unused, non_snake_case)]
+#[repr(C)]
+struct MappedLocalApic {
+ _r0000: Ro<u32>,
+ _pad00: [u32; 3],
+
+ _r0010: Ro<u32>,
+ _pad01: [u32; 3],
+
+ id: Ro<u32>, /* 0020 */
+ _pad02: [u32; 3],
+
+ version: Ro<u32>, /* 0030 */
+ _pad03: [u32; 3],
+
+ _r0040: Ro<u32>,
+ _pad04: [u32; 3],
+
+ _r0050: Ro<u32>,
+ _pad05: [u32; 3],
+
+ _r0060: Ro<u32>,
+ _pad06: [u32; 3],
+
+ _r0070: Ro<u32>,
+ _pad07: [u32; 3],
+
+ task_priority: Ro<u32>, /* 0080 */
+ _pad08: [u32; 3],
+
+ arbitration_priority: Ro<u32>, /* 0090 */
+ _pad09: [u32; 3],
+
+ processor_priority: Ro<u32>, /* 00A0 */
+ _pad10: [u32; 3],
+
+ eoi: Ro<u32>, /* 00B0 */
+ _pad11: [u32; 3],
+
+ remote_read: Ro<u32>, /* 00C0 */
+ _pad12: [u32; 3],
+
+ logical_destination: Ro<u32>, /* 00D0 */
+ _pad13: [u32; 3],
+
+ destination_format: Ro<u32>, /* 00E0 */
+ _pad14: [u32; 3],
+
+ spurious_interrupt_vector: Rw<u32>, /* 00F0 */
+ _pad15: [u32; 3],
+
+ in_service: Ro<[u32; 32]>, /* 0100-0170 */
+
+ trigger_mode: Ro<[u32; 32]>, /* 0180-01F0 */
+
+ interrupt_request: Ro<[u32; 32]>, /* 0200-0270 */
+
+ error_status: Ro<u32>, /* 0280 */
+ _pad16: [u32; 3],
+
+ _r0290: Ro<u32>,
+ _pad17: [u32; 3],
+
+ _r02A0: Ro<u32>,
+ _pad18: [u32; 3],
+
+ _r02B0: Ro<u32>,
+ _pad19: [u32; 3],
+
+ _r02C0: Ro<u32>,
+ _pad20: [u32; 3],
+
+ _r02D0: Ro<u32>,
+ _pad21: [u32; 3],
+
+ _r02E0: Ro<u32>,
+ _pad22: [u32; 3],
+
+ lvt_corrected_machine_check_interrupt: Rw<u32>, /* 02F0 */
+ _pad23: [u32; 3],
+
+ interrupt_command_register: Rw<[u32; 8]>, /* 0300-0310 */
+
+ lvt_timer: Rw<u32>, /* 0320 */
+ _pad25: [u32; 3],
+
+ lvt_thermal_sensor: Rw<u32>, /* 0330 */
+ _pad26: [u32; 3],
+
+ lvt_performance_monitoring_counters: Rw<u32>, /* 0340 */
+ _pad27: [u32; 3],
+
+ lvt_lint0: Rw<u32>, /* 0350 */
+ _pad28: [u32; 3],
+
+ lvt_lint1: Rw<u32>, /* 0360 */
+ _pad29: [u32; 3],
+
+ lvt_error: Rw<u32>, /* 0370 */
+ _pad30: [u32; 3],
+
+ initial_count: Rw<u32>, /* 0380 */
+ _pad31: [u32; 3],
+
+ current_count: Ro<u32>, /* 0390 */
+ _pad32: [u32; 3],
+
+ _r03A0: Ro<u32>,
+ _pad33: [u32; 3],
+
+ _r03B0: Ro<u32>,
+ _pad34: [u32; 3],
+
+ _r03C0: Ro<u32>,
+ _pad35: [u32; 3],
+
+ _r03D0: Ro<u32>,
+ _pad36: [u32; 3],
+
+ divide_conf: Rw<u32>, /* 03E0 */
+ _pad37: [u32; 3],
+
+ _r03F0: Ro<u32>,
+}
+*/
+
+#[allow(unused)]
+struct LocalVectorTable {
+ cmci: Msr,
+ timer: Msr,
+ thermal_sensor: Msr,
+ perfmon: Msr,
+ lint0: Msr,
+ lint1: Msr,
+ error: Msr,
+}
+
+#[allow(unused)]
+pub struct LocalApic {
+ /* raw: &'map mut MappedLocalApic, */
+ id: Msr,
+ version: Msr,
+ task_priority: Msr,
+ processor_priority: Msr,
+ eoi: Msr,
+ logical_destination: Msr,
+ spurious_interrupt_vector: Msr,
+ in_service: [Msr; 8],
+ trigger_mode: [Msr; 8],
+ interrupt_request: [Msr; 8],
+ error_status: Msr,
+ local_vector_table: LocalVectorTable,
+ interrupt_command: Msr,
+ initial_count: Msr,
+ current_count: Msr,
+ divide_config: Msr,
+ self_ipi: Msr,
+}
+
+#[allow(unused)]
+#[derive(Debug, Copy, Clone)]
+#[repr(u32)]
+pub enum IpiDestination {
+ JustMe = 0b01 << 18,
+ All = 0b10 << 18,
+ AllButMe = 0b11 << 18,
+}
+
+#[allow(unused)]
+#[derive(Debug, Copy, Clone)]
+#[repr(u32)]
+pub enum IpiTriggerMode {
+ Edge = 0 << 15,
+ Level = 1 << 15,
+}
+
+#[allow(unused)]
+#[derive(Debug, Copy, Clone)]
+#[repr(u32)]
+pub enum IpiLevel {
+ Deassert = 0 << 14,
+ Assert = 1 << 14,
+}
+
+#[allow(unused)]
+#[derive(Debug, Copy, Clone)]
+#[repr(u32)]
+pub enum IpiDeliveryMode {
+ Fixed = 0b000 << 8,
+ LowestPriority = 0b001 << 8,
+ Smi = 0b010 << 8,
+ Nmi = 0b100 << 8,
+ Init = 0b101 << 8,
+ StartUp = 0b110 << 8,
+}
+
+impl LocalApic {
+ pub fn init() -> LocalApic {
+ const MSR_BASE: u32 = 0x800;
+ /* Set bits 10 and 11 of IA32_APIC_BASE MSR to enable x2APIC */
+ let mut apic_base_msr = Msr::new(0x1b);
+ let mut apic_base = unsafe { apic_base_msr.read() };
+ dprintln!("APIC BASE: 0x{:x}", apic_base);
+ apic_base |= 0b11 << 10;
+ unsafe { apic_base_msr.write(apic_base) };
+
+ /*
+ * See Intel SDM Table 10-6:
+ * Local APIC Register Address Map Supported by x2APIC
+ */
+ LocalApic {
+ id: Msr::new(MSR_BASE + 0x002),
+ version: Msr::new(MSR_BASE + 0x003),
+ task_priority: Msr::new(MSR_BASE + 0x008),
+ processor_priority: Msr::new(MSR_BASE + 0x00a),
+ eoi: Msr::new(MSR_BASE + 0x00b),
+ logical_destination: Msr::new(MSR_BASE + 0x00d),
+ spurious_interrupt_vector: Msr::new(MSR_BASE + 0x00f),
+ in_service: [Msr::new(MSR_BASE + 0x010),
+ Msr::new(MSR_BASE + 0x011),
+ Msr::new(MSR_BASE + 0x012),
+ Msr::new(MSR_BASE + 0x013),
+ Msr::new(MSR_BASE + 0x014),
+ Msr::new(MSR_BASE + 0x015),
+ Msr::new(MSR_BASE + 0x016),
+ Msr::new(MSR_BASE + 0x017)],
+ trigger_mode: [Msr::new(MSR_BASE + 0x018),
+ Msr::new(MSR_BASE + 0x019),
+ Msr::new(MSR_BASE + 0x01a),
+ Msr::new(MSR_BASE + 0x01b),
+ Msr::new(MSR_BASE + 0x01c),
+ Msr::new(MSR_BASE + 0x01d),
+ Msr::new(MSR_BASE + 0x01e),
+ Msr::new(MSR_BASE + 0x01f)],
+ interrupt_request: [Msr::new(MSR_BASE + 0x020),
+ Msr::new(MSR_BASE + 0x021),
+ Msr::new(MSR_BASE + 0x022),
+ Msr::new(MSR_BASE + 0x023),
+ Msr::new(MSR_BASE + 0x024),
+ Msr::new(MSR_BASE + 0x025),
+ Msr::new(MSR_BASE + 0x026),
+ Msr::new(MSR_BASE + 0x027)],
+ error_status: Msr::new(MSR_BASE + 0x028),
+ local_vector_table: LocalVectorTable {
+ cmci: Msr::new(MSR_BASE + 0x02f),
+ timer: Msr::new(MSR_BASE + 0x032),
+ thermal_sensor: Msr::new(MSR_BASE + 0x033),
+ perfmon: Msr::new(MSR_BASE + 0x034),
+ lint0: Msr::new(MSR_BASE + 0x035),
+ lint1: Msr::new(MSR_BASE + 0x036),
+ error: Msr::new(MSR_BASE + 0x037),
+ },
+ interrupt_command: Msr::new(MSR_BASE + 0x030),
+ initial_count: Msr::new(MSR_BASE + 0x038),
+ current_count: Msr::new(MSR_BASE + 0x039),
+ divide_config: Msr::new(MSR_BASE + 0x03e),
+ self_ipi: Msr::new(MSR_BASE + 0x03f),
+ }
+ }
+
+ pub fn id(&self) -> u32 {
+ unsafe { self.id.read() as u32 }
+ }
+
+ pub fn version(&self) -> u32 {
+ unsafe { self.version.read() as u32 }
+ }
+
+ pub fn enable(&mut self) {
+ /* Set bit in SVR 8 to enable local APIC */
+ let mut svr = unsafe { self.spurious_interrupt_vector.read() };
+ svr |= 1 << 8;
+ unsafe { self.spurious_interrupt_vector.write(svr); }
+
+ /*
+ * Set Local Vector Table error register:
+ * Directs APIC errors to interrupt #IRQ_APIC_LVT_ERROR
+ */
+ let mut lvte = unsafe { self.local_vector_table.error.read() as u32 };
+ lvte = (lvte & 0xffffff00) | (IRQ_APIC_LVT_ERROR as u32);
+ unsafe { self.local_vector_table.error.write(lvte as u64); }
+ }
+
+ pub fn send_ipi(&mut self,
+ dest: IpiDestination,
+ trigger_mode: IpiTriggerMode,
+ level: IpiLevel,
+ delivery_mode: IpiDeliveryMode,
+ vector: u8)
+ {
+ unsafe {
+ self.interrupt_command.write((dest as u64)
+ | (trigger_mode as u64)
+ | (level as u64)
+ | (delivery_mode as u64)
+ | (vector as u64));
+ }
+
+ dprintln!("IPI: 0x{:x}", (dest as u64)
+ | (trigger_mode as u64)
+ | (level as u64)
+ | (delivery_mode as u64)
+ | (vector as u64));
+ }
+}
diff --git a/bunny/src/main.rs b/bunny/src/main.rs
new file mode 100644
index 0000000..21fa9cc
--- /dev/null
+++ b/bunny/src/main.rs
@@ -0,0 +1,211 @@
+#![feature(lang_items, panic_info_message, abi_x86_interrupt, core_intrinsics, asm, link_llvm_intrinsics, int_to_from_bytes)]
+#![no_std]
+#![no_main]
+
+extern crate efi;
+extern crate x86_64;
+extern crate volatile;
+
+#[macro_use]
+mod println;
+mod interrupt;
+mod lapic;
+mod io;
+mod uefi;
+mod inttraits;
+
+use core::panic::PanicInfo;
+use core::ptr;
+use core::slice;
+
+use efi::types::Handle;
+use efi::SystemTable;
+use x86_64::instructions::interrupts;
+use x86_64::registers::control;
+
+use interrupt::*;
+use lapic::*;
+use inttraits::*;
+
+static mut SYSTEM_TABLE: *const SystemTable = 0 as *const SystemTable;
+
+fn serial_poke() {
+ const PORT: u16 = 0x3f8;
+
+ unsafe {
+ asm!("out dx, al" :: "{dx}"(PORT+1), "{al}"(0x00) :: "intel", "volatile");
+ asm!("out dx, al" :: "{dx}"(PORT+3), "{al}"(0x80) :: "intel", "volatile");
+ asm!("out dx, al" :: "{dx}"(PORT+0), "{al}"(0x03) :: "intel", "volatile");
+ asm!("out dx, al" :: "{dx}"(PORT+1), "{al}"(0x00) :: "intel", "volatile");
+ asm!("out dx, al" :: "{dx}"(PORT+3), "{al}"(0x03) :: "intel", "volatile");
+ asm!("out dx, al" :: "{dx}"(PORT+2), "{al}"(0xc7) :: "intel", "volatile");
+ asm!("out dx, al" :: "{dx}"(PORT+4), "{al}"(0x0b) :: "intel", "volatile");
+ }
+
+ for c in b"###*-*-*-*-*-*-*-*-*-*-###\r\n\r\n" {
+ let mut status: u8 = 0;
+ while status & 0x20 == 0 {
+ unsafe {
+ asm!("in al, dx" : "={al}"(status) : "{dx}"(PORT+5) :: "intel", "volatile");
+ }
+ }
+
+ unsafe {
+ asm!("out dx, al" :: "{dx}"(PORT), "{al}"(c) :: "intel", "volatile");
+ }
+ }
+}
+
+#[allow(improper_ctypes)]
+extern "C" {
+ #[link_name = "llvm.x86.rdtsc"]
+ fn rdtsc() -> i64;
+}
+
+fn busy() {
+ let init = unsafe { rdtsc() } as u64;
+ let future = init + 1_000_000;
+
+ let mut now = init;
+
+ while now < future {
+ now = unsafe { rdtsc() } as u64;
+ }
+}
+
+#[no_mangle]
+pub extern fn efi_main(_handle: Handle, systab: &SystemTable) -> ! {
+ /*
+ * Disable interrupts to avoid noise generated before we actually
+ * have anything to do *with* interrupts
+ */
+ interrupts::disable();
+
+ /*
+ * Save EFI system table ptr to globally accessible location.
+ * MUST do this before calling println!(), or just about anything else.
+ */
+ unsafe {
+ SYSTEM_TABLE = systab;
+ }
+
+ println!("FUZZY BUNNIES {}", env!("CARGO_PKG_VERSION"));
+ println!("efi_main @ 0x{:x}", efi_main as *const u8 as usize);
+ dprintln!("CR0: {:x?}, CR3: {:x?}", control::Cr0::read(), control::Cr3::read());
+
+ /* Set up basic exception handlers */
+ register_handlers();
+
+ // serial_poke();
+
+ // unsafe { asm!("hlt"); }
+ // let _mapkey = uefi::dump_mem_map().expect("Unable to read UEFI memory map");
+
+ let code = include_bytes!(concat!(env!("OUT_DIR"), "/ap_boot.bin"));
+ let dest = unsafe {
+ slice::from_raw_parts_mut(0x8000 as *mut u8, code.len())
+ };
+
+ let idtr = interrupt::descriptor();
+ dprintln!("copy {} bytes from 0x{:x} to 0x{:x}",
+ code.len(),
+ code.as_ptr() as usize,
+ dest.as_ptr() as usize);
+
+ dest.copy_from_slice(code);
+
+ let cr3_val: u64;
+ unsafe {
+ asm!("mov $0, cr3" : "=r" (cr3_val) ::: "intel");
+ }
+ dest[code.len()-14..code.len()-10].copy_from_slice(&(cr3_val as u32).as_bytes());
+ dest[code.len()-10..code.len()-8].copy_from_slice(&idtr.0.as_bytes());
+ dest[code.len()-8..].copy_from_slice(&idtr.1.as_bytes());
+ dprintln!("patched: {:x?}", &dest[code.len()-14..]);
+
+ unsafe {
+ ptr::write_volatile(0x6000 as *mut u64, 0);
+ ptr::write_volatile(0x6008 as *mut u64, 0);
+ ptr::write_volatile(0x600c as *mut u64, 0);
+ ptr::write_volatile(0x6010 as *mut u64, 0);
+ asm!("mfence; lfence");
+ }
+
+ /* Disable the PICs to prepare for APIC/IOAPIC */
+ unsafe {
+ io::out::<u8>(io::PIC1_DATA, io::PIC_DISABLE);
+ io::out::<u8>(io::PIC2_DATA, io::PIC_DISABLE);
+ }
+
+ let mut bsp_apic = LocalApic::init();
+ println!("APIC ID: {}, VERSION: {}", bsp_apic.id(), bsp_apic.version());
+
+ bsp_apic.enable();
+
+ dprintln!("APIC enabled");
+
+ /* INIT-SIPI-SIPI */
+ dprintln!("INIT ASSERT");
+ bsp_apic.send_ipi(IpiDestination::AllButMe,
+ IpiTriggerMode::Edge,
+ IpiLevel::Assert,
+ IpiDeliveryMode::Init,
+ 0);
+ busy();
+ // println!("INIT LEVEL DEASSERT");
+ // bsp_apic.send_ipi(IpiDestination::AllButMe,
+ // IpiTriggerMode::Level,
+ // IpiLevel::Deassert,
+ // IpiDeliveryMode::Init,
+ // 0);
+ // busy();
+ println!("SIPI spam");
+ let mut n_aps: u8 = 0;
+ // let mut ap_lock: u8;
+ while n_aps < 3 {
+ dprintln!("SIPI");
+ bsp_apic.send_ipi(IpiDestination::AllButMe,
+ IpiTriggerMode::Edge,
+ IpiLevel::Assert,
+ IpiDeliveryMode::StartUp,
+ 0x08);
+ busy();
+
+ unsafe { asm!("mfence; lfence"); }
+
+ // ap_lock = unsafe { ptr::read_volatile(0x6000 as *const u8) };
+ n_aps = unsafe { ptr::read_volatile(0x6001 as *const u8) };
+
+ // println!("ap_lock: {}, n_aps: {}", ap_lock, n_aps);
+ // {
+ // let ap_stats = unsafe { slice::from_raw_parts(0x6002 as *const u8, n_aps as usize) };
+ // println!("stat: {:x?}", ap_stats);
+ // }
+ }
+
+ interrupts::enable();
+
+ loop {
+ unsafe { asm!("hlt"); }
+ }
+}
+
+#[lang = "eh_personality"]
+#[no_mangle]
+pub extern fn eh_personality() { }
+
+#[no_mangle]
+#[panic_handler]
+pub extern fn panic_impl(pi: &PanicInfo) -> ! {
+ println!("!!! PANIC !!!");
+
+ if let Some(loc) = pi.location() {
+ println!("in file {}:{}:{}", loc.file(), loc.line(), loc.column());
+ }
+
+ if let Some(msg) = pi.message() {
+ println!("{}", msg);
+ }
+
+ loop {}
+}
diff --git a/bunny/src/println.rs b/bunny/src/println.rs
new file mode 100644
index 0000000..db59e79
--- /dev/null
+++ b/bunny/src/println.rs
@@ -0,0 +1,31 @@
+#[macro_export]
+macro_rules! print {
+ ($($arg:tt)*) => ({
+ use core::fmt::Write;
+ unsafe { (&*::SYSTEM_TABLE.as_ref().unwrap().con_out) }
+ .write_fmt(format_args!($($arg)*))
+ .expect("could not write to console");
+ });
+}
+
+#[macro_export]
+macro_rules! println {
+ ($fmt:expr) => (print!(concat!($fmt, "\r\n")));
+ ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\r\n"), $($arg)*));
+}
+
+#[macro_export]
+macro_rules! dprint {
+ ($($arg:tt)*) => ({
+ if cfg!(debug_assertions) {
+ print!($($arg)*)
+ }
+ });
+}
+
+#[macro_export]
+macro_rules! dprintln {
+ ($fmt:expr) => (dprint!(concat!($fmt, "\r\n")));
+ ($fmt:expr, $($arg:tt)*) => (dprint!(concat!($fmt, "\r\n"), $($arg)*));
+}
+
diff --git a/bunny/src/uefi.rs b/bunny/src/uefi.rs
new file mode 100644
index 0000000..a4a76d1
--- /dev/null
+++ b/bunny/src/uefi.rs
@@ -0,0 +1,49 @@
+use core::ptr;
+use efi::boot_services::*;
+use efi::types::Status;
+
+extern "win64" fn _wakeup(_ev: &Event, _ctxt: &u64) { }
+
+pub fn sleep(microseconds: u64) {
+ let bs = &unsafe { &*::SYSTEM_TABLE }.boot_services;
+
+ dprintln!("create_event");
+ let mut ev = &Event::default();
+
+ (bs._create_event)(EventType::TIMER,
+ TPL::Application,
+ None,
+ ptr::null(),
+ &mut ev)
+ .as_result()
+ .map(|_| ev)
+ .unwrap();
+
+ dprintln!("set_timer");
+ /* Set timer (unit is 100ns, so multiply microseconds by 10) */
+ bs.set_timer(ev,
+ TimerDelay::Relative,
+ microseconds * 10)
+ .unwrap();
+
+ dprintln!("wait_for_event");
+ bs.wait_for_event(&[ev]).unwrap();
+ dprintln!("close_event");
+ bs.close_event(ev).unwrap();
+}
+
+pub fn dump_mem_map() -> Result<usize, Status> {
+ let bs = &unsafe { &*::SYSTEM_TABLE }.boot_services;
+
+ let mmap = bs.get_memory_map()?;
+
+ println!("{:^16} {:^16} {:^23}", "PHYS START", "PHYS END", "TYPE");
+ for map in mmap.iter() {
+ println!("{:016x} {:016x} {:23?}",
+ map.physical_start as u64,
+ (map.physical_start as u64) + (0x1000 * map.number_of_pages),
+ map.memory_type);
+ }
+
+ Ok(mmap.key)
+}