mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
More SMP
This commit is contained in:
parent
daf9fc50f3
commit
e0dc1c152d
11 changed files with 327 additions and 159 deletions
|
@ -1233,7 +1233,6 @@ int bootboot_main(uint64_t hcl)
|
|||
memcpy((void*)&bootboot->magic,BOOTBOOT_MAGIC,4);
|
||||
bootboot->protocol = PROTOCOL_DYNAMIC | LOADER_RPI;
|
||||
bootboot->size = 128;
|
||||
bootboot->numcores = 4;
|
||||
bootboot->arch.aarch64.mmio_ptr = mmio_base;
|
||||
// set up a framebuffer so that we can write on screen
|
||||
if(!GetLFB(0, 0)) goto viderr;
|
||||
|
@ -1849,12 +1848,13 @@ error:
|
|||
}
|
||||
|
||||
/**
|
||||
* start kernel, run on all cores
|
||||
* start kernel, runs on all cores
|
||||
*/
|
||||
void bootboot_startcore()
|
||||
{
|
||||
// spinlock until BSP finishes
|
||||
do { asm volatile ("dsb sy"); } while(!bsp_done);
|
||||
__sync_fetch_and_add(&bootboot->numcores, 1);
|
||||
|
||||
// enable paging
|
||||
reg=(0xFF << 0) | // Attr=0: normal, IWBWA, OWBWA, NTR
|
||||
|
|
BIN
dist/bootboot.bin
vendored
BIN
dist/bootboot.bin
vendored
Binary file not shown.
BIN
dist/bootboot.efi
vendored
BIN
dist/bootboot.efi
vendored
Binary file not shown.
BIN
dist/bootboot.img
vendored
BIN
dist/bootboot.img
vendored
Binary file not shown.
BIN
dist/bootboot.rom
vendored
BIN
dist/bootboot.rom
vendored
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -1,9 +1,9 @@
|
|||
/* generated by bin2h, do not edit */
|
||||
|
||||
extern unsigned char binary_boot_bin[512];
|
||||
extern unsigned char binary_bootboot_bin[12288];
|
||||
extern unsigned char binary_bootboot_efi[102543];
|
||||
extern unsigned char binary_bootboot_img[35032];
|
||||
extern unsigned char binary_bootboot_bin[12800];
|
||||
extern unsigned char binary_bootboot_efi[102561];
|
||||
extern unsigned char binary_bootboot_img[35064];
|
||||
extern unsigned char binary_bootboot_rv64[8192];
|
||||
extern unsigned char binary_LICENCE_broadcom[1594];
|
||||
extern unsigned char binary_bootcode_bin[52456];
|
||||
|
|
|
@ -828,6 +828,13 @@ ap_start: xor ax, ax
|
|||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
; enable Local APIC
|
||||
mov esi, dword [lapic_ptr]
|
||||
add esi, 0F0h
|
||||
mov eax, dword [esi]
|
||||
or ah, 1h
|
||||
mov dword [esi], eax
|
||||
inc byte [ap_done]
|
||||
; spinlock until BSP finishes
|
||||
@@: pause
|
||||
cmp byte [bsp_done], 0
|
||||
|
@ -1963,14 +1970,21 @@ end if
|
|||
add ebx, 2ch
|
||||
mov edi, lapic_ids
|
||||
.nextmadtentry:
|
||||
cmp word [bootboot.numcores], 256
|
||||
cmp word [numcores], 256
|
||||
jae .dosmp
|
||||
cmp byte [ebx], 0 ; madt_entry.type: is it a Local APIC Processor?
|
||||
jne @f
|
||||
mov al, byte [ebx+4] ; madt_entry.lapicproc.flag & ENABLED
|
||||
and al, 1
|
||||
jz .madterr
|
||||
xor ax, ax
|
||||
mov al, byte [ebx+3] ; madt_entry.lapicproc.lapicid
|
||||
cmp al, 0FFh
|
||||
je .madterr
|
||||
stosw ; ACPI table holds 1 byte id, but internally we have 2 bytes
|
||||
inc word [bootboot.numcores]
|
||||
inc word [numcores]
|
||||
jmp @f
|
||||
.madterr: mov byte [boguscore], 1
|
||||
@@: xor eax, eax
|
||||
mov al, byte [ebx+1] ; madt_entry.size
|
||||
or al, al
|
||||
|
@ -1995,30 +2009,31 @@ end if
|
|||
add esi, 44 ; pcmp header length
|
||||
mov edi, lapic_ids
|
||||
.nextpcmpentry:
|
||||
cmp word [bootboot.numcores], 256
|
||||
cmp word [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]
|
||||
inc word [numcores]
|
||||
add esi, 12
|
||||
@@: add esi, 8
|
||||
dec cx
|
||||
jnz .nextpcmpentry
|
||||
|
||||
; send IPI and SIPI
|
||||
.dosmp: cmp word [bootboot.numcores], 2
|
||||
.dosmp: cmp word [numcores], 2
|
||||
jb .nosmp
|
||||
cmp dword [lapic_ptr], 0
|
||||
jz .nosmp
|
||||
|
||||
if BBDEBUG eq 1
|
||||
xor eax, eax
|
||||
mov dword [gpt_ptr], eax
|
||||
mov dword [gpt_num], eax
|
||||
prot_realmode
|
||||
mov si, dbg_smp
|
||||
mov bx, word [bootboot.numcores]
|
||||
mov bx, word [numcores]
|
||||
mov di, gpt_ptr
|
||||
|
||||
cmp bx, 1000
|
||||
|
@ -2054,7 +2069,11 @@ if BBDEBUG eq 1
|
|||
call real_printfunc
|
||||
mov si, gpt_ptr
|
||||
call real_printfunc
|
||||
mov si, crlf
|
||||
cmp byte [boguscore], 0
|
||||
jz @f
|
||||
mov si, dbg_bogus
|
||||
call real_printfunc
|
||||
@@: mov si, crlf
|
||||
call real_printfunc
|
||||
real_protmode
|
||||
end if
|
||||
|
@ -2065,6 +2084,16 @@ end if
|
|||
mov ecx, (ap_start-ap_trampoline+3)/4
|
||||
repnz movsd
|
||||
|
||||
; enable Local APIC
|
||||
mov esi, dword [lapic_ptr]
|
||||
add esi, 0F0h
|
||||
mov eax, dword [esi]
|
||||
or ah, 1h
|
||||
mov dword [esi], eax
|
||||
|
||||
cmp byte [boguscore], 0
|
||||
jnz .nobcast
|
||||
|
||||
; send Broadcast INIT IPI
|
||||
mov esi, dword [lapic_ptr]
|
||||
add esi, 300h
|
||||
|
@ -2072,6 +2101,7 @@ end if
|
|||
mov dword [esi], eax
|
||||
|
||||
; wait 10 millisec
|
||||
push esi
|
||||
prot_realmode
|
||||
xor cx, cx
|
||||
mov dx, 10000
|
||||
|
@ -2080,12 +2110,15 @@ end if
|
|||
int 15h
|
||||
cli
|
||||
real_protmode
|
||||
pop esi
|
||||
|
||||
; send Broadcast STARTUP IPI
|
||||
mov eax, 0C4607h ; start at 0700:0000h
|
||||
mov dword [esi], eax
|
||||
|
||||
; wait 200 microsec
|
||||
push eax
|
||||
push esi
|
||||
prot_realmode
|
||||
xor cx, cx
|
||||
mov dx, 200
|
||||
|
@ -2094,19 +2127,140 @@ end if
|
|||
int 15h
|
||||
cli
|
||||
real_protmode
|
||||
pop esi
|
||||
pop eax
|
||||
mov dword [esi], eax ; second SIPI
|
||||
jmp .nosmp
|
||||
|
||||
mov eax, 0C4607h ; second SIPI
|
||||
; send IPIs to specific cores one by one
|
||||
.nobcast: xor edx, edx
|
||||
.nextcore: cmp dx, word [numcores]
|
||||
jae .nosmp
|
||||
xor esi, esi
|
||||
mov esi, edx
|
||||
inc edx
|
||||
shl esi, 1
|
||||
add esi, lapic_ids
|
||||
mov bx, word [esi]
|
||||
cmp bx, word [bootboot.bspid]
|
||||
je .nextcore
|
||||
shl ebx, 24
|
||||
|
||||
; clear APIC error
|
||||
mov esi, dword [lapic_ptr]
|
||||
add esi, 280h
|
||||
mov dword [esi], 0
|
||||
mov eax, dword [esi]
|
||||
|
||||
; select AP
|
||||
add esi, 30h
|
||||
mov dword [esi], ebx
|
||||
; trigger INIT IPI
|
||||
sub esi, 10h
|
||||
mov eax, 004500h
|
||||
mov dword [esi], eax
|
||||
|
||||
; wait 200 microsec
|
||||
push esi
|
||||
push edx
|
||||
push ebx
|
||||
prot_realmode
|
||||
xor cx, cx
|
||||
mov dx, 200
|
||||
mov ah, 086h
|
||||
sti
|
||||
int 15h
|
||||
cli
|
||||
real_protmode
|
||||
pop ebx
|
||||
pop edx
|
||||
pop esi
|
||||
|
||||
; select AP
|
||||
add esi, 10h
|
||||
mov dword [esi], ebx
|
||||
; deassert INIT IPI
|
||||
sub esi, 10h
|
||||
mov eax, 008500h
|
||||
mov dword [esi], eax
|
||||
|
||||
; wait 10 millisec
|
||||
push esi
|
||||
push edx
|
||||
push ebx
|
||||
prot_realmode
|
||||
xor cx, cx
|
||||
mov dx, 10000
|
||||
mov ah, 086h
|
||||
sti
|
||||
int 15h
|
||||
cli
|
||||
real_protmode
|
||||
pop ebx
|
||||
pop edx
|
||||
pop esi
|
||||
|
||||
mov byte [ap_done], 0
|
||||
; select AP
|
||||
add esi, 10h
|
||||
mov dword [esi], ebx
|
||||
; send STARTUP IPI
|
||||
sub esi, 10h
|
||||
mov eax, 004607h ; start at 0700:0000h
|
||||
mov dword [esi], eax
|
||||
|
||||
; wait 200 microsec
|
||||
push eax
|
||||
push esi
|
||||
push edx
|
||||
push ebx
|
||||
prot_realmode
|
||||
xor cx, cx
|
||||
mov dx, 200
|
||||
mov ah, 086h
|
||||
sti
|
||||
int 15h
|
||||
cli
|
||||
real_protmode
|
||||
pop ebx
|
||||
pop edx
|
||||
pop esi
|
||||
pop eax
|
||||
|
||||
; do we need a second SIPI?
|
||||
cmp byte [ap_done], 0
|
||||
jnz .nextcore
|
||||
|
||||
; select AP
|
||||
add esi, 10h
|
||||
mov dword [esi], ebx
|
||||
; send STARTUP IPI
|
||||
sub esi, 10h
|
||||
mov dword [esi], eax
|
||||
|
||||
; wait 200 microsec
|
||||
push edx
|
||||
prot_realmode
|
||||
xor cx, cx
|
||||
mov dx, 200
|
||||
mov ah, 086h
|
||||
sti
|
||||
int 15h
|
||||
cli
|
||||
real_protmode
|
||||
pop edx
|
||||
jmp .nextcore
|
||||
|
||||
.nosmp: ; failsafe
|
||||
cmp word [bootboot.numcores], 0
|
||||
cmp word [numcores], 0
|
||||
jnz @f
|
||||
inc word [bootboot.numcores]
|
||||
inc word [numcores]
|
||||
mov ax, word [bootboot.bspid]
|
||||
mov word [lapic_ids], ax
|
||||
mov dword [lapic_ptr], 0
|
||||
@@: ; remove core stacks from memory map
|
||||
xor eax, eax
|
||||
mov ax, word [bootboot.numcores]
|
||||
mov ax, word [numcores]
|
||||
shl eax, 10
|
||||
mov edi, bootboot.mmap
|
||||
add dword [edi], eax
|
||||
|
@ -2283,7 +2437,7 @@ end if
|
|||
;map core stacks (one page per 4 cores)
|
||||
mov edi, 0DFF8h
|
||||
mov eax, 014003h
|
||||
mov cx, word [bootboot.numcores]
|
||||
mov cx, word [numcores]
|
||||
add cx, 3
|
||||
shr cx, 2
|
||||
@@: mov dword[edi], eax
|
||||
|
@ -2379,6 +2533,7 @@ longmode_init:
|
|||
mov ss, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
lock inc word [bootboot.numcores]
|
||||
; find out our lapic id
|
||||
mov eax, dword [lapic_ptr]
|
||||
or eax, eax
|
||||
|
@ -2390,7 +2545,7 @@ longmode_init:
|
|||
; get array index for it
|
||||
xor rbx, rbx
|
||||
mov rsi, lapic_ids
|
||||
mov cx, word [bootboot.numcores]
|
||||
mov cx, word [numcores]
|
||||
@@: lodsw
|
||||
cmp ax, dx
|
||||
je @f
|
||||
|
@ -2762,6 +2917,9 @@ hasinitrd: db 0
|
|||
hasconfig: db 0
|
||||
iscdrom: db 0
|
||||
nosmp: db 0
|
||||
numcores: dw 0
|
||||
ap_done:
|
||||
boguscore: db 0
|
||||
bsp_done: ;flag to indicate APs can run
|
||||
fattype: db 0
|
||||
bkp: dd ' '
|
||||
|
@ -2781,6 +2939,7 @@ 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 numcores ",0
|
||||
dbg_bogus db " (bogus ACPI table)",0
|
||||
dbg_vesa db " * Screen VESA VBE",10,13,0
|
||||
end if
|
||||
backup: db " * Backup initrd",10,13,0
|
||||
|
|
|
@ -76,6 +76,12 @@ extern void bsp64_init(uint64_t apicid);
|
|||
extern void bsp_init();
|
||||
#endif
|
||||
|
||||
#define send_ipi(a,v) do { \
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) = (a << 24); \
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) = v; \
|
||||
while(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & (1 << 12)) __asm__ __volatile__ ("pause" : : : "memory"); \
|
||||
} while(0)
|
||||
|
||||
/*** ELF64 defines and structs ***/
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
@ -754,7 +760,7 @@ void MapPage(uint64_t virt, uint64_t phys)
|
|||
*/
|
||||
int main(void)
|
||||
{
|
||||
int ret=0, i, dsk;
|
||||
int ret=0, i, dsk, boguscore = 0, numcores = 0;
|
||||
uint8_t *pe, *ptr;
|
||||
uint32_t np,sp,r;
|
||||
unsigned char *data;
|
||||
|
@ -789,7 +795,6 @@ int main(void)
|
|||
memcpy(bootboot->magic, BOOTBOOT_MAGIC, 4);
|
||||
bootboot->protocol = PROTOCOL_DYNAMIC | LOADER_COREBOOT;
|
||||
bootboot->size = 128;
|
||||
bootboot->numcores = 1;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"movl $1, %%eax;"
|
||||
|
@ -1125,69 +1130,62 @@ gzerr: panic("Unable to uncompress");
|
|||
i < (int)(sizeof(lapic_ids)/sizeof(lapic_ids[0])); ptr += ptr[1]) {
|
||||
switch(ptr[0]) {
|
||||
case 0: // found Processor Local APIC
|
||||
if((ptr[4] & 1) && lapic_ids[(int)ptr[3]] == 0xFFFF) { lapic_ids[(int)ptr[3]] = i++; }
|
||||
if((ptr[4] & 1) && ptr[3] != 0xFF && lapic_ids[(int)ptr[3]] == 0xFFFF)
|
||||
lapic_ids[(int)ptr[3]] = i++;
|
||||
else
|
||||
boguscore++;
|
||||
break;
|
||||
case 5: lapic_addr = *((uint64_t*)(ptr+4)); break; // found 64 bit Local APIC Address
|
||||
}
|
||||
}
|
||||
if(i && lapic_ids[bootboot->bspid] != 0xFFFF) bootboot->numcores = i;
|
||||
if(i && lapic_ids[bootboot->bspid] != 0xFFFF) numcores = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!nosmp && bootboot->numcores > 1 && lapic_addr) {
|
||||
DBG(" * SMP numcores %d\n", bootboot->numcores);
|
||||
if(!nosmp && numcores > 1 && lapic_addr) {
|
||||
DBG(" * SMP numcores %d%s\n", numcores, boguscore ? " (bogus ACPI table)" : "");
|
||||
memcpy((uint8_t*)0x1000, &ap_trampoline, 128);
|
||||
|
||||
// send INIT IPI (supports up to 256 cores, requires x2APIC to have more)
|
||||
for(i = 0; i < 256; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x280)) = 0; // clear APIC errors
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) & 0x00ffffff) | (i << 24); // select AP
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & 0xfff00000) | 0x00C500; // trigger INIT IPI
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & (1 << 12)); // wait for delivery
|
||||
// deassert
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) & 0x00ffffff) | (i << 24);
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & 0xfff00000) | 0x008500;
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & (1 << 12));
|
||||
}
|
||||
mdelay(10);
|
||||
// send STARTUP IPI
|
||||
for(i = 0; i < 256; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x280)) = 0; // clear APIC errors
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) & 0x00ffffff) | (i << 24); // select AP
|
||||
// trigger IPI, start at 0100:0000h
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & 0xfff0f800) | 0x000601;
|
||||
udelay(200);
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & (1 << 12)); // wait for delivery
|
||||
// send second IPI
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x280)) = 0;
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x310)) & 0x00ffffff) | (i << 24);
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & 0xfff0f800) | 0x000601;
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) & (1 << 12));
|
||||
// enable Local APIC
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x0F0)) = *((volatile uint32_t*)((uintptr_t)lapic_addr + 0x0F0)) | 0x100;
|
||||
|
||||
// if there were no bogus core definitions in the ACPI table, we can do a broadcast (simpler, faster)
|
||||
if(!boguscore) {
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) = 0x0C4500; // trigger bcast INIT IPI
|
||||
mdelay(10); // wait 10 msec
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) = 0x0C4601; // trigger bcast SIPI, start at 0100:0000h
|
||||
udelay(200); // wait 200 usec
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x300)) = 0x0C4601; // trigger second bcast SIPI
|
||||
} else {
|
||||
// supports up to 255 cores (lapicid 255 is bcast address), requires x2APIC to have more
|
||||
for(i = 0; i < 255; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((volatile uint32_t*)((uintptr_t)lapic_addr + 0x280)) = 0; // clear APIC errors
|
||||
r = *((volatile uint32_t*)((uintptr_t)lapic_addr + 0x280));
|
||||
send_ipi(i, 0x004500); // trigger INIT IPI
|
||||
}
|
||||
mdelay(10); // wait 10 msec
|
||||
for(i = 0; i < 255; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((uint8_t*)0x1011) = 0;
|
||||
send_ipi(i, 0x004601); // trigger SIPI, start at 0100:0000h
|
||||
udelay(200); // wait 200 usec
|
||||
if(!*((uint8_t*)0x1011)) {
|
||||
send_ipi(i, 0x004601);
|
||||
udelay(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
numcores = 1;
|
||||
lapic_addr = 0;
|
||||
lapic_ids[bootboot->bspid] = 0;
|
||||
bootboot->numcores = 1;
|
||||
}
|
||||
|
||||
/* Create paging tables */
|
||||
DBG(" * Pagetables PML4 @%p\n",paging);
|
||||
memset(paging, 0, (37+(bootboot->numcores*initstack+PAGESIZE-1)/PAGESIZE)*PAGESIZE);
|
||||
memset(paging, 0, (37+(numcores*initstack+PAGESIZE-1)/PAGESIZE)*PAGESIZE);
|
||||
//PML4
|
||||
paging[0]=(uint64_t)((uintptr_t)paging+PAGESIZE)+3; // pointer to 2M PDPE (16G RAM identity mapped)
|
||||
paging[511]=(uint64_t)((uintptr_t)paging+20*PAGESIZE)+3; // pointer to 4k PDPE (core mapped at -2M)
|
||||
|
@ -1217,14 +1215,14 @@ gzerr: panic("Unable to uncompress");
|
|||
MapPage(bb_addr, (uint64_t)((uintptr_t)bootboot)+1);
|
||||
MapPage(env_addr, (uint64_t)((uintptr_t)environment)+1);
|
||||
// stack at the top of the memory
|
||||
for(i=0; i<((bootboot->numcores*initstack+PAGESIZE-1)/PAGESIZE); i++) {
|
||||
for(i=0; i<((numcores*initstack+PAGESIZE-1)/PAGESIZE); i++) {
|
||||
if(paging[23*512+511-i])
|
||||
panic("Stack smash");
|
||||
paging[23*512+511-i]=(uint64_t)((uintptr_t)paging+(37+i)*PAGESIZE+3); // core stacks
|
||||
}
|
||||
|
||||
/* Get memory map */
|
||||
uint64_t srt, end, ldrend = (uintptr_t)paging + (37+(bootboot->numcores+3)/4)*PAGESIZE;
|
||||
uint64_t srt, end, ldrend = (uintptr_t)paging + (37+(numcores*initstack+PAGESIZE-1)/PAGESIZE)*PAGESIZE;
|
||||
uint64_t iniend = (uint64_t)(uintptr_t)core.ptr + core.size;
|
||||
MMapEnt *mmapent=(MMapEnt *)&(bootboot->mmap);
|
||||
for (i = 0; i < lib_sysinfo.n_memranges; i++) {
|
||||
|
|
|
@ -72,6 +72,7 @@ _L1040:
|
|||
_L1060:
|
||||
movw $16, %ax
|
||||
movw %ax, %ds
|
||||
incb 0x1011
|
||||
// spinlock until BSP finishes
|
||||
1: pause
|
||||
cmpb $0, 0x1010
|
||||
|
@ -118,11 +119,15 @@ bsp_init:
|
|||
* common code for all cores, enable long mode and start kernel *
|
||||
*****************************************************************************/
|
||||
longmode_init:
|
||||
// find our lapic id
|
||||
// enable lapic and find our lapic id
|
||||
movl lapic_addr, %edi
|
||||
or %edi, %edi
|
||||
jz 1f
|
||||
addl $0x20, %edi
|
||||
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
|
||||
|
@ -178,6 +183,7 @@ bootboot_startcore:
|
|||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
lock incb 0x200A // __sync_fetch_and_add(&bootboot->numcores, 1);
|
||||
movzwq %di, %rbx
|
||||
shll $1, %ebx // ebx = lapic id * 2
|
||||
addl $lapic_ids, %ebx
|
||||
|
|
|
@ -382,7 +382,7 @@ EFI_FILE_HANDLE RootDir;
|
|||
EFI_FILE_PROTOCOL *Root;
|
||||
SIMPLE_INPUT_INTERFACE *CI;
|
||||
unsigned char *kne, nosmp=0;
|
||||
volatile char bsp_done=0;
|
||||
volatile char bsp_done=0, ap_done=0;
|
||||
|
||||
// default environment variables. M$ states that 1024x768 must be supported
|
||||
int reqwidth = 1024, reqheight = 768;
|
||||
|
@ -958,10 +958,6 @@ EFI_STATUS
|
|||
report(EFI_STATUS Status,CHAR16 *Msg)
|
||||
{
|
||||
Print(L"BOOTBOOT-PANIC: %s (EFI %r)\n",Msg,Status);
|
||||
#if !defined(USE_MP_SERVICES) || !USE_MP_SERVICES
|
||||
// don't care if we can't free because it isn't allocated
|
||||
uefi_call_wrapper(BS->FreePages, 2, (EFI_PHYSICAL_ADDRESS)0x8000, 1);
|
||||
#endif
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -1398,11 +1394,18 @@ VOID EFIAPI bootboot_startcore(IN VOID* buf)
|
|||
register UINTN core_num = (UINTN)buf;
|
||||
#else
|
||||
(void)buf;
|
||||
register UINT16 core_num = lapic_addr ? lapic_ids[*((volatile uint32_t*)(lapic_addr + 0x20)) >> 24] : 0;
|
||||
register UINT16 core_num = 0;
|
||||
if(lapic_addr) {
|
||||
// enable Local APIC
|
||||
*((volatile uint32_t*)(lapic_addr + 0x0F0)) = *((volatile uint32_t*)(lapic_addr + 0x0F0)) | 0x100;
|
||||
core_num = lapic_ids[*((volatile uint32_t*)(lapic_addr + 0x20)) >> 24];
|
||||
}
|
||||
#endif
|
||||
ap_done = 1;
|
||||
|
||||
// spinlock until BSP finishes (or forever if we got an invalid lapicid, should never happen)
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); } while(!bsp_done && core_num != 0xFFFF);
|
||||
__sync_fetch_and_add(&bootboot->numcores, 1);
|
||||
|
||||
// enable SSE
|
||||
__asm__ __volatile__ (
|
||||
|
@ -1456,7 +1459,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
UINT8 pibuffer[100];
|
||||
EFI_PROCESSOR_INFORMATION *pibuf=(EFI_PROCESSOR_INFORMATION*)pibuffer;
|
||||
#else
|
||||
UINT64 ncycles = 0, currtime, endtime, ap_code = 0x8000;
|
||||
UINT64 ncycles = 0, currtime, endtime;
|
||||
#endif
|
||||
EFI_GUID SerIoGuid = EFI_SERIAL_IO_PROTOCOL_GUID;
|
||||
EFI_SERIAL_IO_PROTOCOL *ser = NULL;
|
||||
|
@ -1467,7 +1470,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
file_t ret={NULL,0};
|
||||
CHAR16 **argv, *initrdfile, *configfile, *help=
|
||||
L"SYNOPSIS\n BOOTBOOT.EFI [ -h | -? | /h | /? | -s ] [ INITRDFILE [ ENVIRONFILE [...] ] ]\n\nDESCRIPTION\n Bootstraps an operating system via the BOOTBOOT Protocol.\n If arguments not given, defaults to\n FS0:\\BOOTBOOT\\INITRD as ramdisk image and\n FS0:\\BOOTBOOT\\CONFIG for boot environment.\n Additional \"key=value\" command line arguments will be appended to the\n environment. If INITRD not found, it will use the first bootable partition\n in GPT. If CONFIG not found, it will look for /sys/config inside the\n INITRD (or partition). With -s it will scan the memory for an initrd ROM.\n\n As this is a loader, it is not supposed to return control to the shell.\n\n";
|
||||
INTN argc, scanmemory=0;
|
||||
INTN argc, scanmemory=0, numcores=0;
|
||||
|
||||
// Initialize UEFI Library
|
||||
InitializeLib(image, systab);
|
||||
|
@ -1496,11 +1499,6 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
} else {
|
||||
configfile=L"\\BOOTBOOT\\CONFIG";
|
||||
}
|
||||
#if !defined(USE_MP_SERVICES) || !USE_MP_SERVICES
|
||||
// Allocate page at fixed address for AP trampoline code as soon as possible
|
||||
status = uefi_call_wrapper(BS->AllocatePages, 4, 2, 1, 1, (EFI_PHYSICAL_ADDRESS*)&ap_code);
|
||||
if(EFI_ERROR(status) || ap_code != 0x8000) ap_code = 0;
|
||||
#endif
|
||||
|
||||
Print(L"Booting OS...\n");
|
||||
|
||||
|
@ -1542,8 +1540,13 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
__asm__ __volatile__ ( "rdtsc" : "=a"(a),"=d"(b)); currtime=((UINT64)b << 32)|a; \
|
||||
} while(currtime < endtime); \
|
||||
} else \
|
||||
for(i = 0; i < n*1000000; i++) __asm__ __volatile__ ("pause" : : : "memory"); \
|
||||
__asm__ __volatile__ ("1: pause; dec %%ecx; or %%ecx, %%ecx; jnz 1b" : : "c"(n*1000) : "memory"); \
|
||||
} while(0)
|
||||
#define send_ipi(a,v) do { \
|
||||
*((volatile uint32_t*)(lapic_addr + 0x310)) = (a << 24); \
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = v; \
|
||||
while(*((volatile uint32_t*)(lapic_addr + 0x300)) & (1 << 12)) __asm__ __volatile__ ("pause" : : : "memory"); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
// locate InitRD in ROM
|
||||
|
@ -1834,7 +1837,6 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
// collect information on system
|
||||
bootboot->protocol=PROTOCOL_DYNAMIC | LOADER_UEFI;
|
||||
bootboot->size=128;
|
||||
bootboot->numcores=1;
|
||||
CopyMem((void *)&(bootboot->initrd_ptr),&initrd.ptr,8);
|
||||
bootboot->initrd_size=((initrd.size+PAGESIZE-1)/PAGESIZE)*PAGESIZE;
|
||||
CopyMem((void *)&(bootboot->arch.x86_64.efi_ptr),&systab,8);
|
||||
|
@ -1897,13 +1899,14 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
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;
|
||||
if(i<1) i = 1;
|
||||
numcores = i;
|
||||
}
|
||||
DBG(L" * SMP numcores %d\n", bootboot->numcores);
|
||||
DBG(L" * SMP numcores %d\n", 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++) {
|
||||
for(i=0; i<numcores; i++) {
|
||||
status = uefi_call_wrapper(mp->GetProcessorInfo, 5, mp, i, pibuf);
|
||||
if(!EFI_ERROR(status)) {
|
||||
if(pibuf->StatusFlag & PROCESSOR_AS_BSP_BIT) {
|
||||
|
@ -1916,10 +1919,10 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
}
|
||||
}
|
||||
} else
|
||||
bootboot->numcores = 1;
|
||||
numcores = 1;
|
||||
#else
|
||||
UINT8 *ptr = (UINT8*)bootboot->arch.x86_64.acpi_ptr, *pe, *data;
|
||||
UINT64 r;
|
||||
UINT64 r, boguscore = 0;
|
||||
for(i = 0; i < (int)(sizeof(lapic_ids)/sizeof(lapic_ids[0])); i++) lapic_ids[i] = 0xFFFF;
|
||||
if(!nosmp && ptr && (ptr[0]=='X' || ptr[0]=='R') && ptr[1]=='S' && ptr[2]=='D' && ptr[3]=='T') {
|
||||
pe = ptr; ptr += 36;
|
||||
|
@ -1933,7 +1936,10 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
i < (int)(sizeof(lapic_ids)/sizeof(lapic_ids[0])); ptr += ptr[1]) {
|
||||
switch(ptr[0]) {
|
||||
case 0: // found Processor Local APIC
|
||||
if((ptr[4] & 1) && lapic_ids[(INTN)ptr[3]] == 0xFFFF) { lapic_ids[(INTN)ptr[3]] = i++; }
|
||||
if((ptr[4] & 1) && ptr[3] != 0xFF && lapic_ids[(INTN)ptr[3]] == 0xFFFF)
|
||||
lapic_ids[(INTN)ptr[3]] = i++;
|
||||
else
|
||||
boguscore++;
|
||||
break;
|
||||
case 5: lapic_addr = *((uint64_t*)(ptr+4)); break; // found 64 bit Local APIC Address
|
||||
}
|
||||
|
@ -1941,25 +1947,19 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
if(i) {
|
||||
bsp_num = lapic_ids[bootboot->bspid];
|
||||
if(bsp_num == 0xFFFF) bsp_num = 0;
|
||||
else bootboot->numcores = i;
|
||||
else {
|
||||
numcores = i;
|
||||
DBG(L" * SMP numcores %d%s\n", numcores, boguscore ? L" (bogus ACPI table)" : L"");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!nosmp && 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, 0x80CC;"
|
||||
"movl %%ds, %%eax; movl %%eax, 0x80D0;"
|
||||
"sgdt 0x80E0" : : : );
|
||||
// save relocated address, relocation record doesn't work in Assembly
|
||||
*((uint64_t*)0x80D8) = (uint64_t)bootboot_startcore;
|
||||
} else
|
||||
bootboot->numcores = 1;
|
||||
if(nosmp || numcores < 2 || !lapic_addr) {
|
||||
numcores = 1;
|
||||
lapic_addr = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// query size of memory map
|
||||
|
@ -1970,7 +1970,7 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
}
|
||||
// allocate memory for memory descriptors. We assume that one or two new memory
|
||||
// descriptor may be created by our next allocate calls and we round up to page size
|
||||
memory_map_size+=2*desc_size;
|
||||
memory_map_size+=16*desc_size;
|
||||
memory_map = NULL;
|
||||
status = uefi_call_wrapper(BS->AllocatePages, 4, 0, 2,
|
||||
(memory_map_size+PAGESIZE-1)/PAGESIZE,
|
||||
|
@ -1982,11 +1982,11 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
// create page tables
|
||||
paging = NULL;
|
||||
status = uefi_call_wrapper(BS->AllocatePages, 4, 0, 2, 37+
|
||||
(bootboot->numcores*initstack+PAGESIZE-1)/PAGESIZE, (EFI_PHYSICAL_ADDRESS*)&paging);
|
||||
(numcores*initstack+PAGESIZE-1)/PAGESIZE, (EFI_PHYSICAL_ADDRESS*)&paging);
|
||||
if (EFI_ERROR(status) || paging == NULL) {
|
||||
return report(EFI_OUT_OF_RESOURCES,L"AllocatePages");
|
||||
}
|
||||
ZeroMem((void*)paging,(37+(bootboot->numcores*initstack+PAGESIZE-1)/PAGESIZE)*PAGESIZE);
|
||||
ZeroMem((void*)paging,(37+(numcores*initstack+PAGESIZE-1)/PAGESIZE)*PAGESIZE);
|
||||
DBG(L" * Pagetables PML4 @%lx\n",paging);
|
||||
//PML4
|
||||
paging[0]=(UINT64)((UINT8 *)paging+PAGESIZE)+3; // pointer to 2M PDPE (16G RAM identity mapped)
|
||||
|
@ -2017,14 +2017,14 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
MapPage(bb_addr, (UINT64)(bootboot)+1);
|
||||
MapPage(env_addr, (UINT64)(env.ptr)+1);
|
||||
// stack at the top of the memory
|
||||
for(i=0; i<(UINTN)((bootboot->numcores*initstack+PAGESIZE-1)/PAGESIZE); i++) {
|
||||
for(i=0; i<(UINTN)((numcores*initstack+PAGESIZE-1)/PAGESIZE); i++) {
|
||||
if(paging[23*512+511-i])
|
||||
return report(EFI_OUT_OF_RESOURCES,L"Stack smash");
|
||||
paging[23*512+511-i]=(UINT64)((UINT8 *)paging+(37+i)*PAGESIZE+3); // core stacks
|
||||
}
|
||||
|
||||
// Get memory map
|
||||
int cnt = 3;
|
||||
int cnt = 3, apmemfree = 0;
|
||||
get_memory_map:
|
||||
DBG(L" * Memory Map @%lx %d bytes try #%d\n", memory_map, memory_map_size, 4-cnt);
|
||||
mmapent = (MMapEnt *)&(bootboot->mmap);
|
||||
|
@ -2042,6 +2042,10 @@ get_memory_map:
|
|||
if(mement==NULL || bootboot->size>=PAGESIZE-128 ||
|
||||
(mement->PhysicalStart==0 && mement->NumberOfPages==0))
|
||||
break;
|
||||
// check if the AP trampoline code's memory is free
|
||||
if( mement->Type==7 && mement->PhysicalStart <= (UINT64)0x8000 &&
|
||||
mement->PhysicalStart+(mement->NumberOfPages*PAGESIZE) > (UINT64)0x8000)
|
||||
apmemfree = 1;
|
||||
// failsafe, don't report our own structures as free
|
||||
if( mement->NumberOfPages==0 ||
|
||||
((mement->PhysicalStart <= (UINT64)bootboot &&
|
||||
|
@ -2079,7 +2083,8 @@ get_memory_map:
|
|||
// --- NO PRINT AFTER THIS POINT ---
|
||||
|
||||
// blue (or red) dot on the top left corner (sort of status report)
|
||||
*((uint64_t*)(bootboot->fb_ptr)) = *((uint64_t*)(bootboot->fb_ptr + bootboot->fb_scanline)) = 0x000000FF000000FFUL;
|
||||
*((volatile uint64_t*)(bootboot->fb_ptr)) =
|
||||
*((volatile uint64_t*)(bootboot->fb_ptr + bootboot->fb_scanline)) = 0x000000FF000000FFUL;
|
||||
|
||||
//inform firmware that we're about to leave it's realm
|
||||
status = uefi_call_wrapper(BS->ExitBootServices, 2, image, map_key);
|
||||
|
@ -2090,54 +2095,55 @@ get_memory_map:
|
|||
}
|
||||
|
||||
#if !defined(USE_MP_SERVICES) || !USE_MP_SERVICES
|
||||
// green dot on the top left corner
|
||||
*((uint64_t*)(bootboot->fb_ptr)) = *((uint64_t*)(bootboot->fb_ptr + bootboot->fb_scanline)) = 0x0000FF000000FF00UL;
|
||||
// green dot on the top left corner (do not allow gcc to rearrange this!!!)
|
||||
*((volatile uint64_t*)(bootboot->fb_ptr)) =
|
||||
*((volatile uint64_t*)(bootboot->fb_ptr + bootboot->fb_scanline)) = 0x0000FF000000FF00UL;
|
||||
__asm__ __volatile__ ("pause" : : : "memory"); // memory barrier
|
||||
|
||||
// start APs
|
||||
if(bootboot->numcores > 1) {
|
||||
// send INIT IPI (supports up to 256 cores, requires x2APIC to have more)
|
||||
for(i = 0; i < 256; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((volatile uint32_t*)(lapic_addr + 0x280)) = 0; // clear APIC errors
|
||||
*((volatile uint32_t*)(lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x310)) & 0x00ffffff) | (i << 24); // select AP
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x300)) & 0xfff00000) | 0x00C500; // trigger INIT IPI
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)(lapic_addr + 0x300)) & (1 << 12)); // wait for delivery
|
||||
// deassert
|
||||
*((volatile uint32_t*)(lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x310)) & 0x00ffffff) | (i << 24);
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x300)) & 0xfff00000) | 0x008500;
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)(lapic_addr + 0x300)) & (1 << 12));
|
||||
}
|
||||
// wait 10 msec
|
||||
sleep(50);
|
||||
// send STARTUP IPI
|
||||
for(i = 0; i < 256; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((volatile uint32_t*)(lapic_addr + 0x280)) = 0; // clear APIC errors
|
||||
*((volatile uint32_t*)(lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x310)) & 0x00ffffff) | (i << 24); // select AP
|
||||
// trigger IPI, start at 0800:0000h
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x300)) & 0xfff0f800) | 0x000608;
|
||||
// wait 200 usec
|
||||
sleep(1);
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)(lapic_addr + 0x300)) & (1 << 12)); // wait for delivery
|
||||
// send second IPI
|
||||
*((volatile uint32_t*)(lapic_addr + 0x280)) = 0;
|
||||
*((volatile uint32_t*)(lapic_addr + 0x310)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x310)) & 0x00ffffff) | (i << 24);
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) =
|
||||
(*((volatile uint32_t*)(lapic_addr + 0x300)) & 0xfff0f800) | 0x000608;
|
||||
do { __asm__ __volatile__ ("pause" : : : "memory"); }
|
||||
while(*((volatile uint32_t*)(lapic_addr + 0x300)) & (1 << 12));
|
||||
if(numcores > 1 && apmemfree) {
|
||||
|
||||
// copy trampoline and save UEFI's 64 bit system registers for the trampoline code
|
||||
__asm__ __volatile__ (
|
||||
"movq $32, %%rcx; movq %0, %%rsi; movq $0x8000, %%rdi; repnz movsq;"
|
||||
"movq %%cr3, %%rax; movq %%rax, 0x80C0;"
|
||||
"movl %%cs, %%eax; movl %%eax, 0x80CC;"
|
||||
"movl %%ds, %%eax; movl %%eax, 0x80D0;"
|
||||
"movq %%rbx, 0x80D8;"
|
||||
"sgdt 0x80E0;" : : "a"((uint64_t)&ap_trampoline), "b"((uint64_t)&bootboot_startcore) : );
|
||||
|
||||
// enable Local APIC
|
||||
*((volatile uint32_t*)(lapic_addr + 0x0F0)) = *((volatile uint32_t*)(lapic_addr + 0x0F0)) | 0x100;
|
||||
|
||||
// if there were no bogus core definitions in the ACPI table, we can do a broadcast (simpler, faster)
|
||||
if(!boguscore) {
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = 0x0C4500; // trigger bcast INIT IPI
|
||||
sleep(50); // wait 10 msec
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = 0x0C4608; // trigger bcast SIPI, start at 0800:0000h
|
||||
sleep(1); // wait 200 usec
|
||||
*((volatile uint32_t*)(lapic_addr + 0x300)) = 0x0C4608; // trigger second bcast SIPI
|
||||
} else {
|
||||
// supports up to 255 cores (lapicid 255 is bcast address), requires x2APIC to have more
|
||||
for(i = 0; i < 255; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
*((volatile uint32_t*)(lapic_addr + 0x280)) = 0; // clear APIC errors
|
||||
a = *((volatile uint32_t*)((uintptr_t)lapic_addr + 0x280));
|
||||
send_ipi(i, 0x004500); // trigger INIT IPI
|
||||
}
|
||||
sleep(50); // wait 10 msec
|
||||
for(i = 0; i < 255; i++) {
|
||||
if(i == bootboot->bspid || lapic_ids[i] == 0xFFFF) continue;
|
||||
ap_done = 0;
|
||||
send_ipi(i, 0x004608); // trigger SIPI, start at 0800:0000h
|
||||
sleep(1); // wait 200 usec
|
||||
if(!ap_done) {
|
||||
send_ipi(i, 0x004608);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
__asm__ __volatile__ ("pause" : : : "memory"); // memory barrier
|
||||
#endif
|
||||
|
||||
// clear the screen
|
||||
|
@ -2150,7 +2156,6 @@ get_memory_map:
|
|||
|
||||
// release AP spinlock
|
||||
bsp_done = 1;
|
||||
__asm__ __volatile__ ("pause" : : : "memory"); // memory barrier
|
||||
bootboot_startcore((VOID*)bsp_num);
|
||||
}
|
||||
return report(status,L"Initrd not found");
|
||||
|
|
Loading…
Reference in a new issue