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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 002fd5f was 002fd5f, checked in by jzr <zarevucky.jiri@…>, 8 years ago

Replace parts of system headers with <_bits/…>.

  • Property mode set to 100644
File size: 8.8 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 <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 <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 <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 "Reserved",
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, vector, "Interruption: %#hx (%s).",
193 (uint16_t) n, vector_to_string(n));
194#endif
195}
196
197/** Handle syscall. */
198sysarg_t break_instruction(unsigned int n, istate_t *istate)
199{
200 sysarg_t ret;
201
202 /*
203 * Move to next instruction after BREAK.
204 */
205 if (istate->cr_ipsr.ri == 2) {
206 istate->cr_ipsr.ri = 0;
207 istate->cr_iip += 16;
208 } else {
209 istate->cr_ipsr.ri++;
210 }
211
212 interrupts_enable();
213 ret = syscall_handler(istate->in0, istate->in1, istate->in2,
214 istate->in3, istate->in4, istate->in5, istate->in6);
215 interrupts_disable();
216
217 return ret;
218}
219
220void universal_handler(unsigned int n, istate_t *istate)
221{
222 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
223 n, vector_to_string(n));
224 panic_badtrap(istate, n, "Interruption: %#hx (%s).",
225 n, vector_to_string(n));
226}
227
228static void end_of_local_irq(void)
229{
230 asm volatile (
231 "mov cr.eoi = r0 ;;"
232 );
233}
234
235void external_interrupt(unsigned int n, istate_t *istate)
236{
237 cr_ivr_t ivr;
238
239 ivr.value = ivr_read();
240 srlz_d();
241
242 irq_t *irq;
243
244 switch (ivr.vector) {
245 case INTERRUPT_SPURIOUS:
246#ifdef CONFIG_DEBUG
247 printf("cpu%d: spurious interrupt\n", CPU->id);
248#endif
249 break;
250
251#ifdef CONFIG_SMP
252 case VECTOR_TLB_SHOOTDOWN_IPI:
253 tlb_shootdown_ipi_recv();
254 end_of_local_irq();
255 break;
256#endif
257
258 case INTERRUPT_TIMER:
259 irq = irq_dispatch_and_lock(ivr.vector);
260 if (irq) {
261 irq->handler(irq);
262 irq_spinlock_unlock(&irq->lock, false);
263 } else {
264 panic("Unhandled Internal Timer Interrupt (%d).",
265 ivr.vector);
266 }
267 break;
268 default:
269 irq = irq_dispatch_and_lock(ivr.vector);
270 if (irq) {
271 /*
272 * The IRQ handler was found.
273 */
274 if (irq->preack) {
275 /* Send EOI before processing the interrupt */
276 end_of_local_irq();
277 }
278 irq->handler(irq);
279 if (!irq->preack)
280 end_of_local_irq();
281 irq_spinlock_unlock(&irq->lock, false);
282 } else {
283 /*
284 * Unhandled interrupt.
285 */
286 end_of_local_irq();
287#ifdef CONFIG_DEBUG
288 printf("\nUnhandled External Interrupt Vector %d\n",
289 ivr.vector);
290#endif
291 }
292 break;
293 }
294}
295
296void trap_virtual_enable_irqs(uint16_t irqmask)
297{
298}
299
300void exception_init(void)
301{
302 unsigned int i;
303
304 for (i = 0; i < IVT_ITEMS; i++)
305 exc_register(i, "universal_handler", false, universal_handler);
306
307 exc_register(EXC_ALT_ITLB_FAULT,
308 vector_to_string(EXC_ALT_ITLB_FAULT), true,
309 alternate_instruction_tlb_fault);
310 exc_register(EXC_ALT_DTLB_FAULT,
311 vector_to_string(EXC_ALT_DTLB_FAULT), true,
312 alternate_data_tlb_fault);
313 exc_register(EXC_NESTED_TLB_FAULT,
314 vector_to_string(EXC_NESTED_TLB_FAULT), false,
315 data_nested_tlb_fault);
316 exc_register(EXC_DATA_D_BIT_FAULT,
317 vector_to_string(EXC_DATA_D_BIT_FAULT), true,
318 data_dirty_bit_fault);
319 exc_register(EXC_INST_A_BIT_FAULT,
320 vector_to_string(EXC_INST_A_BIT_FAULT), true,
321 instruction_access_bit_fault);
322 exc_register(EXC_DATA_A_BIT_FAULT,
323 vector_to_string(EXC_DATA_A_BIT_FAULT), true,
324 data_access_bit_fault);
325 exc_register(EXC_EXT_INTERRUPT,
326 vector_to_string(EXC_EXT_INTERRUPT), true,
327 external_interrupt);
328
329 exc_register(EXC_PAGE_NOT_PRESENT,
330 vector_to_string(EXC_PAGE_NOT_PRESENT), true,
331 page_not_present);
332 exc_register(EXC_DATA_AR_FAULT,
333 vector_to_string(EXC_DATA_AR_FAULT), true,
334 data_access_rights_fault);
335 exc_register(EXC_GENERAL_EXCEPTION,
336 vector_to_string(EXC_GENERAL_EXCEPTION), false,
337 general_exception);
338 exc_register(EXC_DISABLED_FP_REG,
339 vector_to_string(EXC_DISABLED_FP_REG), true,
340 disabled_fp_register);
341}
342
343/** @}
344 */
Note: See TracBrowser for help on using the repository browser.