Adding keyboard interrupt handler
as of right now its busted(doesn't printanythng)
This commit is contained in:
parent
a0752cba62
commit
5bc285b7ca
@ -35,25 +35,28 @@ err_code_handler_%1:
|
||||
jmp common_int_handler
|
||||
%endmacro
|
||||
|
||||
extern interrupt_handler ; external handler (interrupts.c)
|
||||
common_int_handler:
|
||||
; save thigns before do our C-call
|
||||
pushad
|
||||
;push eax
|
||||
;push ecx
|
||||
;push edx
|
||||
;push ebx
|
||||
;push eax ecx edx ebx
|
||||
;push esp ebp esi edi
|
||||
|
||||
;push esp
|
||||
;push ebp
|
||||
;push esi
|
||||
;push edi
|
||||
push ds
|
||||
push es
|
||||
push fs
|
||||
push gs
|
||||
|
||||
;push ds
|
||||
;push es
|
||||
;push fs
|
||||
;push gs
|
||||
|
||||
call interrupt_handler
|
||||
; load the kernel segment descriptor
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov eax, esp ; pushing the stack into the next call
|
||||
push eax
|
||||
mov eax, interrupt_handler
|
||||
call eax ; preserve the eip register past this call
|
||||
|
||||
; segments
|
||||
pop gs
|
||||
@ -61,15 +64,7 @@ common_int_handler:
|
||||
pop es
|
||||
pop ds
|
||||
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebp
|
||||
pop esp
|
||||
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
popad
|
||||
|
||||
add esp, 8
|
||||
; special instruction which lets us jump back to code
|
||||
|
48
interrupts.c
48
interrupts.c
@ -1,8 +1,33 @@
|
||||
#include "stlio.h"
|
||||
#include "interrupts.h"
|
||||
#include "serial.h"
|
||||
#include "mem.h"
|
||||
#include "types.h"
|
||||
|
||||
extern void load_idt();
|
||||
const char* err_msg[] = {
|
||||
"Divide by zero\n",
|
||||
"Debug Exception\n",
|
||||
"Non Maskable Interrupt Exception\n",
|
||||
"Breakpoint Exception\n",
|
||||
"Into Detected Overflow Exception\n",
|
||||
"Out of Bounds Exception\n",
|
||||
"Invalid Opcode Exception\n",
|
||||
"No Coprocessor Exception\n",
|
||||
"Double Fault Exception\n",
|
||||
"Coprocessor Segment Overrun Exception\n",
|
||||
"Bad TSS Exception\n",
|
||||
"Segment Not Present Exception\n",
|
||||
"Stack Fault Exception\n",
|
||||
"General Protection Fault Exception\n",
|
||||
"Page Fault Exception\n",
|
||||
"Unknown Interrupt Exception\n",
|
||||
"Coprocessor Fault Exception\n",
|
||||
"Alignment Check Exception (486+)\n",
|
||||
"Machine Check Exception (Pentium/586+)\n",
|
||||
"Reserved Exceptions\n", /* for 19 - 31 */
|
||||
};
|
||||
|
||||
extern void load_idt(); // found in interrupts_entry.s
|
||||
extern void no_err_handler_1();
|
||||
extern void no_err_handler_2();
|
||||
extern void no_err_handler_3();
|
||||
@ -52,12 +77,27 @@ void setup_idt_entry(u32 t_idx, u32 base, u16 sel, u8 type_attrs) {
|
||||
IDT[t_idx].selector = sel;
|
||||
}
|
||||
|
||||
void int_keyboard(struct cpu_reg_state* cpu) {
|
||||
// Get the keycode from the serial buffer
|
||||
u8 buf[5];
|
||||
memset(buf, 0x00, 5);
|
||||
u8 scancode = serial_read_buffer(0x60);
|
||||
buf[0] = scancode;
|
||||
printf((char*)buf);
|
||||
serial_pic_ack(cpu->int_no);
|
||||
}
|
||||
|
||||
// Generic interrupt handler to be used later on
|
||||
void interrupt_handler(struct cpu_reg_state cpu, struct stack_state stack, u32 interrupt_code) {
|
||||
void interrupt_handler(struct cpu_reg_state cpu) {
|
||||
// treating things on the stack like it were a cpu_reg_state
|
||||
// NOTE: dummy stuff to stop gcc from complaining atm
|
||||
cpu.eax += 1;
|
||||
stack.error_code += interrupt_code;
|
||||
switch(cpu.int_no) {
|
||||
case(i_Keyboard): {
|
||||
// keyboard interrupt handler gets the stuff now
|
||||
int_keyboard(&cpu);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void init_idt() {
|
||||
|
41
interrupts.h
41
interrupts.h
@ -1,32 +1,22 @@
|
||||
#include "types.h"
|
||||
|
||||
// There are more interrupts but tbh i doubt we're going to need them
|
||||
#define i_Timer 0
|
||||
#define i_Keyboard 1
|
||||
#define i_PIC2 2
|
||||
#define i_COM2 3
|
||||
#define i_COM1 4
|
||||
#define i_LPT2 5
|
||||
|
||||
|
||||
struct cpu_reg_state {
|
||||
u32 eax;
|
||||
u32 ecx;
|
||||
u32 edx;
|
||||
u32 ebx;
|
||||
u32 gs, fs, es, ds; // segment registers
|
||||
u32 edi, esi, ebp, esp; // generaal purupose via pushad
|
||||
u32 ebx, edx, ecx, eax;
|
||||
u32 int_no, err_code; // pushed by each interrupt dispatcher
|
||||
u32 eip, cs, eflags, useresp, ss; // processor pushes this automatically
|
||||
};//__attribute__((packed)); // we shouldn't need packing since everythign is dwords here
|
||||
|
||||
u32 esp;
|
||||
u32 ebp;
|
||||
u32 esi;
|
||||
u32 edi;
|
||||
|
||||
u16 ds;
|
||||
u16 es;
|
||||
u16 fs;
|
||||
u16 gs;
|
||||
|
||||
u32 eflags;
|
||||
}__attribute__((packed));
|
||||
|
||||
// Populated by the interrupt handler itself
|
||||
struct stack_state {
|
||||
u32 error_code; // 8 10 11 12 13 14 17 <= ony interrupts that actually use the error code
|
||||
u32 eip;
|
||||
u16 cs;
|
||||
u32 eflags;
|
||||
};
|
||||
|
||||
#define IDT_SIZE 256
|
||||
|
||||
@ -53,4 +43,5 @@ struct IDT_PTR idt_ptr;
|
||||
|
||||
void init_idt();
|
||||
void setup_idt_entry(u32 t_idx, u32 base, u16 sel, u8 type_attrs);
|
||||
//void interrupt_handler(struct cpu_reg_state, struct stack_state, u32);
|
||||
void int_keyboard(struct cpu_reg_state*);
|
||||
void interrupt_handler(struct cpu_reg_state);
|
||||
|
15
serial.c
15
serial.c
@ -72,3 +72,18 @@ u64 serial_write(const char* buffer, const u64 size) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void serial_pic_ack(u32 interrupt) {
|
||||
// ignore things that are too small and too big
|
||||
if(interrupt < PIC1_START_INT || interrupt > PIC2_END_INT) {
|
||||
return;
|
||||
}
|
||||
// Send acknoldgement to the pic that we have handled the interrupt
|
||||
// without this it literally just wait for the ack
|
||||
if(interrupt < PIC2_START_INT) {
|
||||
serialport_write_byte(PIC1_PORT, PIC_ACK);
|
||||
}
|
||||
else {
|
||||
serialport_write_byte(PIC2_PORT, PIC_ACK);
|
||||
}
|
||||
}
|
12
serial.h
12
serial.h
@ -21,6 +21,17 @@
|
||||
#define SERIAL_DEFAULT_MODEM_CFG 0x03
|
||||
|
||||
#define SERIAL_FIFO_EMPTY_CODE 0x20
|
||||
|
||||
#define PIC1_PORT 0x20
|
||||
#define PIC2_PORT 0xA0
|
||||
|
||||
#define PIC1_START_INT 0x20
|
||||
#define PIC1_END_INT 0x27
|
||||
#define PIC2_START_INT 0x28
|
||||
#define PIC2_END_INT 0x2F
|
||||
|
||||
#define PIC_ACK 0x20
|
||||
|
||||
void serial_set_baud_rate(const u16, const u16);
|
||||
|
||||
void serial_configure_line(const u16, const u8);
|
||||
@ -29,3 +40,4 @@ u8 serial_fifo_empty(const u16);
|
||||
|
||||
u64 serial_write(const char* buffer, const u64 size);
|
||||
|
||||
void serial_pic_ack(u32 interrupt);
|
||||
|
Loading…
Reference in New Issue
Block a user