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

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

use [u]int{8|16|32|64}_t type definitions as detected by the autotool
replace direct usage of arch/types.h with typedefs.h

  • 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 <debug.h>
[72f5866d]42#include <console/console.h>
[d99c1d2]43#include <typedefs.h>
[dbd1059]44#include <arch/asm.h>
45#include <arch/barrier.h>
[0259524]46#include <arch/register.h>
[05d9dd89]47#include <arch.h>
[901122b]48#include <syscall/syscall.h>
49#include <print.h>
[9e1c942]50#include <proc/scheduler.h>
[953b0f33]51#include <ipc/sysipc.h>
[d0c5901]52#include <ipc/irq.h>
53#include <ipc/ipc.h>
[de57e060]54#include <synch/spinlock.h>
[7782030]55#include <mm/tlb.h>
[e2b762ec]56#include <symtab.h>
[b60c582]57#include <putchar.h>
[e2b762ec]58
[e2ec980f]59#define VECTORS_64_BUNDLE 20
60#define VECTORS_16_BUNDLE 48
61#define VECTORS_16_BUNDLE_START 0x5000
62#define VECTOR_MAX 0x7f00
63
64#define BUNDLE_SIZE 16
65
[a000878c]66static const char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
[e2ec980f]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
[a000878c]89static const char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
[e2ec980f]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",
[66eb2c8]106 "Single Step Trap vector",
[e2ec980f]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
[a000878c]123static const char *vector_to_string(uint16_t vector)
[e2ec980f]124{
125 ASSERT(vector <= VECTOR_MAX);
126
127 if (vector >= VECTORS_16_BUNDLE_START)
[1b03ed3]128 return vector_names_16_bundle[(vector -
129 VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
[e2ec980f]130 else
[1b03ed3]131 return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
[e2ec980f]132}
133
[a000878c]134static void dump_interrupted_context(istate_t *istate)
[e2ec980f]135{
[a000878c]136 const char *ifa = symtab_fmt_name_lookup(istate->cr_ifa);
137 const char *iipa = symtab_fmt_name_lookup(istate->cr_iipa);
138 const char *iip = symtab_fmt_name_lookup(istate->cr_iip);
139
[e2ec980f]140 putchar('\n');
[2ccd275]141 printf("Interrupted context dump:\n");
[1b03ed3]142 printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
143 istate->ar_bspstore);
144 printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
145 istate->ar_rsc);
146 printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
147 istate->ar_pfs);
148 printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
149 istate->cr_ipsr);
[e2ec980f]150
[1b03ed3]151 printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
152 istate->cr_isr.ei, iip);
[d0c5901]153 printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
154 printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
[e2ec980f]155}
156
[7f1c620]157void general_exception(uint64_t vector, istate_t *istate)
[e2ec980f]158{
[a000878c]159 const char *desc;
160
[25d7709]161 switch (istate->cr_isr.ge_code) {
[6eabb6e6]162 case GE_ILLEGALOP:
[2ccd275]163 desc = "Illegal Operation fault";
164 break;
[6eabb6e6]165 case GE_PRIVOP:
[2ccd275]166 desc = "Privileged Operation fault";
167 break;
[6eabb6e6]168 case GE_PRIVREG:
[2ccd275]169 desc = "Privileged Register fault";
170 break;
[6eabb6e6]171 case GE_RESREGFLD:
[2ccd275]172 desc = "Reserved Register/Field fault";
173 break;
[6eabb6e6]174 case GE_DISBLDISTRAN:
[2ccd275]175 desc = "Disabled Instruction Set Transition fault";
176 break;
[6eabb6e6]177 case GE_ILLEGALDEP:
[2ccd275]178 desc = "Illegal Dependency fault";
179 break;
[6eabb6e6]180 default:
181 desc = "unknown";
[2ccd275]182 break;
183 }
[a000878c]184
[f651e80]185 fault_if_from_uspace(istate, "General Exception (%s).", desc);
[a000878c]186
[874621f]187 dump_interrupted_context(istate);
[f651e80]188 panic("General Exception (%s).", desc);
[e2ec980f]189}
190
[7f1c620]191void disabled_fp_register(uint64_t vector, istate_t *istate)
[9e1c942]192{
[6da1013f]193#ifdef CONFIG_FPU_LAZY
194 scheduler_fpu_lazy_request();
[41fa6f2]195#else
[f651e80]196 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
[1b03ed3]197 (uint16_t) vector, vector_to_string(vector));
[41fa6f2]198 dump_interrupted_context(istate);
[f651e80]199 panic("Interruption: %#hx (%s).", (uint16_t) vector,
[1b03ed3]200 vector_to_string(vector));
[9e1c942]201#endif
202}
203
[7f1c620]204void nop_handler(uint64_t vector, istate_t *istate)
[9e1c942]205{
206}
207
[901122b]208/** Handle syscall. */
[7f1c620]209int break_instruction(uint64_t vector, istate_t *istate)
[e2ec980f]210{
[901122b]211 /*
212 * Move to next instruction after BREAK.
213 */
[25d7709]214 if (istate->cr_ipsr.ri == 2) {
215 istate->cr_ipsr.ri = 0;
216 istate->cr_iip += 16;
[901122b]217 } else {
[25d7709]218 istate->cr_ipsr.ri++;
[901122b]219 }
220
[1b03ed3]221 return syscall_handler(istate->in0, istate->in1, istate->in2,
222 istate->in3, istate->in4, istate->in5, istate->in6);
[e2ec980f]223}
224
[7f1c620]225void universal_handler(uint64_t vector, istate_t *istate)
[e2ec980f]226{
[f651e80]227 fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
[1b03ed3]228 (uint16_t) vector, vector_to_string(vector));
[25d7709]229 dump_interrupted_context(istate);
[f651e80]230 panic("Interruption: %#hx (%s).", (uint16_t) vector,
[1b03ed3]231 vector_to_string(vector));
[e2ec980f]232}
233
[323a5aaf]234static void end_of_local_irq(void)
[7782030]235{
236 asm volatile ("mov cr.eoi=r0;;");
237}
238
239
[7f1c620]240void external_interrupt(uint64_t vector, istate_t *istate)
[dbd1059]241{
[05d9dd89]242 cr_ivr_t ivr;
[666773c]243 irq_t *irq;
[dbd1059]244
[05d9dd89]245 ivr.value = ivr_read();
[dbd1059]246 srlz_d();
[83817ea]247
[666773c]248 switch (ivr.vector) {
249 case INTERRUPT_SPURIOUS:
[de57e060]250#ifdef CONFIG_DEBUG
[666773c]251 printf("cpu%d: spurious interrupt\n", CPU->id);
[de57e060]252#endif
[666773c]253 break;
[953b0f33]254
[7782030]255#ifdef CONFIG_SMP
[666773c]256 case VECTOR_TLB_SHOOTDOWN_IPI:
257 tlb_shootdown_ipi_recv();
258 end_of_local_irq();
259 break;
[7782030]260#endif
261
[666773c]262 case INTERRUPT_TIMER:
263 irq = irq_dispatch_and_lock(ivr.vector);
264 if (irq) {
[6cd9aa6]265 irq->handler(irq);
[666773c]266 spinlock_unlock(&irq->lock);
267 } else {
[f651e80]268 panic("Unhandled Internal Timer Interrupt (%d).",
[666773c]269 ivr.vector);
270 }
271 break;
272 default:
273 irq = irq_dispatch_and_lock(ivr.vector);
274 if (irq) {
275 /*
276 * The IRQ handler was found.
277 */
278 if (irq->preack) {
279 /* Send EOI before processing the interrupt */
280 end_of_local_irq();
281 }
[6cd9aa6]282 irq->handler(irq);
[666773c]283 if (!irq->preack)
284 end_of_local_irq();
285 spinlock_unlock(&irq->lock);
286 } else {
287 /*
288 * Unhandled interrupt.
289 */
290 end_of_local_irq();
[323a5aaf]291#ifdef CONFIG_DEBUG
[666773c]292 printf("\nUnhandled External Interrupt Vector %d\n",
293 ivr.vector);
[323a5aaf]294#endif
[de57e060]295 }
[666773c]296 break;
297 }
[d0c5901]298}
299
[6da1013f]300void trap_virtual_enable_irqs(uint16_t irqmask)
301{
302}
303
[3222efd]304/** @}
[b45c443]305 */
Note: See TracBrowser for help on using the repository browser.