1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add support of interrupt stack table and fix usage of the kernel stack

- some code cleanups
- NMI , Double Fault and Machine Check Exceptions get its own clean
  stack in the interrupt stack table
This commit is contained in:
Stefan Lankes 2015-09-12 17:23:59 +02:00
parent 1be0bd79aa
commit 6e160628d9
8 changed files with 140 additions and 121 deletions

View file

@ -82,8 +82,8 @@ typedef struct {
uint16_t base_lo;
/// Handler function's segment selector.
uint16_t sel;
/// These bits are reserved by Intel
uint8_t always0;
/// index of the interrupt stack table
uint8_t ist_index;
/// These 8 bits contain flags. Exact use depends on the type of interrupt gate.
uint8_t flags;
/// Higher 16 bits of handler function's base address
@ -121,19 +121,9 @@ void idt_install(void);
* @param base base-address of the handler function being installed
* @param sel Segment the IDT will use
* @param flags Flags this entry will have
* @param idx Index of interrupt stack table
*/
void idt_set_gate(unsigned char num, size_t base, unsigned short sel,
unsigned char flags);
/** @brief Configures and returns a IDT entry with chosen attributes
*
* Just feed this function with base, selector and the flags
* you have seen in idt.h
*
* @return a preconfigured idt descriptor
*/
void configure_idt_entry(idt_entry_t *dest_entry, size_t base,
unsigned short sel, unsigned char flags);
void idt_set_gate(uint8_t num, size_t base, uint16_t sel, uint8_t flags, uint8_t idx);
#ifdef __cplusplus
}

View file

@ -87,24 +87,24 @@ extern "C" {
/*
* EFLAGS bits
*/
#define EFLAGS_CF (1 << 0) /* Carry Flag */
#define EFLAGS_FIXED (1 << 1) /* Bit 1 - always on */
#define EFLAGS_PF (1 << 2) /* Parity Flag */
#define EFLAGS_AF (1 << 4) /* Auxiliary carry Flag */
#define EFLAGS_ZF (1 << 6) /* Zero Flag */
#define EFLAGS_SF (1 << 7) /* Sign Flag */
#define EFLAGS_TF (1 << 8) /* Trap Flag */
#define EFLAGS_IF (1 << 9) /* Interrupt Flag */
#define EFLAGS_DF (1 << 10) /* Direction Flag */
#define EFLAGS_OF (1 << 11) /* Overflow Flag */
#define EFLAGS_IOPL (1 << 12) /* I/O Privilege Level (2 bits) */
#define EFLAGS_NT (1 << 14) /* Nested Task */
#define EFLAGS_RF (1 << 16) /* Resume Flag */
#define EFLAGS_VM (1 << 17) /* Virtual Mode */
#define EFLAGS_AC (1 << 18) /* Alignment Check/Access Control */
#define EFLAGS_VIF (1 << 19) /* Virtual Interrupt Flag */
#define EFLAGS_VIP (1 << 20) /* Virtual Interrupt Pending */
#define EFLAGS_ID (1 << 21) /* CPUID detection */
#define EFLAGS_CF (1UL << 0) /* Carry Flag */
#define EFLAGS_FIXED (1UL << 1) /* Bit 1 - always on */
#define EFLAGS_PF (1UL << 2) /* Parity Flag */
#define EFLAGS_AF (1UL << 4) /* Auxiliary carry Flag */
#define EFLAGS_ZF (1UL << 6) /* Zero Flag */
#define EFLAGS_SF (1UL << 7) /* Sign Flag */
#define EFLAGS_TF (1UL << 8) /* Trap Flag */
#define EFLAGS_IF (1UL << 9) /* Interrupt Flag */
#define EFLAGS_DF (1UL << 10) /* Direction Flag */
#define EFLAGS_OF (1UL << 11) /* Overflow Flag */
#define EFLAGS_IOPL (1UL << 12) /* I/O Privilege Level (2 bits) */
#define EFLAGS_NT (1UL << 14) /* Nested Task */
#define EFLAGS_RF (1UL << 16) /* Resume Flag */
#define EFLAGS_VM (1UL << 17) /* Virtual Mode */
#define EFLAGS_AC (1UL << 18) /* Alignment Check/Access Control */
#define EFLAGS_VIF (1UL << 19) /* Virtual Interrupt Flag */
#define EFLAGS_VIP (1UL << 20) /* Virtual Interrupt Pending */
#define EFLAGS_ID (1UL << 21) /* CPUID detection */
// x86 control registers

View file

@ -48,17 +48,21 @@ typedef struct {
uint64_t rsp1;
uint64_t rsp2;
uint32_t res2, res3; // reserved entries
uint64_t ist_rsp1;
uint64_t ist_rsp2;
uint64_t ist_rsp3;
uint64_t ist_rsp4;
uint64_t ist_rsp5;
uint64_t ist_rsp6;
uint64_t ist_rsp7;
uint64_t ist1;
uint64_t ist2;
uint64_t ist3;
uint64_t ist4;
uint64_t ist5;
uint64_t ist6;
uint64_t ist7;
uint32_t res4, res5; // reserved entries
uint16_t res6, bitmap;
} __attribute__ ((packed)) tss_t;
/** @brief Set rsp0 in TSS of the current core
*/
void tss_set_rsp0(size_t ptr);
#ifdef __cplusplus
}
#endif

View file

@ -38,8 +38,10 @@
gdt_ptr_t gp;
// currently, our kernel has full access to the ioports
static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0}};
static uint8_t irq_stacks[MAX_CORES][KERNEL_STACK_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
static tss_t task_state_segments[MAX_CORES] __attribute__ ((aligned (PAGE_SIZE)));
static uint8_t stack_table[MAX_CORES*KERNEL_STACK_SIZE*3];
extern const void boot_stack;
/*
* This is defined in entry.asm. We use this to properly reload
@ -49,6 +51,11 @@ extern void gdt_flush(void);
extern const void boot_stack;
void tss_set_rsp0(size_t stptr)
{
task_state_segments[CORE_ID].rsp0 = stptr;
}
/* Setup a descriptor in the Global Descriptor Table */
void gdt_set_gate(int num, unsigned long base, unsigned long limit,
unsigned char access, unsigned char gran)
@ -137,7 +144,11 @@ void gdt_install(void)
* Create TSS for each core (we use these segments for task switching)
*/
for(i=0; i<MAX_CORES; i++) {
task_state_segments[i].rsp0 = (size_t) irq_stacks[i] + KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].rsp0 = (size_t)&boot_stack + (i+1) * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist1 = (size_t)stack_table + 3*i * KERNEL_STACK_SIZE + KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist2 = (size_t)stack_table + 3*i * KERNEL_STACK_SIZE + 2 * KERNEL_STACK_SIZE - 0x10;
task_state_segments[i].ist3 = (size_t)stack_table + 3*i * KERNEL_STACK_SIZE + 3 * KERNEL_STACK_SIZE - 0x10;
gdt_set_gate(num+i*2, (unsigned long) (task_state_segments+i), sizeof(tss_t)-1,
GDT_FLAG_PRESENT | GDT_FLAG_TSS | GDT_FLAG_RING0, 0);
}

View file

@ -50,8 +50,7 @@
static idt_entry_t idt[256] = {[0 ... 255] = {0, 0, 0, 0, 0, 0, 0}};
static idt_ptr_t idtp;
void configure_idt_entry(idt_entry_t *dest_entry, size_t base,
unsigned short sel, unsigned char flags)
static void configure_idt_entry(idt_entry_t *dest_entry, size_t base, uint16_t sel, uint8_t flags, uint8_t idx)
{
/* The interrupt routine's base address */
dest_entry->base_lo = (base & 0xFFFF);
@ -60,7 +59,7 @@ void configure_idt_entry(idt_entry_t *dest_entry, size_t base,
/* The segment or 'selector' that this IDT entry will use
* is set here, along with any access flags */
dest_entry->sel = sel;
dest_entry->always0 = 0;
dest_entry->ist_index = idx;
dest_entry->flags = flags;
}
@ -68,10 +67,9 @@ void configure_idt_entry(idt_entry_t *dest_entry, size_t base,
* Use this function to set an entry in the IDT. Alot simpler
* than twiddling with the GDT ;)
*/
void idt_set_gate(unsigned char num, size_t base, unsigned short sel,
unsigned char flags)
void idt_set_gate(uint8_t num, size_t base, uint16_t sel, uint8_t flags, uint8_t idx)
{
configure_idt_entry(&idt[num], base, sel, flags);
configure_idt_entry(&idt[num], base, sel, flags, idx);
}
#if 0

View file

@ -164,70 +164,70 @@ static int irq_install(void)
irq_remap();
idt_set_gate(32, (size_t)irq0, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(33, (size_t)irq1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(34, (size_t)irq2, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(35, (size_t)irq3, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(36, (size_t)irq4, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(37, (size_t)irq5, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(38, (size_t)irq6, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(39, (size_t)irq7, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(40, (size_t)irq8, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(41, (size_t)irq9, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(42, (size_t)irq10, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(43, (size_t)irq11, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(44, (size_t)irq12, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(45, (size_t)irq13, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(46, (size_t)irq14, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(47, (size_t)irq15, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(48, (size_t)irq16, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(49, (size_t)irq17, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(50, (size_t)irq18, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(51, (size_t)irq19, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(52, (size_t)irq20, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(53, (size_t)irq21, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(54, (size_t)irq22, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(55, (size_t)irq23, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(112, (size_t)irq80, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(113, (size_t)irq81, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// add APIC interrupt handler
idt_set_gate(123, (size_t)apic_timer, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(124, (size_t)apic_lint0, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(125, (size_t)apic_lint1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(126, (size_t)apic_error, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(127, (size_t)apic_svr, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
return 0;
}

View file

@ -99,69 +99,72 @@ void isrs_install(void)
int i;
idt_set_gate(0, (size_t)isr0, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(1, (size_t)isr1, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// NMI Exception gets its own stack (ist1)
idt_set_gate(2, (size_t)isr2, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 1);
idt_set_gate(3, (size_t)isr3, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(4, (size_t)isr4, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(5, (size_t)isr5, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(6, (size_t)isr6, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(7, (size_t)isr7, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// Double Fault Exception gets its own stack (ist2)
idt_set_gate(8, (size_t)isr8, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 2);
idt_set_gate(9, (size_t)isr9, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(10, (size_t)isr10, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(11, (size_t)isr11, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(12, (size_t)isr12, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(13, (size_t)isr13, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(14, (size_t)isr14, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(15, (size_t)isr15, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(16, (size_t)isr16, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(17, (size_t)isr17, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// Machine Check Exception gets its own stack (ist3)
idt_set_gate(18, (size_t)isr18, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 3);
idt_set_gate(19, (size_t)isr19, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(20, (size_t)isr20, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(21, (size_t)isr21, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(22, (size_t)isr22, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(23, (size_t)isr23, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(24, (size_t)isr24, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(25, (size_t)isr25, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(26, (size_t)isr26, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(27, (size_t)isr27, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(28, (size_t)isr28, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(29, (size_t)isr29, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(30, (size_t)isr30, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
idt_set_gate(31, (size_t)isr31, KERNEL_CODE_SELECTOR,
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP);
IDT_FLAG_PRESENT|IDT_FLAG_RING0|IDT_FLAG_32BIT|IDT_FLAG_INTTRAP, 0);
// install the default handler
for(i=0; i<32; i++)
@ -199,13 +202,16 @@ static const char *exception_messages[] = {
*/
static void fault_handler(struct state *s)
{
if (s->int_no < 32) {
kputs(exception_messages[s->int_no]);
kprintf(" Exception (%d) on core %d at 0x%llx:0x%llx, error code 0x%llx, rflags 0x%llx\n",
s->int_no, CORE_ID, s->cs, s->rip, s->error, s->rflags);
apic_eoi(s->int_no);
irq_enable();
abort();
}
if (s->int_no < 32)
kputs(exception_messages[s->int_no]);
else
kprintf("Unknown exception %d", s->int_no);
kprintf(" Exception (%d) on core %d at 0x%llx:0x%llx, error code 0x%llx, rflags 0x%llx\n",
s->int_no, CORE_ID, s->cs, s->rip, s->error, s->rflags);
apic_eoi(s->int_no);
irq_enable();
abort();
}

View file

@ -34,6 +34,7 @@
#include <hermit/memory.h>
#include <hermit/fs.h>
#include <hermit/vma.h>
#include <asm/tss.h>
#include <asm/elf.h>
#include <asm/page.h>
@ -100,6 +101,9 @@ static int thread_entry(void* arg, size_t ep)
offset -= curr_task->tls_mem_size;
if (curr_task->tls_file_size)
memcpy((void*) (stack+offset), (void*) curr_task->tls_addr, curr_task->tls_file_size);
// align stack to 16 byte boundary
offset = offset & ~0xFULL;
} else writefs(0); // no TLS => clear fs register
// set first argument
@ -112,9 +116,10 @@ static int thread_entry(void* arg, size_t ep)
size_t* get_current_stack(void)
{
task_t* curr_task = per_core(current_task);
size_t stptr = ((size_t) curr_task->stack + KERNEL_STACK_SIZE - 0x10) & ~0xF;
size_t stptr = (size_t) curr_task->stack + KERNEL_STACK_SIZE - 0x10;
set_per_core(kernel_stack, stptr);
tss_set_rsp0(stptr);
// do we change the address space?
if (read_cr3() != curr_task->page_map)
@ -430,16 +435,21 @@ static int load_task(load_args_t* largs)
}
((char**) (stack+offset))[largs->envc] = NULL;
// align stack to be conform to the UNIX ABI
size_t old_offset = offset;
offset = offset & ~0xFULL;
offset -= sizeof(size_t);
// push pointer to env
offset -= sizeof(char**);
if (!(largs->envc))
*((char***) (stack+offset)) = NULL;
else
*((char***) (stack+offset)) = (char**) (stack + offset + sizeof(char**));
*((char***) (stack+offset)) = (char**) (stack + old_offset);
// push pointer to argv
offset -= sizeof(char**);
*((char***) (stack+offset)) = (char**) (stack + offset + 2*sizeof(char**) + (largs->envc+1) * sizeof(char*));
*((char***) (stack+offset)) = (char**) (stack + old_offset + (largs->envc+1) * sizeof(char*));
// push argc on the stack
offset -= sizeof(ssize_t);