diff --git a/Makefile b/Makefile
index ebd42bc..77bfb57 100644
--- a/Makefile
+++ b/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:
diff --git a/arch/x86_64/src/acpi/mod.rs b/arch/x86_64/src/acpi/mod.rs
index eec67cf..81c7b4e 100644
--- a/arch/x86_64/src/acpi/mod.rs
+++ b/arch/x86_64/src/acpi/mod.rs
@@ -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(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(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(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(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");
diff --git a/arch/x86_64/src/start.rs b/arch/x86_64/src/start.rs
index d9221dd..04eb62e 100644
--- a/arch/x86_64/src/start.rs
+++ b/arch/x86_64/src/start.rs
@@ -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");
+ }
+}
diff --git a/bootloader/x86/bootsector.asm b/bootloader/x86/bootsector.asm
index cbf466f..bc50c22 100644
--- a/bootloader/x86/bootsector.asm
+++ b/bootloader/x86/bootsector.asm
@@ -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
diff --git a/bootloader/x86/startup-x86_64.asm b/bootloader/x86/startup-x86_64.asm
index 8ac8d89..8d27857 100644
--- a/bootloader/x86/startup-x86_64.asm
+++ b/bootloader/x86/startup-x86_64.asm
@@ -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