aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/Makefile.inc5
-rw-r--r--src/arch/x86/assembly_entry.S11
-rw-r--r--src/arch/x86/exit_car.S3
-rw-r--r--src/arch/x86/gdt_init.S43
-rw-r--r--src/cpu/x86/32bit/entry32.inc31
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