mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 21:27:36 +00:00
Kernel: Reorganize Arch/x86 directory to Arch/x86_64 after i686 removal
No functional change.
This commit is contained in:
parent
5ff318cf3a
commit
91db482ad3
129 changed files with 482 additions and 1116 deletions
230
Kernel/Arch/x86_64/Boot/ap_setup.S
Normal file
230
Kernel/Arch/x86_64/Boot/ap_setup.S
Normal file
|
@ -0,0 +1,230 @@
|
|||
#include <Kernel/Sections.h>
|
||||
|
||||
.section .text
|
||||
|
||||
.global gdt64ptr
|
||||
gdt64ptr:
|
||||
.quad 0
|
||||
|
||||
.global code64_sel
|
||||
code64_sel:
|
||||
.short 0
|
||||
|
||||
/*
|
||||
The apic_ap_start function will be loaded to P0x00008000 where the APIC
|
||||
will boot the AP from in real mode. This code also contains space for
|
||||
special variables that *must* remain here. When initializing the APIC,
|
||||
the code here gets copied to P0x00008000, the variables in here get
|
||||
populated and then the boot of the APs will be triggered.
|
||||
Having the variables here allows us to access them from real mode. Also, the
|
||||
code here avoids the need for relocation entries.
|
||||
|
||||
Basically, the variables between apic_ap_start and end_apic_ap_start
|
||||
*MUST* remain here and cannot be moved into a .bss or any other location.
|
||||
*/
|
||||
.global apic_ap_start
|
||||
.type apic_ap_start, @function
|
||||
.align 8
|
||||
apic_ap_start:
|
||||
.code16
|
||||
cli
|
||||
jmp $0x800, $(1f - apic_ap_start) /* avoid relocation entries */
|
||||
1:
|
||||
mov %cs, %ax
|
||||
mov %ax, %ds
|
||||
|
||||
xor %ax, %ax
|
||||
mov %ax, %sp
|
||||
|
||||
/* load the first temporary gdt */
|
||||
lgdt (ap_cpu_gdtr_initial - apic_ap_start)
|
||||
|
||||
/* enable PM */
|
||||
movl %cr0, %eax
|
||||
orl $1, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
ljmpl $8, $(apic_ap_start32 - apic_ap_start + 0x8000)
|
||||
apic_ap_start32:
|
||||
.code32
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ss
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
|
||||
movl $0x8000, %ebp
|
||||
|
||||
/* generate a unique ap cpu id (0 means 1st ap, not bsp!) */
|
||||
xorl %eax, %eax
|
||||
incl %eax
|
||||
lock; xaddl %eax, (ap_cpu_id - apic_ap_start)(%ebp) /* avoid relocation entries */
|
||||
movl %eax, %esi
|
||||
|
||||
/* check if we support NX and enable it if we do */
|
||||
movl $0x80000001, %eax
|
||||
cpuid
|
||||
testl $0x100000, %edx
|
||||
je (1f - apic_ap_start + 0x8000)
|
||||
/* turn on IA32_EFER.NXE */
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
orl $0x800, %eax
|
||||
wrmsr
|
||||
1:
|
||||
|
||||
/* load the bsp's cr3 value */
|
||||
movl (ap_cpu_init_cr3 - apic_ap_start)(%ebp), %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
/* Enter Long-mode! ref(https://wiki.osdev.org/Setting_Up_Long_Mode)*/
|
||||
mov $0xC0000080, %ecx /* Set the C-register to 0xC0000080, which is the EFER MSR.*/
|
||||
rdmsr /* Read from the model-specific register.*/
|
||||
or $(1 << 8), %eax /* Set the LM-bit which is the 9th bit (bit 8).*/
|
||||
wrmsr /* Write to the model-specific register.*/
|
||||
|
||||
/* enable PAE + PSE */
|
||||
movl %cr4, %eax
|
||||
orl $0x60, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* enable PG */
|
||||
movl %cr0, %eax
|
||||
orl $0x80000000, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* load the temporary 64-bit gdt from boot that points above 3GB */
|
||||
lgdt (ap_cpu_gdt64ptr - apic_ap_start + 0x8000)
|
||||
|
||||
/* Jump into our identity mapped area, stay in low memory for now.
|
||||
We need to fully enable 64 bit mode before we can adjust rsp and rip
|
||||
to values higher than 4GB */
|
||||
ljmpl $(ap_cpu_gdt64code - ap_cpu_gdt64), $(apic_ap_start64 - apic_ap_start + 0x8000)
|
||||
.code64
|
||||
apic_ap_start64:
|
||||
movq (ap_cpu_kernel_map_base - apic_ap_start)(%rbp), %rbp
|
||||
addq $0x8000, %rbp
|
||||
|
||||
/* find our allocated stack based on the generated id */
|
||||
movq (ap_cpu_init_stacks - apic_ap_start)(%rbp, %rsi, 8), %rsp
|
||||
|
||||
/* Now jump from our identity mapped area into high memory */
|
||||
movq $(1f - apic_ap_start), %rax
|
||||
addq %rbp, %rax
|
||||
jmp *%rax
|
||||
1:
|
||||
mov $0, %ax
|
||||
mov %ax, %ss
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
|
||||
/* flush the TLB */
|
||||
movq %cr3, %rax
|
||||
movq %rax, %cr3
|
||||
|
||||
/* now load the final gdt and idt from the identity mapped area */
|
||||
movq (ap_cpu_gdtr - apic_ap_start)(%rbp), %rax
|
||||
lgdt (%rax)
|
||||
movq (ap_cpu_idtr - apic_ap_start)(%rbp), %rax
|
||||
lidt (%rax)
|
||||
|
||||
/* set same cr0 and cr4 values as the BSP */
|
||||
movq (ap_cpu_init_cr0 - apic_ap_start)(%rbp), %rax
|
||||
movq %rax, %cr0
|
||||
movq (ap_cpu_init_cr4 - apic_ap_start)(%rbp), %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
|
||||
/* Save the cpu id into rdi (first argument), 0 representing the bsp */
|
||||
movq %rsi, %rdi
|
||||
incq %rdi
|
||||
|
||||
/* Save the Processor pointer this CPU is going to use into rsi (second argument) */
|
||||
movq (ap_cpu_init_processor_info_array - apic_ap_start)(%rbp), %rax
|
||||
movq 0(%rax, %rsi, 8), %rsi
|
||||
|
||||
/* Get the entry function */
|
||||
movq (ap_cpu_kernel_entry_function - apic_ap_start)(%rbp), %r10
|
||||
|
||||
movq %rsp, %rbp
|
||||
cld
|
||||
|
||||
/* We are in identity mapped P0x8000 and the BSP will unload this code
|
||||
once all APs are initialized, so call the entry function and return to our
|
||||
infinite loop if it ever were to return. */
|
||||
call *%r10
|
||||
|
||||
loop:
|
||||
hlt
|
||||
jmp loop
|
||||
|
||||
.align 4
|
||||
.global apic_ap_start_size
|
||||
apic_ap_start_size:
|
||||
.2byte end_apic_ap_start - apic_ap_start
|
||||
.align 4
|
||||
ap_cpu_id:
|
||||
.4byte 0x0
|
||||
ap_cpu_gdt:
|
||||
/* null */
|
||||
.8byte 0x0
|
||||
/* code */
|
||||
.4byte 0x0000FFFF
|
||||
.4byte 0x00cf9a00
|
||||
/* data */
|
||||
.4byte 0x0000FFFF
|
||||
.4byte 0x00cf9200
|
||||
ap_cpu_gdt_end:
|
||||
ap_cpu_gdtr_initial:
|
||||
.2byte ap_cpu_gdt_end - ap_cpu_gdt - 1
|
||||
.4byte (ap_cpu_gdt - apic_ap_start) + 0x8000
|
||||
.align 8
|
||||
.global ap_cpu_gdtr
|
||||
ap_cpu_gdtr:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_idtr
|
||||
ap_cpu_idtr:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_init_cr0
|
||||
ap_cpu_init_cr0:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_init_cr3
|
||||
ap_cpu_init_cr3:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_init_cr4
|
||||
ap_cpu_init_cr4:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_gdt64
|
||||
ap_cpu_gdt64:
|
||||
.8byte 0x0
|
||||
.global ap_cpu_gdt64code
|
||||
ap_cpu_gdt64code:
|
||||
.4byte 0xffff
|
||||
.4byte 0xaf9a00
|
||||
.global ap_cpu_gdt64data
|
||||
ap_cpu_gdt64data:
|
||||
.4byte 0xffff
|
||||
.4byte 0xaf9200
|
||||
.global ap_cpu_gdt64ptr
|
||||
ap_cpu_gdt64ptr:
|
||||
.2byte ap_cpu_gdt64ptr - ap_cpu_gdt64 - 1
|
||||
.8byte (ap_cpu_gdt64 - apic_ap_start) + 0x8000
|
||||
.align 8
|
||||
.global ap_cpu_kernel_entry_function
|
||||
ap_cpu_kernel_entry_function:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_kernel_map_base
|
||||
ap_cpu_kernel_map_base:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_init_processor_info_array
|
||||
ap_cpu_init_processor_info_array:
|
||||
.8byte 0x0 /* will be set at runtime */
|
||||
.global ap_cpu_init_stacks
|
||||
ap_cpu_init_stacks:
|
||||
/* array of allocated stack pointers */
|
||||
/* NOTE: ap_cpu_init_stacks must be the last variable before
|
||||
end_apic_ap_start! */
|
||||
.set end_apic_ap_start, .
|
Loading…
Add table
Add a link
Reference in a new issue