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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bab75df6 was bab75df6, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Let kernel code get printf via the standard stdio header. Clean up unused includes.

  • Property mode set to 100644
File size: 9.0 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 <stdio.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 <proc/scheduler.h>
50#include <ipc/sysipc.h>
51#include <ipc/irq.h>
52#include <ipc/ipc.h>
53#include <synch/spinlock.h>
54#include <mm/tlb.h>
55#include <arch/mm/tlb.h>
56#include <symtab.h>
57
58#define VECTORS_64_BUNDLE 20
59#define VECTORS_16_BUNDLE 48
60#define VECTORS_16_BUNDLE_START 0x50
61
62#define VECTOR_MAX 0x7f
63
64static const char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
65 "VHPT Translation vector",
66 "Instruction TLB vector",
67 "Data TLB vector",
68 "Alternate Instruction TLB vector",
69 "Alternate Data TLB vector",
70 "Data Nested TLB vector",
71 "Instruction Key Miss vector",
72 "Data Key Miss vector",
73 "Dirty-Bit vector",
74 "Instruction Access-Bit vector",
75 "Data Access-Bit vector",
76 "Break Instruction vector",
77 "External Interrupt vector",
78 "Virtual External Interrupt vector",
79 "Reserved",
80 "Reserved",
81 "Reserved",
82 "Reserved",
83 "Reserved",
84 "Reserved"
85};
86
87static const char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
88 "Page Not Present vector",
89 "Key Permission vector",
90 "Instruction Access rights vector",
91 "Data Access Rights vector",
92 "General Exception vector",
93 "Disabled FP-Register vector",
94 "NaT Consumption vector",
95 "Speculation vector",
96 "Reserved",
97 "Debug vector",
98 "Unaligned Reference vector",
99 "Unsupported Data Reference vector",
100 "Floating-point Fault vector",
101 "Floating-point Trap vector",
102 "Lower-Privilege Transfer Trap vector",
103 "Taken Branch Trap vector",
104 "Single Step Trap vector",
105 "Reserved",
106 "Reserved",
107 "Reserved",
108 "Reserved",
109 "Reserved",
110 "Reserved",
111 "Reserved",
112 "Reserved",
113 "IA-32 Exception vector",
114 "IA-32 Intercept vector",
115 "IA-32 Interrupt vector",
116 "Reserved",
117 "Reserved",
118 "Reserved"
119};
120
121static const char *vector_to_string(unsigned int n)
122{
123 assert(n <= VECTOR_MAX);
124
125 if (n >= VECTORS_16_BUNDLE_START)
126 return vector_names_16_bundle[n - VECTORS_16_BUNDLE_START];
127 else
128 return vector_names_64_bundle[n / 4];
129}
130
131void istate_decode(istate_t *istate)
132{
133 printf("ar.bsp=%p\tar.bspstore=%p\n",
134 (void *) istate->ar_bsp, (void *) istate->ar_bspstore);
135 printf("ar.rnat=%#0" PRIx64 "\tar.rsc=%#0" PRIx64 "\n",
136 istate->ar_rnat, istate->ar_rsc);
137 printf("ar.ifs=%#0" PRIx64 "\tar.pfs=%#0" PRIx64 "\n",
138 istate->ar_ifs, istate->ar_pfs);
139 printf("cr.isr=%#0" PRIx64 "\tcr.ipsr=%#0" PRIx64 "\n",
140 istate->cr_isr.value, istate->cr_ipsr.value);
141
142 printf("cr.iip=%#0" PRIxPTR ", #%u\t(%s)\n",
143 istate->cr_iip, istate->cr_isr.ei,
144 symtab_fmt_name_lookup(istate->cr_iip));
145 printf("cr.iipa=%#0" PRIxPTR "\t(%s)\n", istate->cr_iipa,
146 symtab_fmt_name_lookup(istate->cr_iipa));
147 printf("cr.ifa=%#0" PRIxPTR "\t(%s)\n", istate->cr_ifa,
148 symtab_fmt_name_lookup(istate->cr_ifa));
149}
150
151void general_exception(unsigned int n, istate_t *istate)
152{
153 const char *desc;
154
155 switch (istate->cr_isr.ge_code) {
156 case GE_ILLEGALOP:
157 desc = "Illegal Operation fault";
158 break;
159 case GE_PRIVOP:
160 desc = "Privileged Operation fault";
161 break;
162 case GE_PRIVREG:
163 desc = "Privileged Register fault";
164 break;
165 case GE_RESREGFLD:
166 desc = "Reserved Register/Field fault";
167 break;
168 case GE_DISBLDISTRAN:
169 desc = "Disabled Instruction Set Transition fault";
170 break;
171 case GE_ILLEGALDEP:
172 desc = "Illegal Dependency fault";
173 break;
174 default:
175 desc = "unknown";
176 break;
177 }
178
179 fault_if_from_uspace(istate, "General Exception (%s).", desc);
180 panic_badtrap(istate, n, "General Exception (%s).", desc);
181}
182
183void disabled_fp_register(unsigned int n, istate_t *istate)
184{
185#ifdef CONFIG_FPU_LAZY
186 scheduler_fpu_lazy_request();
187#else
188 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
189 (uint16_t) n, vector_to_string(n));
190 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
191 (uint16_t) n, vector_to_string(n));
192#endif
193}
194
195#define BREAK_IMM_SYSCALL 0x40000U
196
197/** Handle syscall. */
198sysarg_t break_instruction(unsigned int n, istate_t *istate)
199{
200 sysarg_t ret;
201
202 if (istate->cr_iim != BREAK_IMM_SYSCALL) {
203 fault_if_from_uspace(istate, "Unknown software interrupt: %x",
204 (uint32_t) istate->cr_iim);
205 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
206 (uint16_t) n, vector_to_string(n));
207 }
208
209 /*
210 * Move to next instruction after BREAK.
211 */
212 if (istate->cr_ipsr.ri == 2) {
213 istate->cr_ipsr.ri = 0;
214 istate->cr_iip += 16;
215 } else {
216 istate->cr_ipsr.ri++;
217 }
218
219 interrupts_enable();
220 ret = syscall_handler(istate->in0, istate->in1, istate->in2,
221 istate->in3, istate->in4, istate->in5, istate->in6);
222 interrupts_disable();
223
224 return ret;
225}
226
227void universal_handler(unsigned int n, istate_t *istate)
228{
229 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
230 n, vector_to_string(n));
231 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
232 n, vector_to_string(n));
233}
234
235static void end_of_local_irq(void)
236{
237 asm volatile (
238 "mov cr.eoi = r0 ;;"
239 );
240}
241
242void external_interrupt(unsigned int n, istate_t *istate)
243{
244 cr_ivr_t ivr;
245
246 ivr.value = ivr_read();
247 srlz_d();
248
249 irq_t *irq;
250
251 switch (ivr.vector) {
252 case INTERRUPT_SPURIOUS:
253#ifdef CONFIG_DEBUG
254 printf("cpu%d: spurious interrupt\n", CPU->id);
255#endif
256 break;
257
258#ifdef CONFIG_SMP
259 case VECTOR_TLB_SHOOTDOWN_IPI:
260 tlb_shootdown_ipi_recv();
261 end_of_local_irq();
262 break;
263#endif
264
265 case INTERRUPT_TIMER:
266 irq = irq_dispatch_and_lock(ivr.vector);
267 if (irq) {
268 irq->handler(irq);
269 irq_spinlock_unlock(&irq->lock, false);
270 } else {
271 panic("Unhandled Internal Timer Interrupt (%d).",
272 ivr.vector);
273 }
274 break;
275 default:
276 irq = irq_dispatch_and_lock(ivr.vector);
277 if (irq) {
278 /*
279 * The IRQ handler was found.
280 */
281 if (irq->preack) {
282 /* Send EOI before processing the interrupt */
283 end_of_local_irq();
284 }
285 irq->handler(irq);
286 if (!irq->preack)
287 end_of_local_irq();
288 irq_spinlock_unlock(&irq->lock, false);
289 } else {
290 /*
291 * Unhandled interrupt.
292 */
293 end_of_local_irq();
294#ifdef CONFIG_DEBUG
295 printf("\nUnhandled External Interrupt Vector %d\n",
296 ivr.vector);
297#endif
298 }
299 break;
300 }
301}
302
303void trap_virtual_enable_irqs(uint16_t irqmask)
304{
305}
306
307void exception_init(void)
308{
309 unsigned int i;
310
311 for (i = 0; i < IVT_ITEMS; i++)
312 exc_register(i, "universal_handler", false, universal_handler);
313
314 exc_register(EXC_ALT_ITLB_FAULT,
315 vector_to_string(EXC_ALT_ITLB_FAULT), true,
316 alternate_instruction_tlb_fault);
317 exc_register(EXC_ALT_DTLB_FAULT,
318 vector_to_string(EXC_ALT_DTLB_FAULT), true,
319 alternate_data_tlb_fault);
320 exc_register(EXC_NESTED_TLB_FAULT,
321 vector_to_string(EXC_NESTED_TLB_FAULT), false,
322 data_nested_tlb_fault);
323 exc_register(EXC_DATA_D_BIT_FAULT,
324 vector_to_string(EXC_DATA_D_BIT_FAULT), true,
325 data_dirty_bit_fault);
326 exc_register(EXC_INST_A_BIT_FAULT,
327 vector_to_string(EXC_INST_A_BIT_FAULT), true,
328 instruction_access_bit_fault);
329 exc_register(EXC_DATA_A_BIT_FAULT,
330 vector_to_string(EXC_DATA_A_BIT_FAULT), true,
331 data_access_bit_fault);
332 exc_register(EXC_EXT_INTERRUPT,
333 vector_to_string(EXC_EXT_INTERRUPT), true,
334 external_interrupt);
335
336 exc_register(EXC_PAGE_NOT_PRESENT,
337 vector_to_string(EXC_PAGE_NOT_PRESENT), true,
338 page_not_present);
339 exc_register(EXC_DATA_AR_FAULT,
340 vector_to_string(EXC_DATA_AR_FAULT), true,
341 data_access_rights_fault);
342 exc_register(EXC_GENERAL_EXCEPTION,
343 vector_to_string(EXC_GENERAL_EXCEPTION), false,
344 general_exception);
345 exc_register(EXC_DISABLED_FP_REG,
346 vector_to_string(EXC_DISABLED_FP_REG), true,
347 disabled_fp_register);
348}
349
350/** @}
351 */
Note: See TracBrowser for help on using the repository browser.