Only one AP can start at a time
This commit is contained in:
parent
c74abfc8a7
commit
f14569e313
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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)*);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue