2
* Copyright (c) 2005 Jakub Jermar
3
* Copyright (c) 2005 Jakub Vana
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
10
* - Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* - Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* - The name of the author may not be used to endorse or promote products
16
* derived from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
/** @addtogroup ia64interrupt
36
#include <arch/interrupt.h>
37
#include <interrupt.h>
42
#include <console/console.h>
43
#include <arch/types.h>
45
#include <arch/barrier.h>
46
#include <arch/register.h>
48
#include <syscall/syscall.h>
50
#include <proc/scheduler.h>
51
#include <ipc/sysipc.h>
54
#include <synch/spinlock.h>
59
#define VECTORS_64_BUNDLE 20
60
#define VECTORS_16_BUNDLE 48
61
#define VECTORS_16_BUNDLE_START 0x5000
62
#define VECTOR_MAX 0x7f00
64
#define BUNDLE_SIZE 16
66
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
67
"VHPT Translation vector",
68
"Instruction TLB vector",
70
"Alternate Instruction TLB vector",
71
"Alternate Data TLB vector",
72
"Data Nested TLB vector",
73
"Instruction Key Miss vector",
74
"Data Key Miss vector",
76
"Instruction Access-Bit vector",
77
"Data Access-Bit vector"
78
"Break Instruction vector",
79
"External Interrupt vector"
89
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
90
"Page Not Present vector",
91
"Key Permission vector",
92
"Instruction Access rights vector",
93
"Data Access Rights vector",
94
"General Exception vector",
95
"Disabled FP-Register vector",
96
"NaT Consumption vector",
100
"Unaligned Reference vector",
101
"Unsupported Data Reference vector",
102
"Floating-point Fault vector",
103
"Floating-point Trap vector",
104
"Lower-Privilege Transfer Trap vector",
105
"Taken Branch Trap vector",
106
"Single Step Trap vector",
115
"IA-32 Exception vector",
116
"IA-32 Intercept vector",
117
"IA-32 Interrupt vector",
123
static char *vector_to_string(uint16_t vector);
124
static void dump_interrupted_context(istate_t *istate);
126
char *vector_to_string(uint16_t vector)
128
ASSERT(vector <= VECTOR_MAX);
130
if (vector >= VECTORS_16_BUNDLE_START)
131
return vector_names_16_bundle[(vector -
132
VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
134
return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
137
void dump_interrupted_context(istate_t *istate)
139
char *ifa, *iipa, *iip;
141
ifa = symtab_fmt_name_lookup(istate->cr_ifa);
142
iipa = symtab_fmt_name_lookup(istate->cr_iipa);
143
iip = symtab_fmt_name_lookup(istate->cr_iip);
146
printf("Interrupted context dump:\n");
147
printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
148
istate->ar_bspstore);
149
printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
151
printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
153
printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
156
printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
157
istate->cr_isr.ei, iip);
158
printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
159
printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
162
void general_exception(uint64_t vector, istate_t *istate)
166
switch (istate->cr_isr.ge_code) {
168
desc = "Illegal Operation fault";
171
desc = "Privileged Operation fault";
174
desc = "Privileged Register fault";
177
desc = "Reserved Register/Field fault";
179
case GE_DISBLDISTRAN:
180
desc = "Disabled Instruction Set Transition fault";
183
desc = "Illegal Dependency fault";
190
fault_if_from_uspace(istate, "General Exception (%s).", desc);
192
dump_interrupted_context(istate);
193
panic("General Exception (%s).", desc);
196
void disabled_fp_register(uint64_t vector, istate_t *istate)
198
#ifdef CONFIG_FPU_LAZY
199
scheduler_fpu_lazy_request();
201
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
202
(uint16_t) vector, vector_to_string(vector));
203
dump_interrupted_context(istate);
204
panic("Interruption: %#hx (%s).", (uint16_t) vector,
205
vector_to_string(vector));
209
void nop_handler(uint64_t vector, istate_t *istate)
213
/** Handle syscall. */
214
int break_instruction(uint64_t vector, istate_t *istate)
217
* Move to next instruction after BREAK.
219
if (istate->cr_ipsr.ri == 2) {
220
istate->cr_ipsr.ri = 0;
221
istate->cr_iip += 16;
223
istate->cr_ipsr.ri++;
226
return syscall_handler(istate->in0, istate->in1, istate->in2,
227
istate->in3, istate->in4, istate->in5, istate->in6);
230
void universal_handler(uint64_t vector, istate_t *istate)
232
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
233
(uint16_t) vector, vector_to_string(vector));
234
dump_interrupted_context(istate);
235
panic("Interruption: %#hx (%s).", (uint16_t) vector,
236
vector_to_string(vector));
239
static void end_of_local_irq(void)
241
asm volatile ("mov cr.eoi=r0;;");
245
void external_interrupt(uint64_t vector, istate_t *istate)
250
ivr.value = ivr_read();
253
switch (ivr.vector) {
254
case INTERRUPT_SPURIOUS:
256
printf("cpu%d: spurious interrupt\n", CPU->id);
261
case VECTOR_TLB_SHOOTDOWN_IPI:
262
tlb_shootdown_ipi_recv();
267
case INTERRUPT_TIMER:
268
irq = irq_dispatch_and_lock(ivr.vector);
271
spinlock_unlock(&irq->lock);
273
panic("Unhandled Internal Timer Interrupt (%d).",
278
irq = irq_dispatch_and_lock(ivr.vector);
281
* The IRQ handler was found.
284
/* Send EOI before processing the interrupt */
290
spinlock_unlock(&irq->lock);
293
* Unhandled interrupt.
297
printf("\nUnhandled External Interrupt Vector %d\n",
305
void trap_virtual_enable_irqs(uint16_t irqmask)