Initial commit
This commit is contained in:
194
interrupt/handler.asm.S
Normal file
194
interrupt/handler.asm.S
Normal file
@ -0,0 +1,194 @@
|
||||
format elf64
|
||||
|
||||
; sysvx64call void interrupt_Handler(a, b, c, d, e, f)
|
||||
extrn interrupt_Handler
|
||||
; sysvx64call void interrupt_Handler128(a, b, c, d, e, f)
|
||||
; Input: rax(syscall opcode)
|
||||
extrn interrupt_Handler128
|
||||
|
||||
extrn io_WriteConsoleASCII
|
||||
|
||||
public interrupt_Int0
|
||||
public interrupt_Int1
|
||||
public interrupt_Int2
|
||||
public interrupt_Int3
|
||||
public interrupt_Int4
|
||||
public interrupt_Int5
|
||||
public interrupt_Int6
|
||||
public interrupt_Int7
|
||||
public interrupt_Int8
|
||||
public interrupt_Int9
|
||||
public interrupt_Int10
|
||||
public interrupt_Int11
|
||||
public interrupt_Int12
|
||||
public interrupt_Int13
|
||||
public interrupt_Int14
|
||||
public interrupt_Int15
|
||||
public interrupt_Int16
|
||||
public interrupt_Int17
|
||||
public interrupt_Int18
|
||||
public interrupt_Int19
|
||||
public interrupt_Int20
|
||||
public interrupt_Int21
|
||||
public interrupt_Int22
|
||||
public interrupt_Int23
|
||||
public interrupt_Int24
|
||||
public interrupt_Int25
|
||||
public interrupt_Int26
|
||||
public interrupt_Int27
|
||||
public interrupt_Int28
|
||||
public interrupt_Int29
|
||||
public interrupt_Int30
|
||||
public interrupt_Int31
|
||||
|
||||
public interrupt_Int128
|
||||
|
||||
|
||||
section '.text' executable
|
||||
|
||||
|
||||
macro inth op1 {
|
||||
push rdi
|
||||
mov rdi, op1
|
||||
push rsi
|
||||
push rdx
|
||||
mov rdx, [rsp+24]
|
||||
push rcx
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push rax
|
||||
call interrupt_Handler
|
||||
pop rax
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rcx
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
iretq
|
||||
}
|
||||
|
||||
macro inth_err op1 {
|
||||
push rsi
|
||||
push rdi
|
||||
mov rdi, op1
|
||||
mov esi, [rsp+16]
|
||||
push rdx
|
||||
mov rdx, [rsp+32]
|
||||
push rcx
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push rax
|
||||
call interrupt_Handler
|
||||
pop rax
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rcx
|
||||
pop rdx
|
||||
pop rdi
|
||||
pop rsi
|
||||
add rsp, 8 ; pop the error code
|
||||
iretq
|
||||
}
|
||||
|
||||
interrupt_Int0: ; does not return
|
||||
inth 0
|
||||
interrupt_Int1:
|
||||
inth 1
|
||||
interrupt_Int2:
|
||||
inth 2
|
||||
interrupt_Int3:
|
||||
inth 3
|
||||
interrupt_Int4:
|
||||
inth 4
|
||||
interrupt_Int5:
|
||||
inth 5
|
||||
interrupt_Int6:
|
||||
inth 6
|
||||
interrupt_Int7:
|
||||
inth 7
|
||||
interrupt_Int8:
|
||||
inth 8
|
||||
interrupt_Int9:
|
||||
inth 9
|
||||
interrupt_Int10:
|
||||
inth_err 10
|
||||
interrupt_Int11:
|
||||
inth_err 11
|
||||
interrupt_Int12:
|
||||
inth_err 12
|
||||
interrupt_Int13:
|
||||
inth_err 13
|
||||
interrupt_Int14:
|
||||
inth_err 14
|
||||
interrupt_Int15:
|
||||
inth 15
|
||||
interrupt_Int16:
|
||||
inth 16
|
||||
interrupt_Int17:
|
||||
inth_err 17
|
||||
interrupt_Int18:
|
||||
inth 18
|
||||
interrupt_Int19:
|
||||
inth 19
|
||||
interrupt_Int20:
|
||||
inth 20
|
||||
interrupt_Int21:
|
||||
inth_err 21
|
||||
interrupt_Int22:
|
||||
inth 22
|
||||
interrupt_Int23:
|
||||
inth 23
|
||||
interrupt_Int24:
|
||||
inth 24
|
||||
interrupt_Int25:
|
||||
inth 25
|
||||
interrupt_Int26:
|
||||
inth 26
|
||||
interrupt_Int27:
|
||||
inth 27
|
||||
interrupt_Int28:
|
||||
inth 28
|
||||
interrupt_Int29:
|
||||
inth 29
|
||||
interrupt_Int30:
|
||||
inth 30
|
||||
interrupt_Int31:
|
||||
inth 31
|
||||
|
||||
interrupt_Int128:
|
||||
;sub rsp, 32
|
||||
;mov rcx, interrupt_string
|
||||
;call io_WriteConsoleASCII
|
||||
;add rsp, 32
|
||||
;iretq
|
||||
|
||||
; no need to save the registers
|
||||
;push rax
|
||||
;push rdi
|
||||
;push rsi
|
||||
;push rdx
|
||||
;push rcx
|
||||
;push r8
|
||||
;push r9
|
||||
;push r10
|
||||
;push r11
|
||||
call interrupt_Handler128
|
||||
;pop r11
|
||||
;pop r10
|
||||
;pop r9
|
||||
;pop r8
|
||||
;pop rcx
|
||||
;pop rdx
|
||||
;pop rsi
|
||||
;pop rdi
|
||||
;pop rax
|
||||
iretq
|
52
interrupt/handler.c
Normal file
52
interrupt/handler.c
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
#include "interrupt.h"
|
||||
#include "../runtime/panic_assert.h"
|
||||
|
||||
|
||||
const char *interrupt_Descriptions[] = {
|
||||
"Divide Error Execption",
|
||||
"Debug Exception",
|
||||
"NMI Interrupt",
|
||||
"Breakpoint Exception",
|
||||
"Overflow Exception",
|
||||
"BOUND Range Exceeded Exception",
|
||||
"Invalid Opcode Exception",
|
||||
"Device Not Available Exception",
|
||||
"Double Fault Exception",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Invalid TSS Exception",
|
||||
"Segment Not Present",
|
||||
"Stack Fault Exception",
|
||||
"General Protection Exception",
|
||||
"Page-Fault Exception",
|
||||
"Interrupt 15",
|
||||
"x87 FPU Floating-Point Error",
|
||||
"Alignment Check Exception",
|
||||
"Machine-Check Exception",
|
||||
"SIMD Floating-Point Exception",
|
||||
"Interrupt 20",
|
||||
"Control Protection Exception",
|
||||
"Interrupt 22",
|
||||
"Interrupt 23",
|
||||
"Interrupt 24",
|
||||
"Interrupt 25",
|
||||
"Interrupt 26",
|
||||
"Interrupt 27",
|
||||
"Interrupt 28",
|
||||
"Interrupt 29",
|
||||
"Interrupt 30",
|
||||
"Interrupt 31",
|
||||
};
|
||||
|
||||
SYSV_ABI void interrupt_Handler(int vec, int errcode, uint64_t rip, int c, int d, int e) {
|
||||
io_Printf("Panic: INT %02xh: %s, err=%d(0x%02x), rip=%llx\n", vec, interrupt_Descriptions[vec], errcode, errcode, rip);
|
||||
__Panic_HaltSystem();
|
||||
}
|
||||
|
||||
// handler for INT 80h
|
||||
SYSV_ABI void interrupt_Handler128(int a, int b, int c, int d, int e, int f) {
|
||||
int opcode;
|
||||
asm volatile("mov %%eax, %0"
|
||||
: "=rm"(opcode)); // read the opcode
|
||||
io_Printf("INT 80h: EAX(opcode)=%d, abcdef=[%d,%d,%d,%d,%d,%d]\n", opcode, a, b, c, d, e, f);
|
||||
}
|
38
interrupt/handlers.h
Normal file
38
interrupt/handlers.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// the functions are not to be called, but to be taken address and put into IDT
|
||||
void interrupt_Int0();
|
||||
void interrupt_Int1();
|
||||
void interrupt_Int2();
|
||||
void interrupt_Int3();
|
||||
void interrupt_Int4();
|
||||
void interrupt_Int5();
|
||||
void interrupt_Int6();
|
||||
void interrupt_Int7();
|
||||
void interrupt_Int8();
|
||||
void interrupt_Int9();
|
||||
void interrupt_Int10();
|
||||
void interrupt_Int11();
|
||||
void interrupt_Int12();
|
||||
void interrupt_Int13();
|
||||
void interrupt_Int14();
|
||||
void interrupt_Int15();
|
||||
void interrupt_Int16();
|
||||
void interrupt_Int17();
|
||||
void interrupt_Int18();
|
||||
void interrupt_Int19();
|
||||
void interrupt_Int20();
|
||||
void interrupt_Int21();
|
||||
void interrupt_Int22();
|
||||
void interrupt_Int23();
|
||||
void interrupt_Int24();
|
||||
void interrupt_Int25();
|
||||
void interrupt_Int26();
|
||||
void interrupt_Int27();
|
||||
void interrupt_Int28();
|
||||
void interrupt_Int29();
|
||||
void interrupt_Int30();
|
||||
void interrupt_Int31();
|
||||
|
||||
void interrupt_Int128();
|
118
interrupt/init.c
Normal file
118
interrupt/init.c
Normal file
@ -0,0 +1,118 @@
|
||||
|
||||
#include "interrupt.h"
|
||||
#include "handlers.h"
|
||||
#include "../memory/memory.h"
|
||||
#include "../runtime/stdio.h"
|
||||
#include "../runtime/panic_assert.h"
|
||||
#include "testcode.h"
|
||||
|
||||
interrupt_DescriptorTableReference *interrupt_IDTR, *interrupt_GDTR;
|
||||
bool interrupt_Enabled;
|
||||
|
||||
|
||||
/*
|
||||
SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt) {
|
||||
//io_Printf("interrupt_MapHandler: handler %llx, int %d\n", handler, interrupt);
|
||||
uint64_t *base = (uint64_t *)(KERNEL_IDT_MAPPING + interrupt * 16ull);
|
||||
uint64_t b = 0;
|
||||
|
||||
b |= (uint64_t)handler & 0xFFFFull; // Offset[15:0], 15:0
|
||||
b |= (uint64_t)GDT_EXEC_SELECTOR << 16; // Segment Selector, 31:16
|
||||
b |= IDT_TYPE_32_INTERRUPT_GATE; // Type = 32-bit Interrupt Gate, 44:40
|
||||
b |= IDT_RING0; // Ring 0, 46:45
|
||||
b |= IDT_PRESENT; // Present, 47
|
||||
b |= ((uint64_t)handler & 0xFFFF0000ull) << 32; // Offset[31:16], 63:48
|
||||
|
||||
*base = b;
|
||||
*(base + 1) = (uint64_t)handler >> 32;
|
||||
}
|
||||
*/
|
||||
|
||||
// defined in assembly
|
||||
SYSV_ABI void interrupt_MapHandler(void *handler, int interrupt);
|
||||
|
||||
|
||||
void interrupt_Init() {
|
||||
assert(sizeof(interrupt_DescriptorTableReference) == 10 && "GDTR/IDTR size must be 10 bytes");
|
||||
assert(offsetof(interrupt_DescriptorTableReference, base) == 2 && "GDTR/IDTR must be packed");
|
||||
|
||||
assert(KERNEL_IDTR_MAPPING % 4 == 0 && "IDTR not aligned to 4-byte");
|
||||
assert(KERNEL_GDTR_MAPPING % 4 == 0 && "GDTR not aligned to 4-byte");
|
||||
|
||||
|
||||
// allocate GDTR
|
||||
io_WriteConsoleASCII("interrupt_Init() calling\n");
|
||||
interrupt_GDTR = (interrupt_DescriptorTableReference *)KERNEL_GDTR_MAPPING;
|
||||
interrupt_GDTR->length = 4 * GDT_SIZE_BYTES - 1;
|
||||
interrupt_GDTR->base = (void *)KERNEL_GDT_MAPPING;
|
||||
io_WriteConsoleASCII("GDTR Written\n");
|
||||
|
||||
// set the 2 dummy gdts
|
||||
uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING;
|
||||
gdt[0] = 0;
|
||||
gdt[1] = GDT_EXEC;
|
||||
gdt[2] = GDT_DATA;
|
||||
gdt[3] = GDT_EXEC_RING3;
|
||||
gdt[4] = GDT_DATA_RING3;
|
||||
io_WriteConsoleASCII("GDT Installed\n");
|
||||
|
||||
interrupt_LoadGDT(interrupt_GDTR); // set it!
|
||||
io_WriteConsoleASCII("GDT OK\n");
|
||||
|
||||
//interrupt_Testcode();
|
||||
io_WriteConsoleASCII("Testcode OK\n");
|
||||
|
||||
|
||||
// allocate IDTR
|
||||
//interrupt_IDTR = kMalloc(sizeof(interrupt_DescriptorTableReference));
|
||||
interrupt_IDTR = (interrupt_DescriptorTableReference *)KERNEL_IDTR_MAPPING;
|
||||
interrupt_IDTR->length = KERNEL_IDT_SIZE - 1;
|
||||
interrupt_IDTR->base = (void *)KERNEL_IDT_MAPPING;
|
||||
io_WriteConsoleASCII("IDT Written\n");
|
||||
|
||||
interrupt_MapHandler(interrupt_Int0, 0);
|
||||
interrupt_MapHandler(interrupt_Int1, 1);
|
||||
interrupt_MapHandler(interrupt_Int2, 2);
|
||||
interrupt_MapHandler(interrupt_Int3, 3);
|
||||
interrupt_MapHandler(interrupt_Int4, 4);
|
||||
interrupt_MapHandler(interrupt_Int5, 5);
|
||||
interrupt_MapHandler(interrupt_Int6, 6);
|
||||
interrupt_MapHandler(interrupt_Int7, 7);
|
||||
interrupt_MapHandler(interrupt_Int8, 8);
|
||||
interrupt_MapHandler(interrupt_Int9, 9);
|
||||
interrupt_MapHandler(interrupt_Int10, 10);
|
||||
interrupt_MapHandler(interrupt_Int11, 11);
|
||||
interrupt_MapHandler(interrupt_Int12, 12);
|
||||
interrupt_MapHandler(interrupt_Int13, 13);
|
||||
interrupt_MapHandler(interrupt_Int14, 14);
|
||||
interrupt_MapHandler(interrupt_Int15, 15);
|
||||
interrupt_MapHandler(interrupt_Int16, 16);
|
||||
interrupt_MapHandler(interrupt_Int17, 17);
|
||||
interrupt_MapHandler(interrupt_Int18, 18);
|
||||
interrupt_MapHandler(interrupt_Int19, 19);
|
||||
interrupt_MapHandler(interrupt_Int20, 20);
|
||||
interrupt_MapHandler(interrupt_Int21, 21);
|
||||
interrupt_MapHandler(interrupt_Int22, 22);
|
||||
interrupt_MapHandler(interrupt_Int23, 23);
|
||||
interrupt_MapHandler(interrupt_Int24, 24);
|
||||
interrupt_MapHandler(interrupt_Int25, 25);
|
||||
interrupt_MapHandler(interrupt_Int26, 26);
|
||||
interrupt_MapHandler(interrupt_Int27, 27);
|
||||
interrupt_MapHandler(interrupt_Int28, 28);
|
||||
interrupt_MapHandler(interrupt_Int29, 29);
|
||||
interrupt_MapHandler(interrupt_Int30, 30);
|
||||
interrupt_MapHandler(interrupt_Int31, 31);
|
||||
interrupt_MapHandler(interrupt_Int128, 128);
|
||||
io_WriteConsoleASCII("IDT Installed\n");
|
||||
|
||||
interrupt_LoadIDT(interrupt_IDTR); // set it!
|
||||
|
||||
|
||||
io_WriteConsoleASCII("IDT OK\n");
|
||||
|
||||
interrupt_Enabled = true;
|
||||
asm volatile("sti");
|
||||
|
||||
interrupt_ReloadSegments();
|
||||
io_WriteConsoleASCII("Segment Registers Reloaded\n");
|
||||
}
|
74
interrupt/interrupt.h
Normal file
74
interrupt/interrupt.h
Normal file
@ -0,0 +1,74 @@
|
||||
#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
|
57
interrupt/interrupt_testcode.S
Normal file
57
interrupt/interrupt_testcode.S
Normal file
@ -0,0 +1,57 @@
|
||||
format elf64
|
||||
|
||||
extrn io_WriteConsoleASCII
|
||||
|
||||
|
||||
section '.rodata'
|
||||
interrupt_string:
|
||||
db "Interrupt Testcode", 0x0A, 0x00
|
||||
|
||||
|
||||
section '.data' writable
|
||||
align 4
|
||||
idt:
|
||||
rb 50*16
|
||||
|
||||
idtr:
|
||||
dw (50*16)-1
|
||||
dq idt
|
||||
|
||||
|
||||
section '.text' executable
|
||||
int_handler:
|
||||
push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
sub rsp, 32
|
||||
mov rcx, interrupt_string
|
||||
call io_WriteConsoleASCII
|
||||
add rsp, 32
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
iretq
|
||||
|
||||
|
||||
public interrupt_Testcode
|
||||
interrupt_Testcode:
|
||||
lidt [idtr]
|
||||
mov rax, int_handler
|
||||
mov [idt+49*16], ax
|
||||
mov word [idt+49*16+2], 0x08
|
||||
mov word [idt+49*16+4], 0x8e00
|
||||
shr rax, 16
|
||||
mov [idt+49*16+6], ax
|
||||
shr rax, 16
|
||||
mov [idt+49*16+8], rax
|
||||
|
||||
int 49
|
||||
ret
|
45
interrupt/load_gdt.S
Normal file
45
interrupt/load_gdt.S
Normal file
@ -0,0 +1,45 @@
|
||||
format elf64
|
||||
|
||||
public interrupt_ReloadSegments
|
||||
public interrupt_LoadGDT
|
||||
public interrupt_LoadIDT
|
||||
|
||||
|
||||
section '.text' executable
|
||||
|
||||
; sysvx64call void interrupt_LoadGDT(void* gdtr)
|
||||
;
|
||||
; Input: (void* rdi)
|
||||
; Clobbers: none
|
||||
interrupt_LoadGDT:
|
||||
lgdt [rdi]
|
||||
ret
|
||||
|
||||
; sysvx64call void interrupt_ReloadSegments()
|
||||
;
|
||||
; Clobbers: rax
|
||||
interrupt_ReloadSegments:
|
||||
mov eax, 0x10 ; my data segment
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
|
||||
;jmp 0x08:.flush
|
||||
; as in https://forum.osdev.org/viewtopic.php?f=1&t=30739
|
||||
; farjump does not work in long mode, you need to do a far return:
|
||||
pop rax
|
||||
push qword 0x08 ; my code segment
|
||||
push rax
|
||||
retfq
|
||||
|
||||
; sysvx64call void interrupt_LoadIDT(void* idtr)
|
||||
;
|
||||
; Input: (void* rdi)
|
||||
; Clobbers: none
|
||||
interrupt_LoadIDT:
|
||||
lidt [rdi]
|
||||
ret
|
||||
|
25
interrupt/map_handler.S
Normal file
25
interrupt/map_handler.S
Normal file
@ -0,0 +1,25 @@
|
||||
format elf64
|
||||
|
||||
extrn io_WriteConsoleASCII
|
||||
|
||||
public interrupt_MapHandler
|
||||
|
||||
|
||||
section '.text' executable
|
||||
|
||||
; sysvx64call void interrupt_MapHandler(uint64_t handler, int interrupt)
|
||||
;
|
||||
; Input: (uint64_t rdi, int rsi)
|
||||
; Clobbers: rax, flags
|
||||
interrupt_MapHandler:
|
||||
mov rax, 0xFFFFFFFEC0000000 ; KERNEL_IDT_MAPPING
|
||||
shl rsi, 4 ; rsi *= 16
|
||||
add rsi, rax ; rsi += KERNEL_IDT_MAPPING
|
||||
mov [rsi], di
|
||||
mov word [rsi+2], 0x08 ; GDT_EXEC_SELECTOR (index=1)
|
||||
mov word [rsi+4], 0x8e00
|
||||
shr rdi, 16
|
||||
mov [rsi+6], di
|
||||
shr rdi, 16
|
||||
mov [rsi+8], rdi
|
||||
ret
|
18
interrupt/syscall.S
Normal file
18
interrupt/syscall.S
Normal file
@ -0,0 +1,18 @@
|
||||
format elf64
|
||||
|
||||
public asm_Syscall as 'Syscall' ; syscall is a reserved token
|
||||
|
||||
section ".text" executable
|
||||
|
||||
; sysvx64call int Syscall(int syscall_id, int a,b,c,d,e,f)
|
||||
asm_Syscall:
|
||||
mov rax, rdi
|
||||
mov rdi, rsi
|
||||
mov rsi, rdx
|
||||
mov rdx, rcx
|
||||
mov rcx, r8
|
||||
mov r8, r9
|
||||
mov r9, [rsp+8]
|
||||
int 0x80
|
||||
ret
|
||||
|
8
interrupt/syscall.h
Normal file
8
interrupt/syscall.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../main.h"
|
||||
|
||||
// this function is here, well, mostly just for fun.
|
||||
//
|
||||
// userspace in the far future should need this
|
||||
SYSV_ABI long Syscall(int id, long a, long b, long c, long d, long e, long f);
|
6
interrupt/testcode.h
Normal file
6
interrupt/testcode.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../main.h"
|
||||
|
||||
|
||||
SYSV_ABI void interrupt_Testcode();
|
Reference in New Issue
Block a user