Working PIT irqs, fix GDT bugs
This commit is contained in:
@ -26,13 +26,16 @@ kernel_ldflags := -mcpu=i386 \
|
||||
-ffreestanding \
|
||||
-fno-builtin \
|
||||
-fuse-ld=lld \
|
||||
-flto \
|
||||
-static \
|
||||
-Wl,--build-id=none \
|
||||
-Wl,--gc-sections \
|
||||
-Wl,--strip-all \
|
||||
$(clang_res_dir)/lib/*/libclang_rt.builtins-i386.a
|
||||
|
||||
ifeq ($(build),debug)
|
||||
kernel_ldflags += -g
|
||||
endif
|
||||
|
||||
ifeq ($(build),release)
|
||||
kernel_ldflags += -Wl,--gc-sections \
|
||||
-Wl,--strip-all \
|
||||
-flto
|
||||
endif
|
||||
|
||||
@ -44,7 +44,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.section .bss
|
||||
.align 16
|
||||
__stack_bottom:
|
||||
.skip 16384
|
||||
.skip 8192
|
||||
__stack_top:
|
||||
|
||||
.section .boot, "ax"
|
||||
|
||||
@ -36,6 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <sys/multiboot.h>
|
||||
#include <sys/serialdbg.h>
|
||||
#include <sys/mm.h>
|
||||
#include <sys/pic.h>
|
||||
#include <sys/pit.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/bba.h>
|
||||
#include <mm/liballoc.h>
|
||||
@ -56,13 +58,22 @@ static void dump_multiboot_header(void) {
|
||||
static void mregmap_init1(void) {
|
||||
struct multiboot *mb = multiboot_get();
|
||||
|
||||
mregmap_init();
|
||||
|
||||
struct multiboot_mmap_entry *mmap;
|
||||
usize_t i = 0;
|
||||
for (mmap = (struct multiboot_mmap_entry *)(mb->mmap_addr + VIRT_BASE);
|
||||
(uptr_t)mmap < (mb->mmap_addr + VIRT_BASE + mb->mmap_length);
|
||||
mmap = (struct multiboot_mmap_entry *)((uptr_t)mmap + mmap->size + sizeof(mmap->size))) {
|
||||
dbgf("mmap entry: size=%08x, addr=%08x, len=%08x, type=%u\n",
|
||||
mmap->size, mmap->addr1, mmap->len1, mmap->type);
|
||||
|
||||
/* always skip the first memory map region, because we can't use it */
|
||||
if (i == 0) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
static int type_map[] = {
|
||||
[1] = MREG_AVAIL_RAM,
|
||||
[2] = MREG_I386_PC_RESERVED,
|
||||
@ -78,6 +89,7 @@ static void mregmap_init1(void) {
|
||||
};
|
||||
|
||||
mregmap_add_region(&mreg);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +101,7 @@ static void pmm_init1(void) {
|
||||
usize_t usable_ram_bytes = avail_ram->size;
|
||||
dbgf("usable ram = %08x\n", usable_ram_bytes);
|
||||
|
||||
uptr_t ram_start = ALIGN_UP((uptr_t)&__kernel_end - VIRT_BASE, 0x1000);
|
||||
uptr_t ram_start = ALIGN_UP((uptr_t)&__kernel_end + 0x1000 - VIRT_BASE, 0x1000);
|
||||
uptr_t ram_end = ALIGN_DOWN(0x100000 + usable_ram_bytes, 0x1000);
|
||||
|
||||
usize_t block_size = CFG_I386_PC_PMM_BLOCK_SIZE;
|
||||
@ -122,6 +134,9 @@ void bootmain(void *mbootptr) {
|
||||
pmm_init1();
|
||||
bba_init();
|
||||
mm_init();
|
||||
pit_init();
|
||||
pic_unmask();
|
||||
__asm__ volatile("sti");
|
||||
|
||||
char *string = malloc(12);
|
||||
memset(string, 0, 12);
|
||||
|
||||
@ -40,67 +40,61 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <sys/isr.h>
|
||||
#include <sys/pic.h>
|
||||
|
||||
#define KERNEL_INTR_STACK_SIZE 8192
|
||||
|
||||
static volatile struct gdt_entry gdt[6];
|
||||
static volatile struct gdt_ptr gdtptr;
|
||||
static volatile struct tss tss;
|
||||
static volatile struct idt_entry idt[0x100];
|
||||
static volatile struct idt_ptr idtptr;
|
||||
static volatile byte_t kernel_intr_stack[KERNEL_INTR_STACK_SIZE];
|
||||
|
||||
static struct { volatile uint32_t eflags; atomic_int nesting; } intr_state =
|
||||
{ .eflags = 0, .nesting = 0 };
|
||||
|
||||
static void gdt_make_entry(int index, uint32_t base, uint32_t limit,
|
||||
uint8_t access, uint8_t gran) {
|
||||
gdt[index].base_low = (base & 0xFFFF);
|
||||
gdt[index].base_mid = (base >> 16) & 0xFF;
|
||||
gdt[index].base_up = (base >> 24) & 0xFF;
|
||||
gdt[index].limit_low = (limit & 0xFFFF);
|
||||
gdt[index].gran = ((limit >> 16) & 0x0F);
|
||||
gdt[index].gran |= (gran & 0xF0);
|
||||
gdt[index].access = access;
|
||||
uint8_t type, uint8_t privl, uint8_t system) {
|
||||
gdt[index].limit_low = (uint16_t)limit;
|
||||
gdt[index].limit_up = (uint16_t)(limit >> 16);
|
||||
gdt[index].base_low = (uint16_t)base;
|
||||
gdt[index].base_mid = (uint8_t)(base >> 16);
|
||||
gdt[index].base_up = (uint8_t)(base >> 24);
|
||||
gdt[index].access = type | (system << 4) | (privl << 5) | (1<<7);
|
||||
gdt[index].limit_up |= (1<<7) | (1<<6);
|
||||
}
|
||||
|
||||
static void gdt_init(void) {
|
||||
gdtptr.limit = ELEM_SIZE(gdt) * LEN(gdt) - 1;
|
||||
gdtptr.limit = sizeof(gdt) - 1;
|
||||
gdtptr.base = (uint32_t)&gdt;
|
||||
gdt_make_entry(0, 0, 0, 0, 0);
|
||||
gdt_make_entry(1, 0, 0xFFFFF, 0x9A, 0xCF);
|
||||
gdt_make_entry(2, 0, 0xFFFFF, 0x92, 0xCF);
|
||||
gdt_make_entry(3, 0, 0xFFFFF, 0xFA, 0xCF);
|
||||
gdt_make_entry(4, 0, 0xFFFFF, 0xF2, 0xCF);
|
||||
gdt_make_entry(0, 0, 0, 0, 0, 0);
|
||||
gdt_make_entry(GDT_KCODE, 0, 0xFFFFF, GDT_CODESEG, GDT_KERNEL_PRIVL, GDT_MEMORY);
|
||||
gdt_make_entry(GDT_KDATA, 0, 0xFFFFF, GDT_DATASEG, GDT_KERNEL_PRIVL, GDT_MEMORY);
|
||||
gdt_make_entry(GDT_UCODE, 0, 0xFFFFF, GDT_CODESEG, GDT_USER_PRIVL, GDT_MEMORY);
|
||||
gdt_make_entry(GDT_UDATA, 0, 0xFFFFF, GDT_DATASEG, GDT_USER_PRIVL, GDT_MEMORY);
|
||||
gdt_make_entry(GDT_TSS, (uint32_t)&tss, TSS_SIZE, GDT_TSS_SEG, GDT_KERNEL_PRIVL, GDT_SYSTEM);
|
||||
|
||||
gdt_flush((ptr_t)&gdtptr);
|
||||
}
|
||||
|
||||
static void tss_init(void) {
|
||||
uint32_t base = (uint32_t)&tss;
|
||||
gdt_make_entry(5, base, base + sizeof(struct tss), 0xE9, 0);
|
||||
|
||||
memset((void *)&tss, 0, sizeof(tss));
|
||||
|
||||
uptr_t sp;
|
||||
__asm__ volatile("mov %%esp, %0" : "=r"(sp));
|
||||
|
||||
tss.ss0 = 0x10;
|
||||
tss.esp0 = (uint32_t)sp;
|
||||
tss.cs = 0x08 | 0x3;
|
||||
tss.ds = 0x10 | 0x3;
|
||||
tss.es = 0x10 | 0x3;
|
||||
tss.fs = 0x10 | 0x3;
|
||||
tss.fs = 0x10 | 0x3;
|
||||
tss.ss = 0x10 | 0x3;
|
||||
tss.iomap = sizeof(tss);
|
||||
tss.ldt_selector = 0;
|
||||
tss.prev_tss = GDT_TSS;
|
||||
tss.iomap_base = sizeof(struct tss);
|
||||
tss.esp_0 = (uint32_t)&kernel_intr_stack[KERNEL_INTR_STACK_SIZE - 1];
|
||||
tss.ss_0 = GDT_KERNEL_DS;
|
||||
|
||||
tss_flush();
|
||||
}
|
||||
|
||||
static void idt_make_entry(int index, uint32_t base, uint32_t sel, uint8_t flags) {
|
||||
static void idt_make_entry(int index, uint32_t base, uint32_t sel, uint8_t type, uint8_t access) {
|
||||
volatile struct idt_entry *ent = &idt[index];
|
||||
ent->base_low = (base & 0xFFFF);
|
||||
ent->base_up = ((base >> 16) & 0xFFFF);
|
||||
ent->base_low = (uint16_t)(base & 0xFFFF);
|
||||
ent->base_up = (uint16_t)((base >> 16) & 0xFFFF);
|
||||
ent->sel = (uint16_t)sel;
|
||||
ent->always0 = 0;
|
||||
ent->sel = sel;
|
||||
ent->flags = flags | 0x60;
|
||||
ent->flags = type | (access << 5) | (1<<7);
|
||||
}
|
||||
|
||||
void idt_init(void) {
|
||||
@ -108,55 +102,55 @@ void idt_init(void) {
|
||||
idtptr.base = (uint32_t)idt;
|
||||
idtptr.limit = sizeof(idt) - 1;
|
||||
|
||||
idt_make_entry(0, (uint32_t)&except0, 0x08, 0x8E);
|
||||
idt_make_entry(1, (uint32_t)&except1, 0x08, 0x8E);
|
||||
idt_make_entry(2, (uint32_t)&except2, 0x08, 0x8E);
|
||||
idt_make_entry(3, (uint32_t)&except3, 0x08, 0x8E);
|
||||
idt_make_entry(4, (uint32_t)&except4, 0x08, 0x8E);
|
||||
idt_make_entry(5, (uint32_t)&except5, 0x08, 0x8E);
|
||||
idt_make_entry(6, (uint32_t)&except6, 0x08, 0x8E);
|
||||
idt_make_entry(7, (uint32_t)&except7, 0x08, 0x8E);
|
||||
idt_make_entry(8, (uint32_t)&except8, 0x08, 0x8E);
|
||||
idt_make_entry(9, (uint32_t)&except9, 0x08, 0x8E);
|
||||
idt_make_entry(10, (uint32_t)&except10, 0x08, 0x8E);
|
||||
idt_make_entry(11, (uint32_t)&except11, 0x08, 0x8E);
|
||||
idt_make_entry(12, (uint32_t)&except12, 0x08, 0x8E);
|
||||
idt_make_entry(13, (uint32_t)&except13, 0x08, 0x8E);
|
||||
idt_make_entry(14, (uint32_t)&except14, 0x08, 0x8E);
|
||||
idt_make_entry(15, (uint32_t)&except15, 0x08, 0x8E);
|
||||
idt_make_entry(16, (uint32_t)&except16, 0x08, 0x8E);
|
||||
idt_make_entry(17, (uint32_t)&except17, 0x08, 0x8E);
|
||||
idt_make_entry(18, (uint32_t)&except18, 0x08, 0x8E);
|
||||
idt_make_entry(19, (uint32_t)&except19, 0x08, 0x8E);
|
||||
idt_make_entry(20, (uint32_t)&except20, 0x08, 0x8E);
|
||||
idt_make_entry(21, (uint32_t)&except21, 0x08, 0x8E);
|
||||
idt_make_entry(22, (uint32_t)&except22, 0x08, 0x8E);
|
||||
idt_make_entry(23, (uint32_t)&except23, 0x08, 0x8E);
|
||||
idt_make_entry(24, (uint32_t)&except24, 0x08, 0x8E);
|
||||
idt_make_entry(25, (uint32_t)&except25, 0x08, 0x8E);
|
||||
idt_make_entry(26, (uint32_t)&except26, 0x08, 0x8E);
|
||||
idt_make_entry(27, (uint32_t)&except27, 0x08, 0x8E);
|
||||
idt_make_entry(28, (uint32_t)&except28, 0x08, 0x8E);
|
||||
idt_make_entry(29, (uint32_t)&except29, 0x08, 0x8E);
|
||||
idt_make_entry(30, (uint32_t)&except30, 0x08, 0x8E);
|
||||
idt_make_entry(31, (uint32_t)&except31, 0x08, 0x8E);
|
||||
idt_make_entry(32, (uint32_t)&irq0, 0x08, 0x8E);
|
||||
idt_make_entry(33, (uint32_t)&irq1, 0x08, 0x8E);
|
||||
idt_make_entry(34, (uint32_t)&irq2, 0x08, 0x8E);
|
||||
idt_make_entry(35, (uint32_t)&irq3, 0x08, 0x8E);
|
||||
idt_make_entry(36, (uint32_t)&irq4, 0x08, 0x8E);
|
||||
idt_make_entry(37, (uint32_t)&irq5, 0x08, 0x8E);
|
||||
idt_make_entry(38, (uint32_t)&irq6, 0x08, 0x8E);
|
||||
idt_make_entry(39, (uint32_t)&irq7, 0x08, 0x8E);
|
||||
idt_make_entry(40, (uint32_t)&irq8, 0x08, 0x8E);
|
||||
idt_make_entry(41, (uint32_t)&irq9, 0x08, 0x8E);
|
||||
idt_make_entry(42, (uint32_t)&irq10, 0x08, 0x8E);
|
||||
idt_make_entry(43, (uint32_t)&irq11, 0x08, 0x8E);
|
||||
idt_make_entry(44, (uint32_t)&irq12, 0x08, 0x8E);
|
||||
idt_make_entry(45, (uint32_t)&irq13, 0x08, 0x8E);
|
||||
idt_make_entry(46, (uint32_t)&irq14, 0x08, 0x8E);
|
||||
idt_make_entry(47, (uint32_t)&irq15, 0x08, 0x8E);
|
||||
idt_make_entry(128, (uint32_t)&except128, 0x08, 0xEE);
|
||||
idt_make_entry(0, (uint32_t)&except0, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(1, (uint32_t)&except1, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(2, (uint32_t)&except2, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(3, (uint32_t)&except3, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(4, (uint32_t)&except4, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(5, (uint32_t)&except5, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(6, (uint32_t)&except6, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(7, (uint32_t)&except7, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(8, (uint32_t)&except8, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(9, (uint32_t)&except9, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(10, (uint32_t)&except10, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(11, (uint32_t)&except11, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(12, (uint32_t)&except12, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(13, (uint32_t)&except13, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(14, (uint32_t)&except14, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(15, (uint32_t)&except15, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(16, (uint32_t)&except16, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(17, (uint32_t)&except17, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(18, (uint32_t)&except18, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(19, (uint32_t)&except19, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(20, (uint32_t)&except20, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(21, (uint32_t)&except21, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(22, (uint32_t)&except22, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(23, (uint32_t)&except23, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(24, (uint32_t)&except24, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(25, (uint32_t)&except25, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(26, (uint32_t)&except26, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(27, (uint32_t)&except27, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(28, (uint32_t)&except28, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(29, (uint32_t)&except29, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(30, (uint32_t)&except30, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(31, (uint32_t)&except31, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(32, (uint32_t)&irq0, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(33, (uint32_t)&irq1, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(34, (uint32_t)&irq2, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(35, (uint32_t)&irq3, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(36, (uint32_t)&irq4, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(37, (uint32_t)&irq5, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(38, (uint32_t)&irq6, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(39, (uint32_t)&irq7, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(40, (uint32_t)&irq8, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(41, (uint32_t)&irq9, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(42, (uint32_t)&irq10, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(43, (uint32_t)&irq11, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(44, (uint32_t)&irq12, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(45, (uint32_t)&irq13, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(46, (uint32_t)&irq14, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(47, (uint32_t)&irq15, GDT_KERNEL_CS, 0x0E, 0);
|
||||
idt_make_entry(128, (uint32_t)&except128, GDT_KERNEL_CS, 0x0E, 3);
|
||||
|
||||
idt_flush((ptr_t)&idtptr);
|
||||
}
|
||||
@ -164,8 +158,8 @@ void idt_init(void) {
|
||||
void cpu_init(void) {
|
||||
gdt_init();
|
||||
tss_init();
|
||||
pic_init();
|
||||
idt_init();
|
||||
pic_init();
|
||||
}
|
||||
|
||||
static uint32_t intr_save1(void) {
|
||||
|
||||
@ -35,12 +35,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <libk/types.h>
|
||||
#include <libk/compiler.h>
|
||||
|
||||
#define GDT_MEMORY 1
|
||||
#define GDT_SYSTEM 0
|
||||
|
||||
#define GDT_KERNEL_PRIVL 0
|
||||
#define GDT_USER_PRIVL 3
|
||||
|
||||
#define GDT_KCODE 1
|
||||
#define GDT_KDATA 2
|
||||
#define GDT_UCODE 3
|
||||
#define GDT_UDATA 4
|
||||
#define GDT_TSS 5
|
||||
|
||||
#define GDT_KERNEL_CS (GDT_KCODE << 3)
|
||||
#define GDT_KERNEL_DS (GDT_KDATA << 3)
|
||||
#define GDT_USER_CS (GDT_UCODE << 3)
|
||||
#define GDT_USER_DS (GDT_UDATA << 3)
|
||||
|
||||
#define GDT_CODESEG 0x0A
|
||||
#define GDT_DATASEG 0x02
|
||||
#define GDT_TSS_SEG 0x09
|
||||
|
||||
#define TSS_SIZE 103
|
||||
|
||||
struct gdt_entry {
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_mid;
|
||||
uint8_t access;
|
||||
uint8_t gran;
|
||||
uint8_t limit_up;
|
||||
uint8_t base_up;
|
||||
} packed;
|
||||
|
||||
@ -50,16 +73,43 @@ struct gdt_ptr {
|
||||
} packed;
|
||||
|
||||
struct tss {
|
||||
uint32_t link;
|
||||
uint32_t esp0, ss0;
|
||||
uint32_t esp1, ss1;
|
||||
uint32_t esp2, ss2;
|
||||
uint32_t cr3;
|
||||
uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
|
||||
uint32_t es, cs, ss, ds, fs, gs;
|
||||
uint32_t ldt;
|
||||
uint16_t trap;
|
||||
uint16_t iomap;
|
||||
uint32_t prev_tss;
|
||||
uint32_t esp_0;
|
||||
uint16_t ss_0;
|
||||
uint16_t pad0;
|
||||
uint32_t esp_1;
|
||||
uint16_t ss_1;
|
||||
uint16_t pad1;
|
||||
uint32_t esp_2;
|
||||
uint16_t ss_2;
|
||||
uint16_t pad2;
|
||||
uint32_t reserved;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint16_t es;
|
||||
uint16_t pad3;
|
||||
uint16_t cs;
|
||||
uint16_t pad4;
|
||||
uint16_t ss;
|
||||
uint16_t pad5;
|
||||
uint16_t ds;
|
||||
uint16_t pad6;
|
||||
uint16_t fs;
|
||||
uint16_t pad7;
|
||||
uint16_t gs;
|
||||
uint16_t pad8;
|
||||
uint16_t ldt_selector;
|
||||
uint16_t pad9;
|
||||
uint16_t debug_trap;
|
||||
uint16_t iomap_base;
|
||||
} packed;
|
||||
|
||||
struct idt_entry {
|
||||
@ -76,12 +126,22 @@ struct idt_ptr {
|
||||
} packed;
|
||||
|
||||
struct trapframe {
|
||||
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
|
||||
uint32_t ds;
|
||||
uint32_t cr3;
|
||||
uint32_t trapno;
|
||||
uint32_t edi;
|
||||
uint32_t esi;
|
||||
uint32_t ebp;
|
||||
uint32_t esp;
|
||||
uint32_t ebx;
|
||||
uint32_t edx;
|
||||
uint32_t ecx;
|
||||
uint32_t eax;
|
||||
uint32_t ec;
|
||||
uint32_t eip, cs, eflags, uesp, uss;
|
||||
uint32_t trapno;
|
||||
uint32_t eip;
|
||||
uint32_t cs;
|
||||
uint32_t eflags;
|
||||
uint32_t uesp;
|
||||
uint32_t uss;
|
||||
} packed;
|
||||
|
||||
void cpu_init(void);
|
||||
|
||||
@ -35,5 +35,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
idt_flush:
|
||||
mov 4(%esp), %eax
|
||||
lidt (%eax)
|
||||
sti
|
||||
ret
|
||||
|
||||
@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.extern irq_fini
|
||||
|
||||
.section .text
|
||||
|
||||
#define EXCEPT_NOERR(exc) \
|
||||
.global except ## exc; \
|
||||
.type except ## exc, @function; \
|
||||
@ -86,10 +85,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
EXCEPT_NOERR(128)
|
||||
|
||||
temp_except_hndlr:
|
||||
pushal /* push eax, ecx, edx, ebx, esp, ebp, esi, edi (8*4) */
|
||||
pushal
|
||||
xorl %eax, %eax
|
||||
mov %ds, %ax
|
||||
push %eax /* save ds (4) */
|
||||
push %eax
|
||||
|
||||
/* load kernel DS */
|
||||
mov $0x10, %ax
|
||||
@ -98,12 +97,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
|
||||
mov %cr3, %ecx
|
||||
push %ecx
|
||||
|
||||
/* save frame (4) */
|
||||
push %esp
|
||||
|
||||
call except_fini
|
||||
|
||||
add $0x04, %esp
|
||||
|
||||
/* restore DS */
|
||||
@ -117,7 +114,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
popal
|
||||
add $0x8, %esp
|
||||
|
||||
sti
|
||||
iret
|
||||
|
||||
#define IRQ(irq1) \
|
||||
@ -147,10 +143,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
IRQ(15)
|
||||
|
||||
temp_irq_hndlr:
|
||||
pushal /* push eax, ecx, edx, ebx, esp, ebp, esi, edi (8*4) */
|
||||
pushal
|
||||
xorl %eax, %eax
|
||||
mov %ds, %ax
|
||||
push %eax /* save ds (4) */
|
||||
push %eax
|
||||
|
||||
/* load kernel DS */
|
||||
mov $0x10, %ax
|
||||
@ -159,12 +155,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
|
||||
mov %cr3, %ecx
|
||||
push %ecx
|
||||
|
||||
/* save frame (4) */
|
||||
push %esp
|
||||
|
||||
call irq_fini
|
||||
|
||||
add $0x04, %esp
|
||||
|
||||
/* restore DS */
|
||||
@ -178,5 +172,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
popal
|
||||
add $0x8, %esp
|
||||
|
||||
sti
|
||||
iret
|
||||
|
||||
@ -83,4 +83,20 @@ void irq13(void);
|
||||
void irq14(void);
|
||||
void irq15(void);
|
||||
|
||||
#define ISR_PIT 32+0
|
||||
#define ISR_KBD 32+1
|
||||
#define ISR_COM2 32+3
|
||||
#define ISR_COM1 32+4
|
||||
#define ISR_LPT2 32+5
|
||||
#define ISR_FLOPPY 32+6
|
||||
#define ISR_LPT1 32+7
|
||||
#define ISR_CMOS_RTC 32+8
|
||||
#define ISR_FREE9 32+9
|
||||
#define ISR_FREE10 32+10
|
||||
#define ISR_FREE11 32+11
|
||||
#define ISR_PS2_MOUSE 32+12
|
||||
#define ISR_FPU 32+13
|
||||
#define ISR_PRIM_ATA 32+14
|
||||
#define ISR_SCND_ATA 32+15
|
||||
|
||||
#endif // _SYS_ISR_H
|
||||
|
||||
@ -33,22 +33,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/serialdbg.h>
|
||||
#include <sys/halt.h>
|
||||
#include <sys/pit.h>
|
||||
#include <sys/isr.h>
|
||||
#include <sys/pic.h>
|
||||
#include <config.h>
|
||||
|
||||
void except_fini(struct trapframe *tf) {
|
||||
dbgf("EXCEPTION %u\n", tf->trapno);
|
||||
/* dbgf("trapframe:\n"); */
|
||||
/* dbgf("ds =%08x, edi=%08x, esi=%08x, ebp=%08x\n", */
|
||||
/* tf->ds, tf->edi, tf->esi, tf->ebp); */
|
||||
/* dbgf("esp=%08x, ebx=%08x, edx=%08x, ecx=%08x\n", */
|
||||
/* tf->esp, tf->ebx, tf->edx, tf->ecx); */
|
||||
/* dbgf("trp=%08x, erc=%08x, eip=%08x, cs =%08x\n", */
|
||||
/* tf->trapno, tf->ec, tf->eip, tf->cs); */
|
||||
/* dbgf("efl=%08x, usp=%08x, uss=%08x, cr3=%08x\n", */
|
||||
/* tf->eflags, tf->uesp, tf->uss, tf->cr3); */
|
||||
dbgf("trapframe:\n");
|
||||
dbgf("ds =%08x, edi=%08x, esi=%08x, ebp=%08x\n",
|
||||
tf->ds, tf->edi, tf->esi, tf->ebp);
|
||||
dbgf("esp=%08x, ebx=%08x, edx=%08x, ecx=%08x\n",
|
||||
tf->esp, tf->ebx, tf->edx, tf->ecx);
|
||||
dbgf("trp=%08x, erc=%08x, eip=%08x, cs =%08x\n",
|
||||
tf->trapno, tf->ec, tf->eip, tf->cs);
|
||||
dbgf("efl=%08x, usp=%08x, uss=%08x\n",
|
||||
tf->eflags, tf->uesp, tf->uss);
|
||||
halt();
|
||||
}
|
||||
|
||||
void irq_fini(struct trapframe *tf) {
|
||||
dbgf("IRQ %u\n", tf->trapno);
|
||||
if (tf->trapno == ISR_PIT) {
|
||||
ticks_increment();
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
pic_fini(tf->trapno);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6,7 +6,8 @@ c_files += $(dir_sys)/cpu.c \
|
||||
$(dir_sys)/ioport.c \
|
||||
$(dir_sys)/isr1.c \
|
||||
$(dir_sys)/pic.c \
|
||||
$(dir_sys)/mm.c
|
||||
$(dir_sys)/mm.c \
|
||||
$(dir_sys)/pit.c
|
||||
|
||||
S_files += $(dir_sys)/gdt_flush.S \
|
||||
$(dir_sys)/tss_flush.S \
|
||||
@ -25,4 +26,5 @@ o_files += $(dir_sys)/cpu.o \
|
||||
$(dir_sys)/isr1.o \
|
||||
$(dir_sys)/halt.o \
|
||||
$(dir_sys)/pic.o \
|
||||
$(dir_sys)/mm.o
|
||||
$(dir_sys)/mm.o \
|
||||
$(dir_sys)/pit.o
|
||||
|
||||
@ -29,8 +29,10 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libk/types.h>
|
||||
#include <sys/pic.h>
|
||||
#include <sys/ioport.h>
|
||||
#include <sys/isr.h>
|
||||
|
||||
#define PIC1 0x20
|
||||
#define PIC2 0xA0
|
||||
@ -38,6 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define PIC1_DATA (PIC1 + 1)
|
||||
#define PIC2_CMD PIC2
|
||||
#define PIC2_DATA (PIC2 + 1)
|
||||
#define PIC_EOI 0x20
|
||||
|
||||
#define ICW1_ICW4 0x01
|
||||
#define ICW1_SINGLE 0x02
|
||||
@ -62,10 +65,10 @@ void pic_init(void) {
|
||||
ioport_out8(PIC2_CMD, ICW1_INIT | ICW1_ICW4);
|
||||
ioport_wait();
|
||||
|
||||
ioport_out8(PIC1_DATA, 4);
|
||||
ioport_out8(PIC1_DATA, 0x20);
|
||||
ioport_wait();
|
||||
|
||||
ioport_out8(PIC2_DATA, 2);
|
||||
ioport_out8(PIC2_DATA, 0x28);
|
||||
ioport_wait();
|
||||
|
||||
ioport_out8(PIC1_DATA, 1<<CASCADE_IRQ);
|
||||
@ -79,6 +82,28 @@ void pic_init(void) {
|
||||
ioport_out8(PIC2_DATA, ICW4_8086);
|
||||
ioport_wait();
|
||||
|
||||
ioport_out8(PIC1_DATA, 0xFF);
|
||||
ioport_out8(PIC2_DATA, 0xFF);
|
||||
pic_mask();
|
||||
}
|
||||
|
||||
void pic_mask(void) {
|
||||
ioport_out8(PIC1_DATA, 0xFF);
|
||||
ioport_wait();
|
||||
ioport_out8(PIC2_DATA, 0xFF);
|
||||
ioport_wait();
|
||||
}
|
||||
|
||||
void pic_unmask(void) {
|
||||
ioport_out8(PIC1_DATA, 0);
|
||||
ioport_wait();
|
||||
ioport_out8(PIC2_DATA, 0);
|
||||
ioport_wait();
|
||||
}
|
||||
|
||||
void pic_fini(uint8_t trap) {
|
||||
if (trap >= 40) {
|
||||
ioport_out8(PIC2_CMD, PIC_EOI);
|
||||
ioport_wait();
|
||||
}
|
||||
ioport_out8(PIC1_CMD, PIC_EOI);
|
||||
ioport_wait();
|
||||
}
|
||||
|
||||
@ -32,6 +32,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef _SYS_PIC_H
|
||||
#define _SYS_PIC_H
|
||||
|
||||
#include <libk/types.h>
|
||||
|
||||
void pic_init(void);
|
||||
void pic_mask(void);
|
||||
void pic_unmask(void);
|
||||
void pic_fini(uint8_t trap);
|
||||
|
||||
#endif // _SYS_PIC_H
|
||||
|
||||
82
kernel/platform/i386_pc/sys/pit.c
Normal file
82
kernel/platform/i386_pc/sys/pit.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright 2025 Kamil Kowalczyk
|
||||
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
“AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libk/types.h>
|
||||
#include <sys/pit.h>
|
||||
#include <sys/ioport.h>
|
||||
#include <sync/spinlock.h>
|
||||
|
||||
#define PIT_COUNTER0 0x40
|
||||
#define PIT_CMD 0x43
|
||||
#define PIT_CMD_BINARY 0x00
|
||||
#define PIT_CMD_BCD 0x01
|
||||
#define PIT_CMD_MODE0 0x00
|
||||
#define PIT_CMD_MODE1 0x02
|
||||
#define PIT_CMD_MODE2 0x04
|
||||
#define PIT_CMD_MODE3 0x06
|
||||
#define PIT_CMD_MODE4 0x08
|
||||
#define PIT_CMD_MODE5 0x0A
|
||||
#define PIT_CMD_LATCH 0x00
|
||||
#define PIT_CMD_RW_LOW 0x10
|
||||
#define PIT_CMD_RW_HI 0x20
|
||||
#define PIT_CMD_RW_BOTH 0x30
|
||||
#define PIT_CMD_COUNTER0 0x00
|
||||
#define PIT_CMD_COUNTER1 0x40
|
||||
#define PIT_CMD_COUNTER2 0x80
|
||||
#define PIT_CMD_READBACK 0xC0
|
||||
|
||||
#define PIT_FREQ 1193182
|
||||
|
||||
static uint32_t ticks = 0;
|
||||
static struct spinlock ticks_spinlock;
|
||||
|
||||
uint32_t ticks_get(void) {
|
||||
sl_lock(&ticks_spinlock);
|
||||
uint32_t t = ticks;
|
||||
sl_unlock(&ticks_spinlock);
|
||||
return t;
|
||||
}
|
||||
|
||||
void ticks_increment(void) {
|
||||
sl_lock(&ticks_spinlock);
|
||||
ticks++;
|
||||
sl_unlock(&ticks_spinlock);
|
||||
}
|
||||
|
||||
void pit_init(void) {
|
||||
sl_init(&ticks_spinlock, "ticks");
|
||||
|
||||
uint32_t hz = 1000;
|
||||
uint32_t div = PIT_FREQ / hz;
|
||||
ioport_out8(PIT_CMD, PIT_CMD_BINARY | PIT_CMD_MODE3 | PIT_CMD_RW_BOTH | PIT_CMD_COUNTER0);
|
||||
ioport_out8(PIT_COUNTER0, div & 0xFF);
|
||||
ioport_out8(PIT_COUNTER0, div >> 8);
|
||||
}
|
||||
39
kernel/platform/i386_pc/sys/pit.h
Normal file
39
kernel/platform/i386_pc/sys/pit.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2025 Kamil Kowalczyk
|
||||
|
||||
Redistribution and use in source and binary forms, with or
|
||||
without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
“AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_PIT_H
|
||||
#define _SYS_PIT_H
|
||||
|
||||
void pit_init(void);
|
||||
uint32_t ticks_get(void);
|
||||
void ticks_increment(void);
|
||||
|
||||
#endif // _SYS_PIT_H
|
||||
@ -1,5 +1,5 @@
|
||||
# machine
|
||||
megs: 128
|
||||
megs: 64
|
||||
cpu: model=pentium
|
||||
# roms
|
||||
romimage: file=/usr/share/bochs/BIOS-bochs-latest, options=fastboot
|
||||
|
||||
@ -8,7 +8,7 @@ boot ?= iso
|
||||
|
||||
qemu_extra ?=
|
||||
|
||||
qemu_opts := -M pc -cpu pentium \
|
||||
qemu_opts := -M pc -cpu pentium -m 64M \
|
||||
-serial mon:stdio \
|
||||
$(QEMU_EXTRA)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user