mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
Alternative SMP init
This commit is contained in:
parent
d475acef85
commit
93b561b388
14 changed files with 191 additions and 26 deletions
|
@ -5,7 +5,7 @@ Előre lefordított binárisok mellékelve, egyből használhatók.
|
|||
|
||||
1. *x86_64-efi* a preferált indítási mód x86_64-en.
|
||||
Szabvány GNU eszköztár plusz néhány fájl a gnuefi-ből (mellékelve).
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (95k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (96k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (100k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (100k)
|
||||
|
||||
2. *x86_64-bios* BIOS, Multiboot (GRUB), El Torito (CDROM), bővítő ROM és Linux boot kompatíbilis, RÉGI betöltő.
|
||||
Ha újra akarod fordítani, szükséged lesz a fasm-ra (nincs mellékelve).
|
||||
|
|
|
@ -5,7 +5,7 @@ I provide pre-compiled images ready for use.
|
|||
|
||||
1. *x86_64-efi* the preferred way of booting on x86_64 architecture.
|
||||
Standard GNU toolchain and a few files from gnuefi (included).
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (95k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (96k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (100k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (100k)
|
||||
|
||||
2. *x86_64-bios* BIOS, Multiboot (GRUB), El Torito (CDROM), Expansion ROM and Linux boot compatible, OBSOLETE loader.
|
||||
If you want to recompile this, you'll need fasm (not included).
|
||||
|
|
BIN
dist/bootboot.efi
vendored
BIN
dist/bootboot.efi
vendored
Binary file not shown.
BIN
dist/bootboot.rom
vendored
BIN
dist/bootboot.rom
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@
|
|||
|
||||
extern unsigned char binary_boot_bin[512];
|
||||
extern unsigned char binary_bootboot_bin[11776];
|
||||
extern unsigned char binary_bootboot_efi[96946];
|
||||
extern unsigned char binary_bootboot_efi[100386];
|
||||
extern unsigned char binary_bootboot_img[34672];
|
||||
extern unsigned char binary_LICENCE_broadcom[1594];
|
||||
extern unsigned char binary_bootcode_bin[52480];
|
||||
|
|
|
@ -1088,7 +1088,7 @@ gzerr: panic("Unable to uncompress");
|
|||
for(r = *((uint32_t*)(data + 4)), ptr = data + 44, i = 0; ptr < data + r &&
|
||||
i < (int)(sizeof(lapic_ids)/sizeof(lapic_ids[0])); ptr += ptr[1]) {
|
||||
switch(ptr[0]) {
|
||||
case 0: lapic_ids[i++] = ptr[2]; break; // found Processor Local APIC
|
||||
case 0: lapic_ids[(int)ptr[2]] = i++; break; // found Processor Local APIC
|
||||
case 5: lapic_addr = *((uint64_t*)(ptr+4)); break; // found 64 bit Local APIC Address
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,28 +129,20 @@ bit64:
|
|||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
xorq %rbx, %rbx
|
||||
// find our lapic id
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
shrl $24, %ebx
|
||||
movl %ebx, %edx
|
||||
// get array index for it
|
||||
xorq %rbx, %rbx
|
||||
xorq %rsi, %rsi
|
||||
movl $lapic_ids, %esi
|
||||
movw 0x200C, %cx // bootboot.numcores
|
||||
1: lodsw
|
||||
cmpw %dx, %ax
|
||||
je 1f
|
||||
incw %bx
|
||||
decw %cx
|
||||
jnz 1b
|
||||
xorw %bx, %bx
|
||||
1: shlq $10, %rbx // 1k stack for each core
|
||||
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
|
||||
|
||||
// set stack and call _start() in sys/core
|
||||
xorq %rsp, %rsp // sp = core_num * -1024
|
||||
subq %rbx, %rsp
|
||||
subq %rax, %rsp
|
||||
movl $entrypoint, %esi // GAS does not allow "jmp qword[entrypoint]"
|
||||
lodsq
|
||||
jmp *%rax
|
||||
|
|
|
@ -10,7 +10,7 @@ LDFLAGS += -shared -Bsymbolic -L. $(GNUEFI_CRT_OBJS)
|
|||
|
||||
TARGET = bootboot.efi
|
||||
|
||||
all: tinflate.o $(TARGET)
|
||||
all: tinflate.o smp.o $(TARGET)
|
||||
|
||||
%.efi: %.so
|
||||
@echo " src x86_64-efi (UEFI)"
|
||||
|
@ -19,10 +19,10 @@ all: tinflate.o $(TARGET)
|
|||
@gcc $(GNUEFI_INCLUDES) -Wall -fshort-wchar efirom.c -o efirom $(LIBS)
|
||||
@./efirom $(TARGET) ../dist/bootboot.rom || true
|
||||
@mv $(TARGET) ../dist/$(TARGET)
|
||||
@rm tinflate.o efirom
|
||||
@rm tinflate.o smp.o efirom
|
||||
|
||||
%.so: %.o
|
||||
@ld $(LDFLAGS) tinflate.o $^ -o $@ -lefi -lgnuefi -T $(GNUEFI_LDS)
|
||||
@ld $(LDFLAGS) tinflate.o smp.o $^ -o $@ -lefi -lgnuefi -T $(GNUEFI_LDS)
|
||||
|
||||
%.o: %.c
|
||||
@gcc $(GNUEFI_INCLUDES) $(CFLAGS) -c $< -o $@
|
||||
|
@ -31,5 +31,5 @@ all: tinflate.o $(TARGET)
|
|||
@gcc $(GNUEFI_INCLUDES) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@rm bootboot.o $(TARGET) ../dist/$(TARGET) ../dist/bootboot.rom *.so *.efi efirom tinflate.o 2>/dev/null || true
|
||||
@rm bootboot.o $(TARGET) ../dist/$(TARGET) ../dist/bootboot.rom *.so *.efi efirom tinflate.o smp.o 2>/dev/null || true
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#define BBDEBUG 1
|
||||
//#define GOP_DEBUG BBDEBUG
|
||||
#define USE_MP_SERVICES 0 /* without fallback to ACPI parser and APIC INIT + SIPI */
|
||||
|
||||
#if BBDEBUG
|
||||
#define DBG(fmt, ...) do{Print(fmt,__VA_ARGS__); }while(0);
|
||||
|
@ -156,6 +157,7 @@ typedef struct {
|
|||
struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
|
||||
struct EFI_FILE_PROTOCOL;
|
||||
|
||||
#if USE_MP_SERVICES
|
||||
#ifndef EFI_MP_SERVICES_PROTOCOL_GUID
|
||||
#define EFI_MP_SERVICES_PROTOCOL_GUID \
|
||||
{ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} }
|
||||
|
@ -218,6 +220,10 @@ struct _EFI_MP_SERVICES_PROTOCOL {
|
|||
EFI_MP_SERVICES_DUMMY WhoAmI;
|
||||
};
|
||||
#endif
|
||||
#else
|
||||
extern void ap_trampoline();
|
||||
UINT16 lapic_ids[1024];
|
||||
#endif
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
|
@ -1292,8 +1298,20 @@ LoadCore()
|
|||
*/
|
||||
VOID EFIAPI bootboot_startcore(IN VOID* buf)
|
||||
{
|
||||
#if USE_MP_SERVICES
|
||||
// we have a scalar number, not a pointer, so cast it
|
||||
UINTN core_num = (UINTN)buf;
|
||||
#else
|
||||
(void)buf;
|
||||
UINT16 core_num;
|
||||
__asm__ __volatile__ (
|
||||
"movl $1, %%eax;"
|
||||
"cpuid;"
|
||||
"shrl $24, %%ebx;"
|
||||
"mov %%bx,%0"
|
||||
: "=b"(core_num) : : );
|
||||
core_num = lapic_ids[core_num];
|
||||
#endif
|
||||
|
||||
// spinlock until BSP finishes
|
||||
do { __asm__ __volatile__ ("pause"); } while(!bsp_done);
|
||||
|
@ -1321,7 +1339,7 @@ VOID EFIAPI bootboot_startcore(IN VOID* buf)
|
|||
// pass control over
|
||||
"pushq %0;"
|
||||
"retq"
|
||||
: : "a"(entrypoint), "r"(core_num*1024) : "memory" );
|
||||
: : "a"(entrypoint), "r"((UINTN)core_num*1024) : "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1342,11 +1360,13 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
EFI_PARTITION_TABLE_HEADER *gptHdr;
|
||||
EFI_PARTITION_ENTRY *gptEnt;
|
||||
EFI_INPUT_KEY key;
|
||||
#if USE_MP_SERVICES
|
||||
EFI_EVENT Event;
|
||||
EFI_GUID mpspGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
|
||||
EFI_MP_SERVICES_PROTOCOL *mp;
|
||||
UINT8 pibuffer[100];
|
||||
EFI_PROCESSOR_INFORMATION *pibuf=(EFI_PROCESSOR_INFORMATION*)pibuffer;
|
||||
#endif
|
||||
UINTN bsp_num=0, i, j=0, x,y, handle_size=0,memory_map_size=0, map_key=0, desc_size=0;
|
||||
UINT32 desc_version=0;
|
||||
UINT64 lba_s=0,lba_e=0,sysptr;
|
||||
|
@ -1696,6 +1716,7 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
*kne='\n';
|
||||
|
||||
// Symmetric Multi Processing support
|
||||
#if USE_MP_SERVICES
|
||||
status = uefi_call_wrapper(BS->LocateProtocol, 3, &mpspGuid, NULL, (void**)&mp);
|
||||
if(!EFI_ERROR(status)) {
|
||||
// override default values in bootboot struct
|
||||
|
@ -1722,6 +1743,55 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
UINT8 *ptr = (UINT8*)bootboot->arch.x86_64.acpi_ptr, *pe, *data;
|
||||
UINT64 r, lapic_addr=0, ap_code = 0x8000;
|
||||
ZeroMem(lapic_ids, sizeof(lapic_ids));
|
||||
if(ptr && (ptr[0]=='X' || ptr[0]=='R') && ptr[1]=='S' && ptr[2]=='D' && ptr[3]=='T') {
|
||||
pe = ptr; ptr += 36;
|
||||
// iterate on ACPI table pointers
|
||||
for(r = *((uint32_t*)(pe + 4)); ptr < pe + r; ptr += pe[0] == 'X' ? 8 : 4) {
|
||||
data = (uint8_t*)(uintptr_t)(pe[0] == 'X' ? *((uint64_t*)ptr) : *((uint32_t*)ptr));
|
||||
if(!CompareMem(data, "APIC", 4)) {
|
||||
// found MADT, iterate on its variable length entries
|
||||
lapic_addr = (uint64_t)(*((uint32_t*)(data+0x24)));
|
||||
for(r = *((uint32_t*)(data + 4)), ptr = data + 44, i = 0; ptr < data + r &&
|
||||
i < (int)(sizeof(lapic_ids)/sizeof(lapic_ids[0])); ptr += ptr[1]) {
|
||||
switch(ptr[0]) {
|
||||
case 0: lapic_ids[(INTN)ptr[2]] = i++; break; // found Processor Local APIC
|
||||
case 5: lapic_addr = *((uint64_t*)(ptr+4)); break; // found 64 bit Local APIC Address
|
||||
}
|
||||
}
|
||||
if(i) {
|
||||
bootboot->numcores = i;
|
||||
bsp_num = lapic_ids[bootboot->bspid];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Allocate page at fixed address for AP trampoline code
|
||||
status = uefi_call_wrapper(BS->AllocatePages, 4, 2, 1, 1, (EFI_PHYSICAL_ADDRESS*)&ap_code);
|
||||
if(EFI_ERROR(status)) ap_code = 0;
|
||||
}
|
||||
if(bootboot->numcores > 1 && lapic_addr && ap_code) {
|
||||
DBG(L" * SMP numcores %d\n", bootboot->numcores);
|
||||
CopyMem((uint8_t*)0x8000, &ap_trampoline, 256);
|
||||
// save UEFI's 64 bit system registers for the trampoline code
|
||||
__asm__ __volatile__ (
|
||||
"movq %%cr3, %%rax; movq %%rax, 0x80C0;"
|
||||
"movl %%cs, %%eax; movl %%eax, 0x80C8;"
|
||||
"movl %%ds, %%eax; movl %%eax, 0x80CC;"
|
||||
"sgdt 0x80D0" : : : );
|
||||
// send Broadcast INIT IPI
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = 0x0C4500;
|
||||
uefi_call_wrapper(BS->Stall, 1, 10);
|
||||
// send Broadcast STARTUP IPI
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = 0x0C4608; // start at 0800:0000h
|
||||
uefi_call_wrapper(BS->Stall, 1, 1);
|
||||
// send second SIPI
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = 0x0C4608;
|
||||
}
|
||||
#endif
|
||||
|
||||
// query size of memory map
|
||||
status = uefi_call_wrapper(BS->GetMemoryMap, 5,
|
||||
|
|
103
x86_64-efi/smp.S
Normal file
103
x86_64-efi/smp.S
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* x86_64-efi/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 initialization code.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl ap_trampoline
|
||||
.extern bootboot_startcode
|
||||
|
||||
/*****************************************************************************
|
||||
* things to do on the APs *
|
||||
*****************************************************************************/
|
||||
.align 128
|
||||
.code16
|
||||
/* this code will be relocated to 0x8000 - 0x8100 */
|
||||
ap_trampoline:
|
||||
cli
|
||||
cld
|
||||
ljmp $0, $0x8040
|
||||
.align 16
|
||||
// prot mode GDT
|
||||
_L8010_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
|
||||
_L8030_GDT_value:
|
||||
.word _L8030_GDT_value - _L8010_GDT_table - 1
|
||||
.long 0x8010
|
||||
.long 0, 0
|
||||
.align 64
|
||||
_L8040:
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
lgdtl 0x8030
|
||||
movl %cr0, %eax
|
||||
orl $1, %eax
|
||||
movl %eax, %cr0
|
||||
ljmp $8, $0x8060
|
||||
.align 32
|
||||
.code32
|
||||
_L8060:
|
||||
movw $16, %ax
|
||||
movw %ax, %ds
|
||||
movl $0x368, %eax // Set PAE, MCE, PGE; OSFXSR, OSXMMEXCPT (enable SSE)
|
||||
movl %eax, %cr4
|
||||
movl 0x80C0, %eax // let's hope it's in the first 4G...
|
||||
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
|
||||
lgdtl 0x80D0
|
||||
movl 0x80C8, %eax
|
||||
push %eax
|
||||
push $0x80A0
|
||||
retf
|
||||
.align 32
|
||||
.code64
|
||||
_L80A0:
|
||||
movl 0x80CC, %eax // load long mode segments
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
jmp bootboot_startcode
|
||||
.align 32
|
||||
_L80C0_cr3_value:
|
||||
.long 0, 0
|
||||
_L80C8_cs_value:
|
||||
.long 0
|
||||
_L80CC_ds_value:
|
||||
.long 0
|
||||
_L80D0_gdt_value:
|
||||
.long 0, 0, 0, 0
|
||||
ap_trampoline_end:
|
Loading…
Reference in a new issue