x86_64: Implemented exception handling.

This commit is contained in:
Alex Smith
2012-06-27 15:18:10 +01:00
parent 014f4403ee
commit c9f6d2271f
10 changed files with 373 additions and 56 deletions
@@ -225,6 +225,9 @@ enum x86_vendors {
#define nop() __asm__ ("nop"::)
#define read_cr2(value) \
__asm__("mov %%cr2,%0" : "=r" (value))
#define read_cr3(value) \
__asm__("mov %%cr3,%0" : "=r" (value))
@@ -71,7 +71,7 @@ struct iframe {
unsigned long user_ss;
} _PACKED;
#define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SEG)
#define IFRAME_IS_USER(f) (((f)->cs & DPL_USER) == DPL_USER)
typedef struct arch_cpu_info {
@@ -87,9 +87,8 @@ typedef struct arch_cpu_info {
int model;
int extended_model;
// TSS and double fault TSS for this CPU.
// TSS for this CPU.
struct tss tss;
struct tss double_fault_tss;
} arch_cpu_info;
@@ -1,6 +1,14 @@
/*
* Copyright 2012, Alex Smith, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_ARCH_X86_64_KERNEL_ARGS_H
#define _KERNEL_ARCH_X86_64_KERNEL_ARGS_H
// x86_64 kernel is loaded loaded by the x86 bootloader, kernel_args is
// identical to x86.
#include "../x86/arch_kernel_args.h"
#endif /* _KERNEL_ARCH_X86_64_KERNEL_ARGS_H */
@@ -59,13 +59,21 @@ struct interrupt_descriptor {
uint32 base0 : 16;
uint32 sel : 16;
uint32 ist : 3;
uint32 unused : 5;
uint32 flags : 8;
uint32 unused1 : 5;
uint32 type : 4;
uint32 unused2 : 1;
uint32 dpl : 2;
uint32 present : 1;
uint32 base1 : 16;
uint32 base2 : 32;
uint32 reserved : 32;
} _PACKED;
struct gdt_idt_descr {
uint16 limit;
addr_t base;
} _PACKED;
enum descriptor_privilege_levels {
DPL_KERNEL = 0,
DPL_USER = 3,
@@ -90,6 +98,11 @@ enum descriptor_types {
DT_CODE_DATA_SEGMENT = 1,
};
enum gate_types {
GATE_INTERRUPT = 14,
GATE_TRAP = 15,
};
static inline void
clear_segment_descriptor(segment_descriptor* desc)
@@ -144,6 +157,24 @@ set_tss_descriptor(segment_descriptor* _desc, uint64 base, uint32 limit)
}
static inline void
set_interrupt_descriptor(interrupt_descriptor* desc, uint64 addr, uint32 type,
uint16 seg, uint32 dpl, uint32 ist)
{
desc->base0 = (addr & 0xFFFF);
desc->base1 = ((addr >> 16) & 0xFFFF);
desc->base2 = ((addr >> 32) & 0xFFFFFFFF);
desc->sel = seg;
desc->ist = ist;
desc->type = type;
desc->dpl = dpl;
desc->present = 1;
desc->unused1 = 0;
desc->unused2 = 0;
desc->reserved = 0;
}
#endif /* _ASSEMBLER */
#endif /* _KERNEL_ARCH_X86_64_DESCRIPTORS_H */