2020-09-16 22:41:14 -04:00
|
|
|
/*
|
|
|
|
* x86_64-cb/smp.S
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017 - 2020 bzt (bztsrc@gitlab)
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person
|
|
|
|
* obtaining a copy of this software and associated documentation
|
|
|
|
* files (the "Software"), to deal in the Software without
|
|
|
|
* restriction, including without limitation the rights to use, copy,
|
|
|
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
|
|
* of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be
|
|
|
|
* included in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
* This file is part of the BOOTBOOT Protocol package.
|
|
|
|
* @brief SMP and long mode initialization code.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
.globl ap_trampoline
|
|
|
|
.globl bsp_init
|
2020-10-02 14:36:33 -04:00
|
|
|
.globl bsp64_init
|
2020-09-16 22:41:14 -04:00
|
|
|
.extern lapic_ids
|
|
|
|
|
|
|
|
.text
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* things to do on the APs *
|
|
|
|
*****************************************************************************/
|
|
|
|
.align 128
|
|
|
|
.code16
|
|
|
|
/* this code will be relocated to 0x1000 - 0x1100 */
|
|
|
|
ap_trampoline:
|
|
|
|
cli
|
|
|
|
cld
|
|
|
|
ljmp $0, $0x1040
|
|
|
|
.align 16
|
|
|
|
// prot mode GDT
|
|
|
|
_L1010_GDT_table:
|
|
|
|
.long 0, 0
|
|
|
|
.long 0x0000FFFF, 0x00CF9A00 // flat code
|
|
|
|
.long 0x0000FFFF, 0x008F9200 // flat data
|
|
|
|
.long 0x00000068, 0x00CF8900 // tss, not used but required by VB's vt-x
|
|
|
|
_L1030_GDT_value:
|
|
|
|
.word _L1030_GDT_value - _L1010_GDT_table - 1
|
|
|
|
.long 0x1010
|
|
|
|
.long 0, 0
|
|
|
|
.align 64
|
|
|
|
_L1040:
|
|
|
|
xorw %ax, %ax
|
|
|
|
movw %ax, %ds
|
|
|
|
lgdtl 0x1030
|
|
|
|
movl %cr0, %eax
|
|
|
|
orl $1, %eax
|
|
|
|
movl %eax, %cr0
|
|
|
|
ljmp $8, $0x1060
|
|
|
|
.align 32
|
|
|
|
.code32
|
|
|
|
_L1060:
|
|
|
|
movw $16, %ax
|
|
|
|
movw %ax, %ds
|
|
|
|
// spinlock until BSP finishes
|
|
|
|
1: pause
|
|
|
|
cmpb $0, 0x1010
|
|
|
|
jz 1b
|
|
|
|
// jump back to non-relocated code segment
|
|
|
|
jmp longmode_init
|
|
|
|
.align 128
|
|
|
|
ap_trampoline_end:
|
|
|
|
|
|
|
|
// long mode GDT (here it is aligned and out of execution flow)
|
|
|
|
GDT_table:
|
|
|
|
.long 0, 0
|
|
|
|
.long 0x0000FFFF, 0x00209800 // flat code, ring 0
|
|
|
|
.long 0x0000FFFF, 0x00809200 // flat data
|
|
|
|
.long 0x00000068, 0x00008900 // tss, required by vt-x
|
|
|
|
.long 0, 0
|
|
|
|
GDT_value:
|
|
|
|
.word GDT_value - GDT_table - 1
|
|
|
|
.long GDT_table, 0, 0
|
|
|
|
.word 0
|
2020-10-02 15:03:22 -04:00
|
|
|
.align 8
|
|
|
|
stack64:
|
|
|
|
.long bit64
|
|
|
|
.long 0
|
|
|
|
.quad 8
|
2020-09-16 22:41:14 -04:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* things to do on BSP *
|
|
|
|
*****************************************************************************/
|
2020-10-02 14:36:33 -04:00
|
|
|
/* these are 32 bit encoded instructions */
|
2020-09-16 22:41:14 -04:00
|
|
|
bsp_init:
|
|
|
|
cli
|
2020-10-02 14:36:33 -04:00
|
|
|
cld
|
2020-09-16 22:41:14 -04:00
|
|
|
movb $0xFF, %al // disable PIC
|
|
|
|
outb %al, $0x21
|
|
|
|
outb %al, $0xA1
|
|
|
|
inb $0x70, %al // disable NMI
|
|
|
|
orb $0x80, %al
|
|
|
|
outb %al, $0x70
|
|
|
|
incb 0x1010 // release AP spin lock
|
|
|
|
// fall into long mode initialization code
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* common code for all cores, enable long mode and start kernel *
|
|
|
|
*****************************************************************************/
|
|
|
|
longmode_init:
|
|
|
|
movl $0x368, %eax // Set PAE, MCE, PGE; OSFXSR, OSXMMEXCPT (enable SSE)
|
|
|
|
movl %eax, %cr4
|
|
|
|
movl $0x4000, %eax
|
|
|
|
movl %eax, %cr3
|
|
|
|
movl $0x0C0000080, %ecx // EFR MSR
|
|
|
|
rdmsr
|
|
|
|
orl $0x100, %eax // enable long mode
|
|
|
|
wrmsr
|
|
|
|
|
|
|
|
movl $0x0C0000011, %eax // clear EM, MP (enable SSE) and WP
|
|
|
|
movl %eax, %cr0
|
|
|
|
lgdt GDT_value
|
|
|
|
ljmp $8, $bit64
|
2020-10-02 14:36:33 -04:00
|
|
|
|
2020-09-16 22:41:14 -04:00
|
|
|
.code64
|
2020-10-02 14:36:33 -04:00
|
|
|
/* similar code to above, but these are 64 bit encoded, only needed on BSP if coreboot is compiled for x86_64 */
|
|
|
|
bsp64_init:
|
|
|
|
cli
|
|
|
|
cld
|
|
|
|
movb $0xFF, %al // disable PIC
|
|
|
|
outb %al, $0x21
|
|
|
|
outb %al, $0xA1
|
|
|
|
inb $0x70, %al // disable NMI
|
|
|
|
orb $0x80, %al
|
|
|
|
outb %al, $0x70
|
|
|
|
incb 0x1010 // release AP spin lock
|
2020-10-02 15:03:22 -04:00
|
|
|
xorq %rax, %rax
|
|
|
|
movl $0xC0000011, %eax // enable SSE
|
|
|
|
movq %rax, %cr0
|
|
|
|
movq %cr4, %rax
|
|
|
|
orw $3 << 8, %ax
|
|
|
|
mov %rax, %cr4
|
|
|
|
movl $0x4000, %eax // set up paging
|
|
|
|
movq %rax, %cr3
|
|
|
|
xorq %rax, %rax
|
|
|
|
movl $GDT_value, %eax
|
|
|
|
lgdt (%rax)
|
|
|
|
movl $stack64, %eax // reload CS, that's tricky in long mode because ljmp doesn't work
|
|
|
|
movq %rax, %rsp
|
|
|
|
lretq
|
2020-10-02 14:36:33 -04:00
|
|
|
|
2020-09-16 22:41:14 -04:00
|
|
|
bit64:
|
|
|
|
movl $0x10, %eax // load long mode segments
|
|
|
|
movw %ax, %ds
|
|
|
|
movw %ax, %es
|
|
|
|
movw %ax, %ss
|
|
|
|
movw %ax, %fs
|
|
|
|
movw %ax, %gs
|
2020-09-17 16:36:06 -04:00
|
|
|
xorq %rbx, %rbx
|
2020-09-16 22:41:14 -04:00
|
|
|
// find our lapic id
|
|
|
|
movl $1, %eax
|
|
|
|
cpuid
|
2020-09-17 16:36:06 -04:00
|
|
|
shrl $23, %ebx
|
|
|
|
andb $0xfe, %bl // ebx = lapic id * 2
|
|
|
|
addl $lapic_ids, %ebx
|
|
|
|
xorq %rax, %rax
|
|
|
|
movw (%rbx), %ax // ax = word[lapic_ids + lapic id * 2]
|
|
|
|
1: shlq $10, %rax // 1k stack for each core
|
2020-09-16 22:41:14 -04:00
|
|
|
|
|
|
|
// set stack and call _start() in sys/core
|
|
|
|
xorq %rsp, %rsp // sp = core_num * -1024
|
2020-09-17 16:36:06 -04:00
|
|
|
subq %rax, %rsp
|
2020-10-02 14:36:33 -04:00
|
|
|
xorq %rsi, %rsi
|
2020-09-16 22:41:14 -04:00
|
|
|
movl $entrypoint, %esi // GAS does not allow "jmp qword[entrypoint]"
|
|
|
|
lodsq
|
|
|
|
jmp *%rax
|
|
|
|
hlt
|