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
|
jmp common_int_handler
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
extern interrupt_handler ; external handler (interrupts.c)
|
||||||
common_int_handler:
|
common_int_handler:
|
||||||
; save thigns before do our C-call
|
; save thigns before do our C-call
|
||||||
pushad
|
pushad
|
||||||
;push eax
|
;push eax ecx edx ebx
|
||||||
;push ecx
|
;push esp ebp esi edi
|
||||||
;push edx
|
|
||||||
;push ebx
|
|
||||||
|
|
||||||
;push esp
|
push ds
|
||||||
;push ebp
|
push es
|
||||||
;push esi
|
push fs
|
||||||
;push edi
|
push gs
|
||||||
|
|
||||||
;push ds
|
; load the kernel segment descriptor
|
||||||
;push es
|
mov ax, 0x10
|
||||||
;push fs
|
mov ds, ax
|
||||||
;push gs
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
call interrupt_handler
|
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
|
; segments
|
||||||
pop gs
|
pop gs
|
||||||
@ -61,15 +64,7 @@ common_int_handler:
|
|||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
|
|
||||||
pop edi
|
popad
|
||||||
pop esi
|
|
||||||
pop ebp
|
|
||||||
pop esp
|
|
||||||
|
|
||||||
pop ebx
|
|
||||||
pop edx
|
|
||||||
pop ecx
|
|
||||||
pop eax
|
|
||||||
|
|
||||||
add esp, 8
|
add esp, 8
|
||||||
; special instruction which lets us jump back to code
|
; 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 "interrupts.h"
|
||||||
|
#include "serial.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "types.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_1();
|
||||||
extern void no_err_handler_2();
|
extern void no_err_handler_2();
|
||||||
extern void no_err_handler_3();
|
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;
|
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
|
// 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
|
// treating things on the stack like it were a cpu_reg_state
|
||||||
// NOTE: dummy stuff to stop gcc from complaining atm
|
// NOTE: dummy stuff to stop gcc from complaining atm
|
||||||
cpu.eax += 1;
|
switch(cpu.int_no) {
|
||||||
stack.error_code += interrupt_code;
|
case(i_Keyboard): {
|
||||||
|
// keyboard interrupt handler gets the stuff now
|
||||||
|
int_keyboard(&cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_idt() {
|
void init_idt() {
|
||||||
|
41
interrupts.h
41
interrupts.h
@ -1,32 +1,22 @@
|
|||||||
#include "types.h"
|
#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 {
|
struct cpu_reg_state {
|
||||||
u32 eax;
|
u32 gs, fs, es, ds; // segment registers
|
||||||
u32 ecx;
|
u32 edi, esi, ebp, esp; // generaal purupose via pushad
|
||||||
u32 edx;
|
u32 ebx, edx, ecx, eax;
|
||||||
u32 ebx;
|
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
|
#define IDT_SIZE 256
|
||||||
|
|
||||||
@ -53,4 +43,5 @@ struct IDT_PTR idt_ptr;
|
|||||||
|
|
||||||
void init_idt();
|
void init_idt();
|
||||||
void setup_idt_entry(u32 t_idx, u32 base, u16 sel, u8 type_attrs);
|
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;
|
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_DEFAULT_MODEM_CFG 0x03
|
||||||
|
|
||||||
#define SERIAL_FIFO_EMPTY_CODE 0x20
|
#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_set_baud_rate(const u16, const u16);
|
||||||
|
|
||||||
void serial_configure_line(const u16, const u8);
|
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);
|
u64 serial_write(const char* buffer, const u64 size);
|
||||||
|
|
||||||
|
void serial_pic_ack(u32 interrupt);
|
||||||
|
Loading…
Reference in New Issue
Block a user