123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- #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
|