mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
SSE and SMP support
This commit is contained in:
parent
b6e1f6f89a
commit
a42fd37e81
17 changed files with 470 additions and 123 deletions
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
|||
Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
Copyright (C) 2017 - 2019 bzt (bztsrc@gitlab)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
|
24
README.md
24
README.md
|
@ -5,11 +5,11 @@ 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/bootboot.efi) (93k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (93k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (94k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (93k)
|
||||
|
||||
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).
|
||||
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR, VBR and CDROM boot record too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (10k, loaded by boot.bin, also BBS Expansion ROM and Multiboot compliant)
|
||||
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR, VBR and CDROM boot record too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (11k, loaded by boot.bin, also BBS Expansion ROM and Multiboot compliant)
|
||||
|
||||
3. *aarch64-rpi* ARMv8 boot loader for Raspberry Pi 3
|
||||
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (30k)
|
||||
|
@ -144,7 +144,7 @@ When the kernel gains control, the memory mapping looks like this:
|
|||
0-16G RAM identity mapped (0x0000000400000000)
|
||||
```
|
||||
|
||||
All infomration is passed at linker defined addresses. No API required at all, therefore the BOOTBOOT Protocol is
|
||||
All information is passed at linker defined addresses. No API required at all, therefore the BOOTBOOT Protocol is
|
||||
totally architecture and ABI agnostic. Level 1 expects these symbols at pre-defined addresses you see above, level 2
|
||||
loaders parse the symbol table in executable to get the actual addresses.
|
||||
|
||||
|
@ -169,7 +169,10 @@ load kernels at -2M, therefore limiting the kernel's size in 2M, including confi
|
|||
must be more than enough for all micro-kernels. Bss segment is after the text segment, growing upwards, and it's zerod-out
|
||||
by the loader.
|
||||
|
||||
The stack is at the top of the memory, starting at zero and growing downwards.
|
||||
Co-processor enabled, and if Symmetric Multi Processing supported, all cores are running the same kernel code at once.
|
||||
|
||||
The stack is at the top of the memory, starting at zero and growing downwards. Each core has it's own 1k stack on SMP systems
|
||||
(core 0's stack starts at 0, core 1's at -1024 etc.).
|
||||
|
||||
Environment file
|
||||
----------------
|
||||
|
@ -257,6 +260,7 @@ extern uint8_t fb; // linear framebuffer mapped
|
|||
|
||||
void _start()
|
||||
{
|
||||
/*** NOTE: this code runs on all cores in parallel ***/
|
||||
int x, y, s=bootboot.fb_scanline, w=bootboot.fb_width, h=bootboot.fb_height;
|
||||
|
||||
// cross-hair to see screen dimension detected correctly
|
||||
|
@ -279,6 +283,18 @@ void _start()
|
|||
For compilation, see example bootboot kernel's [Makefile](https://gitlab.com/bztsrc/bootboot/blob/master/mykernel/Makefile) and
|
||||
[link.ld](https://gitlab.com/bztsrc/bootboot/blob/master/mykernel/link.ld).
|
||||
|
||||
Because on an SMP system all cores executing the same code, you probably want to start your kernel with something like:
|
||||
|
||||
```c
|
||||
if (currentcoreid == bootboot.bspid) {
|
||||
/* things to do on the bootstrap processor */
|
||||
} else {
|
||||
/* things to do on the application processor(s) */
|
||||
}
|
||||
```
|
||||
|
||||
On x86_64, 'currentcoreid' is the Local Apic Id (cpuid[eax=1].ebx >> 24), on AArch64 that's (mpidr_el1 & 3).
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ In addition to standard mappings, the MMIO is also mapped in kernel space:
|
|||
-128M MMIO (0xFFFFFFFFF8000000)
|
||||
```
|
||||
|
||||
Code is running in supervisor mode, at EL1. Dummy exception handlers are installed, but your kernel should use it's own
|
||||
handlers as soon as possible.
|
||||
Code is running in supervisor mode, at EL1 on all cores. Dummy exception handlers are installed, but your kernel should use
|
||||
it's own handlers as soon as possible.
|
||||
|
||||
File system drivers
|
||||
-------------------
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* aarch64-rpi/boot.S
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
|
@ -30,7 +30,6 @@
|
|||
.section ".text.boot"
|
||||
|
||||
.global _start
|
||||
.global jumptokernel
|
||||
|
||||
/*********************************************************************
|
||||
* Entry point called by start.elf *
|
||||
|
@ -39,14 +38,8 @@ _start:
|
|||
// magic
|
||||
b 1f
|
||||
.ascii "BOOTBOOT"
|
||||
// read cpu id, stop slave cores
|
||||
1: mrs x7, mpidr_el1
|
||||
and x7, x7, #3
|
||||
cbz x7, 2f
|
||||
1: wfe
|
||||
b 1b
|
||||
2: // set stack before our code
|
||||
ldr x1, =_start
|
||||
// set stack before our code
|
||||
1: ldr x1, =_start
|
||||
// set up EL1
|
||||
mrs x0, CurrentEL
|
||||
and x0, x0, #12
|
||||
|
@ -65,8 +58,8 @@ _start:
|
|||
beq 1f
|
||||
msr sp_el1, x1
|
||||
// set up exception handlers
|
||||
ldr x1, =_vectors
|
||||
msr vbar_el2, x1
|
||||
ldr x2, =_vectors
|
||||
msr vbar_el2, x2
|
||||
// enable CNTP for EL1
|
||||
mrs x0, cnthctl_el2
|
||||
orr x0, x0, #3
|
||||
|
@ -98,7 +91,14 @@ _start:
|
|||
adr x2, 1f
|
||||
msr elr_el2, x2
|
||||
eret
|
||||
1: // clear bss
|
||||
// set up exception handlers
|
||||
1: ldr x2, =_vectors
|
||||
msr vbar_el1, x2
|
||||
// read cpu id, start slave cores
|
||||
mrs x7, mpidr_el1
|
||||
and x7, x7, #3
|
||||
cbnz x7, 3f
|
||||
// clear bss
|
||||
ldr x2, =__bss_start
|
||||
ldr w3, =__bss_size
|
||||
1: cbz w3, 2f
|
||||
|
@ -106,13 +106,9 @@ _start:
|
|||
sub w3, w3, #1
|
||||
cbnz w3, 1b
|
||||
2: mov sp, x1
|
||||
// set up exception handlers
|
||||
ldr x1, =_vectors
|
||||
msr vbar_el1, x1
|
||||
// jump to C code
|
||||
bl bootboot_main
|
||||
1: wfe
|
||||
b 1b
|
||||
3: b bootboot_startcore
|
||||
|
||||
.align 11
|
||||
_vectors:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* aarch64-rpi/bootboot.c
|
||||
*
|
||||
* Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
* Copyright (C) 2017 - 2019 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
@ -755,6 +755,9 @@ unsigned char *kne;
|
|||
// alternative environment name
|
||||
char *cfgname="sys/config";
|
||||
|
||||
uint64_t entrypoint=0, bss=0, *paging, reg, pa;
|
||||
uint8_t bsp_done=0;
|
||||
|
||||
#ifdef _FS_Z_H_
|
||||
/**
|
||||
* SHA-256
|
||||
|
@ -1101,15 +1104,14 @@ void ParseEnvironment(uint8_t *env)
|
|||
}
|
||||
|
||||
/**
|
||||
* bootboot entry point
|
||||
* bootboot entry point, run only on BSP core
|
||||
*/
|
||||
int bootboot_main(uint64_t hcl)
|
||||
{
|
||||
uint8_t *pe,bkp=0;
|
||||
uint32_t np,sp,r,pa,mp;
|
||||
uint32_t np,sp,r,mp;
|
||||
efipart_t *part;
|
||||
volatile bpb_t *bpb;
|
||||
uint64_t entrypoint=0, bss=0, *paging, reg;
|
||||
MMapEnt *mmap;
|
||||
|
||||
/* initialize UART */
|
||||
|
@ -1165,10 +1167,9 @@ int bootboot_main(uint64_t hcl)
|
|||
bootboot = (BOOTBOOT*)&__bootboot;
|
||||
memset(bootboot,0,PAGESIZE);
|
||||
memcpy((void*)&bootboot->magic,BOOTBOOT_MAGIC,4);
|
||||
bootboot->protocol = PROTOCOL_STATIC;
|
||||
bootboot->loader_type = LOADER_RPI;
|
||||
bootboot->protocol = PROTOCOL_STATIC | LOADER_RPI;
|
||||
bootboot->size = 128;
|
||||
bootboot->pagesize = PAGESIZE==4096? 12 : (PAGESIZE==65536 ? 16 : 14);
|
||||
bootboot->numcores = 4;
|
||||
bootboot->aarch64.mmio_ptr = COREMMIO_BASE;
|
||||
// set up a framebuffer so that we can write on screen
|
||||
if(!GetLFB(0, 0)) goto viderr;
|
||||
|
@ -1516,6 +1517,8 @@ gzerr: puts("BOOTBOOT-PANIC: Unable to uncompress\n");
|
|||
uart_hex((uint64_t)core.ptr+core.size,4);
|
||||
uart_putc('\n');
|
||||
#endif
|
||||
/* we have fixed number of cores, nothing to detect */
|
||||
DBG(" * SMP numcores 4\n");
|
||||
|
||||
/* generate memory map to bootboot struct */
|
||||
DBG(" * Memory Map\n");
|
||||
|
@ -1629,7 +1632,7 @@ viderr:
|
|||
#if MEM_DEBUG
|
||||
reg=r;
|
||||
#endif
|
||||
paging[5*512+511]=(uint64_t)((uint8_t*)&__corestack)|0b11|(3<<8)|(1<<10)|(1L<<54); // core stack
|
||||
paging[5*512+511]=(uint64_t)((uint8_t*)&__corestack)|0b11|(3<<8)|(1<<10)|(1L<<54); // core stacks (1k each)
|
||||
// core L3 (lfb)
|
||||
for(r=0;r<16*512;r++)
|
||||
paging[6*512+r]=(uint64_t)((uint8_t*)bootboot->fb_ptr+r*PAGESIZE)|0b11|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //map framebuffer
|
||||
|
@ -1677,6 +1680,35 @@ viderr:
|
|||
for(r=508;r<512;r++) { uart_hex(paging[5*512+r],8); uart_putc(' '); }
|
||||
uart_puts("\n\n");
|
||||
#endif
|
||||
#if DEBUG
|
||||
uart_puts(" * Entry point ");
|
||||
uart_hex(entrypoint,8);
|
||||
uart_putc('\n');
|
||||
#endif
|
||||
// release AP spinlock
|
||||
bsp_done=1;
|
||||
return 0;
|
||||
|
||||
// Wait until Enter or Space pressed, then reboot
|
||||
error:
|
||||
while(r!='\n' && r!=' ') r=uart_getc();
|
||||
uart_puts("\n\n");
|
||||
|
||||
// reset
|
||||
asm volatile("dsb sy; isb");
|
||||
*PM_WATCHDOG = PM_WDOG_MAGIC | 1;
|
||||
*PM_RTSC = PM_WDOG_MAGIC | PM_RTSC_FULLRST;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* start kernel, run on all cores
|
||||
*/
|
||||
void bootboot_startcore()
|
||||
{
|
||||
// spinlock until BSP finishes
|
||||
do { asm volatile ("dsb sy"); } while(!bsp_done);
|
||||
|
||||
// enable paging
|
||||
reg=(0xFF << 0) | // Attr=0: normal, IWBWA, OWBWA, NTR
|
||||
(0x04 << 8) | // Attr=1: device, nGnRE (must be OSH too)
|
||||
|
@ -1713,22 +1745,9 @@ viderr:
|
|||
reg|=(1<<0)/*|(1<<19)|(1<<12)|(1<<2)*/; // set M enable MMU, WXN, I instruction cache, C data cache
|
||||
asm volatile ("msr sctlr_el1, %0; isb" : : "r" (reg));
|
||||
|
||||
// jump to core's _start
|
||||
#if DEBUG
|
||||
uart_puts(" * Entry point ");
|
||||
uart_hex(entrypoint,8);
|
||||
uart_putc('\n');
|
||||
#endif
|
||||
asm volatile ("mov sp,#-16; mov x30, %0; ret" : : "r" (entrypoint));
|
||||
|
||||
// Wait until Enter or Space pressed, then reboot
|
||||
error:
|
||||
while(r!='\n' && r!=' ') r=uart_getc();
|
||||
uart_puts("\n\n");
|
||||
|
||||
// reset
|
||||
asm volatile("dsb sy; isb");
|
||||
*PM_WATCHDOG = PM_WDOG_MAGIC | 1;
|
||||
*PM_RTSC = PM_WDOG_MAGIC | PM_RTSC_FULLRST;
|
||||
while(1);
|
||||
// set stack and call _start() in sys/core
|
||||
asm volatile ( "mrs x0, mpidr_el1;"
|
||||
"and x0, x0, #3;"
|
||||
"sub x0, xzr, x0, lsl #10;" // sp = core_num * -1024
|
||||
"mov sp, x0; mov x30, %0; ret" : : "r" (entrypoint));
|
||||
}
|
||||
|
|
BIN
bootboot.bin
BIN
bootboot.bin
Binary file not shown.
BIN
bootboot.efi
BIN
bootboot.efi
Binary file not shown.
21
bootboot.h
21
bootboot.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* bootboot.h
|
||||
*
|
||||
* Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
* Copyright (C) 2017 - 2019 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
@ -50,9 +50,9 @@ extern "C" {
|
|||
#define PROTOCOL_BIGENDIAN 0x80
|
||||
|
||||
// loader types, just informational
|
||||
#define LOADER_BIOS 0
|
||||
#define LOADER_UEFI 1
|
||||
#define LOADER_RPI 2
|
||||
#define LOADER_BIOS (0<<2)
|
||||
#define LOADER_UEFI (1<<2)
|
||||
#define LOADER_RPI (2<<2)
|
||||
|
||||
// framebuffer pixel format, only 32 bits supported
|
||||
#define FB_ARGB 0
|
||||
|
@ -81,22 +81,17 @@ typedef struct {
|
|||
#define INITRD_MAXSIZE 16 //Mb
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[4]; // 'BOOT', first 64 bytes are platform independent
|
||||
// first 64 bytes is platform independent
|
||||
uint8_t magic[4]; // 'BOOT' magic
|
||||
uint32_t size; // length of bootboot structure, minimum 128
|
||||
|
||||
uint8_t protocol; // 1, static addresses, see PROTOCOL_* above
|
||||
uint8_t loader_type; // see LOADER_* above
|
||||
uint8_t pagesize; // in power of two, 12 = 4096
|
||||
uint8_t protocol; // 1, static addresses, see PROTOCOL_* and LOADER_* above
|
||||
uint8_t fb_type; // framebuffer type, see FB_* above
|
||||
|
||||
uint16_t numcores; // number of processor cores
|
||||
uint16_t bspid; // Bootsrap processor ID (Local APIC Id on x86_64)
|
||||
int16_t timezone; // in minutes -1440..1440
|
||||
|
||||
uint8_t datetime[8]; // in BCD yyyymmddhhiiss UTC (independent to timezone)
|
||||
|
||||
uint64_t initrd_ptr; // ramdisk image position and size
|
||||
uint64_t initrd_size;
|
||||
|
||||
uint8_t *fb_ptr; // framebuffer pointer and dimensions
|
||||
uint32_t fb_size;
|
||||
uint32_t fb_width;
|
||||
|
|
BIN
bootboot.img
BIN
bootboot.img
Binary file not shown.
BIN
bootboot.rom
BIN
bootboot.rom
Binary file not shown.
Binary file not shown.
|
@ -50,6 +50,7 @@ extern uint8_t fb; // linear framebuffer mapped
|
|||
******************************************/
|
||||
void _start()
|
||||
{
|
||||
/*** NOTE: this code runs on all cores in parallel ***/
|
||||
int x, y, s=bootboot.fb_scanline, w=bootboot.fb_width, h=bootboot.fb_height;
|
||||
|
||||
// cross-hair to see screen dimension detected correctly
|
||||
|
@ -90,7 +91,7 @@ void puts(char *s)
|
|||
int x,y,kx=0,line,mask,offs;
|
||||
int bpl=(font->width+7)/8;
|
||||
while(*s) {
|
||||
unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->headersize +
|
||||
unsigned char *glyph = (unsigned char*)&_binary_font_psf_start + font->headersize +
|
||||
(*s>0&&*s<font->numglyph?*s:0)*font->bytesperglyph;
|
||||
offs = (kx * (font->width+1) * 4);
|
||||
for(y=0;y<font->height;y++) {
|
||||
|
|
|
@ -12,7 +12,7 @@ chainload from MBR, VBR (GPT hybrid booting) or from CDROM boot record via __boo
|
|||
Machine state
|
||||
-------------
|
||||
|
||||
IRQs masked. GDT unspecified, but valid, IDT unset. Code is running in supervisor mode in ring 0.
|
||||
IRQs masked. GDT unspecified, but valid, IDT unset. SSE, SMP enabled. Code is running in supervisor mode in ring 0 on all cores.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;*
|
||||
;* x86_64-bios/bootboot.asm
|
||||
;*
|
||||
;* Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
;* Copyright (C) 2017 - 2019 bzt (bztsrc@gitlab)
|
||||
;*
|
||||
;* Permission is hereby granted, free of charge, to any person
|
||||
;* obtaining a copy of this software and associated documentation
|
||||
|
@ -30,7 +30,7 @@
|
|||
;* 1.0.1 (even expansion ROM), El Torito "no emulation" CDROM boot,
|
||||
;* as well as Linux boot protocol.
|
||||
;*
|
||||
;* memory occupied: 800-7C00
|
||||
;* text segment occupied: 800-7C00, bss: 8000-x
|
||||
;*
|
||||
;* Memory map
|
||||
;* 0h - 600h reserved for the system
|
||||
|
@ -49,7 +49,7 @@
|
|||
;* 11000h -12000h PDE 2M
|
||||
;* 12000h -13000h PDE 2M
|
||||
;* 13000h -14000h PTE 4K
|
||||
;* 14000h -15000h core stack
|
||||
;* 14000h -A0000h core stacks (1k per core)
|
||||
;*
|
||||
;* At first big enough free hole, initrd. Usually at 1Mbyte.
|
||||
;*
|
||||
|
@ -480,9 +480,7 @@ getmemmap:
|
|||
mov eax, bootboot_MAGIC
|
||||
mov dword [bootboot.magic], eax
|
||||
mov dword [bootboot.size], 128
|
||||
mov dword [bootboot.pagesize], 12
|
||||
mov dword [bootboot.protocol_ver], PROTOCOL_STATIC
|
||||
mov dword [bootboot.loader_type], LOADER_BIOS
|
||||
mov dword [bootboot.protocol], PROTOCOL_STATIC or LOADER_BIOS
|
||||
mov di, bootboot.mmap
|
||||
mov cx, 800h
|
||||
xor ax, ax
|
||||
|
@ -677,8 +675,7 @@ getmemmap:
|
|||
cmp dword [es:0], '_MP_'
|
||||
jne .smbnotf
|
||||
shl eax, 4
|
||||
mov ebx, dword [es:4]
|
||||
mov dword [bootboot.mp_ptr], ebx
|
||||
mov dword [bootboot.mp_ptr], eax
|
||||
bts dx, 2
|
||||
jmp .smbnotf
|
||||
.smbfound: shl eax, 4
|
||||
|
@ -732,8 +729,34 @@ getmemmap:
|
|||
mov cr0, eax
|
||||
jmp CODE_PROT:protmode_start
|
||||
|
||||
;writes the reason, waits for a key and reboots.
|
||||
;---- enable protmode on APs ----
|
||||
ap_trampoline:
|
||||
;--this code will be relocated to the SIPI address --
|
||||
cli
|
||||
cld
|
||||
jmp 0:ap_start
|
||||
;--relocation end--
|
||||
ap_start: xor ax, ax
|
||||
mov ds, ax
|
||||
lgdt [GDT_value]
|
||||
mov eax, cr0
|
||||
or al, 1
|
||||
mov cr0, eax
|
||||
jmp CODE_PROT:@f
|
||||
USE32
|
||||
@@: mov ax, DATA_PROT
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
; spinlock until BSP finishes
|
||||
@@: pause
|
||||
cmp byte [bsp_done], 0
|
||||
jz @b
|
||||
jmp longmode_init
|
||||
|
||||
;writes the reason, waits for a key and reboots.
|
||||
prot_diefunc:
|
||||
prot_realmode
|
||||
USE16
|
||||
|
@ -857,7 +880,7 @@ prot_readsectorfunc:
|
|||
int 13h
|
||||
jc @f
|
||||
;some buggy BIOSes (like bochs') fail to set carry flag and ax properly
|
||||
cmp byte [si+2], 0h
|
||||
cmp byte [spc_packet+2], 0h
|
||||
jz @f
|
||||
;use 2048 byte sectors instead of 512 if it's a cdrom
|
||||
mov al, byte [lbapacket.sect0]
|
||||
|
@ -1712,6 +1735,144 @@ end if
|
|||
dec cx
|
||||
jnz .nextfree
|
||||
.excludeok:
|
||||
; -------- SMP ---------
|
||||
; clear LAPIC address and logical core id list
|
||||
mov edi, lapic_ptr
|
||||
mov ecx, 512/4+1
|
||||
xor eax, eax
|
||||
repnz stosd
|
||||
; clear flags
|
||||
mov byte [bsp_done], al
|
||||
; try ACPI first
|
||||
mov esi, dword [bootboot.acpi_ptr]
|
||||
or esi, esi
|
||||
jz .trymp
|
||||
mov edx, 4
|
||||
cmp byte [esi], 'X' ; XSDT has 8 bytes pointers, but we can only access 4G
|
||||
jne @f
|
||||
mov edx, 8
|
||||
@@: mov ecx, dword [esi+4]
|
||||
add esi, 024h
|
||||
sub ecx, 024h
|
||||
.nextsdt: mov ebx, dword [esi]
|
||||
add esi, edx
|
||||
cmp dword [ebx], 'APIC' ; look for MADT
|
||||
je .madt
|
||||
sub ecx, edx
|
||||
or ecx, ecx
|
||||
jz .trymp
|
||||
jmp .nextsdt
|
||||
; MADT found.
|
||||
.madt: mov eax, dword [ebx+24h]
|
||||
mov dword [lapic_ptr], eax ; madt.lapic_address
|
||||
mov ecx, dword [ebx+4]
|
||||
sub ecx, 2ch
|
||||
add ebx, 2ch
|
||||
mov edi, lapic_ids
|
||||
.nextmadtentry:
|
||||
cmp word [bootboot.numcores], 256
|
||||
jae .dosmp
|
||||
cmp byte [ebx], 0 ; madt_entry.type: is it a Local APIC Processor?
|
||||
jne @f
|
||||
xor ax, ax
|
||||
mov al, byte [ebx+2] ; madt_entry.lapicproc.lapicid
|
||||
stosw ; ACPI table holds 1 byte id, but internally we have 2 bytes
|
||||
inc word [bootboot.numcores]
|
||||
@@: xor eax, eax
|
||||
mov al, byte [ebx+1] ; madt_entry.size
|
||||
or al, al
|
||||
jz .dosmp
|
||||
add ebx, eax
|
||||
sub ecx, eax
|
||||
cmp ecx, 0
|
||||
jg .nextmadtentry
|
||||
jmp .dosmp
|
||||
|
||||
|
||||
.trymp: ; in lack of ACPI, try legacy MP structures
|
||||
mov esi, dword [bootboot.mp_ptr]
|
||||
or esi, esi
|
||||
jz .nosmp
|
||||
mov esi, dword [esi+4]
|
||||
cmp dword [esi], 'PCMP'
|
||||
jne .nosmp
|
||||
mov eax, dword [esi+36] ; pcmp.lapic_address
|
||||
mov dword [lapic_ptr], eax
|
||||
mov cx, word [esi+34] ; pcmp.numentries
|
||||
add esi, 44 ; pcmp header length
|
||||
mov edi, lapic_ids
|
||||
.nextpcmpentry:
|
||||
cmp word [bootboot.numcores], 256
|
||||
jae .dosmp
|
||||
cmp byte [esi], 0 ; pcmp_entry.type: is it a Local APIC Processor?
|
||||
jne @f
|
||||
xor ax, ax
|
||||
mov al, byte [esi+1] ; pcmp_entry.lapicproc.lapicid
|
||||
stosw ; PCMP has 1 byte id, but we use 2 bytes internally
|
||||
inc word [bootboot.numcores]
|
||||
add esi, 12
|
||||
@@: add esi, 8
|
||||
dec cx
|
||||
jnz .nextpcmpentry
|
||||
|
||||
; send IPI and SIPI
|
||||
.dosmp: cmp word [bootboot.numcores], 2
|
||||
jb .nosmp
|
||||
|
||||
DBG32 dbg_smp
|
||||
|
||||
; relocate AP trampoline
|
||||
mov esi, ap_trampoline
|
||||
mov edi, 7000h
|
||||
mov ecx, (ap_start-ap_trampoline+3)/4
|
||||
repnz movsd
|
||||
|
||||
; send Broadcast INIT IPI
|
||||
mov esi, dword [lapic_ptr]
|
||||
add esi, 300h
|
||||
mov eax, 0C4500h
|
||||
mov dword [esi], eax
|
||||
; wait 10 millisec
|
||||
mov al, 10110000b ; select channel 2, lo/hi access, mode 0, binary
|
||||
out 043h, al
|
||||
mov ax, 1234DDh/1000*10 ; set counter
|
||||
out 042h, al
|
||||
mov al, ah
|
||||
out 042h, al
|
||||
@@: mov al, 0C8h ; read back command, channel 2, flush latch, read status
|
||||
out 043h, al
|
||||
in al, 042h ; read channel 2 status
|
||||
bt ax, 7 ; loop until output high bit set
|
||||
jnc @b
|
||||
|
||||
; send Broadcast STARTUP IPI
|
||||
mov eax, 0C4607h ; start at 0700:0000h
|
||||
mov dword [esi], eax
|
||||
|
||||
; wait 1 millisec (should be 200 microsec minimum)
|
||||
mov al, 10110000b ; select channel 2, lo/hi access, mode 0, binary
|
||||
out 043h, al
|
||||
mov ax, 1234DDh/1000 ; set counter
|
||||
out 042h, al
|
||||
mov al, ah
|
||||
out 042h, al
|
||||
@@: mov al, 0C8h ; read back command, channel 2, flush latch, read status
|
||||
out 043h, al
|
||||
in al, 042h ; read channel 2 status
|
||||
bt ax, 7 ; loop until output high bit set
|
||||
jnc @b
|
||||
|
||||
mov eax, 0C4607h ; second SIPI
|
||||
mov dword [esi], eax
|
||||
|
||||
.nosmp: ; failsafe
|
||||
cmp word [bootboot.numcores], 0
|
||||
jnz @f
|
||||
inc word [bootboot.numcores]
|
||||
mov ax, word [bootboot.bspid]
|
||||
mov word [lapic_ids], ax
|
||||
@@:
|
||||
|
||||
; ------- set video resolution -------
|
||||
prot_realmode
|
||||
|
||||
|
@ -1836,7 +1997,7 @@ end if
|
|||
;address 0xffffffffffe00000
|
||||
xor eax, eax
|
||||
mov edi, 0A000h
|
||||
mov ecx, (15000h-0A000h)/4
|
||||
mov ecx, (14000h+256*1024-0A000h)/4
|
||||
repnz stosd
|
||||
|
||||
;PML4
|
||||
|
@ -1875,7 +2036,17 @@ end if
|
|||
add eax, 4096
|
||||
dec ecx
|
||||
jnz @b
|
||||
mov dword[0DFF8h], 014001h ;map core stack
|
||||
;map core stacks (one page per 4 cores)
|
||||
mov edi, 0DFF8h
|
||||
mov eax, 014001h
|
||||
mov cx, word [bootboot.numcores]
|
||||
add cx, 3
|
||||
shr cx, 2
|
||||
@@: mov dword[edi], eax
|
||||
sub edi, 8
|
||||
add eax, 1000h
|
||||
dec cx
|
||||
jnz @b
|
||||
|
||||
;identity mapping
|
||||
;2M PDPE
|
||||
|
@ -1937,8 +2108,12 @@ end if
|
|||
in al, 70h ;disable NMI
|
||||
or al, 80h
|
||||
out 70h, al
|
||||
;release AP spinlock
|
||||
inc byte [bsp_done]
|
||||
|
||||
mov eax, 1101000b ;Set PAE, MCE, PGE
|
||||
;don't use stack below this line
|
||||
longmode_init:
|
||||
mov eax, 1101101000b ;Set PAE, MCE, PGE; OSFXSR, OSXMMEXCPT (enable SSE)
|
||||
mov cr4, eax
|
||||
mov eax, 0A000h
|
||||
mov cr3, eax
|
||||
|
@ -1948,15 +2123,15 @@ end if
|
|||
wrmsr
|
||||
|
||||
mov eax, cr0
|
||||
and al, 0FBh ;clear EM, MP (enable SSE)
|
||||
or eax, 0C0000001h
|
||||
mov cr0, eax ;enable paging wich cache disabled
|
||||
mov cr0, eax ;enable paging with cache disabled
|
||||
lgdt [GDT_value] ;read 80 bit address
|
||||
jmp @f
|
||||
nop
|
||||
@@: jmp 8:longmode_init
|
||||
@@: jmp 8:@f
|
||||
USE64
|
||||
longmode_init:
|
||||
xor eax, eax
|
||||
@@: xor eax, eax ;load long mode segments
|
||||
mov ax, 10h
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
|
@ -1964,8 +2139,27 @@ longmode_init:
|
|||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
xor rsp, rsp
|
||||
;call _start() at qword[entrypoint]
|
||||
; find out our lapic id
|
||||
mov eax, 1
|
||||
cpuid
|
||||
shr ebx, 24
|
||||
mov edx, ebx
|
||||
; get array index for it
|
||||
xor rbx, rbx
|
||||
mov rsi, lapic_ids
|
||||
mov cx, word [bootboot.numcores]
|
||||
@@: lodsw
|
||||
cmp ax, dx
|
||||
je @f
|
||||
inc ebx
|
||||
dec cx
|
||||
jnz @b
|
||||
xor rbx, rbx
|
||||
@@: shl rbx, 10 ; 1k stack for each core
|
||||
|
||||
; set stack and call _start() in sys/core
|
||||
xor rsp, rsp ;sp = core_num * -1024
|
||||
sub rsp, rbx
|
||||
jmp qword[entrypoint]
|
||||
nop
|
||||
nop
|
||||
|
@ -2322,6 +2516,7 @@ bootdev: db 0
|
|||
readdev: db 0
|
||||
hasinitrd: db 0
|
||||
iscdrom: db 0
|
||||
bsp_done: ;flag to indicate APs can run
|
||||
fattype: db 0
|
||||
bkp: dd ' '
|
||||
if DEBUG eq 1
|
||||
|
@ -2337,6 +2532,7 @@ dbg_gzinitrd db " * Gzip compressed initrd",10,13,0
|
|||
dbg_scan db " * Autodetecting kernel",10,13,0
|
||||
dbg_elf db " * Parsing ELF64",10,13,0
|
||||
dbg_pe db " * Parsing PE32+",10,13,0
|
||||
dbg_smp db " * SMP init",10,13,0
|
||||
dbg_vesa db " * Screen VESA VBE",10,13,0
|
||||
end if
|
||||
backup: db " * Backup initrd",10,13,0
|
||||
|
@ -2383,6 +2579,8 @@ core_len: dd ?
|
|||
gpt_ptr: dd ?
|
||||
gpt_num: dd ?
|
||||
gpt_ent: dd ?
|
||||
lapic_ptr: dd ?
|
||||
lapic_ids:
|
||||
tinf_bss_start:
|
||||
d_end: dd ?
|
||||
d_lzOff: dd ?
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;*
|
||||
;* x86_64-bios/bootboot.inc
|
||||
;*
|
||||
;* Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
;* Copyright (C) 2017 - 2019 bzt (bztsrc@gitlab)
|
||||
;*
|
||||
;* Permission is hereby granted, free of charge, to any person
|
||||
;* obtaining a copy of this software and associated documentation
|
||||
|
@ -47,12 +47,12 @@ PROTOCOL_STATIC equ 1
|
|||
; kernel name parsed from environment, kernel memory addresses parsed from ELF symbols
|
||||
PROTOCOL_DYNAMIC equ 2
|
||||
; big-endian flag
|
||||
PROTOCOL_BIGENDIAN equ 080h
|
||||
PROTOCOL_BIGENDIAN equ 080h
|
||||
|
||||
; loader types, just informational
|
||||
LOADER_BIOS equ 0
|
||||
LOADER_UEFI equ 1
|
||||
LOADER_RPI equ 2
|
||||
LOADER_BIOS equ 0
|
||||
LOADER_UEFI equ 4
|
||||
LOADER_RPI equ 8
|
||||
|
||||
; framebuffer pixel format, only 32 bits supported
|
||||
FB_ARGB equ 0
|
||||
|
@ -81,31 +81,26 @@ MMAP_MMIO equ 4
|
|||
INITRD_MAXSIZE equ 16 ; Mb
|
||||
|
||||
virtual at bootboot
|
||||
; first 64 bytes is platform independent
|
||||
bootboot.magic: dd 0
|
||||
bootboot.size: dd 0
|
||||
|
||||
bootboot.protocol_ver:db 1
|
||||
bootboot.loader_type: db 0
|
||||
bootboot.pagesize: db 0
|
||||
bootboot.protocol: db 1
|
||||
bootboot.fb_type: db 0
|
||||
|
||||
bootboot.numcores: dw 0
|
||||
bootboot.bspid: dw 0
|
||||
bootboot.timezone: dw 0
|
||||
|
||||
bootboot.datetime: dq 0
|
||||
|
||||
bootboot.initrd_ptr: dq 0
|
||||
bootboot.initrd_size: dq 0
|
||||
|
||||
bootboot.fb_ptr: dq 0
|
||||
bootboot.fb_size: dd 0
|
||||
bootboot.fb_width: dd 0
|
||||
bootboot.fb_height: dd 0
|
||||
bootboot.fb_scanline: dd 0
|
||||
|
||||
; architecture specific pointers
|
||||
|
||||
; the rest (64 bytes) is platform specific
|
||||
|
||||
; x86_64
|
||||
bootboot.acpi_ptr: dq 0
|
||||
bootboot.smbi_ptr: dq 0
|
||||
bootboot.efi_ptr: dq 0
|
||||
|
@ -119,3 +114,5 @@ end virtual
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ OS loader application.
|
|||
Machine state
|
||||
-------------
|
||||
|
||||
IRQs masked. GDT unspecified, but valid, IDT unset. Code is running in supervisor mode in ring 0.
|
||||
IRQs masked. GDT unspecified, but valid, IDT unset. SSE, SMP enabled. Code is running in supervisor mode in ring 0 on all cores.
|
||||
|
||||
File system drivers
|
||||
-------------------
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* x86_64-efi/bootboot.c
|
||||
*
|
||||
* Copyright (C) 2017 bzt (bztsrc@gitlab)
|
||||
* Copyright (C) 2017 - 2019 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
@ -123,11 +123,72 @@ typedef struct {
|
|||
} pe_hdr;
|
||||
|
||||
/*** EFI defines and structs ***/
|
||||
extern EFI_GUID GraphicsOutputProtocol;
|
||||
extern EFI_GUID LoadedImageProtocol;
|
||||
struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
|
||||
struct EFI_FILE_PROTOCOL;
|
||||
|
||||
#ifndef EFI_MP_SERVICES_PROTOCOL_GUID
|
||||
#define EFI_MP_SERVICES_PROTOCOL_GUID \
|
||||
{ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} }
|
||||
typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL;
|
||||
|
||||
#define PROCESSOR_AS_BSP_BIT 0x00000001
|
||||
|
||||
typedef struct {
|
||||
UINT64 ProcessorId;
|
||||
UINT32 StatusFlag;
|
||||
} EFI_PROCESSOR_INFORMATION;
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_DUMMY)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This
|
||||
);
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(EFIAPI *EFI_AP_PROCEDURE)(
|
||||
IN OUT VOID *Buffer
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
OUT UINTN *NumberOfProcessors,
|
||||
OUT UINTN *NumberOfEnabledProcessors
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_GET_PROCESSOR_INFO)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN UINTN ProcessorNumber,
|
||||
OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_MP_SERVICES_STARTUP_THIS_AP)(
|
||||
IN EFI_MP_SERVICES_PROTOCOL *This,
|
||||
IN EFI_AP_PROCEDURE Procedure,
|
||||
IN UINTN ProcessorNumber,
|
||||
IN EFI_EVENT WaitEvent OPTIONAL,
|
||||
IN UINTN TimeoutInMicroseconds,
|
||||
IN VOID *ProcedureArgument OPTIONAL,
|
||||
OUT BOOLEAN *Finished OPTIONAL
|
||||
);
|
||||
|
||||
struct _EFI_MP_SERVICES_PROTOCOL {
|
||||
EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors;
|
||||
EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo;
|
||||
EFI_MP_SERVICES_DUMMY StartupAllAPs;
|
||||
EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP;
|
||||
EFI_MP_SERVICES_DUMMY SwitchBSP;
|
||||
EFI_MP_SERVICES_DUMMY EnableDisableAP;
|
||||
EFI_MP_SERVICES_DUMMY WhoAmI;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME)(
|
||||
|
@ -211,7 +272,7 @@ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
|
|||
EFI_FILE_HANDLE RootDir;
|
||||
EFI_FILE_PROTOCOL *Root;
|
||||
SIMPLE_INPUT_INTERFACE *CI;
|
||||
unsigned char *kne;
|
||||
unsigned char *kne, bsp_done=0;
|
||||
|
||||
// default environment variables. M$ states that 1024x768 must be supported
|
||||
int reqwidth = 1024, reqheight = 768;
|
||||
|
@ -1130,6 +1191,46 @@ LoadCore()
|
|||
return report(EFI_LOAD_ERROR,L"Kernel not found in initrd");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize logical cores
|
||||
* Because Local APIC ID is not contiguous, core id != core num
|
||||
*/
|
||||
VOID EFIAPI bootboot_startcore(IN VOID* buf)
|
||||
{
|
||||
// we have a scalar number, not a pointer, so cast it
|
||||
UINTN core_num = (UINTN)buf;
|
||||
|
||||
// spinlock until BSP finishes
|
||||
do { __asm__ __volatile__ ("pause"); } while(!bsp_done);
|
||||
|
||||
// enable SSE
|
||||
__asm__ __volatile__ (
|
||||
"mov %%cr0, %%eax;"
|
||||
"btsw $2, %%ax;"
|
||||
"btrw $1, %%ax;"
|
||||
"mov %%rax, %%cr0;"
|
||||
"mov %%cr4, %%rax;"
|
||||
"orw $3 << 9, %%ax;"
|
||||
"mov %%rax, %%cr4"
|
||||
: );
|
||||
|
||||
// set up paging
|
||||
__asm__ __volatile__ (
|
||||
"mov %0, %%rax;"
|
||||
"mov %%rax, %%cr3"
|
||||
: : "b"(paging) : "memory" );
|
||||
|
||||
// set stack and call _start() in sys/core
|
||||
__asm__ __volatile__ (
|
||||
// get a valid stack for the core we're running on
|
||||
"xorq %%rsp, %%rsp;"
|
||||
"subq %1, %%rsp;" // sp = core_num * -1024
|
||||
// pass control over
|
||||
"pushq %0;"
|
||||
"retq"
|
||||
: : "a"(entrypoint), "r"(core_num*1024) : "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Main EFI application entry point
|
||||
*/
|
||||
|
@ -1148,7 +1249,12 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
EFI_PARTITION_TABLE_HEADER *gptHdr;
|
||||
EFI_PARTITION_ENTRY *gptEnt;
|
||||
EFI_INPUT_KEY key;
|
||||
UINTN i, j=0, handle_size=0,memory_map_size=0, map_key=0, desc_size=0;
|
||||
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;
|
||||
UINTN bsp_num=0, i, j=0, handle_size=0,memory_map_size=0, map_key=0, desc_size=0;
|
||||
UINT32 desc_version=0;
|
||||
UINT64 lba_s=0,lba_e=0;
|
||||
MMapEnt *mmapent, *last=NULL;
|
||||
|
@ -1435,10 +1541,9 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
return report(status, L"GOP failed, no framebuffer");
|
||||
|
||||
// collect information on system
|
||||
bootboot->protocol=PROTOCOL_STATIC;
|
||||
bootboot->loader_type=LOADER_UEFI;
|
||||
bootboot->protocol=PROTOCOL_STATIC | LOADER_UEFI;
|
||||
bootboot->size=128;
|
||||
bootboot->pagesize=12;
|
||||
bootboot->numcores=1;
|
||||
CopyMem((void *)&(bootboot->initrd_ptr),&initrd.ptr,8);
|
||||
bootboot->initrd_size=((initrd.size+PAGESIZE-1)/PAGESIZE)*PAGESIZE;
|
||||
CopyMem((void *)&(bootboot->x86_64.efi_ptr),&systab,8);
|
||||
|
@ -1492,6 +1597,34 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
if(kne!=NULL)
|
||||
*kne='\n';
|
||||
|
||||
// Symmetric Multi Processing support
|
||||
status = uefi_call_wrapper(BS->LocateProtocol, 3, &mpspGuid, NULL, (void**)&mp);
|
||||
if(!EFI_ERROR(status)) {
|
||||
// override default values in bootboot struct
|
||||
status = uefi_call_wrapper(mp->GetNumberOfProcessors, 3, mp, &i, &j);
|
||||
if(!EFI_ERROR(status)) {
|
||||
// failsafe: we cannot map more stacks (each core has 1k)
|
||||
if(i>PAGESIZE/8/2*4) i=PAGESIZE/8/2*4;
|
||||
bootboot->numcores = i;
|
||||
}
|
||||
DBG(L" * SMP numcores %d\n", bootboot->numcores);
|
||||
// start APs
|
||||
status = uefi_call_wrapper(BS->CreateEvent, 5, 0, TPL_NOTIFY, NULL, NULL, &Event);
|
||||
if(!EFI_ERROR(status)) {
|
||||
for(i=0; i<bootboot->numcores; i++) {
|
||||
status = uefi_call_wrapper(mp->GetProcessorInfo, 5, mp, i, pibuf);
|
||||
if(!EFI_ERROR(status)) {
|
||||
if(pibuf->StatusFlag & PROCESSOR_AS_BSP_BIT) {
|
||||
bootboot->bspid = pibuf->ProcessorId;
|
||||
bsp_num = i;
|
||||
} else {
|
||||
uefi_call_wrapper(mp->StartupThisAP, 7, mp, bootboot_startcore, i, Event, 0, (VOID*)i, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// query size of memory map
|
||||
status = uefi_call_wrapper(BS->GetMemoryMap, 5,
|
||||
&memory_map_size, memory_map, NULL, &desc_size, NULL);
|
||||
|
@ -1509,7 +1642,7 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
}
|
||||
|
||||
// create page tables
|
||||
uefi_call_wrapper(BS->AllocatePages, 4, 0, 2, 24, (EFI_PHYSICAL_ADDRESS*)&paging);
|
||||
uefi_call_wrapper(BS->AllocatePages, 4, 0, 2, 23+(bootboot->numcores+3)/4, (EFI_PHYSICAL_ADDRESS*)&paging);
|
||||
if (paging == NULL) {
|
||||
return report(EFI_OUT_OF_RESOURCES,L"AllocatePages");
|
||||
}
|
||||
|
@ -1529,7 +1662,8 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
paging[3*512+1]=(UINT64)(env.ptr)+1;
|
||||
for(i=0;i<(core.size/PAGESIZE);i++)
|
||||
paging[3*512+2+i]=(UINT64)((UINT8 *)core.ptr+i*PAGESIZE+1);
|
||||
paging[3*512+511]=(UINT64)((UINT8 *)paging+23*PAGESIZE+1); // core stack
|
||||
for(i=0; i<(UINTN)((bootboot->numcores+3)/4); i++)
|
||||
paging[3*512+511-i]=(UINT64)((UINT8 *)paging+(23+i)*PAGESIZE+1); // core stacks
|
||||
//identity mapping
|
||||
//2M PDPE
|
||||
for(i=0;i<16;i++)
|
||||
|
@ -1604,18 +1738,9 @@ get_memory_map:
|
|||
return report(status,L"ExitBootServices");
|
||||
}
|
||||
|
||||
//set up paging
|
||||
__asm__ __volatile__ (
|
||||
"mov %0,%%rax;"
|
||||
"mov %%rax,%%cr3"
|
||||
: : "b"(paging) : "memory" );
|
||||
|
||||
//call _start() in sys/core
|
||||
__asm__ __volatile__ (
|
||||
"xorq %%rsp, %%rsp;"
|
||||
"pushq %0;"
|
||||
"retq"
|
||||
: : "a"(entrypoint): "memory" );
|
||||
// release AP spinlock
|
||||
bsp_done = 1;
|
||||
bootboot_startcore((VOID*)bsp_num);
|
||||
}
|
||||
return report(status,L"Initrd not found");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue