]> Joshua Wise's Git repositories - netwatch.git/blame - netwatch/traps.c
Avoid suffering from wrong CS_SEGSEL syndrome.
[netwatch.git] / netwatch / traps.c
CommitLineData
ed22a699
JP
1#include <output.h>
2#include <io.h>
3#include <paging.h>
4
5#include "traps.h"
6
7285933f 7#define CS_SEGSEL 0x8
ed22a699
JP
8
9#define FAULT_WRAPPER(func_name) asm ( \
10 ".global " #func_name "_wrapper\n" \
11 #func_name "_wrapper:\n" \
12 "mov %cr2, %eax\n" \
13 "push %eax\n" \
14 "push %esp\n" \
15 "call " #func_name "\n" \
16); void func_name##_wrapper(void);
17
18#define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) { \
19 *(int *)((void *)idt + (8 * int_number)) = \
20 ((int)func_name##_wrapper & 0xFFFF) | \
21 (CS_SEGSEL << 16); \
22 *(int *)((void *)idt + (8 * int_number) + 4) = \
23 ((int)func_name##_wrapper & 0xFFFF0000) | idt4_value; \
24}
25
26/* The 16 bits at offset 4 from the start of an interrupt gate are a
27 * bitfield, according to the Intel spec:
28 * 15 P - Segment Present - set to 1
29 * 14-13 DPL - Descriptor privilege level - set to 11 for trap/int, 00 for IPI
30 * 12-8 01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates
31 * 7-0 Set to 0
32 * Trap: binary 11101111 0000000, hex EF00.
33 * Interrupt: binary 11101110 0000000, hex EE00.
34 */
35#define TRAP 0xEF00
36#define INTERRUPT 0xEE00
37
38typedef struct trap_t {
39 int cr2;
40 int error_code;
41 int eip;
42 int cs;
43 int eflags;
44 int esp;
45 int ss;
46} trap_t;
47
48void die(struct trap_t * trap) {
49 outputf("Error %08x %%eip %08x", trap->error_code, trap->eip);
50 outputf("%%esp %08x %%eflags %08x", trap->esp, trap->eflags);
51 while(1) asm("hlt");
52}
53
54void fault_gp(struct trap_t * trap) {
55 outputf("GENERAL PROTECTION FAULT");
56 die(trap);
57}
58
59void fault_page(struct trap_t * trap) {
60 outputf("PAGE FAULT: %08x", trap->cr2);
61 die(trap);
62}
63void fault_divide(struct trap_t * trap) {
64 outputf("DIVISION FAULT");
65 die(trap);
66}
67void double_fault(struct trap_t * trap) {
68 outputf("DOUBLE FAULT");
69 die(trap);
70}
71
72FAULT_WRAPPER(fault_gp);
73FAULT_WRAPPER(fault_page);
74FAULT_WRAPPER(fault_divide);
75FAULT_WRAPPER(double_fault);
76
77/* pseudo_descriptor and x86_gate structs from 15-410 basis code. */
78
79struct x86_gate {
80unsigned int filler[2]; //64 bits; or 8 bytes.
81};
82
83static struct x86_gate idt[64];
84
85struct pseudo_descriptor {
86 short pad;
87 unsigned short limit;
88 unsigned long linear_base;
ea82a4d1 89} __attribute__((packed));
ed22a699
JP
90
91void traps_install(void) {
92
93 struct pseudo_descriptor pdesc;
94 pdesc.limit = sizeof(idt) - 1;
923ea2c2 95 pdesc.linear_base = v2p(&idt);
ed22a699
JP
96
97 WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR);
98 WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION);
99 WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT);
100 WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT);
101
102 outb(0x80, 0xCC);
103 asm volatile("lidt %0" : : "m" (pdesc.limit));
104 outb(0x80, 0xCD);
105}
This page took 0.03504 seconds and 4 git commands to generate.