summaryrefslogtreecommitdiff
path: root/arch/x86/machine/trap.h
blob: c5bdc1f23f48ddcdafba9afcc5d908fed3f86466 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
 * Copyright (c) 2011-2014 Richard Braun.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Trap (interrupt and exception) handling.
 *
 * This file is a top header in the inclusion hierarchy, and shouldn't include
 * other headers that may cause circular dependencies.
 */

#ifndef X86_TRAP_H
#define X86_TRAP_H

#include <machine/page.h>

/*
 * Architecture defined traps.
 */
#define TRAP_DE                 0   /* Divide Error */
#define TRAP_DB                 1   /* Debug */
#define TRAP_NMI                2   /* NMI Interrupt */
#define TRAP_BP                 3   /* Breakpoint */
#define TRAP_OF                 4   /* Overflow */
#define TRAP_BR                 5   /* BOUND Range Exceeded */
#define TRAP_UD                 6   /* Invalid Opcode (Undefined Opcode) */
#define TRAP_NM                 7   /* Device Not Available (No Math Coprocessor) */
#define TRAP_DF                 8   /* Double Fault */
#define TRAP_TS                 10  /* Invalid TSS */
#define TRAP_NP                 11  /* Segment Not Present */
#define TRAP_SS                 12  /* Stack-Segment Fault */
#define TRAP_GP                 13  /* General Protection */
#define TRAP_PF                 14  /* Page Fault */
#define TRAP_MF                 16  /* x87 FPU Floating-Point Error (Math Fault) */
#define TRAP_AC                 17  /* Alignment Check */
#define TRAP_MC                 18  /* Machine Check */
#define TRAP_XM                 19  /* SIMD Floating-Point Exception */

/*
 * Traps used for handling external interrupts.
 */
#define TRAP_INTR_FIRST         32
#define TRAP_INTR_LAST          223

/*
 * System defined traps.
 *
 * The local APIC assigns one priority every 16 vectors.
 */
#define TRAP_XCALL              238
#define TRAP_THREAD_SCHEDULE    239
#define TRAP_CPU_HALT           240
#define TRAP_LAPIC_PMC_OF       252
#define TRAP_LAPIC_TIMER        253
#define TRAP_LAPIC_ERROR        254
#define TRAP_LAPIC_SPURIOUS     255

#define TRAP_NR_VECTORS         256

#define TRAP_INTR_TABLE_SIZE    256

#define TRAP_STACK_SIZE PAGE_SIZE

#ifndef __ASSEMBLER__

#include <stdint.h>
#include <stdio.h>

#include <kern/init.h>
#include <kern/macros.h>

#ifdef __LP64__

struct trap_frame {
    uint64_t rax;
    uint64_t rbx;
    uint64_t rcx;
    uint64_t rdx;
    uint64_t rbp;
    uint64_t rsi;
    uint64_t rdi;
    uint64_t r8;
    uint64_t r9;
    uint64_t r10;
    uint64_t r11;
    uint64_t r12;
    uint64_t r13;
    uint64_t r14;
    uint64_t r15;
    uint64_t vector;
    uint64_t error;
    uint64_t rip;
    uint64_t cs;
    uint64_t rflags;
    uint64_t rsp;
    uint64_t ss;
} __packed;

#else /* __LP64__ */

struct trap_frame {
    uint32_t eax;
    uint32_t ebx;
    uint32_t ecx;
    uint32_t edx;
    uint32_t ebp;
    uint32_t esi;
    uint32_t edi;
    uint16_t ds;
    uint16_t es;
    uint16_t fs;
    uint16_t gs;
    uint32_t vector;
    uint32_t error;
    uint32_t eip;
    uint32_t cs;
    uint32_t eflags;
    uint32_t esp;       /* esp and ss are undefined if trapped in kernel */
    uint32_t ss;
} __packed;

#endif /* __LP64__ */

/*
 * Type for trap handler functions.
 */
typedef void (*trap_handler_fn_t)(struct trap_frame *);

static inline void
trap_trigger_double_fault(void)
{
    printf("trap: double fault test\n");
    asm volatile("movl $0xdead, %esp; push $0");
}

/*
 * Unified trap entry point.
 */
void trap_main(struct trap_frame *frame);

/*
 * Register a trap handler.
 */
void trap_register(unsigned int vector, trap_handler_fn_t handler_fn);

/*
 * Display the content of a trap frame.
 */
void trap_frame_show(struct trap_frame *frame);

/*
 * Display the call trace interrupted by the trap of the given frame.
 */
void trap_stack_show(struct trap_frame *frame);

/*
 * Return a pointer to the local interrupt stack.
 *
 * This function is called by the low level trap handling code.
 *
 * Return NULL if no stack switching is required.
 */
void * trap_get_interrupt_stack(const struct trap_frame *frame);

/*
 * This init operation provides :
 *  - initialization of all IDT entries and trap handlers
 *  - double fault exception support
 */
INIT_OP_DECLARE(trap_setup);

#endif /* __ASSEMBLER__ */

#endif /* X86_TRAP_H */