diff options
-rw-r--r-- | src/arch/x86/Makefile.inc | 5 | ||||
-rw-r--r-- | src/arch/x86/assembly_entry.S | 11 | ||||
-rw-r--r-- | src/arch/x86/exit_car.S | 3 | ||||
-rw-r--r-- | src/arch/x86/gdt_init.S | 43 | ||||
-rw-r--r-- | src/cpu/x86/32bit/entry32.inc | 31 |
5 files changed, 59 insertions, 34 deletions
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc index 0f4de166cb..df054f8748 100644 --- a/src/arch/x86/Makefile.inc +++ b/src/arch/x86/Makefile.inc @@ -171,6 +171,7 @@ endif # CONFIG_ARCH_BOOTBLOCK_X86_32 / CONFIG_ARCH_BOOTBLOCK_X86_64 ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y) verstage-y += boot.c +verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S @@ -206,6 +207,9 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y) romstage-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c romstage-y += boot.c +# gdt_init.S is included by entry32.inc when romstage is the first C +# environment. +romstage-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += gdt_init.S romstage-y += cbmem.c romstage-y += cbfs_and_run.c romstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c @@ -283,6 +287,7 @@ postcar-generic-ccopts += -D__POSTCAR__ postcar-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c postcar-y += boot.c +postcar-y += gdt_init.S postcar-y += cbfs_and_run.c postcar-y += cbmem.c postcar-y += cpu_common.c diff --git a/src/arch/x86/assembly_entry.S b/src/arch/x86/assembly_entry.S index a5399b74a5..02f492cfaa 100644 --- a/src/arch/x86/assembly_entry.S +++ b/src/arch/x86/assembly_entry.S @@ -20,15 +20,18 @@ /* * This path is for stages that are post bootblock when employing - * CONFIG_C_ENVIRONMENT_BOOTBLOCK. There's no need to re-load the gdt, - * etc as all those settings are cached within the processor. In order - * to continue with C code execution one needs to set stack pointer and - * clear CAR_GLOBAL variables that are stage specific. + * CONFIG_C_ENVIRONMENT_BOOTBLOCK. The gdt is reloaded to accommodate + * platforms that are executing out of CAR. In order to continue with + * C code execution one needs to set stack pointer and clear CAR_GLOBAL + * variables that are stage specific. */ .section ".text._start", "ax", @progbits .global _start _start: + /* Migrate GDT to this text segment */ + call gdt_init + /* reset stack pointer to CAR stack */ mov $_car_stack_end, %esp diff --git a/src/arch/x86/exit_car.S b/src/arch/x86/exit_car.S index 86d46ca95b..735399b8b1 100644 --- a/src/arch/x86/exit_car.S +++ b/src/arch/x86/exit_car.S @@ -30,6 +30,9 @@ _start: /* Assume stack alignment doesn't matter here as chipset_teardown_car is expected to be implemented in assembly. */ + /* Migrate GDT to this text segment */ + call gdt_init + /* chipset_teardown_car() is expected to disable cache-as-ram. */ call chipset_teardown_car diff --git a/src/arch/x86/gdt_init.S b/src/arch/x86/gdt_init.S new file mode 100644 index 0000000000..6aa2a79b48 --- /dev/null +++ b/src/arch/x86/gdt_init.S @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +.code32 +.section ".text._gdt_", "ax", @progbits + + .globl gdt_init +gdt_init: + lgdt %cs:gdtptr + ret + +.previous + .align 4 +.globl gdtptr +gdt: +gdtptr: + .word gdt_end - gdt -1 /* compute the table limit */ + .long gdt /* we know the offset */ + .word 0 + + /* selgdt 0x08, flat code segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes + for limit */ + + /* selgdt 0x10,flat data segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x93, 0xcf, 0x00 + + /* selgdt 0x18, flat code segment (64-bit) */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xaf, 0x00 + +gdt_end: diff --git a/src/cpu/x86/32bit/entry32.inc b/src/cpu/x86/32bit/entry32.inc index 2caeb40c3f..ae7cc019d9 100644 --- a/src/cpu/x86/32bit/entry32.inc +++ b/src/cpu/x86/32bit/entry32.inc @@ -16,38 +16,9 @@ #include <arch/rom_segs.h> #include <cpu/x86/post_code.h> #include <rules.h> +#include <arch/x86/gdt_init.S> .code32 - - - /* This is the GDT for the ROM stage part of coreboot. It - * is different from the RAM stage GDT which is defined in - * c_start.S - */ - - .align 4 -.globl gdtptr -gdt: -gdtptr: - .word gdt_end - gdt -1 /* compute the table limit */ - .long gdt /* we know the offset */ - .word 0 - - /* selgdt 0x08, flat code segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */ - - /* selgdt 0x10,flat data segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x93, 0xcf, 0x00 - - /* selgdt 0x18, flat code segment (64-bit) */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xaf, 0x00 - -gdt_end: - - /* * When we come here we are in protected mode. We expand * the stack and copies the data segment from ROM to the |