From 592db0ebcf787ac33bf2acb317afa04ef65bfce6 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Sun, 16 May 2021 15:53:14 +0100 Subject: [PATCH] More work on interrupt handling, Started timer interrupt implementation, PIC remapped hopefully successfull --- Makefile | 11 +- README.md | 3 + screenshots/WIP_interruptHandling.png | 3 + src/kernel/arch/i386/boot.s | 426 +++++++++++++++--------- src/kernel/{ => arch/i386/gdt}/gdtc.cpp | 0 src/kernel/{ => arch/i386/gdt}/gdtc.h | 0 src/kernel/{ => arch/i386/idt}/idt.cpp | 111 +++--- src/kernel/arch/i386/idt/idt.h | 81 +++++ src/kernel/arch/i386/pic/pic.cpp | 62 ++++ src/kernel/arch/i386/pic/pic.h | 57 ++++ src/kernel/idt.h | 93 ------ src/kernel/kernel.cpp | 46 +-- src/kernel/kernel.h | 4 +- src/kernel/timer.cpp | 27 ++ src/kernel/timer.h | 6 + 15 files changed, 580 insertions(+), 350 deletions(-) create mode 100644 screenshots/WIP_interruptHandling.png rename src/kernel/{ => arch/i386/gdt}/gdtc.cpp (100%) rename src/kernel/{ => arch/i386/gdt}/gdtc.h (100%) rename src/kernel/{ => arch/i386/idt}/idt.cpp (51%) create mode 100644 src/kernel/arch/i386/idt/idt.h create mode 100644 src/kernel/arch/i386/pic/pic.cpp create mode 100644 src/kernel/arch/i386/pic/pic.h delete mode 100644 src/kernel/idt.h create mode 100644 src/kernel/timer.cpp create mode 100644 src/kernel/timer.h diff --git a/Makefile b/Makefile index 3aec044..aa43673 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o +OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o SRC_DIR = src BUILD_DIR = build @@ -24,7 +24,7 @@ all: clean build build: build_kernel run run: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std + $(EMULATOR) -d int -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std build_kernel: $(OBJ_LINK_LIST) @@ -55,7 +55,12 @@ $(BUILD_DIR)/crtn.o: $(BUILD_DIR)/io.o: $(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti + $(BUILD_DIR)/MMU.o: $(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti + $(BUILD_DIR)/idt.o: - $(CPP) -c $(SRC_DIR)/kernel/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti \ No newline at end of file + $(CPP) -c $(SRC_DIR)/kernel/arch/i386/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/pic.o: + $(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/README.md b/README.md index cf263a6..eefdecd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ ________________________ The first scrolling boot screen. 😲 + +W.I.P - Working on interrupt handling + ________________________ ### The goal diff --git a/screenshots/WIP_interruptHandling.png b/screenshots/WIP_interruptHandling.png new file mode 100644 index 0000000..6c22b50 --- /dev/null +++ b/screenshots/WIP_interruptHandling.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfbde3cc43610681eca3f38e56d8af1d0e5d0ad2f465cb743a5b8ea5c3adbe47 +size 16282 diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 0ea809c..17432e4 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -27,251 +27,365 @@ stack_top: */ # NOTE: I have no clue how I should use these macros. # Have tried to use them in a myriad of ways, none would actually work -.macro irq_NoErrCode code:req - .globl irq\code - irq\code: +.macro irs_NoErrCode code:req + .globl irs\code + irs\code: cli pushb $0 pushb \code - jmp irq_common + jmp irs_common .endm -.macro irq_ErrCode code - .globl irq\code - irq\code: +.macro irs_ErrCode code + .globl irs\code + irs\code: cli pushb \code - jmp irq_common + jmp irs_common .endm +.globl irs0 +irs0: + cli + push $0 + push $0 + jmp irs_common + +.globl irs1 +irs1: + cli + push $0 + push $1 + jmp irs_common + +.globl irs2 +irs2: + cli + push $0 + push $2 + jmp irs_common + +.globl irs3 +irs3: + cli + push $0 + push $3 + jmp irs_common + +.globl irs4 +irs4: + cli + push $0 + push $4 + jmp irs_common + +.globl irs5 +irs5: + cli + push $0 + push $5 + jmp irs_common + +.globl irs6 +irs6: + cli + push $0 + push $6 + jmp irs_common + +.globl irs7 +irs7: + cli + push $0 + push $7 + jmp irs_common + +.globl irs8 +irs8: + cli + push $0 + push $8 + jmp irs_common + +.globl irs9 +irs9: + cli + push $0 + push $9 + jmp irs_common + +.globl irs10 +irs10: + cli + push $0 + push $10 + jmp irs_common + +.globl irs11 +irs11: + cli + push $0 + push $11 + jmp irs_common + +.globl irs12 +irs12: + cli + push $0 + push $12 + jmp irs_common + +.globl irs13 +irs13: + cli + push $13 + jmp irs_common + +.globl irs14 +irs14: + cli + push $0 + push $14 + jmp irs_common + +.globl irs15 +irs15: + cli + push $0 + push $15 + jmp irs_common + +.globl irs16 +irs16: + cli + push $0 + push $16 + jmp irs_common + +.globl irs17 +irs17: + cli + push $0 + push $17 + jmp irs_common + +.globl irs18 +irs18: + cli + push $0 + push $18 + jmp irs_common + +.globl irs19 +irs19: + cli + push $0 + push $19 + jmp irs_common + +.globl irs20 +irs20: + cli + push $0 + push $20 + jmp irs_common + +.globl irs21 +irs21: + cli + push $0 + push $21 + jmp irs_common + +.globl irs22 +irs22: + cli + push $0 + push $22 + jmp irs_common + +.globl irs23 +irs23: + cli + push $0 + push $23 + jmp irs_common + +.globl irs24 +irs24: + cli + push $0 + push $24 + jmp irs_common + +.globl irs25 +irs25: + cli + push $0 + push $25 + jmp irs_common + +.globl irs26 +irs26: + cli + push $0 + push $26 + jmp irs_common + +.globl irs27 +irs27: + cli + push $0 + push $27 + jmp irs_common + +.globl irs28 +irs28: + cli + push $0 + push $28 + jmp irs_common + +.globl irs29 +irs29: + cli + push $0 + push $29 + jmp irs_common + +.globl irs30 +irs30: + cli + push $0 + push $30 + jmp irs_common + +.globl irs31 +irs31: + cli + push $0 + push $31 + jmp irs_common + + + .globl irq0 irq0: cli push $0 - push $0 - jmp irq_common + push $32 + jmp irs_common .globl irq1 irq1: cli push $0 - push $1 - jmp irq_common + push $33 + jmp irs_common .globl irq2 irq2: cli push $0 - push $2 - jmp irq_common + push $34 + jmp irs_common .globl irq3 irq3: cli push $0 - push $3 - jmp irq_common + push $35 + jmp irs_common .globl irq4 irq4: cli push $0 - push $4 - jmp irq_common + push $36 + jmp irs_common .globl irq5 irq5: cli push $0 - push $5 - jmp irq_common + push $37 + jmp irs_common .globl irq6 irq6: cli push $0 - push $6 - jmp irq_common + push $38 + jmp irs_common .globl irq7 irq7: cli push $0 - push $7 - jmp irq_common + push $39 + jmp irs_common .globl irq8 irq8: cli push $0 - push $8 - jmp irq_common + push $40 + jmp irs_common .globl irq9 irq9: cli push $0 - push $9 - jmp irq_common + push $41 + jmp irs_common .globl irq10 irq10: cli push $0 - push $10 - jmp irq_common + push $42 + jmp irs_common .globl irq11 irq11: cli push $0 - push $11 - jmp irq_common + push $43 + jmp irs_common + .globl irq12 irq12: cli push $0 - push $12 - jmp irq_common + push $44 + jmp irs_common .globl irq13 irq13: cli - push $13 - jmp irq_common + push $0 + push $45 + jmp irs_common .globl irq14 irq14: cli push $0 - push $14 - jmp irq_common + push $46 + jmp irs_common .globl irq15 irq15: cli push $0 - push $15 - jmp irq_common - -.globl irq16 -irq16: - cli - push $0 - push $16 - jmp irq_common - -.globl irq17 -irq17: - cli - push $0 - push $17 - jmp irq_common - -.globl irq18 -irq18: - cli - push $0 - push $18 - jmp irq_common - -.globl irq19 -irq19: - cli - push $0 - push $19 - jmp irq_common - -.globl irq20 -irq20: - cli - push $0 - push $20 - jmp irq_common - -.globl irq21 -irq21: - cli - push $0 - push $21 - jmp irq_common - -.globl irq22 -irq22: - cli - push $0 - push $22 - jmp irq_common - -.globl irq23 -irq23: - cli - push $0 - push $23 - jmp irq_common - -.globl irq24 -irq24: - cli - push $0 - push $24 - jmp irq_common - -.globl irq25 -irq25: - cli - push $0 - push $25 - jmp irq_common - -.globl irq26 -irq26: - cli - push $0 - push $26 - jmp irq_common - -.globl irq27 -irq27: - cli - push $0 - push $27 - jmp irq_common - -.globl irq28 -irq28: - cli - push $0 - push $28 - jmp irq_common - -.globl irq29 -irq29: - cli - push $0 - push $29 - jmp irq_common - -.globl irq30 -irq30: - cli - push $0 - push $30 - jmp irq_common - -.globl irq31 -irq31: - cli - push $0 - push $31 - jmp irq_common + push $47 + jmp irs_common - -irq_common: +irs_common: pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax @@ -286,7 +400,7 @@ irq_common: mov %ax, %fs mov %ax, %gs - call irq_handler + call irs_handler pop %eax @@ -296,7 +410,7 @@ irq_common: mov %ax, %gs popa - add $8, %esp # cleans push error and irq code + add $8, %esp # cleans push error and irs code sti iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP diff --git a/src/kernel/gdtc.cpp b/src/kernel/arch/i386/gdt/gdtc.cpp similarity index 100% rename from src/kernel/gdtc.cpp rename to src/kernel/arch/i386/gdt/gdtc.cpp diff --git a/src/kernel/gdtc.h b/src/kernel/arch/i386/gdt/gdtc.h similarity index 100% rename from src/kernel/gdtc.h rename to src/kernel/arch/i386/gdt/gdtc.h diff --git a/src/kernel/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp similarity index 51% rename from src/kernel/idt.cpp rename to src/kernel/arch/i386/idt/idt.cpp index c32d6e4..d515272 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -111,10 +111,9 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ }; -void irq_handler (registers regs) { +void irs_handler (registers regs) { kterm_writestring("received interrupt!\n"); - - + printf(" Interrupt number: %d \n", regs.int_no); if( regs.int_no == 13){ @@ -125,6 +124,10 @@ void irq_handler (registers regs) { } + + + + void init_idt(){ // Initialise the IDT pointer idt_ptr.length = sizeof(IDT_entry) * 255; @@ -133,57 +136,61 @@ void init_idt(){ // TODO: Set everything to zero first - set_id_entry(0, (uint32_t) irq0 , 0x08, 0x8E); - set_id_entry(1, (uint32_t) irq1 , 0x08, 0x8E); - set_id_entry(2, (uint32_t) irq2 , 0x08, 0x8E); - set_id_entry(3, (uint32_t) irq3 , 0x08, 0x8E); - set_id_entry(4, (uint32_t) irq4 , 0x08, 0x8E); - set_id_entry(5, (uint32_t) irq5 , 0x08, 0x8E); - set_id_entry(6, (uint32_t) irq6 , 0x08, 0x8E); - set_id_entry(7, (uint32_t) irq7 , 0x08, 0x8E); - set_id_entry(8, (uint32_t) irq8 , 0x08, 0x8E); - set_id_entry(9, (uint32_t) irq9 , 0x08, 0x8E); - set_id_entry(10, (uint32_t) irq10 , 0x08, 0x8E); - set_id_entry(11, (uint32_t) irq11 , 0x08, 0x8E); - set_id_entry(12, (uint32_t) irq12 , 0x08, 0x8E); - set_id_entry(13, (uint32_t) irq13 , 0x08, 0x8E); - set_id_entry(14, (uint32_t) irq14 , 0x08, 0x8E); - set_id_entry(15, (uint32_t) irq15 , 0x08, 0x8E); - set_id_entry(16, (uint32_t) irq16 , 0x08, 0x8E); - set_id_entry(17, (uint32_t) irq17 , 0x08, 0x8E); - set_id_entry(18, (uint32_t) irq18 , 0x08, 0x8E); - set_id_entry(19, (uint32_t) irq19 , 0x08, 0x8E); - set_id_entry(20, (uint32_t) irq20 , 0x08, 0x8E); - set_id_entry(21, (uint32_t) irq21 , 0x08, 0x8E); - set_id_entry(22, (uint32_t) irq22 , 0x08, 0x8E); - set_id_entry(23, (uint32_t) irq23 , 0x08, 0x8E); - set_id_entry(24, (uint32_t) irq24 , 0x08, 0x8E); - set_id_entry(25, (uint32_t) irq25 , 0x08, 0x8E); - set_id_entry(26, (uint32_t) irq26 , 0x08, 0x8E); - set_id_entry(27, (uint32_t) irq27 , 0x08, 0x8E); - set_id_entry(28, (uint32_t) irq28 , 0x08, 0x8E); - set_id_entry(29, (uint32_t) irq29 , 0x08, 0x8E); - set_id_entry(30, (uint32_t) irq30 , 0x08, 0x8E); - set_id_entry(31, (uint32_t) irq31 , 0x08, 0x8E); + set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8E); + set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E); + set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E); + set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E); + set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E); + set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E); + set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E); + set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E); + set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E); + set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E); + set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E); + set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E); + set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E); + set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E); + set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E); + set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E); + set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E); + set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E); + set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E); + set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E); + set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E); + set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E); + set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E); + set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E); + set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E); + set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E); + set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E); + set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E); + set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E); + set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E); + set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E); + set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E); + + + //print_serial("Remapping PIC\n"); + PIC_remap(0x20, 0x28); + -/* // pic IRQ Table - set_id_entry(32, (uint32_t)irs0, 0x08, 0x8E); - set_id_entry(33, (uint32_t)irs1, 0x08, 0x8E); - set_id_entry(34, (uint32_t)irs2, 0x08, 0x8E); - set_id_entry(35, (uint32_t)irs3, 0x08, 0x8E); - set_id_entry(36, (uint32_t)irs4, 0x08, 0x8E); - set_id_entry(37, (uint32_t)irs5, 0x08, 0x8E); - set_id_entry(38, (uint32_t)irs6, 0x08, 0x8E); - set_id_entry(39, (uint32_t)irs7, 0x08, 0x8E); - set_id_entry(40, (uint32_t)irs8, 0x08, 0x8E); - set_id_entry(41, (uint32_t)irs9, 0x08, 0x8E); - set_id_entry(42, (uint32_t)irs10, 0x08, 0x8E); - set_id_entry(43, (uint32_t)irs11, 0x08, 0x8E); - set_id_entry(44, (uint32_t)irs12, 0x08, 0x8E); - set_id_entry(45, (uint32_t)irs13, 0x08, 0x8E); - set_id_entry(46, (uint32_t)irs14, 0x08, 0x8E); - set_id_entry(47, (uint32_t)irs15, 0x08, 0x8E);*/ + set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E); + set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); + set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E); + set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E); + set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E); + set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E); + set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E); + set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E); + set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E); + set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E); + set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E); + set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E); + set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); + set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E); + set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E); + set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E); idt_flush((uint32_t)&idt_ptr); diff --git a/src/kernel/arch/i386/idt/idt.h b/src/kernel/arch/i386/idt/idt.h new file mode 100644 index 0000000..7281fa9 --- /dev/null +++ b/src/kernel/arch/i386/idt/idt.h @@ -0,0 +1,81 @@ +#pragma once + +#include "stdint.h" +#include "stddef.h" +#include "../vga/colors.h" +#include "../pic/pic.h"; + +#define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) + +extern "C" void kterm_writestring(const char* data ); +extern "C" void kterm_putat(char, uint8_t, size_t, size_t); +extern "C" void kterm_put(char); + + +extern "C" { + struct __attribute__((__packed__)) IDT_entry { + uint16_t offset_1; + uint16_t selector; + uint8_t zero; + uint8_t type_attr; + uint16_t offset_2; + }; + + struct __attribute__((__packed__)) IDT_ptr { + unsigned short length; + unsigned long base; + }; + + struct registers { + uint32_t ds; // Data segment selector + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. + uint32_t int_no, err_code; // Interrupt number and error code (if applicable) + uint32_t eip, cs, eflags, useresp, ss; + }; + + + extern void idt_flush(uint32_t); + void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags); + void init_idt(); + + void irq_handler (registers regs); + + void irs_handler (registers regs); + + extern void irs0 (); + extern void irs1 (); + extern void irs2 (); + extern void irs3 (); + extern void irs4 (); + extern void irs5 (); + extern void irs6 (); + extern void irs7 (); + extern void irs8 (); + extern void irs9 (); + extern void irs10 (); + extern void irs11 (); + extern void irs12 (); + extern void irs13 (); + extern void irs14 (); + extern void irs15 (); + extern void irs16 (); + extern void irs17 (); + extern void irs18 (); + extern void irs19 (); + extern void irs20 (); + extern void irs21 (); + extern void irs22 (); + extern void irs23 (); + extern void irs24 (); + extern void irs25 (); + extern void irs26 (); + extern void irs27 (); + extern void irs28 (); + extern void irs29 (); + extern void irs30 (); + extern void irs31 (); + + + + +} diff --git a/src/kernel/arch/i386/pic/pic.cpp b/src/kernel/arch/i386/pic/pic.cpp new file mode 100644 index 0000000..5f1967c --- /dev/null +++ b/src/kernel/arch/i386/pic/pic.cpp @@ -0,0 +1,62 @@ +#include "pic.h" + +extern "C" void PIC_sendEOI (unsigned char irq){ + if(irq >= 8) + outb(PIC2_COMMAND, PIC_EOI); + outb(PIC1_COMMAND, PIC_EOI); +} + +/* Helper func */ +static uint16_t __pic_get_irq_reg(int ocw3) +{ + /* OCW3 to PIC CMD to get the register values. PIC2 is chained, and + * represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain */ + outb(PIC1_COMMAND, ocw3); + outb(PIC2_COMMAND, ocw3); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} + +/* Returns the combined value of the cascaded PICs irq request register */ +uint16_t pic_get_irr(void) +{ + return __pic_get_irq_reg(PIC_READ_IRR); +} + +/* Returns the combined value of the cascaded PICs in-service register */ +uint16_t pic_get_isr(void) +{ + return __pic_get_irq_reg(PIC_READ_ISR); +} + + +void PIC_remap (int offset1, int offset2 ){ + unsigned char a1, a2; + + a1 = inb(PIC1_DATA); + a2 = inb(PIC2_DATA); + + + // Start initialization + + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC1_DATA, offset1); + io_wait(); + outb(PIC2_DATA, offset2); + io_wait(); + outb(PIC1_DATA, 4); + io_wait(); + outb(PIC2_DATA, 2); + io_wait(); + + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + + outb(PIC1_DATA, a1); + outb(PIC2_DATA, a2); + +} \ No newline at end of file diff --git a/src/kernel/arch/i386/pic/pic.h b/src/kernel/arch/i386/pic/pic.h new file mode 100644 index 0000000..5358f5a --- /dev/null +++ b/src/kernel/arch/i386/pic/pic.h @@ -0,0 +1,57 @@ +#pragma once +#include "../../../io.h" + +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1+1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2+1) + + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +#define PIC_EOI 0x20 +#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */ +#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */ + +extern "C"{ + +extern void irq0 (); +extern void irq1 (); +extern void irq2 (); +extern void irq3 (); +extern void irq4 (); +extern void irq5 (); +extern void irq6 (); +extern void irq7 (); +extern void irq8 (); +extern void irq9 (); +extern void irq10 (); +extern void irq11 (); +extern void irq12 (); +extern void irq13 (); +extern void irq14 (); +extern void irq15 (); + +void PIC_sendEOI (unsigned char irq); + +} + + +static uint16_t __pic_get_irq_reg(int ocw3); +uint16_t pic_get_irr(void); +uint16_t pic_get_isr(void); + + +void PIC_remap (int offset1, int offset2 ); \ No newline at end of file diff --git a/src/kernel/idt.h b/src/kernel/idt.h deleted file mode 100644 index 07c7440..0000000 --- a/src/kernel/idt.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once -#include "stdint.h" -#include "stddef.h" -#include "arch/i386/vga/colors.h" - -#define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) - -extern "C" void kterm_writestring(const char* data ); -extern "C" void kterm_putat(char, uint8_t, size_t, size_t); -extern "C" void kterm_put(char); - - -extern "C" { - struct __attribute__((__packed__)) IDT_entry { - uint16_t offset_1; - uint16_t selector; - uint8_t zero; - uint8_t type_attr; - uint16_t offset_2; - }; - - struct __attribute__((__packed__)) IDT_ptr { - unsigned short length; - unsigned long base; - }; - - struct registers { - uint32_t ds; // Data segment selector - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. - uint32_t int_no, err_code; // Interrupt number and error code (if applicable) - uint32_t eip, cs, eflags, useresp, ss; - }; - - - extern void idt_flush(uint32_t); - void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags); - void init_idt(); - - void irq_handler (registers regs); - - extern void irq0 (); - extern void irq1 (); - extern void irq2 (); - extern void irq3 (); - extern void irq4 (); - extern void irq5 (); - extern void irq6 (); - extern void irq7 (); - extern void irq8 (); - extern void irq9 (); - extern void irq10 (); - extern void irq11 (); - extern void irq12 (); - extern void irq13 (); - extern void irq14 (); - extern void irq15 (); - extern void irq16 (); - extern void irq17 (); - extern void irq18 (); - extern void irq19 (); - extern void irq20 (); - extern void irq21 (); - extern void irq22 (); - extern void irq23 (); - extern void irq24 (); - extern void irq25 (); - extern void irq26 (); - extern void irq27 (); - extern void irq28 (); - extern void irq29 (); - extern void irq30 (); - extern void irq31 (); -/* - extern void irq0 (); - extern void irq1 (); - extern void irq2 (); - extern void irq3 (); - extern void irq4 (); - extern void irq5 (); - extern void irq6 (); - extern void irq7 (); - extern void irq8 (); - extern void irq9 (); - extern void irq10 (); - extern void irq11 (); - extern void irq12 (); - extern void irq13 (); - extern void irq14 (); - extern void irq15 ();*/ - - - -} diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 2530c7a..edd7f22 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -9,10 +9,6 @@ void delay(int t){ asm("NOP"); } - - - - class Test { public: Test(); @@ -20,7 +16,6 @@ class Test { ~Test(); }; - Test::Test(){ kterm_writestring("Create a test object\n"); }; @@ -56,7 +51,6 @@ static int init_serial() { return 0; } - int is_transmit_empty() { return inb(PORT + 5) & 0x20; } @@ -77,7 +71,6 @@ char read_serial() { return inb(PORT); } - void print_serial(const char* string ){ for(size_t i = 0; i < strlen(string); i ++){ write_serial(string[i]); @@ -102,31 +95,13 @@ void test_serial(){ kterm_writestring("\n"); } - - extern "C" { void early_main(){ init_serial(); print_serial("\033[31;42mEarly main called!\n"); - - print_serial("Remapping PIC\n"); - // remap the PIC IRQ table - /*outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, 0x28); - outb(0x21, 0x04); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0);*/ - - - print_serial("done... \n"); - + } void kernel_main (void) { @@ -162,24 +137,7 @@ extern "C" { auto testObject = Test(); testObject.printMe(); - /*IRQ_set_mask(0); - IRQ_set_mask(1); - IRQ_set_mask(2); - IRQ_set_mask(3); - IRQ_set_mask(4); - IRQ_set_mask(5); - IRQ_set_mask(6); - IRQ_set_mask(7); - IRQ_set_mask(8); - IRQ_set_mask(9); - IRQ_set_mask(10); - IRQ_set_mask(11); - IRQ_set_mask(12); - IRQ_set_mask(13); - IRQ_set_mask(14); - IRQ_set_mask(15); - */ - + /** test interrupt handlers **/ asm volatile ("int $0x03"); diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 3b1b0bc..ced720a 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -3,7 +3,7 @@ extern "C" { #include "../libc/include/string.h" #include "arch/i386/tty/kterm.h" } + +#include "arch/i386/idt/idt.h" #include "MMU.h" #include "io.h" -#include "idt.h" -//#include "pic.h" \ No newline at end of file diff --git a/src/kernel/timer.cpp b/src/kernel/timer.cpp new file mode 100644 index 0000000..35a8a4a --- /dev/null +++ b/src/kernel/timer.cpp @@ -0,0 +1,27 @@ +#include "timer.h" + +uint32_t tick = 0; + + +static void timer_callback (registers_t regs ){ + tick ++ ; + kterm_writestring ("tick passed!"); +} + +void init_timer (uint32_t frequency){ + // register timer callback + + uint32_t divisor = 1193180 / frequency; + + // Send the commmand byte + outb(0x43, 0x36); + + // Divisor has to be sent byt-wise , so will send lower then upper bytes + uint8_t low = (uint8_t) (divisor & 0xFF); + uint8_t high = (uint8_t) ((divisor >> 8) & 0xFF); + + outb(0x40, low); + outb(0x40, high); + + +} \ No newline at end of file diff --git a/src/kernel/timer.h b/src/kernel/timer.h new file mode 100644 index 0000000..db8be78 --- /dev/null +++ b/src/kernel/timer.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +void init_timer (uint32_t frequency); \ No newline at end of file