Skip to content

Commit

Permalink
traps: add early boot traps initialization (#68)
Browse files Browse the repository at this point in the history
This allows to debug issues in PMM and pagetables bootstraping code
much easier.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>

Co-authored-by: Bjoern Doebel <[email protected]>
  • Loading branch information
wipawel and bjoernd authored Aug 24, 2020
1 parent 41f91aa commit bc35378
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 5 deletions.
8 changes: 8 additions & 0 deletions arch/x86/boot/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,13 @@ _boot_stack:
.skip BOOT_STACK_SIZE
GLOBAL(_boot_stack_top)

_boot_stack_ist:
.skip BOOT_STACK_SIZE
GLOBAL(_boot_stack_ist_top)

_boot_stack_df:
.skip BOOT_STACK_SIZE
GLOBAL(_boot_stack_df_top)

#define XEN_ELFNOTE_PHYS32_ENTRY 18
ELF_NOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long, _start)
90 changes: 88 additions & 2 deletions arch/x86/boot/segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,17 @@
*/
#include <asm-macros.h>
#include <ktf.h>
#include <lib.h>
#include <processor.h>
#include <segment.h>

gdt_desc_t boot_gdt[] __aligned(16) __data_init = {
extern uint8_t *_boot_stack_ist_top;
extern uint8_t *_boot_stack_df_top;

x86_tss_t __data_init boot_tss __aligned(16);
x86_tss_t __data_init boot_tss_df __aligned(16);

gdt_desc_t __data_init boot_gdt[NR_BOOT_GDT_ENTRIES] __aligned(16) = {
/* clang-format off */
[GDT_NULL].desc = GDT_ENTRY(0x0, 0x0, 0x0),
[GDT_KERN_CS32].desc = GDT_ENTRY(DESC_FLAGS(GR, SZ, P, DPL0, S, CODE, R, A), 0x0, 0xfffff),
Expand All @@ -36,7 +44,85 @@ gdt_desc_t boot_gdt[] __aligned(16) __data_init = {
/* clang-format on */
};

gdt_ptr_t boot_gdt_ptr __data_init = {
gdt_ptr_t __data_init boot_gdt_ptr = {
.size = sizeof(boot_gdt) - 1,
.addr = _ul(&boot_gdt),
};

idt_entry_t __data_init boot_idt[256];

idt_ptr_t boot_idt_ptr __data_init = {
.size = sizeof(boot_idt) - 1,
.addr = _ul(&boot_idt),
};

static void __text_init init_boot_tss(void) {
#if defined(__i386__)
boot_tss_df.iopb = sizeof(boot_tss_df);
boot_tss_df.esp0 = _ul(_boot_stack_df_top);
boot_tss_df.ss = __KERN_DS;
boot_tss_df.ds = __KERN_DS;
boot_tss_df.es = __KERN_DS;
boot_tss_df.fs = __KERN_DS;
boot_tss_df.gs = __KERN_DS;
boot_tss_df.eip = _ul(entry_DF);
boot_tss_df.cs = __KERN_CS;
boot_tss_df.cr3 = read_cr3();

/* Assign identity mapping of the tss_df, because GDT has only 32-bit base. */
boot_gdt[GDT_BOOT_TSS_DF].desc =
GDT_ENTRY(DESC_FLAGS(SZ, P, CODE, A), _ul(&boot_tss_df), sizeof(boot_tss_df) - 1);

/* FIXME */
boot_tss.esp0 = _ul(_boot_stack_ist_top);
boot_tss.ss0 = __KERN_DS;
boot_tss.cr3 = read_cr3();
#elif defined(__x86_64__)
boot_tss.rsp0 = _ul(_boot_stack_ist_top);
boot_tss.ist[0] = _ul(_boot_stack_df_top);
#endif
boot_tss.iopb = sizeof(boot_tss);

/* Assign identity mapping of the tss, because GDT has only 32-bit base. */
boot_gdt[GDT_BOOT_TSS].desc =
GDT_ENTRY(DESC_FLAGS(SZ, P, CODE, A), _ul(&boot_tss), sizeof(boot_tss) - 1);
#if defined(__x86_64__)
boot_gdt[GDT_BOOT_TSS + 1].desc = GDT_ENTRY(0x0, 0x0, 0x0);
#endif

barrier();
ltr(GDT_BOOT_TSS << 3);
}

void __text_init init_boot_traps(void) {
/* clang-format off */
set_intr_gate(&boot_idt[X86_EX_DE], __KERN_CS, _ul(entry_DE), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_DB], __KERN_CS, _ul(entry_DB), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_NMI], __KERN_CS, _ul(entry_NMI), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_BP], __KERN_CS, _ul(entry_BP), GATE_DPL3, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_OF], __KERN_CS, _ul(entry_OF), GATE_DPL3, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_BR], __KERN_CS, _ul(entry_BR), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_UD], __KERN_CS, _ul(entry_UD), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_NM], __KERN_CS, _ul(entry_NM), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_CS], __KERN_CS, _ul(entry_CS), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_TS], __KERN_CS, _ul(entry_TS), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_NP], __KERN_CS, _ul(entry_NP), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_SS], __KERN_CS, _ul(entry_SS), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_GP], __KERN_CS, _ul(entry_GP), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_PF], __KERN_CS, _ul(entry_PF), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_MF], __KERN_CS, _ul(entry_MF), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_AC], __KERN_CS, _ul(entry_AC), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_MC], __KERN_CS, _ul(entry_MC), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_XM], __KERN_CS, _ul(entry_XM), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_VE], __KERN_CS, _ul(entry_VE), GATE_DPL0, GATE_PRESENT, 0);
set_intr_gate(&boot_idt[X86_EX_SE], __KERN_CS, _ul(entry_SE), GATE_DPL0, GATE_PRESENT, 0);
#if defined(__x86_64__)
set_intr_gate(&boot_idt[X86_EX_DF], __KERN_CS, _ul(entry_DF), GATE_DPL0, GATE_PRESENT, 1);
#endif
/* clang-format on */

barrier();
lidt(&boot_idt_ptr);

init_boot_tss();
}
2 changes: 2 additions & 0 deletions common/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic,
/* Initialize console early */
init_console();

init_boot_traps();

if (multiboot_magic == MULTIBOOT_BOOTLOADER_MAGIC) {
/* Indentity mapping is still on, so fill in multiboot structures */
init_multiboot(mbi, &kernel_cmdline);
Expand Down
6 changes: 5 additions & 1 deletion include/arch/x86/segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#define GDT_KERN_DS32 0x2
#define GDT_KERN_CS64 0x3

#define GDT_BOOT_TSS 0x4
#define GDT_BOOT_TSS_DF 0x5

#define GDT_USER_CS32 0x4
#define GDT_USER_DS32 0x5
#define GDT_USER_CS64 0x6
Expand All @@ -43,7 +46,8 @@

#define GDT_PERCPU 0x9

#define NR_GDT_ENTRIES 10
#define NR_BOOT_GDT_ENTRIES 6
#define NR_GDT_ENTRIES 10

#define __KERN_CS32 (GDT_KERN_CS32 << 3)
#define __KERN_DS32 (GDT_KERN_DS32 << 3)
Expand Down
1 change: 1 addition & 0 deletions include/arch/x86/traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#ifndef __ASSEMBLY__

extern void init_traps(unsigned int cpu);
extern void init_boot_traps(void);

#endif /* __ASSEMBLY__ */

Expand Down
2 changes: 0 additions & 2 deletions include/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#ifndef KTF_SETUP_H
#define KTF_SETUP_H

#define KERN_STACK_SIZE (5 * PAGE_SIZE)

#ifndef __ASSEMBLY__
#include <page.h>
#include <string.h>
Expand Down

0 comments on commit bc35378

Please sign in to comment.