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

Last change on this file since 071cb36 was c5429fe, checked in by Jakub Jermar <jakub@…>, 7 years ago

Disambiguate architecture specific doxygroups

  • Property mode set to 100644
File size: 9.1 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 kernel_ia64_interrupt
31 * @{
32 */
33/** @file
34 */
35
36#include <arch/interrupt.h>
37#include <assert.h>
38#include <interrupt.h>
39#include <ddi/irq.h>
40#include <panic.h>
41#include <print.h>
42#include <console/console.h>
43#include <typedefs.h>
44#include <arch/asm.h>
45#include <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 <arch/mm/tlb.h>
57#include <symtab.h>
58#include <putchar.h>
59
60#define VECTORS_64_BUNDLE 20
61#define VECTORS_16_BUNDLE 48
62#define VECTORS_16_BUNDLE_START 0x50
63
64#define VECTOR_MAX 0x7f
65
66static const char *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 "Virtual External Interrupt vector",
81 "Reserved",
82 "Reserved",
83 "Reserved",
84 "Reserved",
85 "Reserved",
86 "Reserved"
87};
88
89static const 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",
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 const char *vector_to_string(unsigned int n)
124{
125 assert(n <= VECTOR_MAX);
126
127 if (n >= VECTORS_16_BUNDLE_START)
128 return vector_names_16_bundle[n - VECTORS_16_BUNDLE_START];
129 else
130 return vector_names_64_bundle[n / 4];
131}
132
133void istate_decode(istate_t *istate)
134{
135 printf("ar.bsp=%p\tar.bspstore=%p\n",
136 (void *) istate->ar_bsp, (void *) istate->ar_bspstore);
137 printf("ar.rnat=%#0" PRIx64 "\tar.rsc=%#0" PRIx64 "\n",
138 istate->ar_rnat, istate->ar_rsc);
139 printf("ar.ifs=%#0" PRIx64 "\tar.pfs=%#0" PRIx64 "\n",
140 istate->ar_ifs, istate->ar_pfs);
141 printf("cr.isr=%#0" PRIx64 "\tcr.ipsr=%#0" PRIx64 "\n",
142 istate->cr_isr.value, istate->cr_ipsr.value);
143
144 printf("cr.iip=%#0" PRIxPTR ", #%u\t(%s)\n",
145 istate->cr_iip, istate->cr_isr.ei,
146 symtab_fmt_name_lookup(istate->cr_iip));
147 printf("cr.iipa=%#0" PRIxPTR "\t(%s)\n", istate->cr_iipa,
148 symtab_fmt_name_lookup(istate->cr_iipa));
149 printf("cr.ifa=%#0" PRIxPTR "\t(%s)\n", istate->cr_ifa,
150 symtab_fmt_name_lookup(istate->cr_ifa));
151}
152
153void general_exception(unsigned int n, istate_t *istate)
154{
155 const char *desc;
156
157 switch (istate->cr_isr.ge_code) {
158 case GE_ILLEGALOP:
159 desc = "Illegal Operation fault";
160 break;
161 case GE_PRIVOP:
162 desc = "Privileged Operation fault";
163 break;
164 case GE_PRIVREG:
165 desc = "Privileged Register fault";
166 break;
167 case GE_RESREGFLD:
168 desc = "Reserved Register/Field fault";
169 break;
170 case GE_DISBLDISTRAN:
171 desc = "Disabled Instruction Set Transition fault";
172 break;
173 case GE_ILLEGALDEP:
174 desc = "Illegal Dependency fault";
175 break;
176 default:
177 desc = "unknown";
178 break;
179 }
180
181 fault_if_from_uspace(istate, "General Exception (%s).", desc);
182 panic_badtrap(istate, n, "General Exception (%s).", desc);
183}
184
185void disabled_fp_register(unsigned int n, istate_t *istate)
186{
187#ifdef CONFIG_FPU_LAZY
188 scheduler_fpu_lazy_request();
189#else
190 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
191 (uint16_t) n, vector_to_string(n));
192 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
193 (uint16_t) n, vector_to_string(n));
194#endif
195}
196
197#define BREAK_IMM_SYSCALL 0x40000U
198
199/** Handle syscall. */
200sysarg_t break_instruction(unsigned int n, istate_t *istate)
201{
202 sysarg_t ret;
203
204 if (istate->cr_iim != BREAK_IMM_SYSCALL) {
205 fault_if_from_uspace(istate, "Unknown software interrupt: %x",
206 (uint32_t) istate->cr_iim);
207 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
208 (uint16_t) n, vector_to_string(n));
209 }
210
211 /*
212 * Move to next instruction after BREAK.
213 */
214 if (istate->cr_ipsr.ri == 2) {
215 istate->cr_ipsr.ri = 0;
216 istate->cr_iip += 16;
217 } else {
218 istate->cr_ipsr.ri++;
219 }
220
221 interrupts_enable();
222 ret = syscall_handler(istate->in0, istate->in1, istate->in2,
223 istate->in3, istate->in4, istate->in5, istate->in6);
224 interrupts_disable();
225
226 return ret;
227}
228
229void universal_handler(unsigned int n, istate_t *istate)
230{
231 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
232 n, vector_to_string(n));
233 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
234 n, vector_to_string(n));
235}
236
237static void end_of_local_irq(void)
238{
239 asm volatile (
240 "mov cr.eoi = r0 ;;"
241 );
242}
243
244void external_interrupt(unsigned int n, istate_t *istate)
245{
246 cr_ivr_t ivr;
247
248 ivr.value = ivr_read();
249 srlz_d();
250
251 irq_t *irq;
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 irq_spinlock_unlock(&irq->lock, false);
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 irq_spinlock_unlock(&irq->lock, false);
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
309void exception_init(void)
310{
311 unsigned int i;
312
313 for (i = 0; i < IVT_ITEMS; i++)
314 exc_register(i, "universal_handler", false, universal_handler);
315
316 exc_register(EXC_ALT_ITLB_FAULT,
317 vector_to_string(EXC_ALT_ITLB_FAULT), true,
318 alternate_instruction_tlb_fault);
319 exc_register(EXC_ALT_DTLB_FAULT,
320 vector_to_string(EXC_ALT_DTLB_FAULT), true,
321 alternate_data_tlb_fault);
322 exc_register(EXC_NESTED_TLB_FAULT,
323 vector_to_string(EXC_NESTED_TLB_FAULT), false,
324 data_nested_tlb_fault);
325 exc_register(EXC_DATA_D_BIT_FAULT,
326 vector_to_string(EXC_DATA_D_BIT_FAULT), true,
327 data_dirty_bit_fault);
328 exc_register(EXC_INST_A_BIT_FAULT,
329 vector_to_string(EXC_INST_A_BIT_FAULT), true,
330 instruction_access_bit_fault);
331 exc_register(EXC_DATA_A_BIT_FAULT,
332 vector_to_string(EXC_DATA_A_BIT_FAULT), true,
333 data_access_bit_fault);
334 exc_register(EXC_EXT_INTERRUPT,
335 vector_to_string(EXC_EXT_INTERRUPT), true,
336 external_interrupt);
337
338 exc_register(EXC_PAGE_NOT_PRESENT,
339 vector_to_string(EXC_PAGE_NOT_PRESENT), true,
340 page_not_present);
341 exc_register(EXC_DATA_AR_FAULT,
342 vector_to_string(EXC_DATA_AR_FAULT), true,
343 data_access_rights_fault);
344 exc_register(EXC_GENERAL_EXCEPTION,
345 vector_to_string(EXC_GENERAL_EXCEPTION), false,
346 general_exception);
347 exc_register(EXC_DISABLED_FP_REG,
348 vector_to_string(EXC_DISABLED_FP_REG), true,
349 disabled_fp_register);
350}
351
352/** @}
353 */
Note: See TracBrowser for help on using the repository browser.