75 lines
2.5 KiB
C
75 lines
2.5 KiB
C
|
#pragma once
|
||
|
|
||
|
#include "../main.h"
|
||
|
#include "stdbool.h"
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define GDT_SIZE_BYTES 4
|
||
|
#define GDT_EXEC 0x00AF9A000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Exec|Readable, Flag=GranularityPage|Long
|
||
|
#define GDT_DATA 0x00EF92000000FFFFull // Base=0, Limit=max, Access=Present|Ring0|TypeUser|Writable, Flag=GranularityPage|Size
|
||
|
#define GDT_EXEC_RING3 0x00AFFA000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Exec|Readable, Flag=GranularityPage|Long
|
||
|
#define GDT_DATA_RING3 0x00EFF2000000FFFFull // Base=0, Limit=max, Access=Present|Ring3|TypeUser|Writable, Flag=GranularityPage|Size
|
||
|
|
||
|
#define GDT_EXEC_SELECTOR 0x08 // SelectorIndex=1, TableIndicator=GDT(0), Privilege=Ring0
|
||
|
#define GDT_DATA_SELECTOR 0x10 // SelectorIndex=2, TableIndicator=GDT(0), Privilege=Ring0
|
||
|
#define GDT_EXEC_RING3_SELECTOR 0x1B // SelectorIndex=3, TableIndicator=GDT(0), Privilege=Ring3
|
||
|
#define GDT_DATA_RING3_SELECTOR 0x23 // SelectorIndex=4, TableIndicator=GDT(0), Privilege=Ring3
|
||
|
|
||
|
#define IDT_PRESENT (1ull << 47)
|
||
|
#define IDT_RING0 0
|
||
|
#define IDT_RING1 (1ull << 45)
|
||
|
#define IDT_RING2 (2ull << 45)
|
||
|
#define IDT_RING3 (3ull << 45)
|
||
|
|
||
|
#define IDT_TYPE_32_CALL_GATE (0x0Cull << 40)
|
||
|
#define IDT_TYPE_32_INTERRUPT_GATE (0x0Eull << 40)
|
||
|
#define IDT_TYPE_32_TRAP_GATE (0x0Full << 40)
|
||
|
|
||
|
typedef struct {
|
||
|
uint16_t length;
|
||
|
void * base;
|
||
|
} PACKED interrupt_DescriptorTableReference;
|
||
|
// address of IDTR and GDTR, allocated by kMalloc() and is never freed
|
||
|
extern interrupt_DescriptorTableReference *interrupt_IDTR, *interrupt_GDTR;
|
||
|
|
||
|
// true if Init() has been called and interrupt handling is on
|
||
|
extern bool interrupt_Enabled;
|
||
|
|
||
|
// initializes interrupt handling like IDT and a dummy GDT
|
||
|
void interrupt_Init();
|
||
|
|
||
|
SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt);
|
||
|
|
||
|
|
||
|
// errorcode is 0 if nonexistent
|
||
|
//
|
||
|
// for IRQs, params are documented in assembly
|
||
|
SYSV_ABI void interrupt_Handler(int vec, int errcode, uint64_t rip, int c, int d, int e);
|
||
|
|
||
|
// defined in assembly
|
||
|
SYSV_ABI void interrupt_LoadGDT(void *gdtr);
|
||
|
SYSV_ABI void interrupt_LoadIDT(void *idtr);
|
||
|
SYSV_ABI void interrupt_ReloadSegments();
|
||
|
|
||
|
|
||
|
#define INTERRUPT_DISABLE \
|
||
|
uintptr_t __interrupt_flags; \
|
||
|
asm volatile("pushf\n\tcli\n\tpop %0" \
|
||
|
: "=r"(__interrupt_flags) \
|
||
|
: \
|
||
|
: "memory")
|
||
|
#define INTERRUPT_RESTORE \
|
||
|
asm volatile("push %0\n\tpopf" \
|
||
|
: \
|
||
|
: "rm"(__interrupt_flags) \
|
||
|
: "memory", "cc")
|
||
|
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|