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

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

major code revision

  • replace spinlocks taken with interrupts disabled with irq_spinlocks
  • change spacing (not indendation) to be tab-size independent
  • use unsigned integer types where appropriate (especially bit flags)
  • visual separation
  • remove argument names in function prototypes
  • string changes
  • correct some formating directives
  • replace various cryptic single-character variables (t, a, m, c, b, etc.) with proper identifiers (thread, task, timeout, as, itm, itc, etc.)
  • unify some assembler constructs
  • unused page table levels are now optimized out in compile time
  • replace several ints (with boolean semantics) with bools
  • use specifically sized types instead of generic types where appropriate (size_t, uint32_t, btree_key_t)
  • improve comments
  • split asserts with conjuction into multiple independent asserts
  • Property mode set to 100644
File size: 7.5 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 <typedefs.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
63#define VECTOR_MAX 0x7f00
64
65#define BUNDLE_SIZE 16
66
67static const char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
68 "VHPT Translation vector",
69 "Instruction TLB vector",
70 "Data TLB vector",
71 "Alternate Instruction TLB vector",
72 "Alternate Data TLB vector",
73 "Data Nested TLB vector",
74 "Instruction Key Miss vector",
75 "Data Key Miss vector",
76 "Dirty-Bit vector",
77 "Instruction Access-Bit vector",
78 "Data Access-Bit vector"
79 "Break Instruction vector",
80 "External Interrupt vector"
81 "Reserved",
82 "Reserved",
83 "Reserved",
84 "Reserved",
85 "Reserved",
86 "Reserved",
87 "Reserved"
88};
89
90static const char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
91 "Page Not Present vector",
92 "Key Permission vector",
93 "Instruction Access rights vector",
94 "Data Access Rights vector",
95 "General Exception vector",
96 "Disabled FP-Register vector",
97 "NaT Consumption vector",
98 "Speculation vector",
99 "Reserved",
100 "Debug vector",
101 "Unaligned Reference vector",
102 "Unsupported Data Reference vector",
103 "Floating-point Fault vector",
104 "Floating-point Trap vector",
105 "Lower-Privilege Transfer Trap vector",
106 "Taken Branch Trap vector",
107 "Single Step Trap vector",
108 "Reserved",
109 "Reserved",
110 "Reserved",
111 "Reserved",
112 "Reserved",
113 "Reserved",
114 "Reserved",
115 "Reserved",
116 "IA-32 Exception vector",
117 "IA-32 Intercept vector",
118 "IA-32 Interrupt vector",
119 "Reserved",
120 "Reserved",
121 "Reserved"
122};
123
124static const char *vector_to_string(uint16_t vector)
125{
126 ASSERT(vector <= VECTOR_MAX);
127
128 if (vector >= VECTORS_16_BUNDLE_START)
129 return vector_names_16_bundle[(vector -
130 VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
131 else
132 return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
133}
134
135static void dump_interrupted_context(istate_t *istate)
136{
137 putchar('\n');
138 printf("Interrupted context dump:\n");
139 printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
140 istate->ar_bspstore);
141 printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
142 istate->ar_rsc);
143 printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
144 istate->ar_pfs);
145 printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
146 istate->cr_ipsr);
147
148 printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei,
149 symtab_fmt_name_lookup(istate->cr_iip));
150 printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa,
151 symtab_fmt_name_lookup(istate->cr_iipa));
152 printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa,
153 symtab_fmt_name_lookup(istate->cr_ifa));
154}
155
156void general_exception(uint64_t vector, istate_t *istate)
157{
158 const char *desc;
159
160 switch (istate->cr_isr.ge_code) {
161 case GE_ILLEGALOP:
162 desc = "Illegal Operation fault";
163 break;
164 case GE_PRIVOP:
165 desc = "Privileged Operation fault";
166 break;
167 case GE_PRIVREG:
168 desc = "Privileged Register fault";
169 break;
170 case GE_RESREGFLD:
171 desc = "Reserved Register/Field fault";
172 break;
173 case GE_DISBLDISTRAN:
174 desc = "Disabled Instruction Set Transition fault";
175 break;
176 case GE_ILLEGALDEP:
177 desc = "Illegal Dependency fault";
178 break;
179 default:
180 desc = "unknown";
181 break;
182 }
183
184 fault_if_from_uspace(istate, "General Exception (%s).", desc);
185
186 dump_interrupted_context(istate);
187 panic("General Exception (%s).", desc);
188}
189
190void disabled_fp_register(uint64_t vector, istate_t *istate)
191{
192#ifdef CONFIG_FPU_LAZY
193 scheduler_fpu_lazy_request();
194#else
195 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
196 (uint16_t) vector, vector_to_string(vector));
197 dump_interrupted_context(istate);
198 panic("Interruption: %#hx (%s).", (uint16_t) vector,
199 vector_to_string(vector));
200#endif
201}
202
203void nop_handler(uint64_t vector, istate_t *istate)
204{
205}
206
207/** Handle syscall. */
208int break_instruction(uint64_t vector, istate_t *istate)
209{
210 /*
211 * Move to next instruction after BREAK.
212 */
213 if (istate->cr_ipsr.ri == 2) {
214 istate->cr_ipsr.ri = 0;
215 istate->cr_iip += 16;
216 } else {
217 istate->cr_ipsr.ri++;
218 }
219
220 return syscall_handler(istate->in0, istate->in1, istate->in2,
221 istate->in3, istate->in4, istate->in5, istate->in6);
222}
223
224void universal_handler(uint64_t vector, istate_t *istate)
225{
226 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
227 (uint16_t) vector, vector_to_string(vector));
228 dump_interrupted_context(istate);
229 panic("Interruption: %#hx (%s).", (uint16_t) vector,
230 vector_to_string(vector));
231}
232
233static void end_of_local_irq(void)
234{
235 asm volatile (
236 "mov cr.eoi=r0;;"
237 );
238}
239
240void external_interrupt(uint64_t vector, istate_t *istate)
241{
242 cr_ivr_t ivr;
243
244 ivr.value = ivr_read();
245 srlz_d();
246
247 irq_t *irq;
248
249 switch (ivr.vector) {
250 case INTERRUPT_SPURIOUS:
251#ifdef CONFIG_DEBUG
252 printf("cpu%d: spurious interrupt\n", CPU->id);
253#endif
254 break;
255
256#ifdef CONFIG_SMP
257 case VECTOR_TLB_SHOOTDOWN_IPI:
258 tlb_shootdown_ipi_recv();
259 end_of_local_irq();
260 break;
261#endif
262
263 case INTERRUPT_TIMER:
264 irq = irq_dispatch_and_lock(ivr.vector);
265 if (irq) {
266 irq->handler(irq);
267 irq_spinlock_unlock(&irq->lock, false);
268 } else {
269 panic("Unhandled Internal Timer Interrupt (%d).",
270 ivr.vector);
271 }
272 break;
273 default:
274 irq = irq_dispatch_and_lock(ivr.vector);
275 if (irq) {
276 /*
277 * The IRQ handler was found.
278 */
279 if (irq->preack) {
280 /* Send EOI before processing the interrupt */
281 end_of_local_irq();
282 }
283 irq->handler(irq);
284 if (!irq->preack)
285 end_of_local_irq();
286 irq_spinlock_unlock(&irq->lock, false);
287 } else {
288 /*
289 * Unhandled interrupt.
290 */
291 end_of_local_irq();
292#ifdef CONFIG_DEBUG
293 printf("\nUnhandled External Interrupt Vector %d\n",
294 ivr.vector);
295#endif
296 }
297 break;
298 }
299}
300
301void trap_virtual_enable_irqs(uint16_t irqmask)
302{
303}
304
305/** @}
306 */
Note: See TracBrowser for help on using the repository browser.