aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-03-04 15:43:28 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-03-04 15:43:28 +0200
commit5f0006cfa7c499a501969641ac7bd630cb4706de (patch)
tree68e792da03c4ec36241dee787bc0dd7835dfd907
parentAdd some comments to keyboard driver (diff)
downloadkernel.cpp-5f0006cfa7c499a501969641ac7bd630cb4706de.tar.xz
pass cpu_state_t to interrupt handler
-rw-r--r--libk/stdlib/abort.cc6
-rw-r--r--makefile2
-rw-r--r--src/boot.S (renamed from src/boot.s)1
-rw-r--r--src/cpu/exceptions.s51
-rw-r--r--src/cpu/interrupts.s50
-rw-r--r--src/cpu/registers.h26
-rw-r--r--src/idt.cc30
-rw-r--r--src/idt/stubs.S82
-rw-r--r--src/makefile4
9 files changed, 133 insertions, 119 deletions
diff --git a/libk/stdlib/abort.cc b/libk/stdlib/abort.cc
index 41bf991..13bee4d 100644
--- a/libk/stdlib/abort.cc
+++ b/libk/stdlib/abort.cc
@@ -12,9 +12,3 @@ void abort() {
__builtin_unreachable();
}
-extern "C" void print_exception(uint8_t irq) {
- printk("exception ", uhex{irq}, '\n');
- asm volatile("cli");
- while (true) asm volatile("hlt");
- __builtin_unreachable();
-};
diff --git a/makefile b/makefile
index f570a4f..9af9064 100644
--- a/makefile
+++ b/makefile
@@ -20,7 +20,7 @@ glitch.elf: $(autogen) $(AS_OBJ) $(CXX_OBJ)
@echo " LD $@"
@$(LD) $(LD_FLAGS) -o $@ $(AS_OBJ) $(CXX_OBJ)
-$(AS_OBJ): $(OBJ_DIR)/%.o: %.s
+$(AS_OBJ): $(OBJ_DIR)/%.o: %.S
@mkdir -p $(@D)
@echo " AS $<"
@$(AS) -target $(TARGET) -nostdlib -Wall -Wextra -c $^ -o $@
diff --git a/src/boot.s b/src/boot.S
index 2286152..fff1644 100644
--- a/src/boot.s
+++ b/src/boot.S
@@ -46,6 +46,7 @@ stack_top:
.global _start
.type _start, @function
_start:
+ mov $stack_bottom, %ebp
mov $stack_top, %esp # point the stack pointer to the stack
/*
diff --git a/src/cpu/exceptions.s b/src/cpu/exceptions.s
deleted file mode 100644
index 9736be1..0000000
--- a/src/cpu/exceptions.s
+++ /dev/null
@@ -1,51 +0,0 @@
-.section .text
-.extern print_exception
-
-.macro exception num
-.global exception\num
-exception\num:
- movb $\num, (exc)
- jmp exception_common
-.endm
-
-exception 0x00
-exception 0x01
-exception 0x02
-exception 0x03
-exception 0x04
-exception 0x05
-exception 0x06
-exception 0x07
-exception 0x08
-exception 0x09
-exception 0x0a
-exception 0x0b
-exception 0x0c
-exception 0x0d
-exception 0x0e
-exception 0x0f
-exception 0x10
-exception 0x11
-exception 0x12
-exception 0x13
-
-exception_common:
- pusha
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
-
- push (exc)
- call print_exception
-
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popa
- iret
-
-.data
- exc: .byte 0
-
diff --git a/src/cpu/interrupts.s b/src/cpu/interrupts.s
deleted file mode 100644
index 17c39e9..0000000
--- a/src/cpu/interrupts.s
+++ /dev/null
@@ -1,50 +0,0 @@
-.section .text
-.extern handle_interrupt
-
-.macro interrupt num
-.global interrupt\num
-interrupt\num:
- movb $\num, (irq)
- jmp interrupt_common
-.endm
-
-interrupt 0x00 # system timer
-interrupt 0x01 # keyboard controller
-interrupt 0x02 # slave pic
-interrupt 0x03 # serial port 2 and 4
-interrupt 0x04 # serial port 1 and 3
-interrupt 0x05 # parallel port 2 and 3, sound card
-interrupt 0x06 # floppy controller
-interrupt 0x07 # parallel port 1
-
-interrupt 0x08 # real-time clock
-interrupt 0x09 # acpi
-interrupt 0x0a #
-interrupt 0x0b #
-interrupt 0x0c # mouse on ps/2
-interrupt 0x0d # fpu
-interrupt 0x0e # primary ATA
-interrupt 0x0f # secondary ATA
-
-interrupt_common:
- pusha
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
-
- pushl %esp
- push (irq)
- call handle_interrupt
- mov %eax, %esp
-
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popa
- iret
-
-.data
- irq: .byte 0
-
diff --git a/src/cpu/registers.h b/src/cpu/registers.h
new file mode 100644
index 0000000..edb6b7b
--- /dev/null
+++ b/src/cpu/registers.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <types.h>
+
+namespace x86 {
+
+struct cpu_state {
+ /* pusha */
+ uint32_t edi, esi; // destination index, source index
+ uint32_t ebp, esp; // base pointer, stack pointer
+ uint32_t ebx, edx, ecx, eax; // general registers
+
+ uint32_t irq;
+ uint32_t error;
+
+ /* stack frame, pushed by cpu */
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t __esp;
+ uint32_t ss;
+} __attribute__((packed));
+
+} // namespace x86
+
+typedef x86::cpu_state cpu_state_t;
diff --git a/src/idt.cc b/src/idt.cc
index 68ae260..363afcd 100644
--- a/src/idt.cc
+++ b/src/idt.cc
@@ -1,22 +1,24 @@
#include "idt.h"
#include <stdlib.h>
#include "cpu/irq.h"
+#include "cpu/registers.h"
#include "ports.h"
static_assert(sizeof(IDT::Pointer) == 6);
+constexpr uint8_t irq_base = 0x20;
static InterruptHandler* handlers[256] = {nullptr};
bool IDT::install(uint8_t irq, InterruptHandler* h) {
- if (h != nullptr && handlers[irq] == nullptr) {
- handlers[irq] = h;
+ if (h != nullptr && handlers[irq + irq_base] == nullptr) {
+ handlers[irq + irq_base] = h;
return true;
}
return false;
}
bool IDT::uninstall(uint8_t irq, InterruptHandler* h) {
- if (handlers[irq] == h) {
- handlers[irq] = nullptr;
+ if (handlers[irq + irq_base] == h) {
+ handlers[irq + irq_base] = nullptr;
return true;
}
return false;
@@ -37,18 +39,28 @@ bool IDT::uninstall(uint8_t irq, InterruptHandler* h) {
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
-extern "C" uint32_t handle_interrupt(uint8_t irq, uint32_t esp) {
- if (handlers[irq] != nullptr) {
- handlers[irq]->trigger();
+extern "C" void print_exception(cpu_state_t* r) {
+ printk("exception ", uhex{r->irq}, " error ", uhex{r->error}, '\n');
+ asm volatile("cli");
+ while (true) asm volatile("hlt");
+ __builtin_unreachable();
+};
+
+extern "C" uint32_t handle_interrupt(cpu_state_t* r) {
+ if (r->irq < irq_base) print_exception(r);
+
+ if (handlers[r->irq] != nullptr) {
+ handlers[r->irq]->trigger();
}
pic1_t pic1;
pic1.write(0x20);
- if (irq > 7) {
+ if (r->irq > 7 + irq_base) {
pic2_t pic2;
pic2.write(0x20);
}
- return esp;
+
+ return reinterpret_cast<uint32_t>(r);
};
IDT::IDT(const uint16_t selector) {
diff --git a/src/idt/stubs.S b/src/idt/stubs.S
new file mode 100644
index 0000000..97f1797
--- /dev/null
+++ b/src/idt/stubs.S
@@ -0,0 +1,82 @@
+.set IRQ_BASE, 0x20
+
+.section .text
+.extern handle_interrupt
+
+.macro interrupt num
+.global interrupt\num
+interrupt\num:
+ push $0
+ push $\num + IRQ_BASE
+ jmp interrupt_common
+.endm
+
+.macro exception num
+.global exception\num
+exception\num:
+ push $0
+ push $\num
+ jmp interrupt_common
+.endm
+
+.macro exception_ec num
+.global exception\num
+exception\num:
+ push $\num
+ jmp interrupt_common
+.endm
+
+/* exceptions */
+exception 0x00
+exception 0x01
+exception 0x02
+exception 0x03
+exception 0x04
+exception 0x05
+exception 0x06
+exception 0x07
+exception_ec 0x08
+exception 0x09
+exception_ec 0x0a
+exception_ec 0x0b
+exception_ec 0x0c
+exception_ec 0x0d
+exception_ec 0x0e
+exception 0x0f
+exception 0x10
+exception_ec 0x11
+exception 0x12
+exception 0x13
+
+/* interrupts - master pic */
+interrupt 0x00 # system timer
+interrupt 0x01 # keyboard controller
+interrupt 0x02 # slave pic
+interrupt 0x03 # serial port 2 and 4
+interrupt 0x04 # serial port 1 and 3
+interrupt 0x05 # parallel port 2 and 3, sound card
+interrupt 0x06 # floppy controller
+interrupt 0x07 # parallel port 1
+/* interrupts - slave pic */
+interrupt 0x08 # real-time clock
+interrupt 0x09 # acpi
+interrupt 0x0a #
+interrupt 0x0b #
+interrupt 0x0c # mouse on ps/2
+interrupt 0x0d # fpu
+interrupt 0x0e # primary ATA
+interrupt 0x0f # secondary ATA
+
+interrupt_common:
+ pusha
+
+ push %esp
+ call handle_interrupt
+ mov %eax, %esp
+
+ popa
+ /* remove error code and irq from stack */
+ add $8, %esp
+
+ iret
+
diff --git a/src/makefile b/src/makefile
index 8db63d6..64853fe 100644
--- a/src/makefile
+++ b/src/makefile
@@ -1,5 +1,5 @@
AS_OBJ += src/boot.o \
- src/cpu/exceptions.o src/cpu/interrupts.o
+ src/idt/stubs.o
CXX_OBJ += src/kernel.o \
src/kernel/dump_gdt.o \
@@ -10,7 +10,7 @@ CXX_OBJ += src/kernel.o \
src/idt.o \
src/idt/interruptgate.o src/idt/interrupthandler.o
-src/cpu/irq.h: $(OBJ_DIR)/src/cpu/exceptions.o $(OBJ_DIR)/src/cpu/interrupts.o
+src/cpu/irq.h: $(OBJ_DIR)/src/idt/stubs.o
@echo " GEN $@"
@echo '#pragma once' > $@
@echo 'extern "C" {' >> $@