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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4fe907b9 was 22a28a69, checked in by Jakub Jermar <jakub@…>, 15 years ago

Rename decode_istate() to istate_decode() and declare it only once in
the generic interrupt.h.

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