os

Toy OS
git clone git://git.margiolis.net/os.git
Log | Files | Refs | README | LICENSE

commit 629d6ca6128374bf9f62bac126465881fcda180a
parent 30f15bfc930e222f54a829b81a0fe24d2256cd33
Author: Christos Margiolis <christos@margiolis.net>
Date:   Tue,  7 Dec 2021 00:38:05 +0200

simplify and improve idt

Diffstat:
Minclude/libc.h | 2+-
Mkern/idt.c | 227+++++++++++++++++++++++++++++++------------------------------------------------
Mkern/idt.h | 52+++++++++++++++++++++++++++++++++++++++++++---------
Mkern/io.h | 1-
Mkern/kbd.c | 4++--
Mkern/libk.c | 22+++++++++++-----------
6 files changed, 145 insertions(+), 163 deletions(-)

diff --git a/include/libc.h b/include/libc.h @@ -4,7 +4,7 @@ #define NULL ((void *)0) #define UNUSED(x) ((void)(x)) #define ARRLEN(x) (sizeof(x) / sizeof(*(x))) -#define __CONCAT(x, y) x ## y +#define CONCAT(x, y) x ## y #define offsetof(s, t) ((u_long)(&(((s *)0->t)))) #endif /* _LIBC_H_ */ diff --git a/kern/idt.c b/kern/idt.c @@ -1,37 +1,22 @@ +#include <libc.h> #include "libk.h" #include "idt.h" #include "io.h" -#define NINT 256 -#define NRSVINT 32 -#define PL_KERN 0 /* Kernel privilege level */ -#define PL_DRV1 1 /* Device driver privilege level 1 */ -#define PL_DRV2 2 /* Device driver privilege level 2 */ -#define PL_USER 3 /* User privilege level */ -#define SEL_KCODE 0x08 /* Kernel code descriptor */ -#define TP_386IGT 0xe /* System 386 interrupt gate */ -/* Type 0..3, DPL 4..6, P 7..8 */ -#define GT_FLAGS(r, t) ((1<<7) | (r<<5) | t) - -#define PIC_MASTER_CMD 0x20 -#define PIC_MASTER_DATA (PIC_MASTER_CMD + 1) -#define PIC_SLAVE_CMD 0xa0 -#define PIC_SLAVE_DATA (PIC_SLAVE_CMD + 1) - -static void idt_set_gate(struct gate_desc *, void *, u_int16_t, u_int8_t); +static void idt_set_gate(struct gate_desc *, void *, u_int, u_int, u_int); static void pic_remap(void); static struct gate_desc idt[NINT]; static intrhand_t isr[NINT] = { NULL }; static void -idt_set_gate(struct gate_desc *gd, void *func, u_int16_t sel, u_int8_t flags) +idt_set_gate(struct gate_desc *gd, void *func, u_int sel, u_int dpl, u_int type) { - gd->gd_off_lo = (u_int32_t)func & 0xffff; - gd->gd_sel = sel; - gd->gd_rsvd = 0; - gd->gd_flags = flags; - gd->gd_off_hi = ((u_int32_t)func >> 16) & 0xffff; + u_int32_t addr; + + addr = (u_int32_t)func; + gd->gd_hi = (addr & 0xffff0000) | SEGP | dpl | type; + gd->gd_lo = (sel << 16) | (addr & 0xffff); } /* TODO: explain. */ @@ -67,125 +52,88 @@ idt_init(void) int i; for (i = 0; i < NINT; i++) - idt_set_gate(&idt[i], &INTVEC(rsvd), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 0], &INTVEC(div), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 1], &INTVEC(dbg), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 2], &INTVEC(nmsk), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 3], &INTVEC(bpt), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 4], &INTVEC(ofl), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 5], &INTVEC(bnd), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 6], &INTVEC(ill), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 7], &INTVEC(dna), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 8], &INTVEC(dbl), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[ 9], &INTVEC(fpusegm), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[10], &INTVEC(tss), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[11], &INTVEC(missing), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[12], &INTVEC(stk), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[13], &INTVEC(prot), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[14], &INTVEC(page), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[15], &INTVEC(rsvd), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[16], &INTVEC(fpu), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[17], &INTVEC(align), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[18], &INTVEC(mchk), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[19], &INTVEC(simd), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); + idt_set_gate(&idt[i], &INTVEC(rsvd), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 0], &INTVEC(div), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 1], &INTVEC(dbg), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 2], &INTVEC(nmsk), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 3], &INTVEC(bpt), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 4], &INTVEC(ofl), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 5], &INTVEC(bnd), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 6], &INTVEC(ill), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 7], &INTVEC(dna), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 8], &INTVEC(dbl), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[ 9], &INTVEC(fpusegm), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[10], &INTVEC(tss), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[11], &INTVEC(missing), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[12], &INTVEC(stk), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[13], &INTVEC(prot), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[14], &INTVEC(page), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[15], &INTVEC(rsvd), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[16], &INTVEC(fpu), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[17], &INTVEC(align), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[18], &INTVEC(mchk), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[19], &INTVEC(simd), KCSEL, SEGPL(KPL), SEGIG); /* 20 - 31 are reserved. */ pic_remap(); - idt_set_gate(&idt[32], &INTVEC(irq0), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[33], &INTVEC(irq1), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[34], &INTVEC(irq2), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[35], &INTVEC(irq3), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[36], &INTVEC(irq4), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[37], &INTVEC(irq5), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[38], &INTVEC(irq6), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[39], &INTVEC(irq7), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[40], &INTVEC(irq8), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[41], &INTVEC(irq9), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[42], &INTVEC(irq10), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[43], &INTVEC(irq11), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[44], &INTVEC(irq12), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[45], &INTVEC(irq13), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[46], &INTVEC(irq14), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - idt_set_gate(&idt[47], &INTVEC(irq15), SEL_KCODE, - GT_FLAGS(PL_KERN, TP_386IGT)); - - /*idt_set_gate(&idt[127], &syscall, SEL_KCODE, GT_FLAGS(PL_KERN, TP_386IGT));*/ + idt_set_gate(&idt[32], &INTVEC(irq0), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[33], &INTVEC(irq1), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[34], &INTVEC(irq2), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[35], &INTVEC(irq3), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[36], &INTVEC(irq4), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[37], &INTVEC(irq5), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[38], &INTVEC(irq6), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[39], &INTVEC(irq7), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[40], &INTVEC(irq8), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[41], &INTVEC(irq9), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[42], &INTVEC(irq10), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[43], &INTVEC(irq11), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[44], &INTVEC(irq12), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[45], &INTVEC(irq13), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[46], &INTVEC(irq14), KCSEL, SEGPL(KPL), SEGIG); + idt_set_gate(&idt[47], &INTVEC(irq15), KCSEL, SEGPL(KPL), SEGIG); + + /*idt_set_gate(&idt[127], &syscall, KCSEL, SEGPL(UPL), SEGIG);*/ r_idt.rd_base = (u_int32_t)&idt; r_idt.rd_limit = NINT * sizeof(struct gate_desc) - 1; __asm__ __volatile("lidt (%0)" : : "r" (&r_idt)); } -static const char *exceptmsg[] = { - "Division By Zero Exception", - "Debug Exception", - "Non Maskable Interrupt Exception", - "Breakpoint Exception", - "Detected Overflow Exception", - "Out of Bounds Exception", - "Invalid Opcode Exception", - "No Coprocessor Exception", - "Double Fault Exception", - "Coprocessor Segment Overrun Exception", - "Bad TSS Exception", - "Segment Not Present Exception", - "Stack Fault Exception", - "General Protection Fault Exception", - "Page Fault Exception", - "Unknown Interrupt Exception", - "Coprocessor Fault Exception", - "Alignment Check Exception (486+)", - "Machine Check Exception (Pentium/586+)", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", - "Reserved Exception", +static const char *exceptmsg[32] = { + "division by zero", + "debug exception", + "non maskable interrupt", + "breakpoint", + "overflow", + "out of bounds", + "invalid opcode", + "no coprocessor", + "double fault", + "coprocessor segment overrun", + "bad tss", + "segment not present", + "stack fault", + "general protection fault", + "page fault", + "15 (reserved)", + "coprocessor fault", + "alignment check exception (486+)", + "machine check exception (pentium/586+)", + "simd error", + "20 (reserved)", + "21 (reserved)", + "22 (reserved)", + "23 (reserved)", + "24 (reserved)", + "25 (reserved)", + "26 (reserved)", + "27 (reserved)", + "28 (reserved)", + "29 (reserved)", + "30 (reserved)", + "31 (reserved)", }; void @@ -194,13 +142,14 @@ intr_handler(struct reg *r) intrhand_t handler; /* TODO: dprintf? */ - if (r->r_intrno < 32) - printf("%s\n", exceptmsg[r->r_intrno]); + /* XXX: why did i write this in the first place???? */ + if (r->r_intrno < ARRLEN(exceptmsg)) + printf("sys: trap: %s\n", exceptmsg[r->r_intrno]); if ((handler = isr[r->r_intrno]) != NULL) handler(r); - else if (r->r_intrno < 32) { - print_regs(r); - panic("%s: system halted...\n", exceptmsg[r->r_intrno]); + else if (r->r_intrno < ARRLEN(exceptmsg)) { + dump_regs(r); + panic("%s: system halted\n", exceptmsg[r->r_intrno]); } /* EOI */ if (r->r_intrno >= 40) @@ -214,9 +163,9 @@ intr_register_handler(u_int8_t intrno, intrhand_t handler) isr[intrno] = handler; } -/* FIXME: not 8? */ +/* FIXME: not #08? */ void -print_regs(struct reg *r) +dump_regs(struct reg *r) { printf("eax=%#08x\tebx=%#08x\tecx=%#08x\tedx=%#08x\n", r->r_eax, r->r_ebx, r->r_ecx, r->r_edx); diff --git a/kern/idt.h b/kern/idt.h @@ -4,19 +4,53 @@ #include <u.h> #include <reg.h> -#define INTVEC(name) __CONCAT(intr_, name) +#define INTVEC(name) CONCAT(intr_, name) + +#define NINT 256 /* number of interrupts */ + +/* gdt segments */ +#define NULLSEG 0 /* null segment */ +#define KCSEG 1 /* kernel code segment */ +#define KDSEG 2 /* kernel data segment */ +#define UCSEG 3 /* user code segment */ +#define UDSEG 4 /* kernel data segment */ +/* TODO: 9front mem.h */ + +#define SELGDT (0 << 2) /* selector is in gdt */ +#define SELLDT (1 << 2) /* selector is in ldt */ + +#define SEGIG (0x0e << 8) /* interrupt gate */ +#define SEGPL(x) ((x) << 13) /* priority level */ +#define SEGP (1 << 15) /* segment present */ + +#define KPL 0 /* kernel priority level */ +#define DPL1 1 /* device driver priority level 1 */ +#define DPL2 2 /* device driver priority level 2 */ +#define UPL 3 /* user priority level */ + +#define SELECTOR(i, t, p) (((i) << 3) | (t) | (p)) + +/* selectors */ +#define NULLSEL SELECTOR(NULLSEG, SELGDT, KPL) +#define KDSEL SELECTOR(KDSEG, SELGDT, KPL) +#define KCSEL SELECTOR(KCSEG, SELGDT, KPL) +#define UCSEL SELECTOR(UCSEG, SELGDT, UPL) +#define UDSEL SELECTOR(UDSEG, SELGDT, UPL) +/* TODO: 9front mem.h */ + +#define PIC_MASTER_CMD 0x20 +#define PIC_MASTER_DATA (PIC_MASTER_CMD + 1) +#define PIC_SLAVE_CMD 0xa0 +#define PIC_SLAVE_DATA (PIC_SLAVE_CMD + 1) struct gate_desc { - u_int16_t gd_off_lo; - u_int16_t gd_sel; - u_int8_t gd_rsvd; - u_int8_t gd_flags; /* type, dpl, p */ - u_int16_t gd_off_hi; + u_int32_t gd_lo; + u_int32_t gd_hi; } __packed; struct region_desc { - u_int16_t rd_limit; - u_int32_t rd_base; + u_int16_t rd_limit; + u_int32_t rd_base; } __packed; enum { @@ -43,6 +77,6 @@ typedef void (*intrhand_t)(struct reg *); void idt_init(void); void intr_handler(struct reg *); void intr_register_handler(u_int8_t, intrhand_t); -void print_regs(struct reg *); /* FIXME: move elsewhere? */ +void dump_regs(struct reg *); /* FIXME: move elsewhere? */ #endif /* _IDT_H_ */ diff --git a/kern/io.h b/kern/io.h @@ -2,7 +2,6 @@ #define _IO_H_ #include <u.h> -#include <reg.h> static inline u_int8_t inb(u_int16_t port) diff --git a/kern/kbd.c b/kern/kbd.c @@ -14,7 +14,7 @@ static void kbd_callback(struct reg *); -static unsigned char kbdus_upper[128] = { +static u_char kbdus_upper[128] = { 0, /* Error */ 27, /* Escape */ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', @@ -52,7 +52,7 @@ static unsigned char kbdus_upper[128] = { 0, /* The rest are undefined */ }; -static unsigned char kbdus_lower[128] = { +static u_char kbdus_lower[128] = { 0, /* Error */ 27, /* Escape */ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', diff --git a/kern/libk.c b/kern/libk.c @@ -29,8 +29,8 @@ div(long *n, int base) { int res; - res = (unsigned long)*n % (unsigned int)base; - *n = (unsigned long)*n / (unsigned int)base; + res = (u_long)*n % (u_int)base; + *n = (u_long)*n / (u_int)base; return (res); } @@ -106,7 +106,7 @@ itoa(char *str, long num, int base, int size, int precision, int flags) void * memset(void *dst, int v, size_t len) { - unsigned char *dst0; + u_char *dst0; dst0 = dst; while (len--) @@ -118,8 +118,8 @@ memset(void *dst, int v, size_t len) void * memcpy(void *dst, const void *src, size_t len) { - const unsigned char *src0; - unsigned char *dst0; + const u_char *src0; + u_char *dst0; src0 = src; dst0 = dst; @@ -183,7 +183,7 @@ strcmp(const char *s1, const char *s2) if (*s1++ == '\0') return (0); - return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); + return (*(const u_char *)s1 - *(const u_char *)(s2 - 1)); } int @@ -258,7 +258,7 @@ repeat: if (!(flags & LEFT)) while (--size > 0) *str++ = ' '; - *str++ = (unsigned char)va_arg(ap, int); + *str++ = (u_char)va_arg(ap, int); while (--size > 0) *str++ = ' '; continue; @@ -279,7 +279,7 @@ repeat: flags |= ZEROPAD; } str = itoa(str, - (unsigned long)va_arg(ap, void *), 16, + (u_long)va_arg(ap, void *), 16, size, precision, flags); continue; case 'n': @@ -318,15 +318,15 @@ repeat: } if (qual == 'l') - n = va_arg(ap, unsigned long); + n = va_arg(ap, u_long); else if (qual == 'h') { - n = (unsigned short)va_arg(ap, int); + n = (u_short)va_arg(ap, int); if (flags & SIGN) n = (short)n; } else if (flags & SIGN) n = va_arg(ap, int); else - n = va_arg(ap, unsigned int); + n = va_arg(ap, u_int); str = itoa(str, n, base, size, precision, flags); } *str = '\0';