@@ -165,10 +165,20 @@ void setup_multiboot(struct mbi_bootinfo *bi)
/* From x86/efi/efistart64.S */
extern void load_idt(void);
+extern void load_gdt_tss(size_t tss_offset);
+
+static void setup_gdt_tss(void)
+{
+ size_t tss_offset;
+
+ tss_offset = setup_tss();
+ load_gdt_tss(tss_offset);
+}
void setup_efi(void)
{
reset_apic();
+ setup_gdt_tss();
setup_idt();
load_idt();
mask_pic_interrupts();
@@ -1,7 +1,22 @@
/* Startup code and pre-defined data structures */
+#include "apic-defs.h"
+#include "asm-generic/page.h"
#include "crt0-efi-x86_64.S"
+.globl ring0stacktop
+.globl ring0stacksize
+
+max_cpus = MAX_TEST_CPUS
+ring0stacksize = PAGE_SIZE
+
+.bss
+
+.globl ring0stacktop
+ . = . + ring0stacksize * max_cpus
+ .align 16
+ring0stacktop:
+
.section .init
.code64
.text
@@ -10,3 +25,30 @@
load_idt:
lidtq idt_descr(%rip)
retq
+
+.globl load_gdt_tss
+load_gdt_tss:
+ /* Load GDT */
+ lgdt gdt64_desc(%rip)
+
+ /* Load TSS */
+ mov %rdi, %rax
+ ltr %ax
+
+ /* Update data segments */
+ mov $0x10, %ax /* 3rd entry in gdt64: 32/64-bit data segment */
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+ mov %ax, %ss
+
+ /*
+ * Update the code segment by putting it on the stack before the return
+ * address, then doing a far return: this will use the new code segment
+ * along with the address.
+ */
+ popq %rdi
+ pushq $0x08 /* 2nd entry in gdt64: 64-bit code segment */
+ pushq %rdi
+ lretq