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