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:
parent
1be0bd79aa
commit
6e160628d9
8 changed files with 140 additions and 121 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue