From 0d995bfb5cc71d99f4f50c848cf8e15d6c178958 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 17 Aug 2016 19:34:33 -0600 Subject: [PATCH] Keep track of AP count, allocate bigger AP stack, stack trace function --- arch/x86_64/src/acpi/mod.rs | 6 +++++- arch/x86_64/src/idt.rs | 2 +- arch/x86_64/src/interrupt.rs | 33 +++++++++++++++++++++++++++++++-- arch/x86_64/src/panic.rs | 21 ++++----------------- arch/x86_64/src/start.rs | 17 +++++++++++++---- kernel/lib.rs | 15 +++------------ 6 files changed, 57 insertions(+), 37 deletions(-) diff --git a/arch/x86_64/src/acpi/mod.rs b/arch/x86_64/src/acpi/mod.rs index ebb5191..786398c 100644 --- a/arch/x86_64/src/acpi/mod.rs +++ b/arch/x86_64/src/acpi/mod.rs @@ -51,8 +51,12 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) { } // Allocate a stack + // TODO: Allocate contiguous let stack_start = allocate_frame().expect("no more frames").start_address().get(); - let stack_end = stack_start + 4096; + for i in 0..62 { + allocate_frame().expect("no more frames"); + } + let stack_end = allocate_frame().expect("no more frames").start_address().get() + 4096; let ap_ready = TRAMPOLINE as *mut u64; let ap_stack_start = unsafe { ap_ready.offset(1) }; diff --git a/arch/x86_64/src/idt.rs b/arch/x86_64/src/idt.rs index dcbc8b4..a5839ba 100644 --- a/arch/x86_64/src/idt.rs +++ b/arch/x86_64/src/idt.rs @@ -30,7 +30,7 @@ pub unsafe fn init_ap() { } interrupt!(blank, { - + }); interrupt!(exception, { diff --git a/arch/x86_64/src/interrupt.rs b/arch/x86_64/src/interrupt.rs index 0d37bbc..e269b08 100644 --- a/arch/x86_64/src/interrupt.rs +++ b/arch/x86_64/src/interrupt.rs @@ -2,22 +2,51 @@ /// Clear interrupts #[inline(always)] -pub unsafe fn disable_interrupts() { +pub unsafe fn disable() { asm!("cli" : : : : "intel", "volatile"); } /// Set interrupts #[inline(always)] -pub unsafe fn enable_interrupts() { +pub unsafe fn enable() { asm!("sti" : : : : "intel", "volatile"); } +/// Set interrupts and halt +#[inline(always)] +pub unsafe fn enable_and_halt() { + asm!("sti + hlt" + : : : : "intel", "volatile"); +} + /// Halt instruction #[inline(always)] pub unsafe fn halt() { asm!("hlt" : : : : "intel", "volatile"); } +/// Get a stack trace +//TODO: Check for stack being mapped before dereferencing +#[inline(never)] +pub unsafe fn stack_trace() { + let mut rbp: usize; + asm!("xchg bx, bx" : "={rbp}"(rbp) : : : "intel", "volatile"); + + println!("TRACE: {:>016X}", rbp); + //Maximum 64 frames + for _frame in 0..64 { + unsafe { + let rip = *(rbp as *const usize).offset(1); + println!(" {:>016X}: {:>016X}", rbp, rip); + if rip == 0 { + break; + } + rbp = *(rbp as *const usize); + } + } +} + /// x86 External Interrupts (1-16). pub static EXCEPTIONS: [Descriptor; 21] = [ Descriptor::new("Division error", Kind::Fault), diff --git a/arch/x86_64/src/panic.rs b/arch/x86_64/src/panic.rs index df0101f..27d361d 100644 --- a/arch/x86_64/src/panic.rs +++ b/arch/x86_64/src/panic.rs @@ -1,6 +1,6 @@ //! Intrinsics for panic handling -use interrupt::halt; +use interrupt; #[cfg(not(test))] #[lang = "eh_personality"] @@ -10,28 +10,15 @@ extern "C" fn eh_personality() {} /// Required to handle panics #[lang = "panic_fmt"] extern "C" fn panic_fmt(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! { - let mut rbp: usize; - unsafe { asm!("xchg bx, bx" : "={rbp}"(rbp) : : : "intel", "volatile"); } - println!("PANIC: {}", fmt); println!("FILE: {}", file); println!("LINE: {}", line); - println!("TRACE: {:>016X}", rbp); - for _frame in 0..16 { //Maximum 16 frames - unsafe { - let rip = *(rbp as *const usize).offset(1); - println!(" {:>016X}: {:>016X}", rbp, rip); - if rip == 0 { - break; - } - rbp = *(rbp as *const usize); - } - } + unsafe { interrupt::stack_trace(); } println!("HALT"); loop { - unsafe { halt() }; + unsafe { interrupt::halt(); } } } @@ -40,6 +27,6 @@ extern "C" fn panic_fmt(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! /// Required to handle panics pub extern "C" fn _Unwind_Resume() -> ! { loop { - unsafe { halt() } + unsafe { interrupt::halt(); } } } diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs index 3526136..48dd997 100644 --- a/arch/x86_64/src/start.rs +++ b/arch/x86_64/src/start.rs @@ -11,6 +11,7 @@ use allocator::{HEAP_START, HEAP_SIZE}; use externs::memset; use gdt; use idt; +use interrupt; use memory; use paging::{self, entry, Page, VirtualAddress}; @@ -19,6 +20,7 @@ static BSS_TEST_ZERO: usize = 0; /// Test of non-zero values in BSS. static BSS_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF; +static AP_COUNT: AtomicUsize = ATOMIC_USIZE_INIT; static BSP_READY: AtomicBool = ATOMIC_BOOL_INIT; static BSP_PAGE_TABLE: AtomicUsize = ATOMIC_USIZE_INIT; @@ -52,8 +54,6 @@ pub unsafe extern fn kstart() -> ! { debug_assert_eq!(BSS_TEST_NONZERO, 0xFFFFFFFFFFFFFFFF); } - BSP_READY.store(false, Ordering::SeqCst); - // Set up GDT gdt::init(); @@ -70,6 +70,9 @@ pub unsafe extern fn kstart() -> ! { // Initialize paging let mut active_table = paging::init(stack_start, stack_end); + // Reset AP variables + AP_COUNT.store(1, Ordering::SeqCst); + BSP_READY.store(false, Ordering::SeqCst); BSP_PAGE_TABLE.store(controlregs::cr3() as usize, Ordering::SeqCst); // Read ACPI tables, starts APs @@ -84,6 +87,8 @@ pub unsafe extern fn kstart() -> ! { } BSP_READY.store(true, Ordering::SeqCst); + + print!("BSP\n"); } kmain(); @@ -99,15 +104,19 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! { idt::init_ap(); // Initialize paging - //let mut active_table = + //let mut active_table = paging::init_ap(stack_start, stack_end, BSP_PAGE_TABLE.load(Ordering::SeqCst)); } + let ap_number = AP_COUNT.fetch_add(1, Ordering::SeqCst); + while ! BSP_READY.load(Ordering::SeqCst) { asm!("pause" : : : : "intel", "volatile"); } + print!("{}", ::core::str::from_utf8_unchecked(&[b'A', b'P', b' ', ap_number as u8 + b'0', b'\n'])); + loop { - asm!("hlt"); + interrupt::enable_and_halt(); } } diff --git a/kernel/lib.rs b/kernel/lib.rs index 0768a61..61ad13d 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -70,7 +70,7 @@ #![feature(question_mark)] #![no_std] -use arch::interrupt::{enable_interrupts, halt}; +use arch::interrupt; /// Architecture specific items (test) #[cfg(test)] @@ -107,17 +107,8 @@ pub mod tests; #[no_mangle] pub extern fn kmain() { - println!("TEST"); - - println!("{:?}", syscall::open(b"debug:", 0)); - println!("{:?}", syscall::open(b"debug:", 0)); - println!("{:?}", syscall::open(b"debug:", 0)); - loop { - unsafe { - enable_interrupts(); - halt(); - } - println!("{:?}", syscall::write(1, b"HALT\n")); + unsafe { interrupt::enable_and_halt(); } + print!("HALT\n"); } }