aboutsummaryrefslogtreecommitdiff
path: root/src/arch/x86/c_start.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/c_start.S')
-rw-r--r--src/arch/x86/c_start.S35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/arch/x86/c_start.S b/src/arch/x86/c_start.S
index cb7d5045ff..9e718fcab0 100644
--- a/src/arch/x86/c_start.S
+++ b/src/arch/x86/c_start.S
@@ -80,6 +80,20 @@ _start:
push_cpu_info
+#if CONFIG(CPU_INFO_V2)
+ /* Allocate the per_cpu_segment_data on the stack */
+ push_per_cpu_segment_data
+
+ /*
+ * Update the BSP's per_cpu_segment_descriptor to point to the
+ * per_cpu_segment_data that was allocated on the stack.
+ */
+ set_segment_descriptor_base $per_cpu_segment_descriptors, %esp
+
+ mov per_cpu_segment_selector, %eax
+ mov %eax, %gs
+#endif
+
/*
* Now we are finished. Memory is up, data is copied and
* bss is cleared. Now we call the main routine and
@@ -127,6 +141,7 @@ gdb_stub_breakpoint:
#endif
.globl gdt, gdt_end
+ .global per_cpu_segment_descriptors, per_cpu_segment_selector
gdtaddr:
.word gdt_end - gdt - 1
@@ -136,7 +151,7 @@ gdtaddr:
.long gdt /* we know the offset */
#endif
- .data
+ .data
/* This is the gdt for GCC part of coreboot.
* It is different from the gdt in ASM part of coreboot
@@ -206,8 +221,26 @@ gdt:
.word 0xffff, 0x0000
.byte 0x00, 0x9b, 0xaf, 0x00
#endif
+#if CONFIG(CPU_INFO_V2)
+per_cpu_segment_descriptors:
+ .rept CONFIG_MAX_CPUS
+ /* flat data segment */
+ .word 0xffff, 0x0000
+#if ENV_X86_64
+ .byte 0x00, 0x92, 0xcf, 0x00
+#else
+ .byte 0x00, 0x93, 0xcf, 0x00
+#endif
+ .endr
+#endif /* CPU_INFO_V2 */
gdt_end:
+#if CONFIG(CPU_INFO_V2)
+/* Segment selector pointing to the first per_cpu_segment_descriptor. */
+per_cpu_segment_selector:
+ .long per_cpu_segment_descriptors - gdt
+#endif /* CPU_INFO_V2 */
+
.section ".text._start", "ax", @progbits
#if ENV_X86_64
SetCodeSelector: