Get the APs into rust code, set stack and page table in trampoline
This commit is contained in:
		
							parent
							
								
									a8948fb246
								
							
						
					
					
						commit
						27d5996abf
					
				
					 5 changed files with 82 additions and 42 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -12,7 +12,7 @@ bochs: build/harddrive.bin | |||
| qemu: build/harddrive.bin | ||||
| 	qemu-system-$(ARCH) -enable-kvm -cpu host -smp 4 -machine q35 \
 | ||||
| 				-serial mon:stdio -drive file=$<,format=raw,index=0,media=disk \
 | ||||
| 				-nographic -d guest_errors | ||||
| 				-nographic -d guest_errors,int,pcall | ||||
| 				#-device intel-iommu | ||||
| 
 | ||||
| FORCE: | ||||
|  |  | |||
|  | @ -2,9 +2,12 @@ | |||
| //! Code to parse the ACPI tables
 | ||||
| 
 | ||||
| use core::intrinsics::{atomic_load, atomic_store}; | ||||
| use x86::controlregs; | ||||
| 
 | ||||
| use allocator::{HEAP_START, HEAP_SIZE}; | ||||
| use memory::{Frame, FrameAllocator}; | ||||
| use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress}; | ||||
| use start::kstart_ap; | ||||
| 
 | ||||
| use self::local_apic::{LocalApic, LocalApicIcr}; | ||||
| use self::madt::{Madt, MadtEntry}; | ||||
|  | @ -21,7 +24,9 @@ pub mod xsdt; | |||
| const TRAMPOLINE: usize = 0x7E00; | ||||
| const AP_STARTUP: usize = 0x8000; | ||||
| 
 | ||||
| pub fn init_sdt(sdt: &'static Sdt) { | ||||
| pub fn init_sdt<A>(sdt: &'static Sdt, allocator: &mut A, active_table: &mut ActivePageTable) | ||||
|     where A: FrameAllocator | ||||
| { | ||||
|     print!("  "); | ||||
|     for &c in sdt.signature.iter() { | ||||
|         print!("{}", c as char); | ||||
|  | @ -42,11 +47,37 @@ pub fn init_sdt(sdt: &'static Sdt) { | |||
|                     println!("        This is my local APIC"); | ||||
|                 } else { | ||||
|                     if asp_local_apic.flags & 1 == 1 { | ||||
|                         // Map trampoline
 | ||||
|                         { | ||||
|                             if active_table.translate_page(Page::containing_address(VirtualAddress::new(TRAMPOLINE))).is_none() { | ||||
|                                 active_table.identity_map(Frame::containing_address(PhysicalAddress::new(TRAMPOLINE)), entry::PRESENT | entry::WRITABLE, allocator); | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         // Map a stack
 | ||||
|                         /* | ||||
|                         let stack_start = HEAP_START + HEAP_SIZE + 4096 + (asp_local_apic.id as usize * (1024 * 1024 + 4096)); | ||||
|                         let stack_end = stack_start + 1024 * 1024; | ||||
|                         { | ||||
|                             let start_page = Page::containing_address(VirtualAddress::new(stack_start)); | ||||
|                             let end_page = Page::containing_address(VirtualAddress::new(stack_end - 1)); | ||||
| 
 | ||||
|                             for page in Page::range_inclusive(start_page, end_page) { | ||||
|                                 active_table.map(page, entry::WRITABLE | entry::NO_EXECUTE, allocator); | ||||
|                             } | ||||
|                         } | ||||
|                         */ | ||||
| 
 | ||||
|                         let ap_ready = TRAMPOLINE as *mut u64; | ||||
|                         let ap_stack = unsafe { ap_ready.offset(1) }; | ||||
|                         let ap_page_table = unsafe { ap_ready.offset(1) }; | ||||
|                         let ap_stack = unsafe { ap_page_table.offset(1) }; | ||||
|                         let ap_code = unsafe { ap_stack.offset(1) }; | ||||
| 
 | ||||
|                         // Set the ap_ready to 0, volatile
 | ||||
|                         unsafe { atomic_store(ap_ready, 0) }; | ||||
|                         unsafe { atomic_store(ap_page_table, 0x70000) }; | ||||
|                         unsafe { atomic_store(ap_stack, 0x7C00) }; | ||||
|                         unsafe { atomic_store(ap_code, kstart_ap as u64) }; | ||||
| 
 | ||||
|                         // Send INIT IPI
 | ||||
|                         { | ||||
|  | @ -99,18 +130,11 @@ pub unsafe fn init<A>(allocator: &mut A, active_table: &mut ActivePageTable) -> | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Map trampoline
 | ||||
|     { | ||||
|         if active_table.translate_page(Page::containing_address(VirtualAddress::new(TRAMPOLINE))).is_none() { | ||||
|             active_table.identity_map(Frame::containing_address(PhysicalAddress::new(TRAMPOLINE)), entry::PRESENT | entry::WRITABLE, allocator); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Search for RSDP
 | ||||
|     if let Some(rsdp) = RSDP::search(start_addr, end_addr) { | ||||
|         println!("{:?}", rsdp); | ||||
| 
 | ||||
|         let mut get_sdt = |sdt_address: usize| -> &'static Sdt { | ||||
|         let get_sdt = |sdt_address: usize, allocator: &mut A, active_table: &mut ActivePageTable| -> &'static Sdt { | ||||
|             if active_table.translate_page(Page::containing_address(VirtualAddress::new(sdt_address))).is_none() { | ||||
|                 let sdt_frame = Frame::containing_address(PhysicalAddress::new(sdt_address)); | ||||
|                 active_table.identity_map(sdt_frame, entry::PRESENT | entry::NO_EXECUTE, allocator); | ||||
|  | @ -118,7 +142,7 @@ pub unsafe fn init<A>(allocator: &mut A, active_table: &mut ActivePageTable) -> | |||
|             &*(sdt_address as *const Sdt) | ||||
|         }; | ||||
| 
 | ||||
|         let rxsdt = get_sdt(rsdp.sdt_address()); | ||||
|         let rxsdt = get_sdt(rsdp.sdt_address(), allocator, active_table); | ||||
| 
 | ||||
|         for &c in rxsdt.signature.iter() { | ||||
|             print!("{}", c as char); | ||||
|  | @ -126,11 +150,13 @@ pub unsafe fn init<A>(allocator: &mut A, active_table: &mut ActivePageTable) -> | |||
|         println!(":"); | ||||
|         if let Some(rsdt) = Rsdt::new(rxsdt) { | ||||
|             for sdt_address in rsdt.iter() { | ||||
|                 init_sdt(get_sdt(sdt_address)); | ||||
|                 let sdt = get_sdt(sdt_address, allocator, active_table); | ||||
|                 init_sdt(sdt, allocator, active_table); | ||||
|             } | ||||
|         } else if let Some(xsdt) = Xsdt::new(rxsdt) { | ||||
|             for sdt_address in xsdt.iter() { | ||||
|                 init_sdt(get_sdt(sdt_address)); | ||||
|                 let sdt = get_sdt(sdt_address, allocator, active_table); | ||||
|                 init_sdt(sdt, allocator, active_table); | ||||
|             } | ||||
|         } else { | ||||
|             println!("UNKNOWN RSDT OR XSDT SIGNATURE"); | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ use externs::memset; | |||
| use gdt; | ||||
| use idt; | ||||
| use memory; | ||||
| use paging::{self, Page, VirtualAddress}; | ||||
| use paging::{self, entry, Page, VirtualAddress}; | ||||
| 
 | ||||
| /// Test of zero values in BSS.
 | ||||
| static BSS_TEST_ZERO: usize = 0; | ||||
|  | @ -21,6 +21,7 @@ extern { | |||
|     fn kmain() -> !; | ||||
| } | ||||
| 
 | ||||
| /// The entry to Rust, all things must be initialized
 | ||||
| #[no_mangle] | ||||
| pub unsafe extern fn kstart() -> ! { | ||||
|     { | ||||
|  | @ -62,7 +63,7 @@ pub unsafe extern fn kstart() -> ! { | |||
|         let heap_end_page = Page::containing_address(VirtualAddress::new(HEAP_START + HEAP_SIZE-1)); | ||||
| 
 | ||||
|         for page in Page::range_inclusive(heap_start_page, heap_end_page) { | ||||
|             active_table.map(page, paging::entry::WRITABLE, &mut allocator); | ||||
|             active_table.map(page, entry::WRITABLE | entry::NO_EXECUTE, &mut allocator); | ||||
|         } | ||||
| 
 | ||||
|         // Read ACPI tables
 | ||||
|  | @ -78,3 +79,10 @@ pub unsafe extern fn kstart() -> ! { | |||
|     asm!("xchg bx, bx" : : : : "intel", "volatile"); | ||||
|     kmain(); | ||||
| } | ||||
| 
 | ||||
| /// Entry to rust for an AP
 | ||||
| pub unsafe extern fn kstart_ap() -> ! { | ||||
|     loop { | ||||
|         asm!("hlt"); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -65,31 +65,31 @@ load: | |||
|     mov [DAPACK.count], cx | ||||
|     mov [DAPACK.seg], dx | ||||
| 
 | ||||
|     mov si, loading | ||||
|     call print | ||||
|     ; mov si, loading | ||||
|     ; call print | ||||
| 
 | ||||
|     mov bx, [DAPACK.addr] | ||||
|     call print_num | ||||
|     ; mov bx, [DAPACK.addr] | ||||
|     ; call print_num | ||||
| 
 | ||||
|     mov al, '#' | ||||
|     call print_char | ||||
| 
 | ||||
|     mov bx, [DAPACK.count] | ||||
|     call print_num | ||||
| 
 | ||||
|     mov al, ' ' | ||||
|     call print_char | ||||
| 
 | ||||
|     mov bx, [DAPACK.seg] | ||||
|     call print_num | ||||
| 
 | ||||
|     mov al, ':' | ||||
|     call print_char | ||||
| 
 | ||||
|     mov bx, [DAPACK.buf] | ||||
|     call print_num | ||||
| 
 | ||||
|     call print_line | ||||
|     ; mov al, '#' | ||||
|     ; call print_char | ||||
|     ; | ||||
|     ; mov bx, [DAPACK.count] | ||||
|     ; call print_num | ||||
|     ; | ||||
|     ; mov al, ' ' | ||||
|     ; call print_char | ||||
|     ; | ||||
|     ; mov bx, [DAPACK.seg] | ||||
|     ; call print_num | ||||
|     ; | ||||
|     ; mov al, ':' | ||||
|     ; call print_char | ||||
|     ; | ||||
|     ; mov bx, [DAPACK.buf] | ||||
|     ; call print_num | ||||
|     ; | ||||
|     ; call print_line | ||||
| 
 | ||||
|     mov dl, [disk] | ||||
|     mov si, DAPACK | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| trampoline: | ||||
|     .ready: dq 0 | ||||
|     .page_table: dq 0 | ||||
|     .stack: dq 0 | ||||
|     .code: dq 0 | ||||
| 
 | ||||
|     times 512 - ($ - trampoline) db 0 | ||||
| 
 | ||||
|  | @ -126,10 +128,14 @@ long_mode_ap: | |||
|     mov gs, rax | ||||
|     mov ss, rax | ||||
| 
 | ||||
|     mov rax, [trampoline.page_table] | ||||
|     mov cr3, rax | ||||
| 
 | ||||
|     mov rsp, [trampoline.stack] | ||||
| 
 | ||||
|     mov qword [trampoline.ready], 1 | ||||
| .lp: | ||||
|     hlt | ||||
|     jmp .lp | ||||
|     mov rax, [trampoline.code] | ||||
|     jmp rax | ||||
| 
 | ||||
| gdtr: | ||||
|     dw gdt.end + 1  ; size | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller