Subversion Repositories HelenOS

Rev

Rev 3343 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 jermar 1
/*
2071 jermar 2
 * Copyright (c) 2005 Jakub Jermar
3
 * Copyright (c) 2005 Jakub Vana
431 jermar 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.
1702 cejka 28
 */
29
 
1705 cejka 30
/** @addtogroup ia64interrupt
1702 cejka 31
 * @{
32
 */
33
/** @file
431 jermar 34
 */
35
 
36
#include <arch/interrupt.h>
1942 jermar 37
#include <interrupt.h>
38
#include <ddi/irq.h>
431 jermar 39
#include <panic.h>
433 jermar 40
#include <print.h>
1942 jermar 41
#include <symtab.h>
42
#include <debug.h>
583 jermar 43
#include <console/console.h>
431 jermar 44
#include <arch/types.h>
45
#include <arch/asm.h>
46
#include <arch/barrier.h>
432 jermar 47
#include <arch/register.h>
433 jermar 48
#include <arch.h>
921 jermar 49
#include <syscall/syscall.h>
50
#include <print.h>
1023 vana 51
#include <proc/scheduler.h>
1265 jermar 52
#include <ipc/sysipc.h>
1507 vana 53
#include <ipc/irq.h>
54
#include <ipc/ipc.h>
1942 jermar 55
#include <synch/spinlock.h>
3665 rimsky 56
#include <mm/tlb.h>
431 jermar 57
 
470 jermar 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
 
65
char *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
 
88
char *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",
2060 jermar 105
    "Single Step Trap vector",
470 jermar 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
 
1780 jermar 122
static char *vector_to_string(uint16_t vector);
958 jermar 123
static void dump_interrupted_context(istate_t *istate);
470 jermar 124
 
1780 jermar 125
char *vector_to_string(uint16_t vector)
431 jermar 126
{
470 jermar 127
    ASSERT(vector <= VECTOR_MAX);
128
 
129
    if (vector >= VECTORS_16_BUNDLE_START)
2608 jermar 130
        return vector_names_16_bundle[(vector -
131
            VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
470 jermar 132
    else
2608 jermar 133
        return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
470 jermar 134
}
135
 
958 jermar 136
void dump_interrupted_context(istate_t *istate)
470 jermar 137
{
138
    char *ifa, *iipa, *iip;
139
 
958 jermar 140
    ifa = get_symtab_entry(istate->cr_ifa);
141
    iipa = get_symtab_entry(istate->cr_iipa);
142
    iip = get_symtab_entry(istate->cr_iip);
470 jermar 143
 
144
    putchar('\n');
472 jermar 145
    printf("Interrupted context dump:\n");
2608 jermar 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);
470 jermar 154
 
2608 jermar 155
    printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
156
        istate->cr_isr.ei, iip);
1507 vana 157
    printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
158
    printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
470 jermar 159
}
160
 
1780 jermar 161
void general_exception(uint64_t vector, istate_t *istate)
470 jermar 162
{
472 jermar 163
    char *desc = "";
164
 
958 jermar 165
    switch (istate->cr_isr.ge_code) {
1882 jermar 166
    case GE_ILLEGALOP:
472 jermar 167
        desc = "Illegal Operation fault";
168
        break;
1882 jermar 169
    case GE_PRIVOP:
472 jermar 170
        desc = "Privileged Operation fault";
171
        break;
1882 jermar 172
    case GE_PRIVREG:
472 jermar 173
        desc = "Privileged Register fault";
174
        break;
1882 jermar 175
    case GE_RESREGFLD:
472 jermar 176
        desc = "Reserved Register/Field fault";
177
        break;
1882 jermar 178
    case GE_DISBLDISTRAN:
472 jermar 179
        desc = "Disabled Instruction Set Transition fault";
180
        break;
1882 jermar 181
    case GE_ILLEGALDEP:
472 jermar 182
        desc = "Illegal Dependency fault";
183
        break;
1882 jermar 184
    default:
185
        desc = "unknown";
472 jermar 186
        break;
187
    }
188
 
1595 palkovsky 189
    fault_if_from_uspace(istate, "General Exception (%s)", desc);
190
 
191
    dump_interrupted_context(istate);
472 jermar 192
    panic("General Exception (%s)\n", desc);
470 jermar 193
}
194
 
1780 jermar 195
void disabled_fp_register(uint64_t vector, istate_t *istate)
1023 vana 196
{
1053 vana 197
#ifdef CONFIG_FPU_LAZY 
1023 vana 198
    scheduler_fpu_lazy_request();  
1053 vana 199
#else
2608 jermar 200
    fault_if_from_uspace(istate, "Interruption: %#hx (%s)",
201
        (uint16_t) vector, vector_to_string(vector));
1053 vana 202
    dump_interrupted_context(istate);
2608 jermar 203
    panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
204
        vector_to_string(vector));
1023 vana 205
#endif
206
}
207
 
1780 jermar 208
void nop_handler(uint64_t vector, istate_t *istate)
1023 vana 209
{
210
}
211
 
921 jermar 212
/** Handle syscall. */
1780 jermar 213
int break_instruction(uint64_t vector, istate_t *istate)
470 jermar 214
{
921 jermar 215
    /*
216
     * Move to next instruction after BREAK.
217
     */
958 jermar 218
    if (istate->cr_ipsr.ri == 2) {
219
        istate->cr_ipsr.ri = 0;
220
        istate->cr_iip += 16;
921 jermar 221
    } else {
958 jermar 222
        istate->cr_ipsr.ri++;
921 jermar 223
    }
224
 
2608 jermar 225
    return syscall_handler(istate->in0, istate->in1, istate->in2,
226
        istate->in3, istate->in4, istate->in5, istate->in6);
470 jermar 227
}
228
 
1780 jermar 229
void universal_handler(uint64_t vector, istate_t *istate)
470 jermar 230
{
2608 jermar 231
    fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n",
232
        (uint16_t) vector, vector_to_string(vector));
958 jermar 233
    dump_interrupted_context(istate);
2608 jermar 234
    panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
235
        vector_to_string(vector));
470 jermar 236
}
237
 
3665 rimsky 238
static void end_of_local_irq(void)
239
{
240
    asm volatile ("mov cr.eoi=r0;;");
241
}
242
 
243
 
1780 jermar 244
void external_interrupt(uint64_t vector, istate_t *istate)
470 jermar 245
{
433 jermar 246
    cr_ivr_t ivr;
431 jermar 247
 
433 jermar 248
    ivr.value = ivr_read();
431 jermar 249
    srlz_d();
444 vana 250
 
1942 jermar 251
        switch (ivr.vector) {
252
        case INTERRUPT_SPURIOUS:
253
#ifdef CONFIG_DEBUG
254
            printf("cpu%d: spurious interrupt\n", CPU->id);
255
#endif
256
            break;
1265 jermar 257
 
3665 rimsky 258
#ifdef CONFIG_SMP
259
        case VECTOR_TLB_SHOOTDOWN_IPI:
260
            tlb_shootdown_ipi_recv();
261
            end_of_local_irq();
262
            break;
263
#endif
264
 
265
        case INTERRUPT_TIMER:
266
            {
267
 
268
                irq_t *irq = irq_dispatch_and_lock(ivr.vector);
269
                if (irq) {
270
                    irq->handler(irq, irq->arg);
271
                    spinlock_unlock(&irq->lock);
272
                } else {
273
                    panic("\nUnhandled Internal Timer Interrupt (%d)\n",ivr.vector);
274
                }
275
            }  
276
            break;
277
 
1942 jermar 278
        default:
3665 rimsky 279
            {
280
 
281
                int ack=false;
282
                irq_t *irq = irq_dispatch_and_lock(ivr.vector);
283
                if (irq) {
284
                    /*
285
                     * The IRQ handler was found.
286
                     */
287
 
288
                    if (irq->preack) {
289
                        /* Send EOI before processing the interrupt */
290
                        end_of_local_irq();
291
                        ack=true;
292
                    }
293
                    irq->handler(irq, irq->arg);
294
                    spinlock_unlock(&irq->lock);
295
                } else {
296
                    /*
297
                     * Unhandled interrupt.
298
                     */
299
                    end_of_local_irq();
300
                    ack=true;
301
#ifdef CONFIG_DEBUG
302
                    printf("\nUnhandled External Interrupt Vector %d\n",ivr.vector);
303
#endif
304
                }
305
                if(!ack) end_of_local_irq();
306
 
307
            }  
308
 
309
 
1942 jermar 310
            break;
311
        }
1507 vana 312
}
313
 
1703 jermar 314
/** @}
1702 cejka 315
 */