Move some code from the trampoline to global_asm!()
This commit is contained in:
@@ -82,8 +82,8 @@ pub(super) fn init(madt: Madt) {
|
||||
let idt_ptr = crate::arch::idt::allocate_and_init_idt(cpu_id);
|
||||
|
||||
let args = KernelArgsAp {
|
||||
stack_end: stack_end as *mut u8,
|
||||
cpu_id,
|
||||
page_table: page_table_physaddr,
|
||||
pcr_ptr,
|
||||
idt_ptr,
|
||||
};
|
||||
@@ -91,16 +91,13 @@ pub(super) fn init(madt: Madt) {
|
||||
let ap_ready = (TRAMPOLINE + 8) as *mut u64;
|
||||
let ap_args_ptr = unsafe { ap_ready.add(1) };
|
||||
let ap_page_table = unsafe { ap_ready.add(2) };
|
||||
let ap_stack_end = unsafe { ap_ready.add(3) };
|
||||
let ap_code = unsafe { ap_ready.add(4) };
|
||||
let ap_code = unsafe { ap_ready.add(3) };
|
||||
|
||||
// Set the ap_ready to 0, volatile
|
||||
unsafe {
|
||||
ap_ready.write(0);
|
||||
ap_args_ptr.write(&args as *const _ as u64);
|
||||
ap_page_table.write(page_table_physaddr as u64);
|
||||
ap_stack_end.write(stack_end as u64);
|
||||
#[expect(clippy::fn_to_numeric_cast)]
|
||||
ap_code.write(kstart_ap as u64);
|
||||
|
||||
// TODO: Is this necessary (this fence)?
|
||||
@@ -127,7 +124,6 @@ pub(super) fn init(madt: Madt) {
|
||||
|
||||
// Send START IPI
|
||||
{
|
||||
//Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
|
||||
let ap_segment = (TRAMPOLINE >> 12) & 0xFF;
|
||||
let mut icr = 0x4600 | ap_segment as u64;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use core::{
|
||||
arch::global_asm,
|
||||
cell::SyncUnsafeCell,
|
||||
hint,
|
||||
mem::offset_of,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
@@ -13,13 +14,8 @@ use core::{
|
||||
use crate::acpi;
|
||||
|
||||
use crate::{
|
||||
allocator,
|
||||
cpu_set::LogicalCpuId,
|
||||
device,
|
||||
devices::graphical_debug,
|
||||
gdt, idt, interrupt,
|
||||
paging::{self, PhysicalAddress, RmmA, RmmArch, TableKind},
|
||||
startup::KernelArgs,
|
||||
allocator, cpu_set::LogicalCpuId, device, devices::graphical_debug, gdt, idt, interrupt,
|
||||
paging, startup::KernelArgs,
|
||||
};
|
||||
|
||||
/// Test of zero values in BSS.
|
||||
@@ -171,14 +167,51 @@ unsafe extern "C" fn start(args_ptr: *const KernelArgs, stack_end: usize) -> ! {
|
||||
}
|
||||
|
||||
pub struct KernelArgsAp {
|
||||
pub stack_end: *mut u8,
|
||||
pub cpu_id: LogicalCpuId,
|
||||
pub page_table: usize,
|
||||
pub pcr_ptr: *mut gdt::ProcessorControlRegion,
|
||||
pub idt_ptr: *mut idt::Idt,
|
||||
}
|
||||
|
||||
// FIXME use extern "custom"
|
||||
unsafe extern "C" {
|
||||
pub fn kstart_ap();
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
global_asm!("
|
||||
.globl kstart_ap
|
||||
kstart_ap:
|
||||
mov esp, dword ptr [edi + {args_stack}]
|
||||
mov [esp + 4], edi
|
||||
mov [esp + 8], esp
|
||||
|
||||
jmp {start_ap}
|
||||
",
|
||||
args_stack = const offset_of!(KernelArgsAp, stack_end),
|
||||
start_ap = sym start_ap,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
global_asm!("
|
||||
.globl kstart_ap
|
||||
kstart_ap:
|
||||
// Note: The System V ABI requires the stack to be aligned to 16 bytes
|
||||
// before the call instruction. As we jump rather than call it has to
|
||||
// be offset by 8 bytes. Additionally reserve a bit more space at the
|
||||
// end of the stack to ensure that the start function returns to
|
||||
// address 0.
|
||||
mov rax, qword ptr [rdi + {args_stack}]
|
||||
lea rsp, [rax - 24]
|
||||
|
||||
jmp {start_ap}
|
||||
",
|
||||
args_stack = const offset_of!(KernelArgsAp, stack_end),
|
||||
start_ap = sym start_ap,
|
||||
);
|
||||
|
||||
/// Entry to rust for an AP
|
||||
pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
|
||||
unsafe extern "C" fn start_ap(args_ptr: *const KernelArgsAp) -> ! {
|
||||
unsafe {
|
||||
let cpu_id = {
|
||||
let args = &*args_ptr;
|
||||
@@ -190,7 +223,6 @@ pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
|
||||
idt::install_idt(args.idt_ptr);
|
||||
|
||||
// Initialize paging
|
||||
RmmA::set_table(TableKind::Kernel, PhysicalAddress::new(args.page_table));
|
||||
paging::init();
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", feature = "profiling"))]
|
||||
|
||||
@@ -11,7 +11,6 @@ trampoline:
|
||||
.ready: dq 0
|
||||
.args_ptr: dq 0
|
||||
.page_table: dq 0
|
||||
.stack_end: dq 0
|
||||
.code: dq 0
|
||||
|
||||
startup_ap:
|
||||
@@ -68,19 +67,11 @@ protected_mode_ap:
|
||||
mov gs, eax
|
||||
mov ss, eax
|
||||
|
||||
mov eax, [trampoline.stack_end]
|
||||
lea esp, [eax - 256]
|
||||
|
||||
mov eax, [trampoline.args_ptr]
|
||||
push eax
|
||||
mov edi, [trampoline.args_ptr]
|
||||
|
||||
mov eax, [trampoline.code]
|
||||
mov dword [trampoline.ready], 1
|
||||
call eax
|
||||
.halt:
|
||||
cli
|
||||
hlt
|
||||
jmp .halt
|
||||
jmp eax
|
||||
|
||||
struc GDTEntry
|
||||
.limitl resw 1
|
||||
|
||||
@@ -11,7 +11,6 @@ trampoline:
|
||||
.ready: dq 0
|
||||
.args_ptr: dq 0
|
||||
.page_table: dq 0
|
||||
.stack_end: dq 0
|
||||
.code: dq 0
|
||||
|
||||
startup_ap:
|
||||
@@ -75,9 +74,6 @@ long_mode_ap:
|
||||
mov gs, rax
|
||||
mov ss, rax
|
||||
|
||||
mov rcx, [trampoline.stack_end]
|
||||
lea rsp, [rcx - 256]
|
||||
|
||||
mov rdi, [trampoline.args_ptr]
|
||||
|
||||
mov rax, [trampoline.code]
|
||||
|
||||
Reference in New Issue
Block a user