source: mainline/kernel/arch/ia64/src/interrupt.c@ b60c582

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b60c582 was b60c582, checked in by Martin Decky <martin@…>, 16 years ago

update for string changes

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * Copyright (c) 2005 Jakub Jermar
3 * Copyright (c) 2005 Jakub Vana
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
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.
17 *
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.
28 */
29
30/** @addtogroup ia64interrupt
31 * @{
32 */
33/** @file
34 */
35
36#include <arch/interrupt.h>
37#include <interrupt.h>
38#include <ddi/irq.h>
39#include <panic.h>
40#include <print.h>
41#include <debug.h>
42#include <console/console.h>
43#include <arch/types.h>
44#include <arch/asm.h>
45#include <arch/barrier.h>
46#include <arch/register.h>
47#include <arch.h>
48#include <syscall/syscall.h>
49#include <print.h>
50#include <proc/scheduler.h>
51#include <ipc/sysipc.h>
52#include <ipc/irq.h>
53#include <ipc/ipc.h>
54#include <synch/spinlock.h>
55#include <mm/tlb.h>
56#include <symtab.h>
57#include <putchar.h>
58
59#define VECTORS_64_BUNDLE 20
60#define VECTORS_16_BUNDLE 48
61#define VECTORS_16_BUNDLE_START 0x5000
62#define VECTOR_MAX 0x7f00
63
64#define BUNDLE_SIZE 16
65
66char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
67 "VHPT Translation vector",
68 "Instruction TLB vector",
69 "Data 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",
75 "Dirty-Bit vector",
76 "Instruction Access-Bit vector",
77 "Data Access-Bit vector"
78 "Break Instruction vector",
79 "External Interrupt vector"
80 "Reserved",
81 "Reserved",
82 "Reserved",
83 "Reserved",
84 "Reserved",
85 "Reserved",
86 "Reserved"
87};
88
89char *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",
97 "Speculation vector",
98 "Reserved",
99 "Debug 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",
107 "Reserved",
108 "Reserved",
109 "Reserved",
110 "Reserved",
111 "Reserved",
112 "Reserved",
113 "Reserved",
114 "Reserved",
115 "IA-32 Exception vector",
116 "IA-32 Intercept vector",
117 "IA-32 Interrupt vector",
118 "Reserved",
119 "Reserved",
120 "Reserved"
121};
122
123static char *vector_to_string(uint16_t vector);
124static void dump_interrupted_context(istate_t *istate);
125
126char *vector_to_string(uint16_t vector)
127{
128 ASSERT(vector <= VECTOR_MAX);
129
130 if (vector >= VECTORS_16_BUNDLE_START)
131 return vector_names_16_bundle[(vector -
132 VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
133 else
134 return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
135}
136
137void dump_interrupted_context(istate_t *istate)
138{
139 char *ifa, *iipa, *iip;
140
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);
144
145 putchar('\n');
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,
150 istate->ar_rsc);
151 printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
152 istate->ar_pfs);
153 printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
154 istate->cr_ipsr);
155
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);
160}
161
162void general_exception(uint64_t vector, istate_t *istate)
163{
164 char *desc = "";
165
166 switch (istate->cr_isr.ge_code) {
167 case GE_ILLEGALOP:
168 desc = "Illegal Operation fault";
169 break;
170 case GE_PRIVOP:
171 desc = "Privileged Operation fault";
172 break;
173 case GE_PRIVREG:
174 desc = "Privileged Register fault";
175 break;
176 case GE_RESREGFLD:
177 desc = "Reserved Register/Field fault";
178 break;
179 case GE_DISBLDISTRAN:
180 desc = "Disabled Instruction Set Transition fault";
181 break;
182 case GE_ILLEGALDEP:
183 desc = "Illegal Dependency fault";
184 break;
185 default:
186 desc = "unknown";
187 break;
188 }
189
190 fault_if_from_uspace(istate, "General Exception (%s).", desc);
191
192 dump_interrupted_context(istate);
193 panic("General Exception (%s).", desc);
194}
195
196void disabled_fp_register(uint64_t vector, istate_t *istate)
197{
198#ifdef CONFIG_FPU_LAZY
199 scheduler_fpu_lazy_request();
200#else
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));
206#endif
207}
208
209void nop_handler(uint64_t vector, istate_t *istate)
210{
211}
212
213/** Handle syscall. */
214int break_instruction(uint64_t vector, istate_t *istate)
215{
216 /*
217 * Move to next instruction after BREAK.
218 */
219 if (istate->cr_ipsr.ri == 2) {
220 istate->cr_ipsr.ri = 0;
221 istate->cr_iip += 16;
222 } else {
223 istate->cr_ipsr.ri++;
224 }
225
226 return syscall_handler(istate->in0, istate->in1, istate->in2,
227 istate->in3, istate->in4, istate->in5, istate->in6);
228}
229
230void universal_handler(uint64_t vector, istate_t *istate)
231{
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));
237}
238
239static void end_of_local_irq(void)
240{
241 asm volatile ("mov cr.eoi=r0;;");
242}
243
244
245void external_interrupt(uint64_t vector, istate_t *istate)
246{
247 cr_ivr_t ivr;
248 irq_t *irq;
249
250 ivr.value = ivr_read();
251 srlz_d();
252
253 switch (ivr.vector) {
254 case INTERRUPT_SPURIOUS:
255#ifdef CONFIG_DEBUG
256 printf("cpu%d: spurious interrupt\n", CPU->id);
257#endif
258 break;
259
260#ifdef CONFIG_SMP
261 case VECTOR_TLB_SHOOTDOWN_IPI:
262 tlb_shootdown_ipi_recv();
263 end_of_local_irq();
264 break;
265#endif
266
267 case INTERRUPT_TIMER:
268 irq = irq_dispatch_and_lock(ivr.vector);
269 if (irq) {
270 irq->handler(irq);
271 spinlock_unlock(&irq->lock);
272 } else {
273 panic("Unhandled Internal Timer Interrupt (%d).",
274 ivr.vector);
275 }
276 break;
277 default:
278 irq = irq_dispatch_and_lock(ivr.vector);
279 if (irq) {
280 /*
281 * The IRQ handler was found.
282 */
283 if (irq->preack) {
284 /* Send EOI before processing the interrupt */
285 end_of_local_irq();
286 }
287 irq->handler(irq);
288 if (!irq->preack)
289 end_of_local_irq();
290 spinlock_unlock(&irq->lock);
291 } else {
292 /*
293 * Unhandled interrupt.
294 */
295 end_of_local_irq();
296#ifdef CONFIG_DEBUG
297 printf("\nUnhandled External Interrupt Vector %d\n",
298 ivr.vector);
299#endif
300 }
301 break;
302 }
303}
304
305void trap_virtual_enable_irqs(uint16_t irqmask)
306{
307}
308
309/** @}
310 */
Note: See TracBrowser for help on using the repository browser.