add 64-bit idt/pic and fix paging

This commit is contained in:
Murphy 2025-04-03 21:32:00 -04:00
parent af6dce3665
commit 16b7b4c2c0
Signed by: freya
GPG key ID: 9FBC6FFD6D2DBF17
15 changed files with 1147 additions and 16 deletions

View file

@ -24,7 +24,12 @@ const boot_src = &[_][]const u8{"boot/boot.S"};
const kernel_src = &[_][]const u8{ const kernel_src = &[_][]const u8{
"kernel/entry.S", // must be first "kernel/entry.S", // must be first
"kernel/kernel.c", "kernel/kernel.c", // main function
"kernel/cpu/cpu.c",
"kernel/cpu/fpu.c",
"kernel/cpu/idt.c",
"kernel/cpu/idt.S",
"kernel/cpu/pic.c",
"kernel/io/io.c", "kernel/io/io.c",
"kernel/io/panic.c", "kernel/io/panic.c",
"kernel/memory/memory.c", "kernel/memory/memory.c",

10
kernel/cpu/cpu.c Normal file
View file

@ -0,0 +1,10 @@
#include "fpu.h"
#include "pic.h"
#include "idt.h"
void cpu_init(void) {
pic_remap();
idt_init();
fpu_init();
}

12
kernel/cpu/fpu.c Normal file
View file

@ -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));
}

14
kernel/cpu/fpu.h Normal file
View file

@ -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 */

666
kernel/cpu/idt.S Normal file
View file

@ -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

204
kernel/cpu/idt.c Normal file
View file

@ -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) {}

68
kernel/cpu/idt.h Normal file
View file

@ -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 */

90
kernel/cpu/pic.c Normal file
View file

@ -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);
}

42
kernel/cpu/pic.h Normal file
View file

@ -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 */

View file

@ -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 */

View file

@ -1,9 +1,16 @@
#include <lib.h> #include <lib.h>
#include <stdio.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 fputc(FILE *stream, char c) {
(void) stream; (void) stream;
(void) c;
// FIXME: !!! serial_out(c);
} }

View file

@ -1,8 +1,12 @@
#include <comus/cpu.h>
#include <comus/memory.h> #include <comus/memory.h>
#include <lib.h>
#include <stdio.h>
void main(void) void main(void)
{ {
cpu_init();
while (1) memory_init(NULL);
; printf("halting...\n");
while(1);
} }

View file

@ -6,8 +6,6 @@ SECTIONS
kernel_start = .; kernel_start = .;
. = ALIGN(0x1000);
.boot : { .boot : {
*(.multiboot) *(.multiboot)
} }
@ -20,12 +18,6 @@ SECTIONS
. = ALIGN(0x1000); . = ALIGN(0x1000);
.data : {
*(.data .data.*)
}
. = ALIGN(0x1000);
.text : { .text : {
*(.text .stub .text.* .gnu.linkonce.t.*) *(.text .stub .text.* .gnu.linkonce.t.*)
} }

View file

@ -573,7 +573,7 @@ void free_pages(void *virt)
unmap_pages(kernel_pml4, virt, pages); 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); volatile struct pte *page = get_page(kernel_pml4, virt_addr);
if (page == NULL) if (page == NULL)

View file

@ -103,7 +103,7 @@ void virtaddr_init(void)
.is_alloc = false, .is_alloc = false,
.is_used = true, .is_used = true,
}; };
memset(bootstrap_nodes, 0, sizeof(bootstrap_nodes)); memsetv(bootstrap_nodes, 0, sizeof(bootstrap_nodes));
bootstrap_nodes[0] = init; bootstrap_nodes[0] = init;
start_node = &bootstrap_nodes[0]; start_node = &bootstrap_nodes[0];
} }