summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-03 21:32:00 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-03 21:32:00 -0400
commit16b7b4c2c008c976ee5948c97a8337d6224c3be9 (patch)
tree70f8402c3a2650d72fb174a43f8893a6f415546b /kernel
parentfix printf (diff)
downloadcomus-16b7b4c2c008c976ee5948c97a8337d6224c3be9.tar.gz
comus-16b7b4c2c008c976ee5948c97a8337d6224c3be9.tar.bz2
comus-16b7b4c2c008c976ee5948c97a8337d6224c3be9.zip
add 64-bit idt/pic and fix paging
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpu/cpu.c10
-rw-r--r--kernel/cpu/fpu.c12
-rw-r--r--kernel/cpu/fpu.h14
-rw-r--r--kernel/cpu/idt.S666
-rw-r--r--kernel/cpu/idt.c204
-rw-r--r--kernel/cpu/idt.h68
-rw-r--r--kernel/cpu/pic.c90
-rw-r--r--kernel/cpu/pic.h42
-rw-r--r--kernel/include/comus/cpu.h17
-rw-r--r--kernel/io/io.c11
-rw-r--r--kernel/kernel.c10
-rw-r--r--kernel/kernel.ld8
-rw-r--r--kernel/memory/paging.c2
-rw-r--r--kernel/memory/virtalloc.c2
14 files changed, 1141 insertions, 15 deletions
diff --git a/kernel/cpu/cpu.c b/kernel/cpu/cpu.c
new file mode 100644
index 0000000..8f37402
--- /dev/null
+++ b/kernel/cpu/cpu.c
@@ -0,0 +1,10 @@
+
+#include "fpu.h"
+#include "pic.h"
+#include "idt.h"
+
+void cpu_init(void) {
+ pic_remap();
+ idt_init();
+ fpu_init();
+}
diff --git a/kernel/cpu/fpu.c b/kernel/cpu/fpu.c
new file mode 100644
index 0000000..f2674a7
--- /dev/null
+++ b/kernel/cpu/fpu.c
@@ -0,0 +1,12 @@
+#include <lib.h>
+
+#include "fpu.h"
+
+void fpu_init(void) {
+ size_t cr4;
+ uint16_t cw = 0x37F;
+ __asm__ volatile ("mov %%cr4, %0" : "=r"(cr4));
+ cr4 |= 0x200;
+ __asm__ volatile ("mov %0, %%cr4" :: "r"(cr4));
+ __asm__ volatile("fldcw %0" :: "m"(cw));
+}
diff --git a/kernel/cpu/fpu.h b/kernel/cpu/fpu.h
new file mode 100644
index 0000000..edb4e81
--- /dev/null
+++ b/kernel/cpu/fpu.h
@@ -0,0 +1,14 @@
+/**
+ * @file fpu.h
+ *
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * FPU functions
+ */
+
+#ifndef FPU_H_
+#define FPU_H_
+
+void fpu_init(void);
+
+#endif /* fpu.h */
diff --git a/kernel/cpu/idt.S b/kernel/cpu/idt.S
new file mode 100644
index 0000000..0ba35f8
--- /dev/null
+++ b/kernel/cpu/idt.S
@@ -0,0 +1,666 @@
+ .global isr_stub_table
+
+ .extern idt_exception_handler
+ .extern idt_pic_timer
+ .extern idt_pic_keyboard
+ .extern idt_pic_mouse
+ .extern idt_pic_eoi
+
+.macro PUSHALL
+ pushq %rax
+ pushq %rbx
+ pushq %rcx
+ pushq %rdx
+ pushq %rsi
+ pushq %rdi
+ pushq %rbp
+ pushq %r8
+ pushq %r9
+ pushq %r10
+ pushq %r11
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+.endm
+
+.macro POPALL
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %r11
+ popq %r10
+ popq %r9
+ popq %r8
+ popq %rbp
+ popq %rdi
+ popq %rsi
+ popq %rdx
+ popq %rcx
+ popq %rbx
+ popq %rax
+.endm
+
+# call the exception handler with the interrupt number
+# args: interrupt number
+.macro ISRException num
+ .align 8
+isr_stub_\num:
+ PUSHALL
+ cld
+ movq $\num, %rdi # exception number
+ movq $0, %rsi # placeholder error code
+ movq %rsp, %rdx # top of stack
+ callq idt_exception_handler
+ POPALL
+ iretq
+.endm
+
+# call the exception handler with the interrupt number
+# these exceptions also put an error code on the stack
+# args: interrupt number
+.macro ISRExceptionCode num
+ .align 8
+isr_stub_\num:
+ # retrieve the error code without corrupting registers
+ mov %eax, isr_tmp
+ popq %rax
+ mov %eax, isr_err_code
+ movq isr_tmp, %rax
+ PUSHALL
+ cld
+ movq $\num, %rdi # exception number
+ movq isr_err_code, %rsi # error code
+ movq %rsp, %rdx # top of stack
+ callq idt_exception_handler
+ POPALL
+ iretq
+.endm
+
+.macro PICGeneric num
+ .align 8
+isr_stub_\num:
+ PUSHALL
+ cld
+ movq $\num, %rdi
+ callq idt_pic_eoi
+ POPALL
+ iretq
+.endm
+
+.macro PICTimer num
+ .align 8
+isr_stub_\num:
+ PUSHALL
+ cld
+ callq idt_pic_timer
+ movq $\num, %rdi
+ callq idt_pic_eoi
+ POPALL
+ iretq
+.endm
+
+.macro PICKeyboard num
+ .align 8
+isr_stub_\num:
+ PUSHALL
+ cld
+ callq idt_pic_keyboard
+ movq $\num, %rdi
+ callq idt_pic_eoi
+ POPALL
+ iretq
+.endm
+
+.macro PICMouse num
+ .align 8
+isr_stub_\num:
+ PUSHALL
+ cld
+ callq idt_pic_mouse
+ movq $\num, %rdi
+ callq idt_pic_eoi
+ POPALL
+ iretq
+.endm
+
+# do nothing
+# args: interrupt number
+.macro ISRIgnore num
+ .align 8
+isr_stub_\num:
+ iretq
+.endm
+
+# isr temp storage
+ .section .data
+isr_tmp:
+ .quad 0
+isr_err_code:
+ .quad 0
+
+# isr stub table
+ .section .rodata
+ .align 16
+ .code64
+isr_stub_table:
+ .quad isr_stub_0
+ .quad isr_stub_1
+ .quad isr_stub_2
+ .quad isr_stub_3
+ .quad isr_stub_4
+ .quad isr_stub_5
+ .quad isr_stub_6
+ .quad isr_stub_7
+ .quad isr_stub_8
+ .quad isr_stub_9
+ .quad isr_stub_10
+ .quad isr_stub_11
+ .quad isr_stub_12
+ .quad isr_stub_13
+ .quad isr_stub_14
+ .quad isr_stub_15
+ .quad isr_stub_16
+ .quad isr_stub_17
+ .quad isr_stub_18
+ .quad isr_stub_19
+ .quad isr_stub_20
+ .quad isr_stub_21
+ .quad isr_stub_22
+ .quad isr_stub_23
+ .quad isr_stub_24
+ .quad isr_stub_25
+ .quad isr_stub_26
+ .quad isr_stub_27
+ .quad isr_stub_28
+ .quad isr_stub_29
+ .quad isr_stub_30
+ .quad isr_stub_31
+ .quad isr_stub_32
+ .quad isr_stub_33
+ .quad isr_stub_34
+ .quad isr_stub_35
+ .quad isr_stub_36
+ .quad isr_stub_37
+ .quad isr_stub_38
+ .quad isr_stub_39
+ .quad isr_stub_40
+ .quad isr_stub_41
+ .quad isr_stub_42
+ .quad isr_stub_43
+ .quad isr_stub_44
+ .quad isr_stub_45
+ .quad isr_stub_46
+ .quad isr_stub_47
+ .quad isr_stub_48
+ .quad isr_stub_49
+ .quad isr_stub_50
+ .quad isr_stub_51
+ .quad isr_stub_52
+ .quad isr_stub_53
+ .quad isr_stub_54
+ .quad isr_stub_55
+ .quad isr_stub_56
+ .quad isr_stub_57
+ .quad isr_stub_58
+ .quad isr_stub_59
+ .quad isr_stub_60
+ .quad isr_stub_61
+ .quad isr_stub_62
+ .quad isr_stub_63
+ .quad isr_stub_64
+ .quad isr_stub_65
+ .quad isr_stub_66
+ .quad isr_stub_67
+ .quad isr_stub_68
+ .quad isr_stub_69
+ .quad isr_stub_70
+ .quad isr_stub_71
+ .quad isr_stub_72
+ .quad isr_stub_73
+ .quad isr_stub_74
+ .quad isr_stub_75
+ .quad isr_stub_76
+ .quad isr_stub_77
+ .quad isr_stub_78
+ .quad isr_stub_79
+ .quad isr_stub_80
+ .quad isr_stub_81
+ .quad isr_stub_82
+ .quad isr_stub_83
+ .quad isr_stub_84
+ .quad isr_stub_85
+ .quad isr_stub_86
+ .quad isr_stub_87
+ .quad isr_stub_88
+ .quad isr_stub_89
+ .quad isr_stub_90
+ .quad isr_stub_91
+ .quad isr_stub_92
+ .quad isr_stub_93
+ .quad isr_stub_94
+ .quad isr_stub_95
+ .quad isr_stub_96
+ .quad isr_stub_97
+ .quad isr_stub_98
+ .quad isr_stub_99
+ .quad isr_stub_100
+ .quad isr_stub_101
+ .quad isr_stub_102
+ .quad isr_stub_103
+ .quad isr_stub_104
+ .quad isr_stub_105
+ .quad isr_stub_106
+ .quad isr_stub_107
+ .quad isr_stub_108
+ .quad isr_stub_109
+ .quad isr_stub_110
+ .quad isr_stub_111
+ .quad isr_stub_112
+ .quad isr_stub_113
+ .quad isr_stub_114
+ .quad isr_stub_115
+ .quad isr_stub_116
+ .quad isr_stub_117
+ .quad isr_stub_118
+ .quad isr_stub_119
+ .quad isr_stub_120
+ .quad isr_stub_121
+ .quad isr_stub_122
+ .quad isr_stub_123
+ .quad isr_stub_124
+ .quad isr_stub_125
+ .quad isr_stub_126
+ .quad isr_stub_127
+ .quad isr_stub_128
+ .quad isr_stub_129
+ .quad isr_stub_130
+ .quad isr_stub_131
+ .quad isr_stub_132
+ .quad isr_stub_133
+ .quad isr_stub_134
+ .quad isr_stub_135
+ .quad isr_stub_136
+ .quad isr_stub_137
+ .quad isr_stub_138
+ .quad isr_stub_139
+ .quad isr_stub_140
+ .quad isr_stub_141
+ .quad isr_stub_142
+ .quad isr_stub_143
+ .quad isr_stub_144
+ .quad isr_stub_145
+ .quad isr_stub_146
+ .quad isr_stub_147
+ .quad isr_stub_148
+ .quad isr_stub_149
+ .quad isr_stub_150
+ .quad isr_stub_151
+ .quad isr_stub_152
+ .quad isr_stub_153
+ .quad isr_stub_154
+ .quad isr_stub_155
+ .quad isr_stub_156
+ .quad isr_stub_157
+ .quad isr_stub_158
+ .quad isr_stub_159
+ .quad isr_stub_160
+ .quad isr_stub_161
+ .quad isr_stub_162
+ .quad isr_stub_163
+ .quad isr_stub_164
+ .quad isr_stub_165
+ .quad isr_stub_166
+ .quad isr_stub_167
+ .quad isr_stub_168
+ .quad isr_stub_169
+ .quad isr_stub_170
+ .quad isr_stub_171
+ .quad isr_stub_172
+ .quad isr_stub_173
+ .quad isr_stub_174
+ .quad isr_stub_175
+ .quad isr_stub_176
+ .quad isr_stub_177
+ .quad isr_stub_178
+ .quad isr_stub_179
+ .quad isr_stub_180
+ .quad isr_stub_181
+ .quad isr_stub_182
+ .quad isr_stub_183
+ .quad isr_stub_184
+ .quad isr_stub_185
+ .quad isr_stub_186
+ .quad isr_stub_187
+ .quad isr_stub_188
+ .quad isr_stub_189
+ .quad isr_stub_190
+ .quad isr_stub_191
+ .quad isr_stub_192
+ .quad isr_stub_193
+ .quad isr_stub_194
+ .quad isr_stub_195
+ .quad isr_stub_196
+ .quad isr_stub_197
+ .quad isr_stub_198
+ .quad isr_stub_199
+ .quad isr_stub_200
+ .quad isr_stub_201
+ .quad isr_stub_202
+ .quad isr_stub_203
+ .quad isr_stub_204
+ .quad isr_stub_205
+ .quad isr_stub_206
+ .quad isr_stub_207
+ .quad isr_stub_208
+ .quad isr_stub_209
+ .quad isr_stub_210
+ .quad isr_stub_211
+ .quad isr_stub_212
+ .quad isr_stub_213
+ .quad isr_stub_214
+ .quad isr_stub_215
+ .quad isr_stub_216
+ .quad isr_stub_217
+ .quad isr_stub_218
+ .quad isr_stub_219
+ .quad isr_stub_220
+ .quad isr_stub_221
+ .quad isr_stub_222
+ .quad isr_stub_223
+ .quad isr_stub_224
+ .quad isr_stub_225
+ .quad isr_stub_226
+ .quad isr_stub_227
+ .quad isr_stub_228
+ .quad isr_stub_229
+ .quad isr_stub_230
+ .quad isr_stub_231
+ .quad isr_stub_232
+ .quad isr_stub_233
+ .quad isr_stub_234
+ .quad isr_stub_235
+ .quad isr_stub_236
+ .quad isr_stub_237
+ .quad isr_stub_238
+ .quad isr_stub_239
+ .quad isr_stub_240
+ .quad isr_stub_241
+ .quad isr_stub_242
+ .quad isr_stub_243
+ .quad isr_stub_244
+ .quad isr_stub_245
+ .quad isr_stub_246
+ .quad isr_stub_247
+ .quad isr_stub_248
+ .quad isr_stub_249
+ .quad isr_stub_250
+ .quad isr_stub_251
+ .quad isr_stub_252
+ .quad isr_stub_253
+ .quad isr_stub_254
+ .quad isr_stub_255
+
+# isr stubs
+ .section .text
+ .code64
+
+ISRException 0
+ISRException 1
+ISRException 2
+ISRException 3
+ISRException 4
+ISRException 5
+ISRException 6
+ISRException 7
+ISRExceptionCode 8
+ISRException 9
+ISRExceptionCode 10
+ISRExceptionCode 11
+ISRExceptionCode 12
+ISRExceptionCode 13
+ISRExceptionCode 14
+ISRException 15
+ISRException 16
+ISRExceptionCode 17
+ISRException 18
+ISRException 19
+ISRException 20
+ISRExceptionCode 21
+ISRException 22
+ISRException 23
+ISRException 24
+ISRException 25
+ISRException 26
+ISRException 27
+ISRException 28
+ISRExceptionCode 29
+ISRExceptionCode 30
+ISRException 31
+
+PICTimer 32 # 0
+PICKeyboard 33 # 1
+PICGeneric 34 # 2
+PICGeneric 35 # 3
+PICGeneric 36 # 4
+PICGeneric 37 # 5
+PICGeneric 38 # 6
+PICGeneric 39 # 7
+PICGeneric 40 # 8
+PICGeneric 41 # 9
+PICGeneric 42 # 10
+PICGeneric 43 # 11
+PICMouse 44 # 12
+PICGeneric 45 # 13
+PICGeneric 46 # 14
+PICGeneric 47 # 15
+
+ISRIgnore 48
+ISRIgnore 49
+ISRIgnore 50
+ISRIgnore 51
+ISRIgnore 52
+ISRIgnore 53
+ISRIgnore 54
+ISRIgnore 55
+ISRIgnore 56
+ISRIgnore 57
+ISRIgnore 58
+ISRIgnore 59
+ISRIgnore 60
+ISRIgnore 61
+ISRIgnore 62
+ISRIgnore 63
+ISRIgnore 64
+ISRIgnore 65
+ISRIgnore 66
+ISRIgnore 67
+ISRIgnore 68
+ISRIgnore 69
+ISRIgnore 70
+ISRIgnore 71
+ISRIgnore 72
+ISRIgnore 73
+ISRIgnore 74
+ISRIgnore 75
+ISRIgnore 76
+ISRIgnore 77
+ISRIgnore 78
+ISRIgnore 79
+ISRIgnore 80
+ISRIgnore 81
+ISRIgnore 82
+ISRIgnore 83
+ISRIgnore 84
+ISRIgnore 85
+ISRIgnore 86
+ISRIgnore 87
+ISRIgnore 88
+ISRIgnore 89
+ISRIgnore 90
+ISRIgnore 91
+ISRIgnore 92
+ISRIgnore 93
+ISRIgnore 94
+ISRIgnore 95
+ISRIgnore 96
+ISRIgnore 97
+ISRIgnore 98
+ISRIgnore 99
+ISRIgnore 100
+ISRIgnore 101
+ISRIgnore 102
+ISRIgnore 103
+ISRIgnore 104
+ISRIgnore 105
+ISRIgnore 106
+ISRIgnore 107
+ISRIgnore 108
+ISRIgnore 109
+ISRIgnore 110
+ISRIgnore 111
+ISRIgnore 112
+ISRIgnore 113
+ISRIgnore 114
+ISRIgnore 115
+ISRIgnore 116
+ISRIgnore 117
+ISRIgnore 118
+ISRIgnore 119
+ISRIgnore 120
+ISRIgnore 121
+ISRIgnore 122
+ISRIgnore 123
+ISRIgnore 124
+ISRIgnore 125
+ISRIgnore 126
+ISRIgnore 127
+ISRIgnore 128
+ISRIgnore 129
+ISRIgnore 130
+ISRIgnore 131
+ISRIgnore 132
+ISRIgnore 133
+ISRIgnore 134
+ISRIgnore 135
+ISRIgnore 136
+ISRIgnore 137
+ISRIgnore 138
+ISRIgnore 139
+ISRIgnore 140
+ISRIgnore 141
+ISRIgnore 142
+ISRIgnore 143
+ISRIgnore 144
+ISRIgnore 145
+ISRIgnore 146
+ISRIgnore 147
+ISRIgnore 148
+ISRIgnore 149
+ISRIgnore 150
+ISRIgnore 151
+ISRIgnore 152
+ISRIgnore 153
+ISRIgnore 154
+ISRIgnore 155
+ISRIgnore 156
+ISRIgnore 157
+ISRIgnore 158
+ISRIgnore 159
+ISRIgnore 160
+ISRIgnore 161
+ISRIgnore 162
+ISRIgnore 163
+ISRIgnore 164
+ISRIgnore 165
+ISRIgnore 166
+ISRIgnore 167
+ISRIgnore 168
+ISRIgnore 169
+ISRIgnore 170
+ISRIgnore 171
+ISRIgnore 172
+ISRIgnore 173
+ISRIgnore 174
+ISRIgnore 175
+ISRIgnore 176
+ISRIgnore 177
+ISRIgnore 178
+ISRIgnore 179
+ISRIgnore 180
+ISRIgnore 181
+ISRIgnore 182
+ISRIgnore 183
+ISRIgnore 184
+ISRIgnore 185
+ISRIgnore 186
+ISRIgnore 187
+ISRIgnore 188
+ISRIgnore 189
+ISRIgnore 190
+ISRIgnore 191
+ISRIgnore 192
+ISRIgnore 193
+ISRIgnore 194
+ISRIgnore 195
+ISRIgnore 196
+ISRIgnore 197
+ISRIgnore 198
+ISRIgnore 199
+ISRIgnore 200
+ISRIgnore 201
+ISRIgnore 202
+ISRIgnore 203
+ISRIgnore 204
+ISRIgnore 205
+ISRIgnore 206
+ISRIgnore 207
+ISRIgnore 208
+ISRIgnore 209
+ISRIgnore 210
+ISRIgnore 211
+ISRIgnore 212
+ISRIgnore 213
+ISRIgnore 214
+ISRIgnore 215
+ISRIgnore 216
+ISRIgnore 217
+ISRIgnore 218
+ISRIgnore 219
+ISRIgnore 220
+ISRIgnore 221
+ISRIgnore 222
+ISRIgnore 223
+ISRIgnore 224
+ISRIgnore 225
+ISRIgnore 226
+ISRIgnore 227
+ISRIgnore 228
+ISRIgnore 229
+ISRIgnore 230
+ISRIgnore 231
+ISRIgnore 232
+ISRIgnore 233
+ISRIgnore 234
+ISRIgnore 235
+ISRIgnore 236
+ISRIgnore 237
+ISRIgnore 238
+ISRIgnore 239
+ISRIgnore 240
+ISRIgnore 241
+ISRIgnore 242
+ISRIgnore 243
+ISRIgnore 244
+ISRIgnore 245
+ISRIgnore 246
+ISRIgnore 247
+ISRIgnore 248
+ISRIgnore 249
+ISRIgnore 250
+ISRIgnore 251
+ISRIgnore 252
+ISRIgnore 253
+ISRIgnore 254
+ISRIgnore 255
diff --git a/kernel/cpu/idt.c b/kernel/cpu/idt.c
new file mode 100644
index 0000000..af12fff
--- /dev/null
+++ b/kernel/cpu/idt.c
@@ -0,0 +1,204 @@
+#include "stdlib.h"
+#include <lib.h>
+#include <comus/memory.h>
+#include <comus/asm.h>
+
+#include "idt.h"
+#include "pic.h"
+
+#define IDT_SIZE 256
+
+struct idt_entry {
+ uint16_t isr_low; // low 16 bits of isr
+ uint16_t kernel_cs; // kernel segment selector
+ uint8_t ist; // interrupt stack table
+ uint8_t flags; // gate type, privilege level, present bit
+ uint16_t isr_mid; // middle 16 bits of isr
+ uint32_t isr_high; // high 32 bits of isr
+ uint32_t reserved;
+} __attribute__((packed));
+
+struct idtr {
+ uint16_t size;
+ uint64_t address;
+} __attribute__((packed));
+
+// interrupt gate
+#define GATE_64BIT_INT 0x0E
+// trap gate
+#define GATE_64BIT_TRAP 0x0F
+
+// privilege ring allowed to call interrupt
+#define RING0 0x00
+#define RING1 0x20
+#define RING2 0x40
+#define RING3 0x60
+
+// interrupt is present in IDT
+#define PRESENT 0x80
+
+__attribute__((aligned(0x10)))
+static struct idt_entry idt[256];
+
+static struct idtr idtr;
+// from idt.S
+extern void *isr_stub_table[];
+
+// initialize and load the IDT
+void idt_init(void) {
+ // initialize idtr
+ idtr.address = (uint64_t)&idt;
+ idtr.size = (uint16_t)sizeof(struct idt_entry) * IDT_SIZE - 1;
+
+ // initialize idt
+ for (size_t vector = 0; vector < IDT_SIZE; vector++) {
+ struct idt_entry *entry = &idt[vector];
+
+ uint64_t isr = (uint64_t)isr_stub_table[vector];
+ // interrupts before 0x20 are for cpu exceptions
+ uint8_t gate_type = (vector < 0x20) ? GATE_64BIT_TRAP : GATE_64BIT_INT;
+
+ entry->kernel_cs = 0x08; // offset of 1 into GDT
+ entry->ist = 0;
+ entry->flags = PRESENT | RING0 | gate_type;
+ entry->isr_low = isr & 0xffff;
+ entry->isr_mid = (isr >> 16) & 0xffff;
+ entry->isr_high = (isr >> 32) & 0xffffffff;
+ entry->reserved = 0;
+ }
+
+ __asm__ volatile ("lidt %0" : : "m"(idtr));
+}
+
+static void isr_print_regs(struct isr_regs *regs) {
+ printf("rax: %#016lx (%lu)\n", regs->rax, regs->rax);
+ printf("rbx: %#016lx (%lu)\n", regs->rbx, regs->rbx);
+ printf("rcx: %#016lx (%lu)\n", regs->rcx, regs->rcx);
+ printf("rdx: %#016lx (%lu)\n", regs->rdx, regs->rdx);
+ printf("rsi: %#016lx (%lu)\n", regs->rsi, regs->rsi);
+ printf("rdi: %#016lx (%lu)\n", regs->rdi, regs->rdi);
+ printf("rsp: %#016lx (%lu)\n", regs->rsp, regs->rsp);
+ printf("rbp: %#016lx (%lu)\n", regs->rbp, regs->rbp);
+ printf("r8 : %#016lx (%lu)\n", regs->r8 , regs->r8 );
+ printf("r9 : %#016lx (%lu)\n", regs->r9 , regs->r9 );
+ printf("r10: %#016lx (%lu)\n", regs->r10, regs->r10);
+ printf("r11: %#016lx (%lu)\n", regs->r11, regs->r11);
+ printf("r12: %#016lx (%lu)\n", regs->r12, regs->r12);
+ printf("r13: %#016lx (%lu)\n", regs->r13, regs->r13);
+ printf("r14: %#016lx (%lu)\n", regs->r14, regs->r14);
+ printf("r15: %#016lx (%lu)\n", regs->r15, regs->r15);
+ printf("rip: %#016lx (%lu)\n", regs->rip, regs->rip);
+ printf("rflags: %#016lx (%lu)\n", regs->rflags, regs->rflags);
+ struct rflags *rflags = (struct rflags *)regs->rflags;
+ puts("rflags: ");
+ if (rflags->cf) puts("CF ");
+ if (rflags->pf) puts("PF ");
+ if (rflags->af) puts("AF ");
+ if (rflags->zf) puts("ZF ");
+ if (rflags->sf) puts("SF ");
+ if (rflags->tf) puts("TF ");
+ if (rflags->if_) puts("IF ");
+ if (rflags->df) puts("DF ");
+ if (rflags->of) puts("OF ");
+ if (rflags->iopl) puts("IOPL ");
+ if (rflags->nt) puts("NT ");
+ if (rflags->md) puts("MD ");
+ if (rflags->rf) puts("RF ");
+ if (rflags->vm) puts("VM ");
+ if (rflags->ac) puts("AC ");
+ if (rflags->vif) puts("VIF ");
+ if (rflags->vip) puts("VIP ");
+ if (rflags->id) puts("ID ");
+ puts("\n");
+}
+
+#define EX_DEBUG 0x01
+#define EX_BREAKPOINT 0x03
+#define EX_PAGE_FAULT 0x0e
+
+// Intel manual vol 3 ch 6.3.1
+char *EXCEPTIONS[] = {
+ "Division Error",
+ "Debug",
+ "NMI",
+ "Breakpoint",
+ "Overflow",
+ "BOUND Range Exceeded",
+ "Invalid Opcode",
+ "Device Not Available",
+ "Double Fault",
+ "Coprocessor Segment Overrun",
+ "Invalid TSS",
+ "Segment Not Present",
+ "Stack-Segment Fault",
+ "General Protection Fault",
+ "Page Fault",
+ "Reserved",
+ "x87 Floating-Point Error",
+ "Alignment Check",
+ "Machine Check",
+ "SIMD Floaing-Point Exception",
+ "Virtualization Exception",
+ "Control Protection Exception",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Hypervisor Injection Exception",
+ "VMM Communication Exception",
+ "Security Exception",
+ "Reserved",
+};
+
+void idt_exception_handler(uint64_t exception, uint64_t code, struct isr_regs *state) {
+ uint64_t cr2;
+
+ switch (exception) {
+ case EX_PAGE_FAULT:
+ // page faults store the offending address in cr2
+ __asm__ volatile ("mov %%cr2, %0" : "=r"(cr2));
+ if (!load_page((void *)cr2))
+ return;
+ }
+
+ puts("\n\n!!! EXCEPTION !!!\n");
+ printf("%#02lX %s\n", exception, EXCEPTIONS[exception]);
+ printf("Error code %#lX\n", code);
+
+ if (exception == EX_PAGE_FAULT) {
+ printf("Page fault address: %#016lx\n", cr2);
+ }
+
+ puts("\n");
+
+ isr_print_regs(state);
+
+ puts("\n");
+
+ while (1) {
+ halt();
+ }
+}
+
+void idt_pic_eoi(uint8_t exception) {
+ pic_eoi(exception - PIC_REMAP_OFFSET);
+}
+
+int counter = 0;
+
+void idt_pic_timer(void) {
+ // print a message once we know the timer works
+ // but avoid spamming the logs
+ if (counter == 3) {
+ //kputs("pic timer!\n");
+ }
+ if (counter <= 3) {
+ counter++;
+ }
+}
+
+void idt_pic_keyboard(void) {}
+
+void idt_pic_mouse(void) {}
diff --git a/kernel/cpu/idt.h b/kernel/cpu/idt.h
new file mode 100644
index 0000000..46ef4a3
--- /dev/null
+++ b/kernel/cpu/idt.h
@@ -0,0 +1,68 @@
+/**
+ * @file idt.h
+ *
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * IDT functions
+ */
+
+#ifndef IDT_H_
+#define IDT_H_
+
+#include <stdint.h>
+
+struct isr_regs {
+ uint64_t r15;
+ uint64_t r14;
+ uint64_t r13;
+ uint64_t r12;
+ uint64_t r11;
+ uint64_t r10;
+ uint64_t r9;
+ uint64_t r8;
+ uint64_t rbp;
+ uint64_t rdi;
+ uint64_t rsi;
+ uint64_t rdx;
+ uint64_t rcx;
+ uint64_t rbx;
+ uint64_t rax;
+
+ uint64_t rip;
+ uint64_t cs;
+ uint64_t rflags;
+ uint64_t rsp;
+ uint64_t ss;
+};
+
+struct rflags {
+ uint64_t cf : 1,
+ : 1,
+ pf : 1,
+ : 1,
+ af : 1,
+ : 1,
+ zf : 1,
+ sf : 1,
+
+ tf : 1,
+ if_ : 1,
+ df : 1,
+ of : 1,
+ iopl : 2,
+ nt : 1,
+ md : 1,
+
+ rf : 1,
+ vm : 1,
+ ac : 1,
+ vif : 1,
+ vip : 1,
+ id : 1,
+ : 42;
+};
+
+void idt_init(void);
+
+#endif /* idt.h */
+
diff --git a/kernel/cpu/pic.c b/kernel/cpu/pic.c
new file mode 100644
index 0000000..7065a03
--- /dev/null
+++ b/kernel/cpu/pic.c
@@ -0,0 +1,90 @@
+#include <comus/asm.h>
+
+#include "pic.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 PIC_EOI 0x20 /* End-of-interrupt command code */
+
+#define ICW1_ICW4 0x01 /* Indicates that ICW4 will be present */
+#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) */
+
+void pic_remap(void) {
+ uint8_t a1, a2;
+
+ a1 = inb(PIC1_DATA); // save masks
+ a2 = inb(PIC2_DATA);
+
+ outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
+ io_wait();
+ outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
+ io_wait();
+ outb(PIC1_DATA, PIC_REMAP_OFFSET); // ICW2: Master PIC vector offset
+ io_wait();
+ outb(PIC2_DATA, PIC_REMAP_OFFSET + 8); // ICW2: Slave PIC vector offset
+ io_wait();
+ outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
+ io_wait();
+ outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
+ io_wait();
+
+ outb(PIC1_DATA, ICW4_8086); // ICW4: have the PICs use 8086 mode (and not 8080 mode)
+ io_wait();
+ outb(PIC2_DATA, ICW4_8086);
+ io_wait();
+
+ outb(PIC1_DATA, a1); // restore saved masks.
+ outb(PIC2_DATA, a2);
+}
+
+void pic_mask(int irq) {
+ uint16_t port;
+ uint8_t mask;
+ if (irq < 8) {
+ port = PIC1_DATA;
+ } else {
+ port = PIC2_DATA;
+ irq -= 8;
+ }
+ mask = inb(port) | (1 << irq);
+ outb(port, mask);
+}
+
+void pic_unmask(int irq) {
+ uint16_t port;
+ uint8_t mask;
+ if (irq < 8) {
+ port = PIC1_DATA;
+ } else {
+ irq -= 8;
+ port = PIC2_DATA;
+ }
+ mask = inb(port) & ~(1 << irq);
+ outb(port, mask);
+}
+
+void pic_disable(void) {
+ outb(PIC1_DATA, 0xff);
+ outb(PIC2_DATA, 0xff);
+}
+
+void pic_eoi(int irq) {
+ if (irq >= 8) {
+ outb(PIC2_COMMAND, PIC_EOI);
+ }
+ outb(PIC1_COMMAND, PIC_EOI);
+}
diff --git a/kernel/cpu/pic.h b/kernel/cpu/pic.h
new file mode 100644
index 0000000..0d1aa3a
--- /dev/null
+++ b/kernel/cpu/pic.h
@@ -0,0 +1,42 @@
+/**
+ * @file pic.h
+ *
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * PIC functions
+ */
+
+#ifndef PIC_H_
+#define PIC_H_
+
+#define PIC_REMAP_OFFSET 0x20
+
+/**
+ * Remaps the pie, i.e. initializes it
+ */
+void pic_remap(void);
+
+/**
+ * Masks an external irq to stop firing until un masked
+ * @param irq - the irq to mask
+ */
+void pic_mask(int irq);
+
+/**
+ * Unmasks an external irq to allow interrupts to continue for that irq
+ * @param irq - the irq to unmask
+ */
+void pic_unmask(int irq);
+
+/**
+ * Disabled the pick
+ */
+void pic_disable(void);
+
+/**
+ * Tells the pick that the interrupt has ended
+ * @param irq - the irq that has ended
+ */
+void pic_eoi(int irq);
+
+#endif /* pic.h */
diff --git a/kernel/include/comus/cpu.h b/kernel/include/comus/cpu.h
new file mode 100644
index 0000000..58fb33d
--- /dev/null
+++ b/kernel/include/comus/cpu.h
@@ -0,0 +1,17 @@
+/**
+ * @file cpu.h
+ *
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * CPU initalization functions
+ */
+
+#ifndef _CPU_H
+#define _CPU_H
+
+/**
+ * Initalize current cpu
+ */
+void cpu_init(void);
+
+#endif /* cpu.h */
diff --git a/kernel/io/io.c b/kernel/io/io.c
index a68114d..11acfdb 100644
--- a/kernel/io/io.c
+++ b/kernel/io/io.c
@@ -1,9 +1,16 @@
#include <lib.h>
#include <stdio.h>
+#include <comus/asm.h>
+
+#define PORT 0x3F8
+static void serial_out(uint8_t ch) {
+ // wait for output to be free
+ while ((inb(PORT + 5) & 0x20) == 0);
+ outb(PORT, ch);
+}
void fputc(FILE *stream, char c) {
(void) stream;
- (void) c;
- // FIXME: !!!
+ serial_out(c);
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index ac0546c..862425a 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -1,8 +1,12 @@
+#include <comus/cpu.h>
#include <comus/memory.h>
+#include <lib.h>
+#include <stdio.h>
void main(void)
{
-
- while (1)
- ;
+ cpu_init();
+ memory_init(NULL);
+ printf("halting...\n");
+ while(1);
}
diff --git a/kernel/kernel.ld b/kernel/kernel.ld
index 8ee6a5b..de5971e 100644
--- a/kernel/kernel.ld
+++ b/kernel/kernel.ld
@@ -6,8 +6,6 @@ SECTIONS
kernel_start = .;
- . = ALIGN(0x1000);
-
.boot : {
*(.multiboot)
}
@@ -20,12 +18,6 @@ SECTIONS
. = ALIGN(0x1000);
- .data : {
- *(.data .data.*)
- }
-
- . = ALIGN(0x1000);
-
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
}
diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c
index 045afc7..d10cf6d 100644
--- a/kernel/memory/paging.c
+++ b/kernel/memory/paging.c
@@ -573,7 +573,7 @@ void free_pages(void *virt)
unmap_pages(kernel_pml4, virt, pages);
}
-int kload_page(void *virt_addr)
+int load_page(void *virt_addr)
{
volatile struct pte *page = get_page(kernel_pml4, virt_addr);
if (page == NULL)
diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c
index a9f25af..2b64b72 100644
--- a/kernel/memory/virtalloc.c
+++ b/kernel/memory/virtalloc.c
@@ -103,7 +103,7 @@ void virtaddr_init(void)
.is_alloc = false,
.is_used = true,
};
- memset(bootstrap_nodes, 0, sizeof(bootstrap_nodes));
+ memsetv(bootstrap_nodes, 0, sizeof(bootstrap_nodes));
bootstrap_nodes[0] = init;
start_node = &bootstrap_nodes[0];
}