1
0
Fork 0
mirror of https://gitlab.com/bztsrc/bootboot.git synced 2023-02-13 20:54:32 -05:00
bztsrc--bootboot/x86_64-cb/smp.S

204 lines
6.1 KiB
ArmAsm
Raw Normal View History

2020-09-16 22:41:14 -04:00
/*
* x86_64-cb/smp.S
*
2021-01-15 15:07:25 -05:00
* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
2020-09-16 22:41:14 -04:00
*
* 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
.extern lapic_addr
2021-01-20 23:54:39 -05:00
.extern initstack
2020-09-16 22:41:14 -04:00
.text
/*****************************************************************************
* things to do on the APs *
*****************************************************************************/
.balign 128
2020-09-16 22:41:14 -04:00
.code16
/* this code will be relocated to 0x1000 - 0x1100 */
ap_trampoline:
cli
cld
ljmp $0, $0x1040
.balign 16
2020-09-16 22:41:14 -04:00
// 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
.balign 64
2020-09-16 22:41:14 -04:00
_L1040:
xorw %ax, %ax
movw %ax, %ds
lgdtl 0x1030
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
ljmp $8, $0x1060
.balign 32
2020-09-16 22:41:14 -04:00
.code32
_L1060:
movw $16, %ax
movw %ax, %ds
2021-01-24 00:14:50 -05:00
incb 0x1011
2020-09-16 22:41:14 -04:00
// spinlock until BSP finishes
1: pause
cmpb $0, 0x1010
jz 1b
// jump back to non-relocated code segment
ljmp $8, $longmode_init
.balign 128
2020-09-16 22:41:14 -04:00
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
.balign 8
2020-10-02 15:03:22 -04:00
stack64:
.long bootboot_startcore
2020-10-02 15:03:22 -04:00
.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:
2021-01-24 00:14:50 -05:00
// enable lapic and find our lapic id
movl lapic_addr, %edi
or %edi, %edi
jz 1f
2021-01-24 00:14:50 -05:00
addl $0xF0, %edi
movl (%edi), %eax
or $0x1, %ah
movl %eax, (%edi)
subl $0xD0, %edi
movl (%edi), %edi
shrl $24, %edi
1: // do not clobber di
2020-09-16 22:41:14 -04:00
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, $bootboot_startcore
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:
// do not clobber di
2020-10-02 14:36:33 -04:00
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
/* IN: di = apic id of current core */
bootboot_startcore:
2020-09-16 22:41:14 -04:00
movl $0x10, %eax // load long mode segments
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
movzwq %di, %rbx
shll $1, %ebx // ebx = lapic id * 2
2020-09-17 16:36:06 -04:00
addl $lapic_ids, %ebx
xorq %rax, %rax
movw (%rbx), %ax // ax = word[lapic_ids + lapic id * 2]
movl $initstack, %ebx
2021-01-20 23:54:39 -05:00
movl (%rbx), %ebx
movzwq %ax, %rdi
2021-01-20 23:54:39 -05:00
mulq %rbx // 1k stack for each core
2020-09-16 22:41:14 -04:00
// set stack and call _start() in sys/core
2021-01-20 23:54:39 -05:00
xorq %rsp, %rsp // sp = core_num * -initstack
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