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