Only one AP can start at a time
This commit is contained in:
		
							parent
							
								
									c74abfc8a7
								
							
						
					
					
						commit
						f14569e313
					
				
					 4 changed files with 23 additions and 12 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller