From df083e306a53e6a45a5730e7059032be43cc75ff Mon Sep 17 00:00:00 2001 From: Nick Shipp Date: Sun, 30 Sep 2018 17:05:47 -0400 Subject: Dirty rotten commit full of badness Milestone: Got SMP cores booting and into long mode. The rest is all trash, but maybe trash worth a future archaeological dig. --- .gitmodules | 3 + bunny/Cargo.toml | 10 + bunny/build.rs | 13 + bunny/libefi | 1 + bunny/src/interrupt.rs | 1213 ++++++++++++++++++++++++++++++++++++++++++++++++ bunny/src/inttraits.rs | 14 + bunny/src/io.rs | 18 + bunny/src/lapic.rs | 313 +++++++++++++ bunny/src/main.rs | 211 +++++++++ bunny/src/println.rs | 31 ++ bunny/src/uefi.rs | 49 ++ 11 files changed, 1876 insertions(+) create mode 100644 .gitmodules create mode 100644 bunny/Cargo.toml create mode 100644 bunny/build.rs create mode 160000 bunny/libefi create mode 100644 bunny/src/interrupt.rs create mode 100644 bunny/src/inttraits.rs create mode 100644 bunny/src/io.rs create mode 100644 bunny/src/lapic.rs create mode 100644 bunny/src/main.rs create mode 100644 bunny/src/println.rs create mode 100644 bunny/src/uefi.rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d82a40a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "bunny/libefi"] + path = bunny/libefi + url = https://github.com/reynoldsbd/libefi diff --git a/bunny/Cargo.toml b/bunny/Cargo.toml new file mode 100644 index 0000000..5f6ae9d --- /dev/null +++ b/bunny/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "bunny" +version = "0.1.0" +authors = ["Nick Shipp "] +build = "build.rs" + +[dependencies] +efi = { path = "libefi" } +x86_64 = "*" +volatile = "*" diff --git a/bunny/build.rs b/bunny/build.rs new file mode 100644 index 0000000..58b8695 --- /dev/null +++ b/bunny/build.rs @@ -0,0 +1,13 @@ +use std::process::Command; +use std::env; + +fn main() { + let out_dir = env::var("OUT_DIR").unwrap(); + let obj = format!("{}/ap_boot.bin", out_dir); + + Command::new("nasm") + .args(&["-Wall", "-fbin", "src/ap_boot.s", "-o"]) + .arg(&obj) + .status() + .unwrap(); +} diff --git a/bunny/libefi b/bunny/libefi new file mode 160000 index 0000000..eb7ea42 --- /dev/null +++ b/bunny/libefi @@ -0,0 +1 @@ +Subproject commit eb7ea420e9f2d8f61961556db9e669fe165ec6cb 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::() - 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::()) } + } +} + +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(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, + _pad00: [u32; 3], + + _r0010: Ro, + _pad01: [u32; 3], + + id: Ro, /* 0020 */ + _pad02: [u32; 3], + + version: Ro, /* 0030 */ + _pad03: [u32; 3], + + _r0040: Ro, + _pad04: [u32; 3], + + _r0050: Ro, + _pad05: [u32; 3], + + _r0060: Ro, + _pad06: [u32; 3], + + _r0070: Ro, + _pad07: [u32; 3], + + task_priority: Ro, /* 0080 */ + _pad08: [u32; 3], + + arbitration_priority: Ro, /* 0090 */ + _pad09: [u32; 3], + + processor_priority: Ro, /* 00A0 */ + _pad10: [u32; 3], + + eoi: Ro, /* 00B0 */ + _pad11: [u32; 3], + + remote_read: Ro, /* 00C0 */ + _pad12: [u32; 3], + + logical_destination: Ro, /* 00D0 */ + _pad13: [u32; 3], + + destination_format: Ro, /* 00E0 */ + _pad14: [u32; 3], + + spurious_interrupt_vector: Rw, /* 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, /* 0280 */ + _pad16: [u32; 3], + + _r0290: Ro, + _pad17: [u32; 3], + + _r02A0: Ro, + _pad18: [u32; 3], + + _r02B0: Ro, + _pad19: [u32; 3], + + _r02C0: Ro, + _pad20: [u32; 3], + + _r02D0: Ro, + _pad21: [u32; 3], + + _r02E0: Ro, + _pad22: [u32; 3], + + lvt_corrected_machine_check_interrupt: Rw, /* 02F0 */ + _pad23: [u32; 3], + + interrupt_command_register: Rw<[u32; 8]>, /* 0300-0310 */ + + lvt_timer: Rw, /* 0320 */ + _pad25: [u32; 3], + + lvt_thermal_sensor: Rw, /* 0330 */ + _pad26: [u32; 3], + + lvt_performance_monitoring_counters: Rw, /* 0340 */ + _pad27: [u32; 3], + + lvt_lint0: Rw, /* 0350 */ + _pad28: [u32; 3], + + lvt_lint1: Rw, /* 0360 */ + _pad29: [u32; 3], + + lvt_error: Rw, /* 0370 */ + _pad30: [u32; 3], + + initial_count: Rw, /* 0380 */ + _pad31: [u32; 3], + + current_count: Ro, /* 0390 */ + _pad32: [u32; 3], + + _r03A0: Ro, + _pad33: [u32; 3], + + _r03B0: Ro, + _pad34: [u32; 3], + + _r03C0: Ro, + _pad35: [u32; 3], + + _r03D0: Ro, + _pad36: [u32; 3], + + divide_conf: Rw, /* 03E0 */ + _pad37: [u32; 3], + + _r03F0: Ro, +} +*/ + +#[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::(io::PIC1_DATA, io::PIC_DISABLE); + io::out::(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 { + 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) +} -- cgit v1.2.3-54-g00ecf