@@ -32,19 +32,35 @@ fn default_vm(
3232 core : usize ,
3333 mem : u64 ,
3434 info : & BootInfo ,
35+ add_uart : bool ,
3536) -> Arc < RwLock < vm:: VirtualMachine > > {
36- let mut config = vm:: VirtualMachineConfig :: new ( vec ! [ core as u8 ] , mem) ;
37+ let physical_config = if add_uart == false {
38+ vm:: PhysicalDeviceConfig :: default ( )
39+ } else {
40+ vm:: PhysicalDeviceConfig {
41+ serial : Some (
42+ physdev:: com:: Uart8250 :: new ( 0x3f8 )
43+ . expect ( "Failed to create UART" ) ,
44+ ) ,
45+ }
46+ } ;
47+
48+ let mut config =
49+ vm:: VirtualMachineConfig :: new ( vec ! [ core as u8 ] , mem, physical_config) ;
3750
3851 // FIXME: When `map_bios` may return an error, log the error.
3952 config. map_bios ( "seabios.bin" . into ( ) ) . unwrap_or ( ( ) ) ;
4053
41- let device_map = config. device_map ( ) ;
54+ let device_map = config. virtual_devices_mut ( ) ;
4255 device_map
4356 . register_device ( virtdev:: acpi:: AcpiRuntime :: new ( 0xb000 ) . unwrap ( ) )
4457 . unwrap ( ) ;
4558 device_map
4659 . register_device ( virtdev:: debug:: DebugPort :: new ( core as u64 , 0x402 ) )
4760 . unwrap ( ) ;
61+ device_map
62+ . register_device ( virtdev:: com:: Uart8250 :: new ( core as u64 , 0x3F8 ) )
63+ . unwrap ( ) ;
4864 device_map
4965 . register_device ( virtdev:: vga:: VgaController :: new ( ) )
5066 . unwrap ( ) ;
@@ -161,11 +177,6 @@ unsafe fn kmain(mut boot_info: BootInfo) -> ! {
161177
162178 // physdev::keyboard::Ps2Controller::init().expect("Failed to init ps2 controller");
163179
164- // let uart = physdev::com::Uart8250::new(0x3f8);
165- // unsafe {interrupt::enable_interrupts()};
166-
167- // loop {}
168-
169180 // If the boot method provided an RSDT, use that one. Otherwise, search the
170181 // BIOS areas for it.
171182 let rsdt = boot_info
@@ -202,64 +213,64 @@ unsafe fn kmain(mut boot_info: BootInfo) -> ! {
202213 for apic_id in apic_ids. iter ( ) {
203214 map. insert (
204215 * apic_id as usize ,
205- default_vm ( * apic_id as usize , 256 , & boot_info) ,
216+ default_vm ( * apic_id as usize , 256 , & boot_info, * apic_id == 0 ) ,
206217 ) ;
207218 }
208219
209220 vm:: VM_MAP = Some ( map) ;
210221
211222 debug ! ( "AP_STARTUP address: 0x{:x}" , AP_STARTUP_ADDR ) ;
212223
213- // for (idx, apic_id) in apic_ids.into_iter().enumerate() {
214- // if apic_id == local_apic.id() as u32 {
215- // continue;
216- // }
217-
218- // // Allocate a stack for the AP
219- // let stack = vec![0u8; 100 * 1024];
220-
221- // // Get the the bottom of the stack and align
222- // let stack_bottom =
223- // (stack.as_ptr() as u64 + stack.len() as u64) & 0xFFFFFFFFFFFFFFF0;
224-
225- // core::mem::forget(stack);
226-
227- // core::ptr::write_volatile(&mut AP_STACK_ADDR as *mut u64, stack_bottom);
228-
229- // // Map the APIC ids to a sequential list and pass it to the AP
230- // core::ptr::write_volatile(&mut AP_IDX as *mut u64, idx as u64);
231-
232- // // mfence to ensure that the APs see the new stack address
233- // core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
234-
235- // debug!("Send INIT to AP id={}", apic_id);
236- // local_apic.send_ipi(
237- // apic_id,
238- // apic::DstShorthand::NoShorthand,
239- // apic::TriggerMode::Edge,
240- // apic::Level::Assert,
241- // apic::DstMode::Physical,
242- // apic::DeliveryMode::Init,
243- // 0,
244- // );
245-
246- // debug!("Send SIPI to AP id={}", apic_id);
247- // local_apic.send_ipi(
248- // apic_id,
249- // apic::DstShorthand::NoShorthand,
250- // apic::TriggerMode::Edge,
251- // apic::Level::Assert,
252- // apic::DstMode::Physical,
253- // apic::DeliveryMode::StartUp,
254- // (AP_STARTUP_ADDR >> 12) as u8,
255- // );
256-
257- // // Wait until the AP reports that it is done with startup
258- // while core::ptr::read_volatile(&AP_READY as *const u8) != 1 {}
259-
260- // // Once the AP is done, clear the ready flag
261- // core::ptr::write_volatile(&mut AP_READY as *mut u8, 0);
262- // }
224+ for ( idx, apic_id) in apic_ids. into_iter ( ) . enumerate ( ) {
225+ if apic_id == local_apic. id ( ) as u32 {
226+ continue ;
227+ }
228+
229+ // Allocate a stack for the AP
230+ let stack = vec ! [ 0u8 ; 100 * 1024 ] ;
231+
232+ // Get the the bottom of the stack and align
233+ let stack_bottom =
234+ ( stack. as_ptr ( ) as u64 + stack. len ( ) as u64 ) & 0xFFFFFFFFFFFFFFF0 ;
235+
236+ core:: mem:: forget ( stack) ;
237+
238+ core:: ptr:: write_volatile ( & mut AP_STACK_ADDR as * mut u64 , stack_bottom) ;
239+
240+ // Map the APIC ids to a sequential list and pass it to the AP
241+ core:: ptr:: write_volatile ( & mut AP_IDX as * mut u64 , idx as u64 ) ;
242+
243+ // mfence to ensure that the APs see the new stack address
244+ core:: sync:: atomic:: fence ( core:: sync:: atomic:: Ordering :: SeqCst ) ;
245+
246+ debug ! ( "Send INIT to AP id={}" , apic_id) ;
247+ local_apic. send_ipi (
248+ apic_id,
249+ apic:: DstShorthand :: NoShorthand ,
250+ apic:: TriggerMode :: Edge ,
251+ apic:: Level :: Assert ,
252+ apic:: DstMode :: Physical ,
253+ apic:: DeliveryMode :: Init ,
254+ 0 ,
255+ ) ;
256+
257+ debug ! ( "Send SIPI to AP id={}" , apic_id) ;
258+ local_apic. send_ipi (
259+ apic_id,
260+ apic:: DstShorthand :: NoShorthand ,
261+ apic:: TriggerMode :: Edge ,
262+ apic:: Level :: Assert ,
263+ apic:: DstMode :: Physical ,
264+ apic:: DeliveryMode :: StartUp ,
265+ ( AP_STARTUP_ADDR >> 12 ) as u8 ,
266+ ) ;
267+
268+ // Wait until the AP reports that it is done with startup
269+ while core:: ptr:: read_volatile ( & AP_READY as * const u8 ) != 1 { }
270+
271+ // Once the AP is done, clear the ready flag
272+ core:: ptr:: write_volatile ( & mut AP_READY as * mut u8 , 0 ) ;
273+ }
263274
264275 vcpu:: mp_entry_point ( )
265276}
0 commit comments