|
|
|
@ -3,28 +3,21 @@ use memory::*;
|
|
|
|
|
use core::ptr::{read_volatile, write_volatile};
|
|
|
|
|
use x86_64::registers::control_regs::cr3;
|
|
|
|
|
|
|
|
|
|
extern {
|
|
|
|
|
fn entryother_start(); // physical addr of entryother
|
|
|
|
|
fn entryother_end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ENTRYOTHER_ADDR: u32 = 0x7000;
|
|
|
|
|
|
|
|
|
|
pub fn start_other_cores(acpi: &AcpiResult, ms: &mut MemorySet) {
|
|
|
|
|
use consts::KERNEL_OFFSET;
|
|
|
|
|
ms.push(MemoryArea::new_identity(ENTRYOTHER_ADDR as usize - 1, ENTRYOTHER_ADDR as usize + 1, MemoryAttr::default(), "entry_other"));
|
|
|
|
|
ms.push(MemoryArea::new_identity(entryother_start as usize, entryother_start as usize + 1, MemoryAttr::default(), "entry_other"));
|
|
|
|
|
ms.push(MemoryArea::new_kernel(KERNEL_OFFSET, KERNEL_OFFSET + 1, MemoryAttr::default(), "entry_other3"));
|
|
|
|
|
copy_entryother();
|
|
|
|
|
ms.push(MemoryArea::new_identity(ENTRYOTHER_ADDR as usize, ENTRYOTHER_ADDR as usize + 1, MemoryAttr::default().execute(), "entry_other.text"));
|
|
|
|
|
ms.push(MemoryArea::new_kernel(KERNEL_OFFSET, KERNEL_OFFSET + 1, MemoryAttr::default(), "entry_other.ctrl"));
|
|
|
|
|
|
|
|
|
|
let args = unsafe{ &mut *(ENTRYOTHER_ADDR as *mut EntryArgs).offset(-1) };
|
|
|
|
|
let args = unsafe { &mut *(0x8000 as *mut EntryArgs).offset(-1) };
|
|
|
|
|
for i in 1 .. acpi.cpu_num {
|
|
|
|
|
let apic_id = acpi.cpu_acpi_ids[i as usize];
|
|
|
|
|
let ms = MemorySet::new(7);
|
|
|
|
|
*args = EntryArgs {
|
|
|
|
|
kstack: ms.kstack_top() as u64,
|
|
|
|
|
page_table: ms._page_table_addr().0 as u32,
|
|
|
|
|
stack: 0x8000, // just enough stack to get us to entry64mp
|
|
|
|
|
page_table: cr3().0 as u32,
|
|
|
|
|
stack: args as *const _ as u32, // just enough stack to get us to entry64mp
|
|
|
|
|
};
|
|
|
|
|
unsafe { MS = Some(ms); }
|
|
|
|
|
start_ap(apic_id, ENTRYOTHER_ADDR);
|
|
|
|
@ -32,16 +25,6 @@ pub fn start_other_cores(acpi: &AcpiResult, ms: &mut MemorySet) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn copy_entryother() {
|
|
|
|
|
use rlibc::memmove;
|
|
|
|
|
let entryother_start = entryother_start as usize;
|
|
|
|
|
let entryother_end = entryother_end as usize;
|
|
|
|
|
let size = entryother_end - entryother_start;
|
|
|
|
|
assert!(size <= 0x1000, "entryother code is too large, not supported.");
|
|
|
|
|
unsafe{ memmove(ENTRYOTHER_ADDR as *mut u8, entryother_start as *mut u8, size); }
|
|
|
|
|
debug!("smp: copied entryother code to 0x7000");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct EntryArgs {
|
|
|
|
|