diff options
Diffstat (limited to 'bunny/src/main.rs')
-rw-r--r-- | bunny/src/main.rs | 153 |
1 files changed, 52 insertions, 101 deletions
diff --git a/bunny/src/main.rs b/bunny/src/main.rs index e7f5c70..c5b1d10 100644 --- a/bunny/src/main.rs +++ b/bunny/src/main.rs @@ -1,34 +1,41 @@ -#![feature(lang_items, panic_info_message, abi_x86_interrupt, core_intrinsics, asm, link_llvm_intrinsics, int_to_from_bytes)] +#![feature(lang_items, panic_info_message, abi_x86_interrupt, core_intrinsics, asm, link_llvm_intrinsics, abi_efiapi)] #![no_std] #![no_main] -extern crate efi; -extern crate x86_64; -extern crate volatile; +extern crate rlibc; +extern crate alloc; +extern crate uefi; +extern crate uefi_services; + +#[macro_use] +extern crate log; #[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 core::ffi::c_void; +use core::sync::atomic::{AtomicUsize, Ordering}; -use efi::types::Handle; -use efi::SystemTable; +use uefi::prelude::*; +use uefi::proto::pi::mp::MpServices; use x86_64::instructions::interrupts; use self::interrupt::*; -use self::lapic::*; -use self::inttraits::*; -const NUM_CORES: u8 = 4; +const NUM_CORES: usize = 4; +// const RESOLUTION: (usize, usize) = (1920, 1080); -static mut SYSTEM_TABLE: *const SystemTable = 0 as *const SystemTable; +static mut SYSTEM_TABLE: Option<SystemTable<Boot>> = None; +static AP_COUNT: AtomicUsize = AtomicUsize::new(0); + +pub(crate) fn system_table() -> &'static SystemTable<Boot> { + unsafe { SYSTEM_TABLE.as_ref().expect("System table is missing!") } +} #[allow(improper_ctypes)] extern "C" { @@ -48,92 +55,56 @@ fn busy() { } } -#[no_mangle] -pub extern fn efi_main(_handle: Handle, systab: &SystemTable) -> ! { +extern "efiapi" fn ap_main(_ctxt: *mut c_void) { + AP_COUNT.fetch_add(1, Ordering::SeqCst); + // loop { + // unsafe { asm!("hlt"); } + // } +} + +#[entry] +fn efi_main(_handle: uefi::Handle, systab: SystemTable<Boot>) -> Status { /* * 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; - } + uefi_services::init(&systab).expect_success("Failed to init services"); + systab.stdout() + .reset(false) + .expect_success("Failed to reset stdout"); + + interrupts::disable(); - println!("FUZZY BUNNIES {}", env!("CARGO_PKG_VERSION")); - println!("efi_main @ 0x{:x}", efi_main as *const u8 as usize); + /* Save global reference to the system table */ + unsafe { SYSTEM_TABLE = Some(systab); } /* Set up basic exception handlers */ register_handlers(); - /* Set up AP bootstrap (real->long transition) code */ - let code = include_bytes!(concat!(env!("OUT_DIR"), "/ap_boot.bin")); - let dest = unsafe { - /* Copy the code to somewhere in the first 1MB of memory */ - slice::from_raw_parts_mut(0x8000 as *mut u8, code.len()) - }; - - dest.copy_from_slice(code); - - /* Read initial CR3 register to pass off to other cores */ - let cr3_val: u64; - unsafe { - asm!("mov $0, cr3" : "=r" (cr3_val) ::: "intel"); - } - - let idtr = interrupt::descriptor(); - - /* Fill in CR3 (u32) and IDTR (u16; u64) at the end of the bootstrap code */ - 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()); + interrupts::enable(); - /* Initialize AP mutex (unlocked) and count (0) */ - unsafe { - ptr::write_volatile(0x6000 as *mut u16, 0); - } + info!("FUZZY BUNNIES {}", env!("CARGO_PKG_VERSION")); + info!("efi_main @ 0x{:x}", efi_main as *const u8 as usize); - /* Disable the PICs to prepare for other cores */ - unsafe { - io::out::<u8>(io::PIC1_DATA, io::PIC_DISABLE); - io::out::<u8>(io::PIC2_DATA, io::PIC_DISABLE); - } + let mp = unsafe { &*system_table() + .boot_services() + .locate_protocol::<MpServices>() + .expect_success("Failed to get MP services") + .get() }; - let mut bsp_apic = LocalApic::init(); - bsp_apic.enable(); + info!("Processors: {:?}", mp.get_number_of_processors()); - /* INIT-SIPI-SIPI: Brings up other cores */ - bsp_apic.send_ipi(IpiDestination::AllButMe, - IpiTriggerMode::Edge, - IpiLevel::Assert, - IpiDeliveryMode::Init, - 0); - busy(); + mp.startup_all_aps(false, ap_main, ptr::null_mut(), None) + .expect_success("Failed to start APs"); + info!("huh?"); - /* - * Wait for cores to get themselves figured out, retrying the SIPI - * broadcast until everyone is accounted for. - */ - let mut n_aps: u8 = 0; - while n_aps < NUM_CORES-1 { - bsp_apic.send_ipi(IpiDestination::AllButMe, - IpiTriggerMode::Edge, - IpiLevel::Assert, - IpiDeliveryMode::StartUp, - 0x08); + while AP_COUNT.load(Ordering::SeqCst) < NUM_CORES - 1 { + info!("{} cores", AP_COUNT.load(Ordering::SeqCst)); busy(); - - n_aps = unsafe { ptr::read_volatile(0x6001 as *const u8) }; } - dprintln!("All cores online"); + info!("{} APs online", AP_COUNT.load(Ordering::SeqCst)); /* All good, turn interrupts back on and idle */ interrupts::enable(); @@ -142,23 +113,3 @@ pub extern fn efi_main(_handle: Handle, systab: &SystemTable) -> ! { 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 {} -} |