diff c1d40df49550393f3afe53fb6e6d500dfa8eb7a8 uncommitted --- /dev/null +++ b/sys/src/boot/efi/aa64.s @@ -1,0 +1,95 @@ +#define SYSREG(op0,op1,Cn,Cm,op2) SPR(((op0)<<19|(op1)<<16|(Cn)<<12|(Cm)<<8|(op2)<<5)) +#define SCTLR_EL1 SYSREG(3,0,1,0,0) + +#define NSH (1<<2 | 3) +#define NSHST (1<<2 | 2) +#define SY (3<<2 | 3) + +TEXT start(SB), 1, $-4 +_base: + MOV R0, R3 + MOV R1, R4 + + MOV $setSB(SB), R0 + BL rebase(SB) + MOV R0, R28 + + MOV $argsbuf<>(SB), R0 + MOV R0, confaddr(SB) + + MOV R3, R0 + MOV R4, 0x08(FP) + B efimain(SB) + +TEXT rebase(SB), 1, $-4 + ADR _base, R1 + SUB $0x8200, R0 + ADD R1, R0 + RETURN + +TEXT eficall(SB), 1, $-4 + MOV R0, R8 + MOV 0x08(FP), R0 + MOV 0x10(FP), R1 + MOV 0x18(FP), R2 + MOV 0x20(FP), R3 + MOV 0x28(FP), R4 + MOV 0x30(FP), R5 + MOV 0x38(FP), R6 + MOV 0x40(FP), R7 + B (R8) + +TEXT mmudisable<>(SB), 1, $-4 +#define SCTLRCLR \ + /* RES0 */ ( 3<<30 \ + /* RES0 */ | 1<<27 \ + /* UCI */ | 1<<26 \ + /* EE */ | 1<<25 \ + /* RES0 */ | 1<<21 \ + /* E0E */ | 1<<24 \ + /* WXN */ | 1<<19 \ + /* nTWE */ | 1<<18 \ + /* RES0 */ | 1<<17 \ + /* nTWI */ | 1<<16 \ + /* UCT */ | 1<<15 \ + /* DZE */ | 1<<14 \ + /* RES0 */ | 1<<13 \ + /* RES0 */ | 1<<10 \ + /* UMA */ | 1<<9 \ + /* SA0 */ | 1<<4 \ + /* SA */ | 1<<3 \ + /* A */ | 1<<1 ) +#define SCTLRSET \ + /* RES1 */ ( 3<<28 \ + /* RES1 */ | 3<<22 \ + /* RES1 */ | 1<<20 \ + /* RES1 */ | 1<<11 ) +#define SCTLRMMU \ + /* I */ ( 1<<12 \ + /* C */ | 1<<2 \ + /* M */ | 1<<0 ) + + /* initialise SCTLR, MMU and caches off */ + ISB $SY + MRS SCTLR_EL1, R0 + BIC $(SCTLRCLR | SCTLRMMU), R0 + ORR $SCTLRSET, R0 + ISB $SY + MSR R0, SCTLR_EL1 + ISB $SY + + DSB $NSHST + TLBI R0, 0,8,7,0 /* VMALLE1 */ + DSB $NSH + ISB $SY + RETURN + +TEXT jump(SB), 1, $-4 + MOV R0, R3 + MOV R1, R4 + BL mmudisable<>(SB) + MOV R4, R0 + B (R3) + +GLOBL confaddr(SB), $8 +GLOBL argsbuf<>(SB), $0x1000 --- a/sys/src/boot/efi/efi.c +++ b/sys/src/boot/efi/efi.c @@ -10,6 +10,16 @@ int (*read)(void *f, void *data, int len); void (*close)(void *f); +/* + * on ia32 and amd64, we use IMAGE_FILE_RELOCS_STRIPPED which + * disables relocations, so this is a no-op. + * + * on arm64, the EFI loader can move our code, so we need to + * update some of our stored addresses (such as callbacks) + * which assume we are loaded at our requested base address. + */ +extern void *rebase(void *addr); + void putc(int c) { @@ -297,6 +307,10 @@ f = nil; if(pxeinit(&f) && isoinit(&f) && fsinit(&f)) print("no boot devices\n"); + + read = rebase(read); + close = rebase(close); + open = rebase(open); for(;;){ kern = configure(f, path); --- a/sys/src/boot/efi/fns.h +++ b/sys/src/boot/efi/fns.h @@ -5,7 +5,7 @@ extern char hex[]; void usleep(int t); -void jump(void *pc); +void jump(void *pc, void *arg); int pxeinit(void **pf); int isoinit(void **pf); --- /dev/null +++ b/sys/src/boot/efi/ia32.s @@ -1,0 +1,47 @@ +#include "mem.h" + +TEXT start(SB), 1, $0 + CALL reloc(SP) + +TEXT reloc(SB), 1, $0 + MOVL 0(SP), SI + SUBL $reloc-IMAGEBASE(SB), SI + MOVL $IMAGEBASE, DI + MOVL $edata-IMAGEBASE(SB), CX + CLD + REP; MOVSB + MOVL $efimain(SB), DI + MOVL DI, (SP) + RET + +TEXT jump(SB), $0 + CLI + MOVL 4(SP), AX + JMP *AX + +TEXT eficall(SB), 1, $0 + MOVL SP, SI + MOVL SP, DI + MOVL $(4*16), CX + SUBL CX, DI + ANDL $~15ULL, DI + SUBL $8, DI + + MOVL 4(SI), AX + LEAL 8(DI), SP + + CLD + REP; MOVSB + SUBL $(4*16), SI + + CALL AX + + MOVL SI, SP + RET + +TEXT rebase(SB), 1, $0 + MOVL 4(SP), AX + RET + +GLOBL confaddr(SB), $4 +DATA confaddr(SB)/4, $CONFADDR --- a/sys/src/boot/efi/iso.c +++ b/sys/src/boot/efi/iso.c @@ -24,8 +24,10 @@ uchar dirlen; uchar extlen; - uchar lba[8]; - uchar len[8]; + ulong lba; + ulong lbabe; + ulong len; + ulong lenbe; uchar date[7]; @@ -133,8 +135,24 @@ break; if(d.dirlen == 0) continue; /* zero padding to next sector */ - if(read(ex, &d.dirlen + 1, Dirsz-1) != Dirsz-1) + if(read(ex, &d.extlen, 1) != 1) break; + if(read(ex, &d.lba, 4) != 4) + break; + if(read(ex, &d.lbabe, 4) != 4) + break; + if(read(ex, &d.len, 4) != 4) + break; + if(read(ex, &d.lenbe, 4) != 4) + break; + if(read(ex, d.date, 7) != 7) + break; + if(read(ex, d.flags, 3) != 3) + break; + if(read(ex, d.seq, 4) != 4) + break; + if(read(ex, &d.namelen, 1) != 1) + break; if(read(ex, name, d.namelen) != d.namelen) break; i = d.dirlen - (Dirsz + d.namelen); @@ -158,8 +176,8 @@ i = end - path; if(d.namelen == i && memcmp(name, path, i) == 0){ ex->rp = ex->ep; - ex->lba = *((ulong*)d.lba); - ex->len = *((ulong*)d.len); + ex->lba = d.lba; + ex->len = d.len; if(*end == 0) return 0; else if(d.flags[0] & 2){ --- a/sys/src/boot/efi/mkfile +++ b/sys/src/boot/efi/mkfile @@ -1,4 +1,4 @@ -TARG=bootia32.efi bootx64.efi efiboot.fat +TARG=bootia32.efi bootx64.efi bootaa64.efi efiboot.fat HFILES=fns.h mem.h IMAGEBASE=0x8000 CFLAGS=-FTVw @@ -9,55 +9,37 @@ install:V: $TARG cp $prereq /386 -bootia32.efi: pe32.8 efi.8 fs.8 pxe.8 iso.8 sub.8 - 8l -l -H3 -T$IMAGEBASE -o $target $prereq - -pe32.8: pe32.s - 8a $PEFLAGS pe32.s - -efi.8: efi.c efi.h - 8c $CFLAGS efi.c - -fs.8: fs.c efi.h - 8c $CFLAGS fs.c - -pxe.8: pxe.c efi.h - 8c $CFLAGS pxe.c - -iso.8: iso.c efi.h - 8c $CFLAGS iso.c - -sub.8: sub.c - 8c $CFLAGS sub.c - +%.8: %.s + 8a $PEFLAGS $stem.s +%.8: %.c + 8c $CFLAGS $stem.c +bootia32.efi: ia32.8 efi.8 fs.8 pxe.8 iso.8 sub.8 + 8l -l -s -R1 -T0x8200 -o bootia32.out $prereq + aux/aout2efi -Z$IMAGEBASE -o $target bootia32.out %.8: $HFILES -bootx64.efi: pe64.6 efi.6 fs.6 pxe.6 iso.6 sub.6 - 6l -l -s -R1 -T$IMAGEBASE -o bootx64.out $prereq - dd -if bootx64.out -bs 1 -iseek 40 >$target +%.6: %.s + 6a $PEFLAGS $stem.s +%.6: %.c + 6c $CFLAGS $stem.c +bootx64.efi: x64.6 efi.6 fs.6 pxe.6 iso.6 sub.6 + 6l -l -s -R1 -T0x8200 -o bootx64.out $prereq + aux/aout2efi -Z$IMAGEBASE -o $target bootx64.out +%.6: $HFILES -pe64.6: pe64.s - 6a $PEFLAGS pe64.s -efi.6: efi.c efi.h - 6c $CFLAGS efi.c +%.7: %.s + 7a $PEFLAGS $stem.s +%.7: %.c + 7c $CFLAGS $stem.c +bootaa64.efi: aa64.7 efi.7 fs.7 pxe.7 iso.7 sub.7 + 7l -l -s -R1 -T0x8200 -o bootaa64.out $prereq + aux/aout2efi -Z$IMAGEBASE -o $target bootaa64.out +%.7: $HFILES -fs.6: fs.c efi.h - 6c $CFLAGS fs.c -pxe.6: pxe.c efi.h - 6c $CFLAGS pxe.c - -iso.6: iso.c efi.h - 6c $CFLAGS iso.c - -sub.6: sub.c - 6c $CFLAGS sub.c - -%.6: $HFILES - -efiboot.fat:D: bootia32.efi bootx64.efi +efiboot.fat:D: bootia32.efi bootx64.efi bootaa64.efi s = $target.$pid rm -f $target dd -if /dev/zero -of $target -bs 1024 -count 1024 @@ -68,6 +50,7 @@ mkdir /n/esp/efi/boot cp bootia32.efi /n/esp/efi/boot cp bootx64.efi /n/esp/efi/boot + cp bootaa64.efi /n/esp/efi/boot unmount /n/esp rm /srv/$s @@ -84,7 +67,7 @@ disk/mk9660 -B 386/9bootiso -E 386/efiboot.fat -p <{echo +} -s tmp $target rm -r tmp -test.fat:D: bootia32.efi bootx64.efi +test.fat:D: bootia32.efi bootx64.efi bootaa64.efi s = $target.$pid rm -f $target dd -if /dev/zero -of $target -bs 65536 -count 128 @@ -95,6 +78,7 @@ mkdir /n/esp/efi/boot cp bootia32.efi /n/esp/efi/boot cp bootx64.efi /n/esp/efi/boot + cp bootaa64.efi /n/esp/efi/boot cp /386/9pc /n/esp echo 'bootfile=9pc' >/n/esp/plan9.ini unmount /n/esp @@ -102,4 +86,4 @@ clean:V: - rm -f *.[68] *.out $TARG test.* + rm -f *.[678] *.out $TARG test.* --- a/sys/src/boot/efi/pe32.s +++ /dev/null @@ -1,159 +1,0 @@ -TEXT mzhdr(SB), 1, $0 - BYTE $'M'; BYTE $'Z' - - WORD $0 /* e_cblp UNUSED */ - WORD $0 /* e_cp UNUSED */ - WORD $0 /* e_crlc UNUSED */ - WORD $0 /* e_cparhdr UNUSED */ - WORD $0 /* e_minalloc UNUSED */ - WORD $0 /* e_maxalloc UNUSED */ - WORD $0 /* e_ss UNUSED */ - WORD $0 /* e_sp UNUSED */ - WORD $0 /* e_csum UNUSED */ - WORD $0 /* e_ip UNUSED */ - WORD $0 /* e_cs UNUSED */ - WORD $0 /* e_lsarlc UNUSED */ - WORD $0 /* e_ovno UNUSED */ - - WORD $0 /* e_res UNUSED */ - WORD $0 - WORD $0 - WORD $0 - WORD $0 - - WORD $0 /* e_oemid UNUSED */ - - WORD $0 /* e_res2 UNUSED */ - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - - LONG $pehdr-IMAGEBASE(SB) /* offset to pe header */ - -TEXT pehdr(SB), 1, $0 - BYTE $'P'; BYTE $'E'; BYTE $0; BYTE $0 - - WORD $0x014C /* Machine (Intel 386) */ - WORD $1 /* NumberOfSections */ - LONG $0 /* TimeDateStamp UNUSED */ - LONG $0 /* PointerToSymbolTable UNUSED */ - LONG $0 /* NumberOfSymbols UNUSED */ - WORD $0xE0 /* SizeOfOptionalHeader */ - WORD $2103 /* Characteristics (no relocations, executable, 32 bit) */ - - WORD $0x10B /* Magic (PE32) */ - BYTE $9 /* MajorLinkerVersion UNUSED */ - BYTE $0 /* MinorLinkerVersion UNUSED */ - LONG $0 /* SizeOfCode UNUSED */ - LONG $0 /* SizeOfInitializedData UNUSED */ - LONG $0 /* SizeOfUninitializedData UNUSED */ - LONG $start-IMAGEBASE(SB)/* AddressOfEntryPoint */ - LONG $0 /* BaseOfCode UNUSED */ - LONG $0 /* BaseOfData UNUSED */ - LONG $IMAGEBASE /* ImageBase */ - LONG $0x200 /* SectionAlignment */ - LONG $0x200 /* FileAlignment */ - WORD $4 /* MajorOperatingSystemVersion UNUSED */ - WORD $0 /* MinorOperatingSystemVersion UNUSED */ - WORD $0 /* MajorImageVersion UNUSED */ - WORD $0 /* MinorImageVersion UNUSED */ - WORD $4 /* MajorSubsystemVersion */ - WORD $0 /* MinorSubsystemVersion UNUSED */ - LONG $0 /* Win32VersionValue UNUSED */ - LONG $end-IMAGEBASE(SB) /* SizeOfImage */ - LONG $start-IMAGEBASE(SB)/* SizeOfHeaders */ - LONG $0 /* CheckSum UNUSED */ - WORD $10 /* Subsystem (10 = efi application) */ - WORD $0 /* DllCharacteristics UNUSED */ - LONG $0 /* SizeOfStackReserve UNUSED */ - LONG $0 /* SizeOfStackCommit UNUSED */ - LONG $0 /* SizeOfHeapReserve UNUSED */ - LONG $0 /* SizeOfHeapCommit UNUSED */ - LONG $0 /* LoaderFlags UNUSED */ - LONG $16 /* NumberOfRvaAndSizes UNUSED */ - - LONG $0; LONG $0 - LONG $0; LONG $0 - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - - BYTE $'.'; BYTE $'t'; BYTE $'e'; BYTE $'x' - BYTE $'t'; BYTE $0; BYTE $0; BYTE $0 - LONG $edata-(IMAGEBASE+0x200)(SB) /* VirtualSize */ - LONG $start-IMAGEBASE(SB) /* VirtualAddress */ - LONG $edata-(IMAGEBASE+0x200)(SB) /* SizeOfData */ - LONG $start-IMAGEBASE(SB) /* PointerToRawData */ - LONG $0 /* PointerToRelocations UNUSED */ - LONG $0 /* PointerToLinenumbers UNUSED */ - WORD $0 /* NumberOfRelocations UNUSED */ - WORD $0 /* NumberOfLinenumbers UNUSED */ - LONG $0x86000020 /* Characteristics (code, execute, read, write) */ - - /* padding to get start(SB) at IMAGEBASE+0x200 */ - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - -TEXT start(SB), 1, $0 - CALL reloc(SP) - -TEXT reloc(SB), 1, $0 - MOVL 0(SP), SI - SUBL $reloc-IMAGEBASE(SB), SI - MOVL $IMAGEBASE, DI - MOVL $edata-IMAGEBASE(SB), CX - CLD - REP; MOVSB - MOVL $efimain(SB), DI - MOVL DI, (SP) - RET - -TEXT jump(SB), $0 - CLI - MOVL 4(SP), AX - JMP *AX - -TEXT eficall(SB), 1, $0 - MOVL SP, SI - MOVL SP, DI - MOVL $(4*16), CX - SUBL CX, DI - ANDL $~15ULL, DI - SUBL $8, DI - - MOVL 4(SI), AX - LEAL 8(DI), SP - - CLD - REP; MOVSB - SUBL $(4*16), SI - - CALL AX - - MOVL SI, SP - RET --- a/sys/src/boot/efi/pe64.s +++ /dev/null @@ -1,237 +1,0 @@ -TEXT mzhdr(SB), 1, $0 - BYTE $'M'; BYTE $'Z' - - WORD $0 /* e_cblp UNUSED */ - WORD $0 /* e_cp UNUSED */ - WORD $0 /* e_crlc UNUSED */ - WORD $0 /* e_cparhdr UNUSED */ - WORD $0 /* e_minalloc UNUSED */ - WORD $0 /* e_maxalloc UNUSED */ - WORD $0 /* e_ss UNUSED */ - WORD $0 /* e_sp UNUSED */ - WORD $0 /* e_csum UNUSED */ - WORD $0 /* e_ip UNUSED */ - WORD $0 /* e_cs UNUSED */ - WORD $0 /* e_lsarlc UNUSED */ - WORD $0 /* e_ovno UNUSED */ - - WORD $0 /* e_res UNUSED */ - WORD $0 - WORD $0 - WORD $0 - WORD $0 - - WORD $0 /* e_oemid UNUSED */ - - WORD $0 /* e_res2 UNUSED */ - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - WORD $0 - - LONG $pehdr-IMAGEBASE(SB) /* offset to pe header */ - -TEXT pehdr(SB), 1, $0 - BYTE $'P'; BYTE $'E'; BYTE $0; BYTE $0 - - WORD $0x8664 /* Machine (AMD64) */ - WORD $1 /* NumberOfSections */ - LONG $0 /* TimeDateStamp UNUSED */ - LONG $0 /* PointerToSymbolTable UNUSED */ - LONG $0 /* NumberOfSymbols UNUSED */ - WORD $0xF0 /* SizeOfOptionalHeader */ - WORD $2223 /* Characteristics */ - - WORD $0x20B /* Magic (PE32+) */ - BYTE $9 /* MajorLinkerVersion UNUSED */ - BYTE $0 /* MinorLinkerVersion UNUSED */ - LONG $0 /* SizeOfCode UNUSED */ - LONG $0 /* SizeOfInitializedData UNUSED */ - LONG $0 /* SizeOfUninitializedData UNUSED */ - LONG $start-IMAGEBASE(SB)/* AddressOfEntryPoint */ - LONG $0 /* BaseOfCode UNUSED */ - - QUAD $IMAGEBASE /* ImageBase */ - LONG $0x200 /* SectionAlignment */ - LONG $0x200 /* FileAlignment */ - WORD $4 /* MajorOperatingSystemVersion UNUSED */ - WORD $0 /* MinorOperatingSystemVersion UNUSED */ - WORD $0 /* MajorImageVersion UNUSED */ - WORD $0 /* MinorImageVersion UNUSED */ - WORD $4 /* MajorSubsystemVersion */ - WORD $0 /* MinorSubsystemVersion UNUSED */ - LONG $0 /* Win32VersionValue UNUSED */ - LONG $end-IMAGEBASE(SB) /* SizeOfImage */ - LONG $start-IMAGEBASE(SB)/* SizeOfHeaders */ - LONG $0 /* CheckSum UNUSED */ - WORD $10 /* Subsystem (10 = efi application) */ - WORD $0 /* DllCharacteristics UNUSED */ - QUAD $0 /* SizeOfStackReserve UNUSED */ - QUAD $0 /* SizeOfStackCommit UNUSED */ - QUAD $0 /* SizeOfHeapReserve UNUSED */ - QUAD $0 /* SizeOfHeapCommit UNUSED */ - LONG $0 /* LoaderFlags UNUSED */ - LONG $16 /* NumberOfRvaAndSizes UNUSED */ - - LONG $0; LONG $0 - LONG $0; LONG $0 - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - LONG $0; LONG $0 /* RVA */ - - BYTE $'.'; BYTE $'t'; BYTE $'e'; BYTE $'x' - BYTE $'t'; BYTE $0; BYTE $0; BYTE $0 - LONG $edata-(IMAGEBASE+0x200)(SB) /* VirtualSize */ - LONG $start-IMAGEBASE(SB) /* VirtualAddress */ - LONG $edata-(IMAGEBASE+0x200)(SB) /* SizeOfData */ - LONG $start-IMAGEBASE(SB) /* PointerToRawData */ - LONG $0 /* PointerToRelocations UNUSED */ - LONG $0 /* PointerToLinenumbers UNUSED */ - WORD $0 /* NumberOfRelocations UNUSED */ - WORD $0 /* NumberOfLinenumbers UNUSED */ - LONG $0x86000020 /* Characteristics (code, execute, read, write) */ - - /* padding to get start(SB) at IMAGEBASE+0x200 */ - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0; - LONG $0; LONG $0; LONG $0; LONG $0 - -MODE $64 - -TEXT start(SB), 1, $-4 - /* spill arguments */ - MOVQ CX, 8(SP) - MOVQ DX, 16(SP) - - CALL reloc(SP) - -TEXT reloc(SB), 1, $-4 - MOVQ 0(SP), SI - SUBQ $reloc-IMAGEBASE(SB), SI - MOVQ $IMAGEBASE, DI - MOVQ $edata-IMAGEBASE(SB), CX - CLD - REP; MOVSB - - MOVQ 16(SP), BP - MOVQ $efimain(SB), DI - MOVQ DI, (SP) - RET - -TEXT eficall(SB), 1, $-4 - MOVQ SP, SI - MOVQ SP, DI - MOVL $(8*16), CX - SUBQ CX, DI - ANDQ $~15ULL, DI - LEAQ 16(DI), SP - CLD - REP; MOVSB - SUBQ $(8*16), SI - - MOVQ 0(SP), CX - MOVQ 8(SP), DX - MOVQ 16(SP), R8 - MOVQ 24(SP), R9 - CALL BP - - MOVQ SI, SP - RET - -#include "mem.h" - -TEXT jump(SB), 1, $-4 - CLI - - /* load zero length idt */ - MOVL $_idtptr64p<>(SB), AX - MOVL (AX), IDTR - - /* load temporary gdt */ - MOVL $_gdtptr64p<>(SB), AX - MOVL (AX), GDTR - - /* load CS with 32bit code segment */ - PUSHQ $SELECTOR(3, SELGDT, 0) - PUSHQ $_warp32<>(SB) - RETFQ - -MODE $32 - -TEXT _warp32<>(SB), 1, $-4 - - /* load 32bit data segments */ - MOVL $SELECTOR(2, SELGDT, 0), AX - MOVW AX, DS - MOVW AX, ES - MOVW AX, FS - MOVW AX, GS - MOVW AX, SS - - /* turn off paging */ - MOVL CR0, AX - ANDL $0x7fffffff, AX /* ~(PG) */ - MOVL AX, CR0 - - MOVL $0, AX - MOVL AX, CR3 - - /* disable long mode */ - MOVL $0xc0000080, CX /* Extended Feature Enable */ - RDMSR - ANDL $0xfffffeff, AX /* Long Mode Disable */ - WRMSR - - /* diable pae */ - MOVL CR4, AX - ANDL $0xffffff5f, AX /* ~(PAE|PGE) */ - MOVL AX, CR4 - - JMP *BP - -TEXT _gdt<>(SB), 1, $-4 - /* null descriptor */ - LONG $0 - LONG $0 - - /* (KESEG) 64 bit long mode exec segment */ - LONG $(0xFFFF) - LONG $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR) - - /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */ - LONG $(0xFFFF) - LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW) - - /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */ - LONG $(0xFFFF) - LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR) - -TEXT _gdtptr64p<>(SB), 1, $-4 - WORD $(4*8-1) - QUAD $_gdt<>(SB) - -TEXT _idtptr64p<>(SB), 1, $-4 - WORD $0 - QUAD $0 --- a/sys/src/boot/efi/sub.c +++ b/sys/src/boot/efi/sub.c @@ -149,11 +149,12 @@ return 0; } -#define BOOTLINE ((char*)CONFADDR) +#define BOOTLINE confaddr #define BOOTLINELEN 64 -#define BOOTARGS ((char*)(CONFADDR+BOOTLINELEN)) +#define BOOTARGS (confaddr+BOOTLINELEN) #define BOOTARGSLEN (4096-0x200-BOOTLINELEN) +extern char *confaddr; static char *confend; static char* @@ -329,6 +330,13 @@ return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; } +static uvlong +beswall(uvlong l) +{ + uchar *p = (uchar*)&l; + return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40) | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24) | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8) | (uvlong)p[7]; +} + char* bootkern(void *f) { @@ -342,8 +350,12 @@ e = (uchar*)(beswal(ex.entry) & ~0xF0000000UL); switch(beswal(ex.magic)){ case S_MAGIC: - if(readn(f, e, 8) != 8) + case R_MAGIC: + if(readn(f, &e, 8) != 8) goto Error; + /* load low address */ + e = (uchar*)(beswall((uvlong)e) & 0x0FFFFFFFUL); + break; case I_MAGIC: break; default: @@ -371,7 +383,7 @@ memconf(findconf("*e820=")?nil:&confend); unload(); - jump(e); + jump(e, BOOTARGS); Error: return "i/o error"; --- /dev/null +++ b/sys/src/boot/efi/x64.s @@ -1,0 +1,124 @@ +MODE $64 + +TEXT start(SB), 1, $-4 + /* spill arguments */ + MOVQ CX, 8(SP) + MOVQ DX, 16(SP) + + CALL reloc(SP) + +TEXT reloc(SB), 1, $-4 + MOVQ 0(SP), SI + SUBQ $reloc-IMAGEBASE(SB), SI + MOVQ $IMAGEBASE, DI + MOVQ $edata-IMAGEBASE(SB), CX + CLD + REP; MOVSB + + MOVQ 16(SP), BP + MOVQ $efimain(SB), DI + MOVQ DI, (SP) + RET + +TEXT eficall(SB), 1, $-4 + MOVQ SP, SI + MOVQ SP, DI + MOVL $(8*16), CX + SUBQ CX, DI + ANDQ $~15ULL, DI + LEAQ 16(DI), SP + CLD + REP; MOVSB + SUBQ $(8*16), SI + + MOVQ 0(SP), CX + MOVQ 8(SP), DX + MOVQ 16(SP), R8 + MOVQ 24(SP), R9 + CALL BP + + MOVQ SI, SP + RET + +TEXT rebase(SB), 1, $-4 + MOVQ BP, AX + RET + +#include "mem.h" + +TEXT jump(SB), 1, $-4 + CLI + + /* load zero length idt */ + MOVL $_idtptr64p<>(SB), AX + MOVL (AX), IDTR + + /* load temporary gdt */ + MOVL $_gdtptr64p<>(SB), AX + MOVL (AX), GDTR + + /* load CS with 32bit code segment */ + PUSHQ $SELECTOR(3, SELGDT, 0) + PUSHQ $_warp32<>(SB) + RETFQ + +MODE $32 + +TEXT _warp32<>(SB), 1, $-4 + + /* load 32bit data segments */ + MOVL $SELECTOR(2, SELGDT, 0), AX + MOVW AX, DS + MOVW AX, ES + MOVW AX, FS + MOVW AX, GS + MOVW AX, SS + + /* turn off paging */ + MOVL CR0, AX + ANDL $0x7fffffff, AX /* ~(PG) */ + MOVL AX, CR0 + + MOVL $0, AX + MOVL AX, CR3 + + /* disable long mode */ + MOVL $0xc0000080, CX /* Extended Feature Enable */ + RDMSR + ANDL $0xfffffeff, AX /* Long Mode Disable */ + WRMSR + + /* diable pae */ + MOVL CR4, AX + ANDL $0xffffff5f, AX /* ~(PAE|PGE) */ + MOVL AX, CR4 + + JMP *BP + +TEXT _gdt<>(SB), 1, $-4 + /* null descriptor */ + LONG $0 + LONG $0 + + /* (KESEG) 64 bit long mode exec segment */ + LONG $(0xFFFF) + LONG $(SEGL|SEGG|SEGP|(0xF<<16)|SEGPL(0)|SEGEXEC|SEGR) + + /* 32 bit data segment descriptor for 4 gigabytes (PL 0) */ + LONG $(0xFFFF) + LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW) + + /* 32 bit exec segment descriptor for 4 gigabytes (PL 0) */ + LONG $(0xFFFF) + LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR) + +TEXT _gdtptr64p<>(SB), 1, $-4 + WORD $(4*8-1) + QUAD $_gdt<>(SB) + +TEXT _idtptr64p<>(SB), 1, $-4 + WORD $0 + QUAD $0 + +GLOBL confaddr(SB), $8 +DATA confaddr(SB)/8, $CONFADDR