libpayload: Add x86_64 (64-bit) support
This patch introduces x86_64 (64-bit) support to the payload, building upon the existing x86 (32-bit) architecture. Files necessary for 64-bit compilation are now guarded by the `CONFIG_LP_ARCH_X86_64` Kconfig option. BUG=b:242829490 TEST=Able to verify all valid combinations between coreboot and payload with this patch. Payload Entry Point Behavior with below code. +----------------+--------------------+----------------------------+ | LP_ARCH_X86_64 | Payload Entry Mode | Description | +----------------+--------------------+----------------------------+ | No | 32-bit | Direct protected mode init | +----------------+--------------------+----------------------------+ | Yes | 32-bit | Protected to long mode | +----------------+--------------------+----------------------------+ | Yes | 64-bit | Long mode initialization | +----------------+--------------------+----------------------------+ Change-Id: I69fda47bedf1a14807b1515c4aed6e3a1d5b8585 Signed-off-by: Subrata Banik <subratabanik@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81968 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
@ -106,17 +106,22 @@ menu "Architecture Options"
|
|||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Target Architecture"
|
prompt "Target Architecture"
|
||||||
default ARCH_X86
|
default ARCH_X86_32
|
||||||
|
|
||||||
config ARCH_ARM
|
config ARCH_ARM
|
||||||
bool "ARM"
|
bool "ARM"
|
||||||
help
|
help
|
||||||
Support the ARM architecture
|
Support the ARM architecture
|
||||||
|
|
||||||
config ARCH_X86
|
config ARCH_X86_32
|
||||||
bool "x86"
|
bool "x86_32"
|
||||||
help
|
help
|
||||||
Support the x86 architecture
|
Support the x86_32 architecture
|
||||||
|
|
||||||
|
config ARCH_X86_64
|
||||||
|
bool "x86_64"
|
||||||
|
help
|
||||||
|
Support the x86_64 architecture
|
||||||
|
|
||||||
config ARCH_ARM64
|
config ARCH_ARM64
|
||||||
bool "ARM64"
|
bool "ARM64"
|
||||||
@ -133,6 +138,12 @@ config ARCH_MOCK
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config ARCH_X86
|
||||||
|
bool
|
||||||
|
default y if ARCH_X86_32 || ARCH_X86_64
|
||||||
|
help
|
||||||
|
Support the x86 architecture
|
||||||
|
|
||||||
config MULTIBOOT
|
config MULTIBOOT
|
||||||
bool "Multiboot header support"
|
bool "Multiboot header support"
|
||||||
depends on ARCH_X86
|
depends on ARCH_X86
|
||||||
|
@ -118,7 +118,8 @@ ARCH-y := $(ARCHDIR-y)
|
|||||||
# override here.
|
# override here.
|
||||||
ARCH-$(CONFIG_LP_ARCH_ARM) := arm
|
ARCH-$(CONFIG_LP_ARCH_ARM) := arm
|
||||||
ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
|
ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
|
||||||
ARCH-$(CONFIG_LP_ARCH_X86) := x86_32
|
ARCH-$(CONFIG_LP_ARCH_X86_32) := x86_32
|
||||||
|
ARCH-$(CONFIG_LP_ARCH_X86_64) := x86_64
|
||||||
ARCH-$(CONFIG_LP_ARCH_MOCK) := mock
|
ARCH-$(CONFIG_LP_ARCH_MOCK) := mock
|
||||||
|
|
||||||
# Five cases where we don't need fully populated $(obj) lists:
|
# Five cases where we don't need fully populated $(obj) lists:
|
||||||
|
@ -96,7 +96,7 @@ $(obj)/libpayload-config.h: $(KCONFIG_AUTOHEADER) $(obj)/libpayload.config
|
|||||||
cmp $@ $< 2>/dev/null || cp $< $@
|
cmp $@ $< 2>/dev/null || cp $< $@
|
||||||
|
|
||||||
library-targets = $(addsuffix .a,$(addprefix $(obj)/,$(libraries))) $(obj)/libpayload.a
|
library-targets = $(addsuffix .a,$(addprefix $(obj)/,$(libraries))) $(obj)/libpayload.a
|
||||||
lib: $$(library-targets)
|
lib: $$(library-targets) $(obj)/libpayload.ldscript
|
||||||
|
|
||||||
extract_nth=$(word $(1), $(subst |, ,$(2)))
|
extract_nth=$(word $(1), $(subst |, ,$(2)))
|
||||||
|
|
||||||
@ -115,11 +115,15 @@ $(obj)/%.a: $$(%-objs)
|
|||||||
printf " AR $(subst $(CURDIR)/,,$(@))\n"
|
printf " AR $(subst $(CURDIR)/,,$(@))\n"
|
||||||
printf "create $@\n$(foreach objc,$(filter-out %.a,$^),addmod $(objc)\n)$(foreach lib,$(filter %.a,$^),addlib $(lib)\n)save\nend\n" | $(AR) -M
|
printf "create $@\n$(foreach objc,$(filter-out %.a,$^),addmod $(objc)\n)$(foreach lib,$(filter %.a,$^),addlib $(lib)\n)save\nend\n" | $(AR) -M
|
||||||
|
|
||||||
|
$(obj)/libpayload.ldscript: arch/$(ARCHDIR-y)/libpayload.ldscript
|
||||||
|
@printf " LDSCRIPT $@\n"
|
||||||
|
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -P -x assembler-with-cpp -undef -o $@ $<
|
||||||
|
|
||||||
install: real-target
|
install: real-target
|
||||||
printf " INSTALL $(DESTDIR)/libpayload/lib\n"
|
printf " INSTALL $(DESTDIR)/libpayload/lib\n"
|
||||||
install -m 755 -d $(DESTDIR)/libpayload/lib
|
install -m 755 -d $(DESTDIR)/libpayload/lib
|
||||||
install -m 644 $(library-targets) $(DESTDIR)/libpayload/lib/
|
install -m 644 $(library-targets) $(DESTDIR)/libpayload/lib/
|
||||||
install -m 644 arch/$(ARCHDIR-y)/libpayload.ldscript $(DESTDIR)/libpayload/lib/
|
install -m 644 $(obj)/libpayload.ldscript $(DESTDIR)/libpayload/lib/
|
||||||
install -m 755 -d $(DESTDIR)/libpayload/lib/$(ARCHDIR-y)
|
install -m 755 -d $(DESTDIR)/libpayload/lib/$(ARCHDIR-y)
|
||||||
printf " INSTALL $(DESTDIR)/libpayload/include\n"
|
printf " INSTALL $(DESTDIR)/libpayload/include\n"
|
||||||
install -m 755 -d $(DESTDIR)/libpayload/include
|
install -m 755 -d $(DESTDIR)/libpayload/include
|
||||||
|
@ -27,16 +27,26 @@
|
|||||||
##
|
##
|
||||||
|
|
||||||
ifneq ($(CONFIG_LP_COMPILER_LLVM_CLANG),y)
|
ifneq ($(CONFIG_LP_COMPILER_LLVM_CLANG),y)
|
||||||
|
ifeq ($(CONFIG_LP_ARCH_X86_64),y)
|
||||||
|
CFLAGS += -mpreferred-stack-boundary=4
|
||||||
|
else
|
||||||
CFLAGS += -mpreferred-stack-boundary=2
|
CFLAGS += -mpreferred-stack-boundary=2
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
libc-y += head.S
|
libc-$(CONFIG_LP_ARCH_X86_32) += head.S
|
||||||
|
libc-$(CONFIG_LP_ARCH_X86_64) += head_64.S
|
||||||
|
libc-$(CONFIG_LP_ARCH_X86_64) += pt.S
|
||||||
libc-y += main.c sysinfo.c
|
libc-y += main.c sysinfo.c
|
||||||
libc-y += timer.c coreboot.c util.S
|
libc-y += timer.c coreboot.c util.S
|
||||||
libc-y += exec.S virtual.c
|
libc-y += virtual.c
|
||||||
libc-y += selfboot.c cache.c
|
libc-y += selfboot.c cache.c
|
||||||
libc-y += exception_asm.S exception.c
|
libc-y += exception.c
|
||||||
libc-y += delay.c
|
libc-y += delay.c
|
||||||
|
libc-$(CONFIG_LP_ARCH_X86_32) += exec.c
|
||||||
|
libc-$(CONFIG_LP_ARCH_X86_32) += exec.S
|
||||||
|
libc-$(CONFIG_LP_ARCH_X86_32) += exception_asm.S
|
||||||
|
libc-$(CONFIG_LP_ARCH_X86_64) += exception_asm_64.S
|
||||||
|
|
||||||
# Will fall back to default_memXXX() in libc/memory.c if GPL not allowed.
|
# Will fall back to default_memXXX() in libc/memory.c if GPL not allowed.
|
||||||
libc-$(CONFIG_LP_GPL) += string.c
|
libc-$(CONFIG_LP_GPL) += string.c
|
||||||
|
@ -34,7 +34,13 @@
|
|||||||
|
|
||||||
#define IF_FLAG (1 << 9)
|
#define IF_FLAG (1 << 9)
|
||||||
|
|
||||||
u32 exception_stack[0x400] __attribute__((aligned(8)));
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
|
#define REGISTER_FMT "0x%016zx"
|
||||||
|
#else
|
||||||
|
#define REGISTER_FMT "0x%08zx"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u8 exception_stack[0x400] __aligned(16);
|
||||||
|
|
||||||
static interrupt_handler handlers[256];
|
static interrupt_handler handlers[256];
|
||||||
|
|
||||||
@ -143,17 +149,27 @@ static void dump_exception_state(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("EIP: 0x%08x\n", exception_state->regs.eip);
|
printf("REG_IP: " REGISTER_FMT "\n", exception_state->regs.reg_ip);
|
||||||
|
printf("REG_FLAGS: " REGISTER_FMT "\n", exception_state->regs.reg_flags);
|
||||||
|
printf("REG_AX: " REGISTER_FMT "\n", exception_state->regs.reg_ax);
|
||||||
|
printf("REG_BX: " REGISTER_FMT "\n", exception_state->regs.reg_bx);
|
||||||
|
printf("REG_CX: " REGISTER_FMT "\n", exception_state->regs.reg_cx);
|
||||||
|
printf("REG_DX: " REGISTER_FMT "\n", exception_state->regs.reg_dx);
|
||||||
|
printf("REG_SP: " REGISTER_FMT "\n", exception_state->regs.reg_sp);
|
||||||
|
printf("REG_BP: " REGISTER_FMT "\n", exception_state->regs.reg_bp);
|
||||||
|
printf("REG_SI: " REGISTER_FMT "\n", exception_state->regs.reg_si);
|
||||||
|
printf("REG_DI: " REGISTER_FMT "\n", exception_state->regs.reg_di);
|
||||||
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
|
printf("REG_R8: 0x%016zx\n", exception_state->regs.reg_r8);
|
||||||
|
printf("REG_R9: 0x%016zx\n", exception_state->regs.reg_r9);
|
||||||
|
printf("REG_R10: 0x%016zx\n", exception_state->regs.reg_r10);
|
||||||
|
printf("REG_R11: 0x%016zx\n", exception_state->regs.reg_r11);
|
||||||
|
printf("REG_R12: 0x%016zx\n", exception_state->regs.reg_r12);
|
||||||
|
printf("REG_R13: 0x%016zx\n", exception_state->regs.reg_r13);
|
||||||
|
printf("REG_R14: 0x%016zx\n", exception_state->regs.reg_r14);
|
||||||
|
printf("REG_R15: 0x%016zx\n", exception_state->regs.reg_r15);
|
||||||
|
#endif
|
||||||
printf("CS: 0x%04x\n", exception_state->regs.cs);
|
printf("CS: 0x%04x\n", exception_state->regs.cs);
|
||||||
printf("EFLAGS: 0x%08x\n", exception_state->regs.eflags);
|
|
||||||
printf("EAX: 0x%08x\n", exception_state->regs.eax);
|
|
||||||
printf("ECX: 0x%08x\n", exception_state->regs.ecx);
|
|
||||||
printf("EDX: 0x%08x\n", exception_state->regs.edx);
|
|
||||||
printf("EBX: 0x%08x\n", exception_state->regs.ebx);
|
|
||||||
printf("ESP: 0x%08x\n", exception_state->regs.esp);
|
|
||||||
printf("EBP: 0x%08x\n", exception_state->regs.ebp);
|
|
||||||
printf("ESI: 0x%08x\n", exception_state->regs.esi);
|
|
||||||
printf("EDI: 0x%08x\n", exception_state->regs.edi);
|
|
||||||
printf("DS: 0x%04x\n", exception_state->regs.ds);
|
printf("DS: 0x%04x\n", exception_state->regs.ds);
|
||||||
printf("ES: 0x%04x\n", exception_state->regs.es);
|
printf("ES: 0x%04x\n", exception_state->regs.es);
|
||||||
printf("SS: 0x%04x\n", exception_state->regs.ss);
|
printf("SS: 0x%04x\n", exception_state->regs.ss);
|
||||||
@ -164,7 +180,7 @@ static void dump_exception_state(void)
|
|||||||
void exception_dispatch(void)
|
void exception_dispatch(void)
|
||||||
{
|
{
|
||||||
die_if(exception_state->vector >= ARRAY_SIZE(handlers),
|
die_if(exception_state->vector >= ARRAY_SIZE(handlers),
|
||||||
"Invalid vector %u\n", exception_state->vector);
|
"Invalid vector %zu\n", exception_state->vector);
|
||||||
|
|
||||||
u8 vec = exception_state->vector;
|
u8 vec = exception_state->vector;
|
||||||
|
|
||||||
@ -184,7 +200,7 @@ void exception_dispatch(void)
|
|||||||
vec);
|
vec);
|
||||||
|
|
||||||
dump_exception_state();
|
dump_exception_state();
|
||||||
dump_stack(exception_state->regs.esp, 512);
|
dump_stack(exception_state->regs.reg_sp, 512);
|
||||||
/* We don't call apic_eoi because we don't want to ack the interrupt and
|
/* We don't call apic_eoi because we don't want to ack the interrupt and
|
||||||
allow another interrupt to wake the processor. */
|
allow another interrupt to wake the processor. */
|
||||||
halt();
|
halt();
|
||||||
@ -197,6 +213,10 @@ success:
|
|||||||
|
|
||||||
void exception_init(void)
|
void exception_init(void)
|
||||||
{
|
{
|
||||||
|
/* TODO: Add exception init code for x64, currently only supporting 32-bit code */
|
||||||
|
if (CONFIG(LP_ARCH_X86_64))
|
||||||
|
return;
|
||||||
|
|
||||||
exception_stack_end = exception_stack + ARRAY_SIZE(exception_stack);
|
exception_stack_end = exception_stack + ARRAY_SIZE(exception_stack);
|
||||||
exception_init_asm();
|
exception_init_asm();
|
||||||
}
|
}
|
||||||
@ -206,6 +226,17 @@ void set_interrupt_handler(u8 vector, interrupt_handler handler)
|
|||||||
handlers[vector] = handler;
|
handlers[vector] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
|
static uint64_t eflags(void)
|
||||||
|
{
|
||||||
|
uint64_t eflags;
|
||||||
|
asm volatile(
|
||||||
|
"pushfq\n\t"
|
||||||
|
"popq %0\n\t"
|
||||||
|
: "=rm" (eflags));
|
||||||
|
return eflags;
|
||||||
|
}
|
||||||
|
#else
|
||||||
static uint32_t eflags(void)
|
static uint32_t eflags(void)
|
||||||
{
|
{
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
@ -215,6 +246,7 @@ static uint32_t eflags(void)
|
|||||||
: "=rm" (eflags));
|
: "=rm" (eflags));
|
||||||
return eflags;
|
return eflags;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void enable_interrupts(void)
|
void enable_interrupts(void)
|
||||||
{
|
{
|
||||||
|
221
payloads/libpayload/arch/x86/exception_asm_64.S
Normal file
221
payloads/libpayload/arch/x86/exception_asm_64.S
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2024 Google Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
.global exception_stack_end
|
||||||
|
exception_stack_end:
|
||||||
|
.quad 0
|
||||||
|
.global exception_state
|
||||||
|
exception_state:
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
/* Some temporary variables which are used while saving exception state. */
|
||||||
|
vector:
|
||||||
|
.quad 0
|
||||||
|
error_code:
|
||||||
|
.quad 0
|
||||||
|
old_rsp:
|
||||||
|
.quad 0
|
||||||
|
old_rax:
|
||||||
|
.quad 0
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each exception vector has a small stub associated with it which sets aside
|
||||||
|
* the error code, if any, records which vector we entered from, and calls
|
||||||
|
* the common exception entry point. Some exceptions have error codes and some
|
||||||
|
* don't, so we have a macro for each type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.macro stub num
|
||||||
|
exception_stub_\num:
|
||||||
|
movq $0, error_code
|
||||||
|
movq $\num, vector
|
||||||
|
jmp exception_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro stub_err num
|
||||||
|
exception_stub_\num:
|
||||||
|
pop error_code
|
||||||
|
movq $\num, vector
|
||||||
|
jmp exception_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.altmacro
|
||||||
|
.macro user_defined_stubs from, to
|
||||||
|
stub \from
|
||||||
|
.if \to-\from
|
||||||
|
user_defined_stubs %(from+1),\to
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
stub 0
|
||||||
|
stub 1
|
||||||
|
stub 2
|
||||||
|
stub 3
|
||||||
|
stub 4
|
||||||
|
stub 5
|
||||||
|
stub 6
|
||||||
|
stub 7
|
||||||
|
stub_err 8
|
||||||
|
stub 9
|
||||||
|
stub_err 10
|
||||||
|
stub_err 11
|
||||||
|
stub_err 12
|
||||||
|
stub_err 13
|
||||||
|
stub_err 14
|
||||||
|
stub 15
|
||||||
|
stub 16
|
||||||
|
stub_err 17
|
||||||
|
stub 18
|
||||||
|
stub 19
|
||||||
|
stub 20
|
||||||
|
stub 21
|
||||||
|
stub 22
|
||||||
|
stub 23
|
||||||
|
stub 24
|
||||||
|
stub 25
|
||||||
|
stub 26
|
||||||
|
stub 27
|
||||||
|
stub 28
|
||||||
|
stub 29
|
||||||
|
stub_err 30
|
||||||
|
stub 31
|
||||||
|
/* Split the macro so we avoid a stack overflow. */
|
||||||
|
user_defined_stubs 32, 63
|
||||||
|
user_defined_stubs 64, 127
|
||||||
|
user_defined_stubs 128, 191
|
||||||
|
user_defined_stubs 192, 255
|
||||||
|
|
||||||
|
exception_common:
|
||||||
|
|
||||||
|
/* Return from the exception. */
|
||||||
|
iretl
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need segment selectors for the IDT, so we need to know where things are
|
||||||
|
* in the GDT. We set one up here which is pretty standard and largely copied
|
||||||
|
* from coreboot.
|
||||||
|
*/
|
||||||
|
.align 16
|
||||||
|
gdt:
|
||||||
|
/* selgdt 0, unused */
|
||||||
|
.word 0x0000, 0x0000
|
||||||
|
.byte 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
|
/* selgdt 8, unused */
|
||||||
|
.word 0x0000, 0x0000
|
||||||
|
.byte 0x00, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
|
/* selgdt 0x10, flat 4GB code segment */
|
||||||
|
.word 0xffff, 0x0000
|
||||||
|
.byte 0x00, 0x9b, 0xcf, 0x00
|
||||||
|
|
||||||
|
/* selgdt 0x18, flat 4GB data segment */
|
||||||
|
.word 0xffff, 0x0000
|
||||||
|
.byte 0x00, 0x92, 0xcf, 0x00
|
||||||
|
|
||||||
|
/* selgdt 0x20, flat x64 code segment */
|
||||||
|
.word 0xffff, 0x0000
|
||||||
|
.byte 0x00, 0x9b, 0xaf, 0x00
|
||||||
|
gdt_end:
|
||||||
|
|
||||||
|
/* GDT pointer for use with lgdt */
|
||||||
|
.global gdt_ptr
|
||||||
|
gdt_ptr:
|
||||||
|
.word gdt_end - gdt - 1
|
||||||
|
.quad gdt
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record the target and construct the actual entry at init time. This
|
||||||
|
* is necessary because the linker doesn't want to construct the entry
|
||||||
|
* for us.
|
||||||
|
*/
|
||||||
|
.macro interrupt_gate target
|
||||||
|
.quad \target
|
||||||
|
.quad \target
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.altmacro
|
||||||
|
.macro user_defined_gates from, to
|
||||||
|
interrupt_gate exception_stub_\from
|
||||||
|
.if \to-\from
|
||||||
|
user_defined_gates %(from+1),\to
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
.global idt
|
||||||
|
idt:
|
||||||
|
interrupt_gate exception_stub_0
|
||||||
|
interrupt_gate exception_stub_1
|
||||||
|
interrupt_gate exception_stub_2
|
||||||
|
interrupt_gate exception_stub_3
|
||||||
|
interrupt_gate exception_stub_4
|
||||||
|
interrupt_gate exception_stub_5
|
||||||
|
interrupt_gate exception_stub_6
|
||||||
|
interrupt_gate exception_stub_7
|
||||||
|
interrupt_gate exception_stub_8
|
||||||
|
interrupt_gate exception_stub_9
|
||||||
|
interrupt_gate exception_stub_10
|
||||||
|
interrupt_gate exception_stub_11
|
||||||
|
interrupt_gate exception_stub_12
|
||||||
|
interrupt_gate exception_stub_13
|
||||||
|
interrupt_gate exception_stub_14
|
||||||
|
interrupt_gate exception_stub_15
|
||||||
|
interrupt_gate exception_stub_16
|
||||||
|
interrupt_gate exception_stub_17
|
||||||
|
interrupt_gate exception_stub_18
|
||||||
|
interrupt_gate exception_stub_19
|
||||||
|
interrupt_gate exception_stub_20
|
||||||
|
interrupt_gate exception_stub_21
|
||||||
|
interrupt_gate exception_stub_22
|
||||||
|
interrupt_gate exception_stub_23
|
||||||
|
interrupt_gate exception_stub_24
|
||||||
|
interrupt_gate exception_stub_25
|
||||||
|
interrupt_gate exception_stub_26
|
||||||
|
interrupt_gate exception_stub_27
|
||||||
|
interrupt_gate exception_stub_28
|
||||||
|
interrupt_gate exception_stub_29
|
||||||
|
interrupt_gate exception_stub_30
|
||||||
|
interrupt_gate exception_stub_31
|
||||||
|
user_defined_gates 32, 63
|
||||||
|
user_defined_gates 64, 127
|
||||||
|
user_defined_gates 128, 191
|
||||||
|
user_defined_gates 192, 255
|
||||||
|
idt_end:
|
||||||
|
|
||||||
|
/* IDT pointer for use with lidt */
|
||||||
|
idt_ptr:
|
||||||
|
.word idt_end - idt - 1
|
||||||
|
.quad idt
|
||||||
|
|
||||||
|
.global exception_init_asm
|
||||||
|
exception_init_asm:
|
||||||
|
ret
|
@ -29,8 +29,10 @@
|
|||||||
#include <libpayload-config.h>
|
#include <libpayload-config.h>
|
||||||
#include <libpayload.h>
|
#include <libpayload.h>
|
||||||
|
|
||||||
#if CONFIG(LP_ARCH_X86)
|
#if CONFIG(LP_ARCH_X86_32)
|
||||||
extern void i386_do_exec(long addr, int argc, char **argv, int *ret);
|
extern void i386_do_exec(long addr, int argc, char **argv, int *ret);
|
||||||
|
#else
|
||||||
|
#error "exec does not currently support x86_64."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +47,7 @@ int exec(long addr, int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int val = -1;
|
int val = -1;
|
||||||
|
|
||||||
#if CONFIG(LP_ARCH_X86)
|
#if CONFIG(LP_ARCH_X86_32)
|
||||||
i386_do_exec(addr, argc, argv, &val);
|
i386_do_exec(addr, argc, argv, &val);
|
||||||
#endif
|
#endif
|
||||||
return val;
|
return val;
|
@ -15,6 +15,7 @@
|
|||||||
#include <exception.h>
|
#include <exception.h>
|
||||||
#include <gdb.h>
|
#include <gdb.h>
|
||||||
#include <libpayload.h>
|
#include <libpayload.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
static const u8 type_to_signal[] = {
|
static const u8 type_to_signal[] = {
|
||||||
[EXC_DE] = GDB_SIGFPE,
|
[EXC_DE] = GDB_SIGFPE,
|
||||||
@ -53,12 +54,15 @@ void gdb_arch_init(void)
|
|||||||
|
|
||||||
void gdb_arch_enter(void)
|
void gdb_arch_enter(void)
|
||||||
{
|
{
|
||||||
u32 *esp;
|
u8 *stack_pointer;
|
||||||
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
asm volatile ("mov %%esp, %0" : "=r"(esp) );
|
asm volatile ("movq %%rsp, %0" : "=r"(stack_pointer));
|
||||||
|
#else
|
||||||
|
asm volatile ("mov %%esp, %0" : "=r"(stack_pointer));
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Avoid reentrant exceptions, just call the hook if in one already. */
|
/* Avoid reentrant exceptions, just call the hook if in one already. */
|
||||||
if (esp >= exception_stack && esp <= exception_stack_end)
|
if (stack_pointer >= exception_stack && stack_pointer <= exception_stack_end)
|
||||||
gdb_exception_hook(EXC_BP);
|
gdb_exception_hook(EXC_BP);
|
||||||
else
|
else
|
||||||
asm volatile ("int3");
|
asm volatile ("int3");
|
||||||
@ -66,12 +70,12 @@ void gdb_arch_enter(void)
|
|||||||
|
|
||||||
int gdb_arch_set_single_step(int on)
|
int gdb_arch_set_single_step(int on)
|
||||||
{
|
{
|
||||||
const u32 tf_bit = 1 << 8;
|
const size_t tf_bit = 1 << 8;
|
||||||
|
|
||||||
if (on)
|
if (on)
|
||||||
exception_state->regs.eflags |= tf_bit;
|
exception_state->regs.reg_flags |= tf_bit;
|
||||||
else
|
else
|
||||||
exception_state->regs.eflags &= ~tf_bit;
|
exception_state->regs.reg_flags &= ~tf_bit;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
141
payloads/libpayload/arch/x86/head_64.S
Normal file
141
payloads/libpayload/arch/x86/head_64.S
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 Google Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define IA32_EFER 0xC0000080
|
||||||
|
#define EFER_LME (1 << 8)
|
||||||
|
|
||||||
|
.code32
|
||||||
|
.global _entry
|
||||||
|
.section .text._entry
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: Critical Code Section - 32/64-bit Compatibility
|
||||||
|
* This code between `_entry` and `jnz _init64` is executed during system initialization.
|
||||||
|
* It MUST function correctly regardless of whether the system is booting in:
|
||||||
|
* - 32-bit protected mode
|
||||||
|
* - 64-bit long mode
|
||||||
|
* To achieve this, ONLY use instructions that produce identical binary output in both modes.
|
||||||
|
* Thoroughly test ALL modifications to this section in BOTH 32-bit and 64-bit boot
|
||||||
|
* environments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
_entry:
|
||||||
|
|
||||||
|
/* Add multiboot header and jump around it when building with multiboot support. */
|
||||||
|
#if CONFIG(LP_MULTIBOOT)
|
||||||
|
#include "multiboot_header.inc"
|
||||||
|
#endif
|
||||||
|
/* No interrupts, please. */
|
||||||
|
cli
|
||||||
|
|
||||||
|
movl $IA32_EFER, %ecx
|
||||||
|
rdmsr
|
||||||
|
testl $EFER_LME, %eax
|
||||||
|
jnz _init64
|
||||||
|
|
||||||
|
lgdt %cs:gdt_ptr
|
||||||
|
|
||||||
|
/* save pointer to coreboot tables */
|
||||||
|
movl 4(%esp), %eax
|
||||||
|
/*
|
||||||
|
* NOTE: coreboot tables has passed over the top of the stack
|
||||||
|
* while calling in protected mode.
|
||||||
|
*/
|
||||||
|
movl %eax, cb_header_ptr
|
||||||
|
|
||||||
|
call init_page_table
|
||||||
|
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
|
||||||
|
|
||||||
|
/* Jump to selgdt 0x20, flat x64 code segment */
|
||||||
|
ljmp $0x20, $_entry64
|
||||||
|
|
||||||
|
.code64
|
||||||
|
.align 16
|
||||||
|
_init64:
|
||||||
|
movabs $gdt_ptr, %rax
|
||||||
|
lgdt (%rax)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: The `cb_header_ptr` has passed as the first argument
|
||||||
|
* to the x86-64 calling convention.
|
||||||
|
*/
|
||||||
|
movq %rdi, cb_header_ptr
|
||||||
|
|
||||||
|
call init_page_table
|
||||||
|
movq $pm4le, %rax
|
||||||
|
|
||||||
|
/* load identity mapped page tables */
|
||||||
|
movq %rax, %cr3
|
||||||
|
|
||||||
|
_entry64:
|
||||||
|
/* Store current stack pointer and set up new stack. */
|
||||||
|
movq %rsp, %rax
|
||||||
|
movabs $_estack, %rsp
|
||||||
|
|
||||||
|
push %rax
|
||||||
|
|
||||||
|
fninit
|
||||||
|
movq %cr0, %rax
|
||||||
|
andq $0xFFFFFFFFFFFFFFFB, %rax /* clear EM */
|
||||||
|
orq $0x00000022, %rax /* set MP, NE */
|
||||||
|
movq %rax, %cr0
|
||||||
|
|
||||||
|
movq %cr4, %rax
|
||||||
|
orq $0x00000600, %rax /* set OSFXSR, OSXMMEXCPT */
|
||||||
|
movq %rax, %cr4
|
||||||
|
|
||||||
|
/* Let's rock. */
|
||||||
|
call start_main
|
||||||
|
|
||||||
|
/* %rax has the return value - pass it on unmolested */
|
||||||
|
_leave:
|
||||||
|
/* Restore old stack. */
|
||||||
|
pop %rsp
|
||||||
|
|
||||||
|
/* Return to the original context. */
|
||||||
|
ret
|
@ -26,8 +26,13 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
OUTPUT_ARCH(x86_64)
|
||||||
|
#else
|
||||||
OUTPUT_FORMAT(elf32-i386)
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
OUTPUT_ARCH(i386)
|
OUTPUT_ARCH(i386)
|
||||||
|
#endif
|
||||||
|
|
||||||
ENTRY(_entry)
|
ENTRY(_entry)
|
||||||
|
|
||||||
|
149
payloads/libpayload/arch/x86/pt.S
Normal file
149
payloads/libpayload/arch/x86/pt.S
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2024 Google Inc.
|
||||||
|
*
|
||||||
|
* 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 .bss
|
||||||
|
#define _PRES (1ULL << 0)
|
||||||
|
#define _RW (1ULL << 1)
|
||||||
|
#define _US (1ULL << 2)
|
||||||
|
#define _A (1ULL << 5)
|
||||||
|
#define _D (1ULL << 6)
|
||||||
|
#define _PS (1ULL << 7)
|
||||||
|
|
||||||
|
.section .bss.pm4le
|
||||||
|
.global pm4le
|
||||||
|
.align 4096
|
||||||
|
pm4le:
|
||||||
|
.skip 8
|
||||||
|
|
||||||
|
.section .bss.main_page_table
|
||||||
|
.global main_page_table
|
||||||
|
.align 4096
|
||||||
|
main_page_table:
|
||||||
|
.skip 8192
|
||||||
|
|
||||||
|
.section .bss.extra_page_table
|
||||||
|
.global extra_page_table
|
||||||
|
.align 4096
|
||||||
|
extra_page_table:
|
||||||
|
.skip 32
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: 32-bit/64-bit Mode Compatibility for Page Table Initialization
|
||||||
|
* This `init_page_table` function is designed to work in both 32-bit protected
|
||||||
|
* mode AND 64-bit long mode.
|
||||||
|
*
|
||||||
|
* Key Considerations:
|
||||||
|
* - Assembly Instructions: Use ONLY instructions that have the SAME binary representation
|
||||||
|
* in both 32-bit and 64-bit modes.
|
||||||
|
* - `.code64` Directive: We're compiling with `.code64` to ensure the assembler uses
|
||||||
|
* the correct 64-bit version of instructions (e.g., `inc`).
|
||||||
|
* - Register Notation:
|
||||||
|
* - Use 64-bit register names (like `%rsi`) for register-indirect addressing to avoid
|
||||||
|
* incorrect address size prefixes.
|
||||||
|
* - It's safe to use `%esi` with `mov` instructions, as the high 32 bits are zeroed
|
||||||
|
* in 64-bit mode.
|
||||||
|
*
|
||||||
|
* IMPORTANT:
|
||||||
|
* Thoroughly test ANY changes to this function in BOTH 32-bit and 64-bit boot environments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.code64
|
||||||
|
.section .text.init_page_table
|
||||||
|
.globl init_page_table
|
||||||
|
.type init_page_table, @function
|
||||||
|
|
||||||
|
init_page_table:
|
||||||
|
mov $0x80000001, %eax
|
||||||
|
cpuid
|
||||||
|
test $(1 << 26), %edx
|
||||||
|
jnz setup_1gb
|
||||||
|
|
||||||
|
setup_2mb:
|
||||||
|
mov $2048, %edi
|
||||||
|
mov $(_PRES + _RW + _US + _PS + _A + _D), %eax
|
||||||
|
mov $0, %ecx
|
||||||
|
mov $main_page_table, %esi
|
||||||
|
|
||||||
|
loop_2mb:
|
||||||
|
mov %eax, (%rsi, %rcx, 8)
|
||||||
|
mov $0, 4(%rsi, %rcx, 8)
|
||||||
|
add $0x200000, %eax
|
||||||
|
inc %ecx
|
||||||
|
cmp %edi, %ecx
|
||||||
|
jb loop_2mb
|
||||||
|
|
||||||
|
mov $4, %edi
|
||||||
|
mov $main_page_table, %eax
|
||||||
|
add $(_PRES + _RW + _US + _A), %eax
|
||||||
|
mov $0, %ecx
|
||||||
|
mov $extra_page_table, %esi
|
||||||
|
|
||||||
|
fill_extra_page_table:
|
||||||
|
mov %eax, (%rsi, %rcx, 8)
|
||||||
|
mov $0, 4(%rsi, %rcx, 8)
|
||||||
|
add $4096, %eax
|
||||||
|
inc %ecx
|
||||||
|
cmp %edi, %ecx
|
||||||
|
jb fill_extra_page_table
|
||||||
|
|
||||||
|
mov $extra_page_table, %eax
|
||||||
|
jmp leave
|
||||||
|
|
||||||
|
setup_1gb:
|
||||||
|
mov $512, %edi
|
||||||
|
mov $(_PRES + _RW + _US + _PS + _A + _D), %eax
|
||||||
|
mov $0, %ebx
|
||||||
|
mov $0, %ecx
|
||||||
|
mov $main_page_table, %esi
|
||||||
|
|
||||||
|
loop_1gb:
|
||||||
|
mov %eax, (%rsi, %rcx, 8)
|
||||||
|
mov %ebx, 4(%rsi, %rcx, 8)
|
||||||
|
add $0x40000000, %eax
|
||||||
|
cmp $0x40000000, %eax
|
||||||
|
ja no_overflow_1gb
|
||||||
|
inc %ebx
|
||||||
|
no_overflow_1gb:
|
||||||
|
inc %ecx
|
||||||
|
cmp %edi, %ecx
|
||||||
|
jb loop_1gb
|
||||||
|
|
||||||
|
mov $main_page_table, %eax
|
||||||
|
|
||||||
|
leave:
|
||||||
|
or $(_PRES + _RW + _US + _A), %eax
|
||||||
|
mov %eax, pm4le
|
||||||
|
|
||||||
|
ret
|
@ -81,6 +81,16 @@ void *memcpy(void *dest, const void *src, size_t n)
|
|||||||
{
|
{
|
||||||
unsigned long d0, d1, d2;
|
unsigned long d0, d1, d2;
|
||||||
|
|
||||||
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
|
asm volatile(
|
||||||
|
"rep ; movsq\n\t"
|
||||||
|
"mov %4,%%rcx\n\t"
|
||||||
|
"rep ; movsb\n\t"
|
||||||
|
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
|
||||||
|
: "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
#else
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"rep ; movsl\n\t"
|
"rep ; movsl\n\t"
|
||||||
"movl %4,%%ecx\n\t"
|
"movl %4,%%ecx\n\t"
|
||||||
@ -89,6 +99,7 @@ void *memcpy(void *dest, const void *src, size_t n)
|
|||||||
: "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
|
: "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
|
||||||
: "memory"
|
: "memory"
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,11 @@ if [ "$CONFIG_LP_ARCH_ARM64" = "y" ]; then
|
|||||||
fi
|
fi
|
||||||
if [ "$CONFIG_LP_ARCH_X86" = "y" ]; then
|
if [ "$CONFIG_LP_ARCH_X86" = "y" ]; then
|
||||||
_ARCHDIR=x86
|
_ARCHDIR=x86
|
||||||
_ARCHEXTRA="-m32 "
|
if [ "$CONFIG_LP_ARCH_X86_32" = "y" ]; then
|
||||||
|
_ARCHEXTRA="-m32 "
|
||||||
|
else
|
||||||
|
_ARCHEXTRA="-m64 "
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$CONFIG_LP_ARCH_MOCK" = "y" ]; then
|
if [ "$CONFIG_LP_ARCH_MOCK" = "y" ]; then
|
||||||
_ARCHDIR=mock
|
_ARCHDIR=mock
|
||||||
@ -122,13 +126,10 @@ CMDLINE=
|
|||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
while [ $# -gt 0 ]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
-m32|-fno-stack-protector)
|
-m32|-fno-stack-protector|-m64)
|
||||||
shift
|
shift
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
-m64)
|
|
||||||
error "Invalid option --64 - only 32 bit architectures are supported"
|
|
||||||
;;
|
|
||||||
-c)
|
-c)
|
||||||
DOLINK=0
|
DOLINK=0
|
||||||
;;
|
;;
|
||||||
|
@ -66,7 +66,7 @@ static u8 *ahci_prdbuf_init(ahci_dev_t *const dev,
|
|||||||
u8 *const user_buf, const size_t len,
|
u8 *const user_buf, const size_t len,
|
||||||
const int out)
|
const int out)
|
||||||
{
|
{
|
||||||
if ((u32)user_buf & 1) {
|
if ((uintptr_t)user_buf & 1) {
|
||||||
printf("ahci: Odd buffer pointer (%p).\n", user_buf);
|
printf("ahci: Odd buffer pointer (%p).\n", user_buf);
|
||||||
if (dev->buf) /* orphaned buffer */
|
if (dev->buf) /* orphaned buffer */
|
||||||
free(dev->buf - *(dev->buf - 1));
|
free(dev->buf - *(dev->buf - 1));
|
||||||
@ -76,7 +76,7 @@ static u8 *ahci_prdbuf_init(ahci_dev_t *const dev,
|
|||||||
dev->user_buf = user_buf;
|
dev->user_buf = user_buf;
|
||||||
dev->write_back = !out;
|
dev->write_back = !out;
|
||||||
dev->buflen = len;
|
dev->buflen = len;
|
||||||
if ((u32)dev->buf & 1) {
|
if ((uintptr_t)dev->buf & 1) {
|
||||||
dev->buf[0] = 1;
|
dev->buf[0] = 1;
|
||||||
dev->buf += 1;
|
dev->buf += 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -274,7 +274,7 @@ uhci_stop(hci_t *controller)
|
|||||||
|
|
||||||
#define UHCI_SLEEP_TIME_US 30
|
#define UHCI_SLEEP_TIME_US 30
|
||||||
#define UHCI_TIMEOUT (USB_MAX_PROCESSING_TIME_US / UHCI_SLEEP_TIME_US)
|
#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 *)(((unsigned long)(x))&~0xf))
|
||||||
|
|
||||||
static td_t *
|
static td_t *
|
||||||
wait_for_completed_qh(hci_t *controller, qh_t *qh)
|
wait_for_completed_qh(hci_t *controller, qh_t *qh)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#ifndef _ARCH_EXCEPTION_H
|
#ifndef _ARCH_EXCEPTION_H
|
||||||
#define _ARCH_EXCEPTION_H
|
#define _ARCH_EXCEPTION_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void exception_init_asm(void);
|
void exception_init_asm(void);
|
||||||
@ -38,20 +39,28 @@ void disable_interrupts(void);
|
|||||||
/** Returns 1 if interrupts are enabled. */
|
/** Returns 1 if interrupts are enabled. */
|
||||||
int interrupts_enabled(void);
|
int interrupts_enabled(void);
|
||||||
|
|
||||||
struct exception_state
|
#if CONFIG(LP_ARCH_X86_64)
|
||||||
{
|
struct exception_state {
|
||||||
/* Careful: x86/gdb.c currently relies on the size and order of regs. */
|
/* Careful: x86/gdb.c currently relies on the size and order of regs. */
|
||||||
struct {
|
struct {
|
||||||
u32 eax;
|
size_t reg_ax;
|
||||||
u32 ecx;
|
size_t reg_bx;
|
||||||
u32 edx;
|
size_t reg_cx;
|
||||||
u32 ebx;
|
size_t reg_dx;
|
||||||
u32 esp;
|
size_t reg_si;
|
||||||
u32 ebp;
|
size_t reg_di;
|
||||||
u32 esi;
|
size_t reg_bp;
|
||||||
u32 edi;
|
size_t reg_sp;
|
||||||
u32 eip;
|
size_t reg_r8;
|
||||||
u32 eflags;
|
size_t reg_r9;
|
||||||
|
size_t reg_r10;
|
||||||
|
size_t reg_r11;
|
||||||
|
size_t reg_r12;
|
||||||
|
size_t reg_r13;
|
||||||
|
size_t reg_r14;
|
||||||
|
size_t reg_r15;
|
||||||
|
size_t reg_ip;
|
||||||
|
size_t reg_flags;
|
||||||
u32 cs;
|
u32 cs;
|
||||||
u32 ss;
|
u32 ss;
|
||||||
u32 ds;
|
u32 ds;
|
||||||
@ -59,13 +68,39 @@ struct exception_state
|
|||||||
u32 fs;
|
u32 fs;
|
||||||
u32 gs;
|
u32 gs;
|
||||||
} regs;
|
} regs;
|
||||||
u32 error_code;
|
size_t error_code;
|
||||||
u32 vector;
|
size_t vector;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
#else
|
||||||
|
struct exception_state {
|
||||||
|
/* Careful: x86/gdb.c currently relies on the size and order of regs. */
|
||||||
|
struct {
|
||||||
|
size_t reg_ax;
|
||||||
|
size_t reg_cx;
|
||||||
|
size_t reg_dx;
|
||||||
|
size_t reg_bx;
|
||||||
|
size_t reg_sp;
|
||||||
|
size_t reg_bp;
|
||||||
|
size_t reg_si;
|
||||||
|
size_t reg_di;
|
||||||
|
size_t reg_ip;
|
||||||
|
size_t reg_flags;
|
||||||
|
u32 cs;
|
||||||
|
u32 ss;
|
||||||
|
u32 ds;
|
||||||
|
u32 es;
|
||||||
|
u32 fs;
|
||||||
|
u32 gs;
|
||||||
|
} regs;
|
||||||
|
size_t error_code;
|
||||||
|
size_t vector;
|
||||||
|
} __packed;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern struct exception_state *exception_state;
|
extern struct exception_state *exception_state;
|
||||||
|
|
||||||
extern u32 exception_stack[];
|
extern u8 exception_stack[];
|
||||||
extern u32 *exception_stack_end;
|
extern u8 *exception_stack_end;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EXC_DE = 0, /* Divide by zero */
|
EXC_DE = 0, /* Divide by zero */
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
libc-$(CONFIG_LP_LIBC) += malloc.c printf.c console.c string.c
|
libc-$(CONFIG_LP_LIBC) += malloc.c printf.c console.c string.c
|
||||||
libc-$(CONFIG_LP_LIBC) += memory.c ctype.c lib.c libgcc.c
|
libc-$(CONFIG_LP_LIBC) += memory.c ctype.c lib.c libgcc.c
|
||||||
libc-$(CONFIG_LP_LIBC) += rand.c time.c exec.c
|
libc-$(CONFIG_LP_LIBC) += rand.c time.c
|
||||||
libc-$(CONFIG_LP_LIBC) += readline.c getopt_long.c sysinfo.c
|
libc-$(CONFIG_LP_LIBC) += readline.c getopt_long.c sysinfo.c
|
||||||
libc-$(CONFIG_LP_LIBC) += args.c
|
libc-$(CONFIG_LP_LIBC) += args.c
|
||||||
libc-$(CONFIG_LP_LIBC) += strlcpy.c
|
libc-$(CONFIG_LP_LIBC) += strlcpy.c
|
||||||
|
@ -15,7 +15,8 @@ vboot-fixup-includes = $(filter -I$(coreboottop)/%, $(1)) \
|
|||||||
$(filter-out -I$(coreboottop)/%,$(1)))))
|
$(filter-out -I$(coreboottop)/%,$(1)))))
|
||||||
|
|
||||||
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_ARM) := arm
|
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_ARM) := arm
|
||||||
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_X86) := x86
|
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_X86_32) := x86
|
||||||
|
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_X86_64) := x86_64
|
||||||
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
|
VBOOT_FIRMWARE_ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
|
||||||
|
|
||||||
ifneq ($(CONFIG_LP_ARCH_MOCK),)
|
ifneq ($(CONFIG_LP_ARCH_MOCK),)
|
||||||
|
Reference in New Issue
Block a user