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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 656b789 was e2b762ec, checked in by Jiri Svoboda <jirik.svoboda@…>, 17 years ago

Make kernel symbol information optional.

  • 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
57#ifdef CONFIG_SYMTAB
58#include <symtab.h>
59#endif
60
61#define VECTORS_64_BUNDLE 20
62#define VECTORS_16_BUNDLE 48
63#define VECTORS_16_BUNDLE_START 0x5000
64#define VECTOR_MAX 0x7f00
65
66#define BUNDLE_SIZE 16
67
68char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
69 "VHPT Translation vector",
70 "Instruction TLB vector",
71 "Data TLB vector",
72 "Alternate Instruction TLB vector",
73 "Alternate Data TLB vector",
74 "Data Nested TLB vector",
75 "Instruction Key Miss vector",
76 "Data Key Miss vector",
77 "Dirty-Bit vector",
78 "Instruction Access-Bit vector",
79 "Data Access-Bit vector"
80 "Break Instruction vector",
81 "External Interrupt vector"
82 "Reserved",
83 "Reserved",
84 "Reserved",
85 "Reserved",
86 "Reserved",
87 "Reserved",
88 "Reserved"
89};
90
91char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
92 "Page Not Present vector",
93 "Key Permission vector",
94 "Instruction Access rights vector",
95 "Data Access Rights vector",
96 "General Exception vector",
97 "Disabled FP-Register vector",
98 "NaT Consumption vector",
99 "Speculation vector",
100 "Reserved",
101 "Debug vector",
102 "Unaligned Reference vector",
103 "Unsupported Data Reference vector",
104 "Floating-point Fault vector",
105 "Floating-point Trap vector",
106 "Lower-Privilege Transfer Trap vector",
107 "Taken Branch Trap vector",
108 "Single Step Trap vector",
109 "Reserved",
110 "Reserved",
111 "Reserved",
112 "Reserved",
113 "Reserved",
114 "Reserved",
115 "Reserved",
116 "Reserved",
117 "IA-32 Exception vector",
118 "IA-32 Intercept vector",
119 "IA-32 Interrupt vector",
120 "Reserved",
121 "Reserved",
122 "Reserved"
123};
124
125static char *vector_to_string(uint16_t vector);
126static void dump_interrupted_context(istate_t *istate);
127
128char *vector_to_string(uint16_t vector)
129{
130 ASSERT(vector <= VECTOR_MAX);
131
132 if (vector >= VECTORS_16_BUNDLE_START)
133 return vector_names_16_bundle[(vector -
134 VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
135 else
136 return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
137}
138
139void dump_interrupted_context(istate_t *istate)
140{
141 char *ifa, *iipa, *iip;
142
143#ifdef CONFIG_SYMTAB
144 ifa = get_symtab_entry(istate->cr_ifa);
145 iipa = get_symtab_entry(istate->cr_iipa);
146 iip = get_symtab_entry(istate->cr_iip);
147#else
148 ifa = iipa = iip = "n/a";
149#endif
150
151 putchar('\n');
152 printf("Interrupted context dump:\n");
153 printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
154 istate->ar_bspstore);
155 printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
156 istate->ar_rsc);
157 printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
158 istate->ar_pfs);
159 printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
160 istate->cr_ipsr);
161
162 printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
163 istate->cr_isr.ei, iip);
164 printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
165 printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
166}
167
168void general_exception(uint64_t vector, istate_t *istate)
169{
170 char *desc = "";
171
172 switch (istate->cr_isr.ge_code) {
173 case GE_ILLEGALOP:
174 desc = "Illegal Operation fault";
175 break;
176 case GE_PRIVOP:
177 desc = "Privileged Operation fault";
178 break;
179 case GE_PRIVREG:
180 desc = "Privileged Register fault";
181 break;
182 case GE_RESREGFLD:
183 desc = "Reserved Register/Field fault";
184 break;
185 case GE_DISBLDISTRAN:
186 desc = "Disabled Instruction Set Transition fault";
187 break;
188 case GE_ILLEGALDEP:
189 desc = "Illegal Dependency fault";
190 break;
191 default:
192 desc = "unknown";
193 break;
194 }
195
196 fault_if_from_uspace(istate, "General Exception (%s).", desc);
197
198 dump_interrupted_context(istate);
199 panic("General Exception (%s).", desc);
200}
201
202void disabled_fp_register(uint64_t vector, istate_t *istate)
203{
204#ifdef CONFIG_FPU_LAZY
205 scheduler_fpu_lazy_request();
206#else
207 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
208 (uint16_t) vector, vector_to_string(vector));
209 dump_interrupted_context(istate);
210 panic("Interruption: %#hx (%s).", (uint16_t) vector,
211 vector_to_string(vector));
212#endif
213}
214
215void nop_handler(uint64_t vector, istate_t *istate)
216{
217}
218
219/** Handle syscall. */
220int break_instruction(uint64_t vector, istate_t *istate)
221{
222 /*
223 * Move to next instruction after BREAK.
224 */
225 if (istate->cr_ipsr.ri == 2) {
226 istate->cr_ipsr.ri = 0;
227 istate->cr_iip += 16;
228 } else {
229 istate->cr_ipsr.ri++;
230 }
231
232 return syscall_handler(istate->in0, istate->in1, istate->in2,
233 istate->in3, istate->in4, istate->in5, istate->in6);
234}
235
236void universal_handler(uint64_t vector, istate_t *istate)
237{
238 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
239 (uint16_t) vector, vector_to_string(vector));
240 dump_interrupted_context(istate);
241 panic("Interruption: %#hx (%s).", (uint16_t) vector,
242 vector_to_string(vector));
243}
244
245static void end_of_local_irq(void)
246{
247 asm volatile ("mov cr.eoi=r0;;");
248}
249
250
251void external_interrupt(uint64_t vector, istate_t *istate)
252{
253 cr_ivr_t ivr;
254 irq_t *irq;
255
256 ivr.value = ivr_read();
257 srlz_d();
258
259 switch (ivr.vector) {
260 case INTERRUPT_SPURIOUS:
261#ifdef CONFIG_DEBUG
262 printf("cpu%d: spurious interrupt\n", CPU->id);
263#endif
264 break;
265
266#ifdef CONFIG_SMP
267 case VECTOR_TLB_SHOOTDOWN_IPI:
268 tlb_shootdown_ipi_recv();
269 end_of_local_irq();
270 break;
271#endif
272
273 case INTERRUPT_TIMER:
274 irq = irq_dispatch_and_lock(ivr.vector);
275 if (irq) {
276 irq->handler(irq);
277 spinlock_unlock(&irq->lock);
278 } else {
279 panic("Unhandled Internal Timer Interrupt (%d).",
280 ivr.vector);
281 }
282 break;
283 default:
284 irq = irq_dispatch_and_lock(ivr.vector);
285 if (irq) {
286 /*
287 * The IRQ handler was found.
288 */
289 if (irq->preack) {
290 /* Send EOI before processing the interrupt */
291 end_of_local_irq();
292 }
293 irq->handler(irq);
294 if (!irq->preack)
295 end_of_local_irq();
296 spinlock_unlock(&irq->lock);
297 } else {
298 /*
299 * Unhandled interrupt.
300 */
301 end_of_local_irq();
302#ifdef CONFIG_DEBUG
303 printf("\nUnhandled External Interrupt Vector %d\n",
304 ivr.vector);
305#endif
306 }
307 break;
308 }
309}
310
311void trap_virtual_enable_irqs(uint16_t irqmask)
312{
313}
314
315/** @}
316 */
Note: See TracBrowser for help on using the repository browser.