commit 629d6ca6128374bf9f62bac126465881fcda180a
parent 30f15bfc930e222f54a829b81a0fe24d2256cd33
Author: Christos Margiolis <christos@margiolis.net>
Date: Tue, 7 Dec 2021 00:38:05 +0200
simplify and improve idt
Diffstat:
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';