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

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

Support for sparc64 FPU context.

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[dbd1059]1/*
2 * Copyright (C) 2005 Jakub Jermar
[e2ec980f]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>
37#include <panic.h>
[05d9dd89]38#include <print.h>
[72f5866d]39#include <console/console.h>
[dbd1059]40#include <arch/types.h>
41#include <arch/asm.h>
42#include <arch/barrier.h>
[0259524]43#include <arch/register.h>
[154049e]44#include <arch/drivers/it.h>
[05d9dd89]45#include <arch.h>
[e2ec980f]46#include <symtab.h>
47#include <debug.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>
[874621f]54#include <interrupt.h>
[953b0f33]55
[dbd1059]56
[e2ec980f]57#define VECTORS_64_BUNDLE 20
58#define VECTORS_16_BUNDLE 48
59#define VECTORS_16_BUNDLE_START 0x5000
60#define VECTOR_MAX 0x7f00
61
62#define BUNDLE_SIZE 16
63
[d0c5901]64
[e2ec980f]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",
105 "Single STep Trap vector",
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)
130 return vector_names_16_bundle[(vector-VECTORS_16_BUNDLE_START)/(16*BUNDLE_SIZE)];
131 else
132 return vector_names_64_bundle[vector/(64*BUNDLE_SIZE)];
133}
134
[25d7709]135void dump_interrupted_context(istate_t *istate)
[e2ec980f]136{
137 char *ifa, *iipa, *iip;
138
[25d7709]139 ifa = get_symtab_entry(istate->cr_ifa);
140 iipa = get_symtab_entry(istate->cr_iipa);
141 iip = get_symtab_entry(istate->cr_iip);
[e2ec980f]142
143 putchar('\n');
[2ccd275]144 printf("Interrupted context dump:\n");
[cf85e24c]145 printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp, istate->ar_bspstore);
[d0c5901]146 printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat, istate->ar_rsc);
147 printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs, istate->ar_pfs);
148 printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value, istate->cr_ipsr);
[e2ec980f]149
[d0c5901]150 printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei, iip);
151 printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
152 printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
[e2ec980f]153}
154
[7f1c620]155void general_exception(uint64_t vector, istate_t *istate)
[e2ec980f]156{
[2ccd275]157 char *desc = "";
158
[25d7709]159 switch (istate->cr_isr.ge_code) {
[6eabb6e6]160 case GE_ILLEGALOP:
[2ccd275]161 desc = "Illegal Operation fault";
162 break;
[6eabb6e6]163 case GE_PRIVOP:
[2ccd275]164 desc = "Privileged Operation fault";
165 break;
[6eabb6e6]166 case GE_PRIVREG:
[2ccd275]167 desc = "Privileged Register fault";
168 break;
[6eabb6e6]169 case GE_RESREGFLD:
[2ccd275]170 desc = "Reserved Register/Field fault";
171 break;
[6eabb6e6]172 case GE_DISBLDISTRAN:
[2ccd275]173 desc = "Disabled Instruction Set Transition fault";
174 break;
[6eabb6e6]175 case GE_ILLEGALDEP:
[2ccd275]176 desc = "Illegal Dependency fault";
177 break;
[6eabb6e6]178 default:
179 desc = "unknown";
[2ccd275]180 break;
181 }
182
[874621f]183 fault_if_from_uspace(istate, "General Exception (%s)", desc);
184
185 dump_interrupted_context(istate);
[2ccd275]186 panic("General Exception (%s)\n", desc);
[e2ec980f]187}
188
[7f1c620]189void disabled_fp_register(uint64_t vector, istate_t *istate)
[9e1c942]190{
[41fa6f2]191#ifdef CONFIG_FPU_LAZY
[9e1c942]192 scheduler_fpu_lazy_request();
[41fa6f2]193#else
[7f1c620]194 fault_if_from_uspace(istate, "Interruption: %#hx (%s)", (uint16_t) vector, vector_to_string(vector));
[41fa6f2]195 dump_interrupted_context(istate);
[7f1c620]196 panic("Interruption: %#hx (%s)\n", (uint16_t) vector, vector_to_string(vector));
[9e1c942]197#endif
198}
199
200
[7f1c620]201void nop_handler(uint64_t vector, istate_t *istate)
[9e1c942]202{
203}
204
205
[901122b]206/** Handle syscall. */
[7f1c620]207int break_instruction(uint64_t vector, istate_t *istate)
[e2ec980f]208{
[901122b]209 /*
210 * Move to next instruction after BREAK.
211 */
[25d7709]212 if (istate->cr_ipsr.ri == 2) {
213 istate->cr_ipsr.ri = 0;
214 istate->cr_iip += 16;
[901122b]215 } else {
[25d7709]216 istate->cr_ipsr.ri++;
[901122b]217 }
218
[5c089c3a]219 if (istate->in4 < SYSCALL_END)
220 return syscall_table[istate->in4](istate->in0, istate->in1, istate->in2, istate->in3);
[901122b]221 else
[5c089c3a]222 panic("Undefined syscall %d", istate->in4);
[901122b]223
224 return -1;
[e2ec980f]225}
226
[7f1c620]227void universal_handler(uint64_t vector, istate_t *istate)
[e2ec980f]228{
[7f1c620]229 fault_if_from_uspace(istate,"Interruption: %#hx (%s)\n",(uint16_t) vector, vector_to_string(vector));
[25d7709]230 dump_interrupted_context(istate);
[7f1c620]231 panic("Interruption: %#hx (%s)\n", (uint16_t) vector, vector_to_string(vector));
[e2ec980f]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();
[83817ea]240
[dd118f0]241 switch(ivr.vector) {
[6eabb6e6]242 case INTERRUPT_TIMER:
[154049e]243 it_interrupt();
[6eabb6e6]244 break;
245 case INTERRUPT_SPURIOUS:
[05d9dd89]246 printf("cpu%d: spurious interrupt\n", CPU->id);
247 break;
[6eabb6e6]248 default:
[05d9dd89]249 panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector);
250 break;
[dbd1059]251 }
252}
[953b0f33]253
[6eabb6e6]254void virtual_interrupt(uint64_t irq, void *param)
[d0c5901]255{
256 switch(irq) {
[6eabb6e6]257 case IRQ_KBD:
258 if (kbd_uspace)
259 ipc_irq_send_notif(irq);
260 break;
261 default:
262 panic("\nUnhandled Virtual Interrupt request %d\n", irq);
[d0c5901]263 break;
264 }
265}
266
[953b0f33]267/* Reregister irq to be IPC-ready */
[7f1c620]268void irq_ipc_bind_arch(unative_t irq)
[953b0f33]269{
[6eabb6e6]270 if(irq == IRQ_KBD) {
271 kbd_uspace = 1;
[d0c5901]272 return;
273 }
[a175a67]274 return;
[953b0f33]275 panic("not implemented\n");
276 /* TODO */
277}
[b45c443]278
[3222efd]279/** @}
[b45c443]280 */
Note: See TracBrowser for help on using the repository browser.