Implementing IDT in long mode
Posted: Sat Nov 27, 2021 7:59 am
Hi,
I've been stuck in this problem for quite a while (specifically 3 days ). Can anyone give me advice? Here is the code, please fix it for me:
In idt.h
In idt.c:
In isr-stub.asm:
In isr.h:
In isr.c:
Thank you everyone!
NeonLightions
I've been stuck in this problem for quite a while (specifically 3 days ). Can anyone give me advice? Here is the code, please fix it for me:
In idt.h
Code: Select all
#ifndef IDT_H
#define IDT_H
#include <stdint.h>
#include <stddef.h>
/**
* @brief 64-bit IDT entry, 16 byte wise
*
*/
typedef struct idt_entry {
uint16_t base_low;
uint16_t segment_selector;
uint8_t ist;
uint8_t gate_type : 4;
uint8_t reserved1 : 1;
uint8_t dpl : 2;
uint8_t present : 1;
uint16_t base_middle;
uint32_t base_high;
uint32_t reserved2;
}__attribute__((packed)) idt_entry_t;
typedef struct idt_descriptor {
uint16_t size;
uint64_t base;
}__attribute__((packed)) idt_descriptor_t;
void idt_init();
#endif
Code: Select all
#include "idt.h"
/** We have 256 interrupt gate, entry from 0..31 are
* reserved for CPU, 32..47 will reserved for IRQ,
* all gates from 48..255 are free for our OS
*/
static idt_entry_t idt_table[256];
/**
* @brief IDT descriptor, use for load IDT
*/
static idt_descriptor_t idtr;
static inline
void idt_set_gate(uint8_t num, uint64_t base, uint16_t seg_sel,
uint8_t gate_type, uint8_t dpl)
{
idt_entry_t *this = &idt_table[num];
this->base_low = base & 0xFFFFFFFF;
this->base_middle = (base >> 16) & 0xFFFFFFFF;
this->base_high = (base >> 32) & 0xFFFFFFFF;
this->segment_selector = seg_sel;
this->gate_type = gate_type;
this->dpl = dpl;
this->present = 1;
this->reserved1 = 0;
this->reserved2 = 0;
this->ist = 0;
}
#include "isr.h"
#include "../memory/gdt.h"
void
idt_init()
{
asm volatile("cli");
idtr.base = (uint64_t) &idt_table;
idtr.size = sizeof(idt_entry_t) * 256;
memset(&idt_table, 0, sizeof(idt_entry_t) * 256);
idt_set_gate(0, (uint64_t) isr_0, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(1, (uint64_t) isr_1, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(2, (uint64_t) isr_2, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(3, (uint64_t) isr_3, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(4, (uint64_t) isr_4, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(5, (uint64_t) isr_5, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(6, (uint64_t) isr_6, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(7, (uint64_t) isr_7, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(8, (uint64_t) isr_8, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(9, (uint64_t) isr_9, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(10, (uint64_t) isr_10, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(11, (uint64_t) isr_11, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(12, (uint64_t) isr_12, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(13, (uint64_t) isr_13, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(14, (uint64_t) isr_14, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(15, (uint64_t) isr_15, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(16, (uint64_t) isr_16, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(17, (uint64_t) isr_17, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(18, (uint64_t) isr_18, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(19, (uint64_t) isr_19, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(20, (uint64_t) isr_20, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(21, (uint64_t) isr_21, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(22, (uint64_t) isr_22, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(23, (uint64_t) isr_23, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(24, (uint64_t) isr_24, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(5, (uint64_t) isr_25, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(26, (uint64_t) isr_26, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(27, (uint64_t) isr_27, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(28, (uint64_t) isr_28, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(29, (uint64_t) isr_29, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(30, (uint64_t) isr_30, SEGMENT_KCODE_OFFSET, 0xE, 0);
idt_set_gate(31, (uint64_t) isr_31, SEGMENT_KCODE_OFFSET, 0xE, 0);
asm volatile("sti");
}
Code: Select all
section .text
%macro ISR_NOERR 1
global isr_%1
isr_%1:
push qword 0
push qword %1
jmp isr_handler_stub
%endmacro
%macro ISR_ERR 1
global isr_%1
isr_%1:
push qword %1
jmp isr_handler_stub
%endmacro
%macro pushaq 1
push rax
push rcx
push rdx
push rbx
push rbp
push rsi
push rdi
%endmacro
%macro popaq 1
pop rdi
pop rsi
pop rbp
pop rbx
pop rdx
pop rcx
pop rax
%endmacro
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_ERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_ERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
extern isr_handler
isr_handler_stub:
;push rax
;push rcx
;push rdx
;push rbx
;push rsp
;push rbp
;push rsi
;push rdi
;push r8
;push r9
;push r10
;push r11
;push r12
;push r13
;push r14
;push r15
pushaq 1
mov word ax, ds
push rax
mov rax, rsp
push rax
mov word ax, 0x10
mov word ds, ax
mov word es, ax
mov word fs, ax
mov word gs, ax
call isr_handler
add qword rsp, 8
pop rax
mov word ds, ax
mov word es, ax
mov word fs, ax
mov word gs, ax
;pop r15
;pop r14
;pop r13
;pop r12
;pop r11
;pop r10
;pop r9
;pop r8
;pop rdi
;pop rsi
;pop rbp
;pop rsp
;pop rbx
;pop rdx
;pop rcx
;pop rax
popaq 1
add qword rsp, 16
iret
Code: Select all
#ifndef ISR_H
#define ISR_H
#include <stdint.h>
#include "../common/printf.h"
typedef struct interrupt_state {
uint64_t ds; /** Pushed by isr_handler_stub */
//uint64_t r15, r14, r13, r12, r11, r10, r9, r8; /** Pushed by isr_handler_stub */
uint64_t rdi, rsi, rbp, useless, rbx, rdx, rcx, rax; /** Pushed by isr_handler_stub */
uint64_t int_no, err_code; /** Pushed by CPU when interrupt fired */
uint64_t rip, cs, rflags, rsp, ss; /** Pushed by CPU when interrupt fired */
}__attribute__((packed)) interrupt_state_t;
typedef void (*isr_t)(interrupt_state_t *);
void isr_register(uint8_t int_no, isr_t handler);
void isr_handler(interrupt_state_t *state);
extern void isr_0();
extern void isr_1();
extern void isr_2();
extern void isr_3();
extern void isr_4();
extern void isr_5();
extern void isr_6();
extern void isr_7();
extern void isr_8();
extern void isr_9();
extern void isr_10();
extern void isr_11();
extern void isr_12();
extern void isr_13();
extern void isr_14();
extern void isr_15();
extern void isr_16();
extern void isr_17();
extern void isr_18();
extern void isr_19();
extern void isr_20();
extern void isr_21();
extern void isr_22();
extern void isr_23();
extern void isr_24();
extern void isr_25();
extern void isr_26();
extern void isr_27();
extern void isr_28();
extern void isr_29();
extern void isr_30();
extern void isr_31();
#endif
Code: Select all
#include "isr.h"
static isr_t isr_table[256] = { NULL };
inline void
isr_register(uint8_t int_no, isr_t handler)
{
if (isr_table[int_no] != NULL) {
cprintf(VGA_COLOR_RED, "ERROR: isr_register: handler for interrupt %#x already registered", int_no);
return;
}
isr_table[int_no] = handler;
}
void
isr_handler(interrupt_state_t *state)
{
uint8_t num = state->int_no;
cprintf(VGA_COLOR_CYAN, "INFO: isr_handler: caught interrupt %#x", num);
}
NeonLightions