Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/82016?usp=email )
Change subject: NOTFORMERGE: Add 32bit entry point for x86-64 libpayload ......................................................................
NOTFORMERGE: Add 32bit entry point for x86-64 libpayload
This adds a few fixes and a 32bit entry point that jumps to long mode. This also fixes some libpayload compilation errors
UNTESTED
Change-Id: Ic2f02b5874c0406b16f0b5d1491c95cc71f38d49 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M payloads/libpayload/arch/x64/Makefile.mk M payloads/libpayload/arch/x64/exception_asm.S M payloads/libpayload/arch/x64/head.S M payloads/libpayload/arch/x64/libpayload.ldscript M payloads/libpayload/arch/x64/multiboot.c A payloads/libpayload/arch/x64/pt.S M payloads/libpayload/curses/Makefile.mk M payloads/libpayload/drivers/storage/ahci_common.c M payloads/libpayload/drivers/usb/uhci.c 9 files changed, 102 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/82016/1
diff --git a/payloads/libpayload/arch/x64/Makefile.mk b/payloads/libpayload/arch/x64/Makefile.mk index 604c001..3236b04 100644 --- a/payloads/libpayload/arch/x64/Makefile.mk +++ b/payloads/libpayload/arch/x64/Makefile.mk @@ -31,6 +31,7 @@ endif
head.o-y += head.S +libc-y += pt.S libc-y += main.c sysinfo.c libc-y += timer.c coreboot.c util.S libc-y += exec.S virtual.c diff --git a/payloads/libpayload/arch/x64/exception_asm.S b/payloads/libpayload/arch/x64/exception_asm.S index d626dd3..43fdf80 100644 --- a/payloads/libpayload/arch/x64/exception_asm.S +++ b/payloads/libpayload/arch/x64/exception_asm.S @@ -239,6 +239,7 @@ gdt_end:
/* GDT pointer for use with lgdt */ +.global gdt_ptr gdt_ptr: .word gdt_end - gdt - 1 .quad gdt diff --git a/payloads/libpayload/arch/x64/head.S b/payloads/libpayload/arch/x64/head.S index fd1237d..2ffd5c2 100644 --- a/payloads/libpayload/arch/x64/head.S +++ b/payloads/libpayload/arch/x64/head.S @@ -27,7 +27,9 @@ * SUCH DAMAGE. */
- .code64 +#define IA32_EFER 0xC0000080 + + .code32 .global _entry .text .align 16 @@ -55,6 +57,8 @@ .long _end .long _init
+ + /* * This function saves off the previous stack and switches us to our * own execution environment. @@ -63,6 +67,34 @@ /* No interrupts, please. */ cli
+ lgdt gdt_ptr + + movl $PM4LE, %eax + + /* load identity mapped page tables */ + movl %eax, %cr3 + + /* enable PAE */ + movl %cr4, %eax + btsl $5, %eax + movl %eax, %cr4 + + /* enable long mode */ + movl $(IA32_EFER), %ecx + rdmsr + btsl $8, %eax + wrmsr + + /* enable paging */ + movl %cr0, %eax + btsl $31, %eax + movl %eax, %cr0 + + ljmp $0x48, $_entry64 + +.code64 +_entry64: + /* Store RDI and RSI */ mov %rdi, loader_rdi mov %rsi, loader_rsi diff --git a/payloads/libpayload/arch/x64/libpayload.ldscript b/payloads/libpayload/arch/x64/libpayload.ldscript index 2a661be..058215c 100644 --- a/payloads/libpayload/arch/x64/libpayload.ldscript +++ b/payloads/libpayload/arch/x64/libpayload.ldscript @@ -27,7 +27,7 @@ */
OUTPUT_FORMAT(elf64-x86-64) -OUTPUT_ARCH(x86_64) +OUTPUT_ARCH(i386:x86-64)
ENTRY(_entry)
diff --git a/payloads/libpayload/arch/x64/multiboot.c b/payloads/libpayload/arch/x64/multiboot.c index eb0fc3a..0f9c5e3 100644 --- a/payloads/libpayload/arch/x64/multiboot.c +++ b/payloads/libpayload/arch/x64/multiboot.c @@ -108,7 +108,7 @@ { struct multiboot_header *table;
- if (loader_edi != MULTIBOOT_MAGIC) + if (loader_rdi != MULTIBOOT_MAGIC) return -1;
table = (struct multiboot_header *) phys_to_virt(loader_rsi); diff --git a/payloads/libpayload/arch/x64/pt.S b/payloads/libpayload/arch/x64/pt.S new file mode 100644 index 0000000..a948ff1 --- /dev/null +++ b/payloads/libpayload/arch/x64/pt.S @@ -0,0 +1,61 @@ +/* + * + * Copyright (C) 2022 Arthur Heymans arthur@aheymans.xyz + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * For reference see "AMD64 Architecture Programmer's Manual Volume 2", + * Document 24593-Rev. 3.31-July 2019 Chapter 5.3.4 + * + * Page table attributes: WB, User+Supervisor, Present, Writeable, Accessed, Dirty + */ + +.section .rodata +#define _PRES (1ULL << 0) +#define _RW (1ULL << 1) +#define _US (1ULL << 2) +#define _A (1ULL << 5) +#define _D (1ULL << 6) +#define _PS (1ULL << 7) +#define _GEN_DIR(a) (_PRES + _RW + _US + _A + (a)) +#define _GEN_PAGE(a) (_PRES + _RW + _US + _PS + _A + _D + (a)) + +.global PM4LE +.align 4096 +PM4LE: +.quad _GEN_DIR(PDPE_table) + +.align 4096 +PDE_tables: /* identity map 2MiB pages */ +.rept 2048 +.quad _GEN_PAGE(0x200000 * ((. - PDE_tables) >> 3)) +.endr + +.align 4096 +PDPE_table: /* Point to PDE */ +.rept 4 +.quad _GEN_DIR(PDE_tables + 4096 * ((. - PDPE_table) >> 3)) +.endr diff --git a/payloads/libpayload/curses/Makefile.mk b/payloads/libpayload/curses/Makefile.mk index 99f8d70..2a9b948 100644 --- a/payloads/libpayload/curses/Makefile.mk +++ b/payloads/libpayload/curses/Makefile.mk @@ -38,7 +38,7 @@
ifeq ($(CONFIG_LP_PDCURSES),y) PDCURSES := PDCurses -INCLUDES += -D_LP64=0 -Icurses/$(PDCURSES) -Icurses/pdcurses-backend -Icurses/menu -Icurses/form +INCLUDES += -Icurses/$(PDCURSES) -Icurses/pdcurses-backend -Icurses/menu -Icurses/form endif
libcurses-$(CONFIG_LP_PDCURSES) += pdcurses-backend/pdcdisp.c diff --git a/payloads/libpayload/drivers/storage/ahci_common.c b/payloads/libpayload/drivers/storage/ahci_common.c index f3abc5f..abc67c3 100644 --- a/payloads/libpayload/drivers/storage/ahci_common.c +++ b/payloads/libpayload/drivers/storage/ahci_common.c @@ -66,7 +66,7 @@ u8 *const user_buf, const size_t len, const int out) { - if ((u32)user_buf & 1) { + if ((uintptr_t)user_buf & 1) { printf("ahci: Odd buffer pointer (%p).\n", user_buf); if (dev->buf) /* orphaned buffer */ free(dev->buf - *(dev->buf - 1)); @@ -76,7 +76,7 @@ dev->user_buf = user_buf; dev->write_back = !out; dev->buflen = len; - if ((u32)dev->buf & 1) { + if ((uintptr_t)dev->buf & 1) { dev->buf[0] = 1; dev->buf += 1; } else { diff --git a/payloads/libpayload/drivers/usb/uhci.c b/payloads/libpayload/drivers/usb/uhci.c index eb252cd..b0d73b8 100644 --- a/payloads/libpayload/drivers/usb/uhci.c +++ b/payloads/libpayload/drivers/usb/uhci.c @@ -274,7 +274,7 @@
#define UHCI_SLEEP_TIME_US 30 #define UHCI_TIMEOUT (USB_MAX_PROCESSING_TIME_US / UHCI_SLEEP_TIME_US) -#define GET_TD(x) ((void*)(((unsigned int)(x))&~0xf)) +#define GET_TD(x) ((void*)(((long unsigned int)(x))&~0xf))
static td_t * wait_for_completed_qh(hci_t *controller, qh_t *qh)