Only one AP can start at a time

This commit is contained in:
Jeremy Soller 2016-09-01 17:08:43 -06:00
parent c74abfc8a7
commit f14569e313
4 changed files with 23 additions and 12 deletions

View file

@ -2,11 +2,12 @@
//! Code to parse the ACPI tables
use core::intrinsics::{atomic_load, atomic_store};
use core::sync::atomic::Ordering;
use interrupt;
use memory::{allocate_frame, Frame};
use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use start::kstart_ap;
use start::{kstart_ap, AP_READY};
use self::local_apic::{LocalApic, LocalApicIcr};
use self::madt::{Madt, MadtEntry};
@ -40,10 +41,10 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
for madt_entry in madt.iter() {
println!(" {:?}", madt_entry);
match madt_entry {
MadtEntry::LocalApic(asp_local_apic) => if asp_local_apic.id == me {
MadtEntry::LocalApic(ap_local_apic) => if ap_local_apic.id == me {
println!(" This is my local APIC");
} else {
if asp_local_apic.flags & 1 == 1 {
if ap_local_apic.flags & 1 == 1 {
// Map trampoline
{
if active_table.translate_page(Page::containing_address(VirtualAddress::new(TRAMPOLINE))).is_none() {
@ -69,28 +70,33 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
unsafe { atomic_store(ap_stack_start, stack_start as u64) };
unsafe { atomic_store(ap_stack_end, stack_end as u64) };
unsafe { atomic_store(ap_code, kstart_ap as u64) };
AP_READY.store(false, Ordering::SeqCst);
// Send INIT IPI
{
let icr = 0x00004500 | (asp_local_apic.id as u64) << 32;
println!(" Sending IPI to {}: {:>016X} {:?}", asp_local_apic.id, icr, LocalApicIcr::from_bits(icr));
let icr = 0x00004500 | (ap_local_apic.id as u64) << 32;
println!(" Sending IPI to {}: {:>016X} {:?}", ap_local_apic.id, icr, LocalApicIcr::from_bits(icr));
local_apic.set_icr(icr);
}
// Send START IPI
{
let ap_segment = (AP_STARTUP >> 12) & 0xFF;
let icr = 0x00004600 | ((asp_local_apic.id as u64) << 32) | ap_segment as u64; //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
println!(" Sending SIPI to {}: {:>016X} {:?}", asp_local_apic.id, icr, LocalApicIcr::from_bits(icr));
let icr = 0x00004600 | ((ap_local_apic.id as u64) << 32) | ap_segment as u64; //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
println!(" Sending SIPI to {}: {:>016X} {:?}", ap_local_apic.id, icr, LocalApicIcr::from_bits(icr));
local_apic.set_icr(icr);
}
// Wait for trampoline ready
println!(" Waiting for AP {}", asp_local_apic.id);
println!(" Waiting for AP {}", ap_local_apic.id);
while unsafe { atomic_load(ap_ready) } == 0 {
interrupt::pause();
}
println!(" AP {} is ready!", asp_local_apic.id);
println!(" AP {} is trampolined!", ap_local_apic.id);
while ! AP_READY.load(Ordering::SeqCst) {
interrupt::pause();
}
println!(" AP {} is ready!", ap_local_apic.id);
} else {
println!(" CPU Disabled");
}

View file

@ -24,7 +24,8 @@ extern crate x86;
macro_rules! print {
($($arg:tt)*) => ({
use core::fmt::Write;
let _ = write!($crate::console::CONSOLE.lock(), $($arg)*);
let mut console = $crate::console::CONSOLE.lock();
let _ = write!(console, $($arg)*);
});
}

View file

@ -92,7 +92,7 @@ pub unsafe fn init(stack_start: usize, stack_end: usize) -> ActivePageTable {
let uncacheable = 0;
let write_combining = 1;
let write_through = 4;
let write_protected = 5;
//let write_protected = 5;
let write_back = 6;
let uncached = 7;

View file

@ -27,6 +27,7 @@ static mut TBSS_TEST_ZERO: usize = 0;
static mut TDATA_TEST_NONZERO: usize = 0xFFFFFFFFFFFFFFFF;
static AP_COUNT: AtomicUsize = ATOMIC_USIZE_INIT;
pub static AP_READY: AtomicBool = ATOMIC_BOOL_INIT;
static BSP_READY: AtomicBool = ATOMIC_BOOL_INIT;
static HEAP_FRAME: AtomicUsize = ATOMIC_USIZE_INIT;
@ -94,6 +95,7 @@ pub unsafe extern fn kstart() -> ! {
// Reset AP variables
AP_COUNT.store(0, Ordering::SeqCst);
AP_READY.store(false, Ordering::SeqCst);
BSP_READY.store(false, Ordering::SeqCst);
HEAP_FRAME.store(0, Ordering::SeqCst);
@ -127,7 +129,7 @@ pub unsafe extern fn kstart() -> ! {
device::init(&mut active_table);
// Read ACPI tables, starts APs
// acpi::init(&mut active_table);
acpi::init(&mut active_table);
BSP_READY.store(true, Ordering::SeqCst);
}
@ -187,6 +189,8 @@ pub unsafe extern fn kstart_ap(stack_start: usize, stack_end: usize) -> ! {
// Init devices for AP
device::init_ap(&mut active_table);
AP_READY.store(true, Ordering::SeqCst);
}
let ap_number = AP_COUNT.fetch_add(1, Ordering::SeqCst);