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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 411b6a6 was 6cd9aa6, checked in by Jakub Jermar <jakub@…>, 16 years ago

IRQ handlers are using one superfluous argument and an unused elipsis.
On the other hand, IRQ claim functions would need to be passed the instance
argument.

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