Subversion Repositories HelenOS

Rev

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