257 lines
4.1 KiB
ArmAsm
257 lines
4.1 KiB
ArmAsm
|
|
#include "apic-defs.h"
|
|
|
|
.globl boot_idt
|
|
boot_idt = 0
|
|
|
|
.globl idt_descr
|
|
.globl tss_descr
|
|
.globl gdt64_desc
|
|
|
|
ipi_vector = 0x20
|
|
|
|
max_cpus = 64
|
|
|
|
.bss
|
|
|
|
. = . + 4096 * max_cpus
|
|
.align 16
|
|
stacktop:
|
|
|
|
. = . + 4096
|
|
.align 16
|
|
ring0stacktop:
|
|
|
|
.data
|
|
|
|
.align 4096
|
|
.globl ptl2
|
|
ptl2:
|
|
i = 0
|
|
.rept 512 * 4
|
|
.quad 0x1e7 | (i << 21)
|
|
i = i + 1
|
|
.endr
|
|
|
|
.align 4096
|
|
ptl3:
|
|
.quad ptl2 + 7 + 0 * 4096
|
|
.quad ptl2 + 7 + 1 * 4096
|
|
.quad ptl2 + 7 + 2 * 4096
|
|
.quad ptl2 + 7 + 3 * 4096
|
|
|
|
.align 4096
|
|
ptl4:
|
|
.quad ptl3 + 7
|
|
|
|
.align 4096
|
|
|
|
gdt64_desc:
|
|
.word gdt64_end - gdt64 - 1
|
|
.quad gdt64
|
|
|
|
gdt64:
|
|
.quad 0
|
|
.quad 0x00af9b000000ffff // 64-bit code segment
|
|
.quad 0x00cf93000000ffff // 32/64-bit data segment
|
|
.quad 0x00af1b000000ffff // 64-bit code segment, not present
|
|
.quad 0x00cf9b000000ffff // 32-bit code segment
|
|
.quad 0x008f9b000000FFFF // 16-bit code segment
|
|
.quad 0x008f93000000FFFF // 16-bit data segment
|
|
.quad 0x00cffb000000ffff // 32-bit code segment (user)
|
|
.quad 0x00cff3000000ffff // 32/64-bit data segment (user)
|
|
.quad 0x00affb000000ffff // 64-bit code segment (user)
|
|
|
|
.quad 0 // 6 spare selectors
|
|
.quad 0
|
|
.quad 0
|
|
.quad 0
|
|
.quad 0
|
|
.quad 0
|
|
|
|
tss_descr:
|
|
.rept max_cpus
|
|
.quad 0x000089000000ffff // 64-bit avail tss
|
|
.quad 0 // tss high addr
|
|
.endr
|
|
gdt64_end:
|
|
|
|
i = 0
|
|
.globl tss
|
|
tss:
|
|
.rept max_cpus
|
|
.long 0
|
|
.quad ring0stacktop - i * 4096
|
|
.quad 0, 0
|
|
.quad 0, 0, 0, 0, 0, 0, 0, 0
|
|
.long 0, 0, 0
|
|
i = i + 1
|
|
.endr
|
|
tss_end:
|
|
|
|
mb_boot_info: .quad 0
|
|
|
|
.section .init
|
|
|
|
.code32
|
|
|
|
mb_magic = 0x1BADB002
|
|
mb_flags = 0x0
|
|
|
|
# multiboot header
|
|
.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
|
|
mb_cmdline = 16
|
|
|
|
MSR_GS_BASE = 0xc0000101
|
|
|
|
.macro setup_percpu_area
|
|
lea -4096(%esp), %eax
|
|
mov $0, %edx
|
|
mov $MSR_GS_BASE, %ecx
|
|
wrmsr
|
|
.endm
|
|
|
|
.globl start
|
|
start:
|
|
mov %ebx, mb_boot_info
|
|
mov $stacktop, %esp
|
|
setup_percpu_area
|
|
call prepare_64
|
|
jmpl $8, $start64
|
|
|
|
prepare_64:
|
|
lgdt gdt64_desc
|
|
|
|
mov %cr4, %eax
|
|
bts $5, %eax // pae
|
|
mov %eax, %cr4
|
|
|
|
mov $ptl4, %eax
|
|
mov %eax, %cr3
|
|
|
|
efer = 0xc0000080
|
|
mov $efer, %ecx
|
|
rdmsr
|
|
bts $8, %eax
|
|
wrmsr
|
|
|
|
mov %cr0, %eax
|
|
bts $0, %eax
|
|
bts $31, %eax
|
|
mov %eax, %cr0
|
|
ret
|
|
|
|
smp_stacktop: .long 0xa0000
|
|
|
|
.align 16
|
|
|
|
gdt32:
|
|
.quad 0
|
|
.quad 0x00cf9b000000ffff // flat 32-bit code segment
|
|
.quad 0x00cf93000000ffff // flat 32-bit data segment
|
|
gdt32_end:
|
|
|
|
.code16
|
|
sipi_entry:
|
|
mov %cr0, %eax
|
|
or $1, %eax
|
|
mov %eax, %cr0
|
|
lgdtl gdt32_descr - sipi_entry
|
|
ljmpl $8, $ap_start32
|
|
|
|
gdt32_descr:
|
|
.word gdt32_end - gdt32 - 1
|
|
.long gdt32
|
|
|
|
sipi_end:
|
|
|
|
.code32
|
|
ap_start32:
|
|
mov $0x10, %ax
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
mov %ax, %ss
|
|
mov $-4096, %esp
|
|
lock/xaddl %esp, smp_stacktop
|
|
setup_percpu_area
|
|
call prepare_64
|
|
ljmpl $8, $ap_start64
|
|
|
|
.code64
|
|
ap_start64:
|
|
call load_tss
|
|
call enable_apic
|
|
call enable_x2apic
|
|
sti
|
|
nop
|
|
lock incw cpu_online_count
|
|
|
|
1: hlt
|
|
jmp 1b
|
|
|
|
start64:
|
|
call load_tss
|
|
call mask_pic_interrupts
|
|
call enable_apic
|
|
call smp_init
|
|
call enable_x2apic
|
|
mov mb_boot_info(%rip), %rbx
|
|
mov %rbx, %rdi
|
|
call setup_get_initrd
|
|
call setup_environ
|
|
mov mb_cmdline(%rbx), %eax
|
|
mov %rax, __args(%rip)
|
|
call __setup_args
|
|
mov __argc(%rip), %edi
|
|
lea __argv(%rip), %rsi
|
|
lea __environ(%rip), %rdx
|
|
call main
|
|
mov %eax, %edi
|
|
call exit
|
|
|
|
idt_descr:
|
|
.word 16 * 256 - 1
|
|
.quad boot_idt
|
|
|
|
load_tss:
|
|
lidtq idt_descr
|
|
mov $(APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
|
|
mov (%rax), %eax
|
|
shr $24, %eax
|
|
mov %eax, %ebx
|
|
shl $4, %ebx
|
|
mov $((tss_end - tss) / max_cpus), %edx
|
|
imul %edx
|
|
add $tss, %rax
|
|
mov %ax, tss_descr+2(%rbx)
|
|
shr $16, %rax
|
|
mov %al, tss_descr+4(%rbx)
|
|
shr $8, %rax
|
|
mov %al, tss_descr+7(%rbx)
|
|
shr $8, %rax
|
|
mov %eax, tss_descr+8(%rbx)
|
|
lea tss_descr-gdt64(%rbx), %rax
|
|
ltr %ax
|
|
ret
|
|
|
|
smp_init:
|
|
cld
|
|
lea sipi_entry, %rsi
|
|
xor %rdi, %rdi
|
|
mov $(sipi_end - sipi_entry), %rcx
|
|
rep/movsb
|
|
mov $APIC_DEFAULT_PHYS_BASE, %eax
|
|
movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT | APIC_INT_ASSERT), APIC_ICR(%rax)
|
|
movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_INIT), APIC_ICR(%rax)
|
|
movl $(APIC_DEST_ALLBUT | APIC_DEST_PHYSICAL | APIC_DM_STARTUP), APIC_ICR(%rax)
|
|
call fwcfg_get_nb_cpus
|
|
1: pause
|
|
cmpw %ax, cpu_online_count
|
|
jne 1b
|
|
smp_init_done:
|
|
ret
|
|
|
|
cpu_online_count: .word 1
|