aboutsummaryrefslogtreecommitdiff
path: root/bunny/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bunny/src/main.rs')
-rw-r--r--bunny/src/main.rs139
1 files changed, 43 insertions, 96 deletions
diff --git a/bunny/src/main.rs b/bunny/src/main.rs
index 4a3eb74..c5b1d10 100644
--- a/bunny/src/main.rs
+++ b/bunny/src/main.rs
@@ -1,7 +1,12 @@
-#![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 rlibc;
+extern crate alloc;
+extern crate uefi;
+extern crate uefi_services;
+
#[macro_use]
extern crate log;
@@ -11,26 +16,25 @@ mod interrupt;
mod lapic;
mod io;
mod inttraits;
-mod efifb;
use core::ptr;
-use core::slice;
-use core::panic::PanicInfo;
+use core::ffi::c_void;
+use core::sync::atomic::{AtomicUsize, Ordering};
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 RESOLUTION: (usize, usize) = (1920, 1080);
+const NUM_CORES: usize = 4;
+// const RESOLUTION: (usize, usize) = (1920, 1080);
-static mut SYSTEM_TABLE: Option<&'static SystemTable> = None;
+static mut SYSTEM_TABLE: Option<SystemTable<Boot>> = None;
+static AP_COUNT: AtomicUsize = AtomicUsize::new(0);
-pub(crate) fn system_table() -> &'static SystemTable {
- SYSTEM_TABLE.expect("System table is missing!")
+pub(crate) fn system_table() -> &'static SystemTable<Boot> {
+ unsafe { SYSTEM_TABLE.as_ref().expect("System table is missing!") }
}
#[allow(improper_ctypes)]
@@ -51,93 +55,56 @@ fn busy() {
}
}
-#[no_mangle]
-pub extern fn efi_main(_handle: uefi::Handle, systab: &'static 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
*/
+
+ uefi_services::init(&systab).expect_success("Failed to init services");
+ systab.stdout()
+ .reset(false)
+ .expect_success("Failed to reset stdout");
+
interrupts::disable();
/* Save global reference to the system table */
- SYSTEM_TABLE = Some(systab);
+ unsafe { SYSTEM_TABLE = Some(systab); }
/* Set up basic exception handlers */
register_handlers();
- /* Initialize early framebuffer */
- efifb::init();
-
interrupts::enable();
info!("FUZZY BUNNIES {}", env!("CARGO_PKG_VERSION"));
info!("efi_main @ 0x{:x}", efi_main as *const u8 as usize);
- /* 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);
+ let mp = unsafe { &*system_table()
+ .boot_services()
+ .locate_protocol::<MpServices>()
+ .expect_success("Failed to get MP services")
+ .get() };
- /* 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();
+ info!("Processors: {:?}", mp.get_number_of_processors());
- /* 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());
-
- /* Initialize AP mutex (unlocked) and count (0) */
- unsafe {
- ptr::write_volatile(0x6000 as *mut u16, 0);
- }
-
- /* Disable the PICs to prepare for other cores */
- interrupts::disable();
- unsafe {
- io::out::<u8>(io::PIC1_DATA, io::PIC_DISABLE);
- io::out::<u8>(io::PIC2_DATA, io::PIC_DISABLE);
- }
+ mp.startup_all_aps(false, ap_main, ptr::null_mut(), None)
+ .expect_success("Failed to start APs");
+ info!("huh?");
- let mut bsp_apic = LocalApic::init();
- bsp_apic.enable();
-
- /* INIT-SIPI-SIPI: Brings up other cores */
- bsp_apic.send_ipi(IpiDestination::AllButMe,
- IpiTriggerMode::Edge,
- IpiLevel::Assert,
- IpiDeliveryMode::Init,
- 0);
- busy();
-
- /*
- * 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) };
}
- debug!("All cores online");
+ info!("{} APs online", AP_COUNT.load(Ordering::SeqCst));
/* All good, turn interrupts back on and idle */
interrupts::enable();
@@ -146,23 +113,3 @@ pub extern fn efi_main(_handle: uefi::Handle, systab: &'static 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 {}
-}