Subversion Repositories HelenOS

Rev

Rev 3906 | Rev 4137 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3906 Rev 4132
1
/*
1
/*
2
 * Copyright (c) 2005 Jakub Jermar
2
 * Copyright (c) 2005 Jakub Jermar
3
 * Copyright (c) 2005 Jakub Vana
3
 * Copyright (c) 2005 Jakub Vana
4
 * All rights reserved.
4
 * All rights reserved.
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
8
 * are met:
8
 * are met:
9
 *
9
 *
10
 * - Redistributions of source code must retain the above copyright
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
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
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.
16
 *   derived from this software without specific prior written permission.
17
 *
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
28
 */
29
 
29
 
30
/** @addtogroup ia64interrupt
30
/** @addtogroup ia64interrupt
31
 * @{
31
 * @{
32
 */
32
 */
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#include <arch/interrupt.h>
36
#include <arch/interrupt.h>
37
#include <interrupt.h>
37
#include <interrupt.h>
38
#include <ddi/irq.h>
38
#include <ddi/irq.h>
39
#include <panic.h>
39
#include <panic.h>
40
#include <print.h>
40
#include <print.h>
41
#include <symtab.h>
-
 
42
#include <debug.h>
41
#include <debug.h>
43
#include <console/console.h>
42
#include <console/console.h>
44
#include <arch/types.h>
43
#include <arch/types.h>
45
#include <arch/asm.h>
44
#include <arch/asm.h>
46
#include <arch/barrier.h>
45
#include <arch/barrier.h>
47
#include <arch/register.h>
46
#include <arch/register.h>
48
#include <arch.h>
47
#include <arch.h>
49
#include <syscall/syscall.h>
48
#include <syscall/syscall.h>
50
#include <print.h>
49
#include <print.h>
51
#include <proc/scheduler.h>
50
#include <proc/scheduler.h>
52
#include <ipc/sysipc.h>
51
#include <ipc/sysipc.h>
53
#include <ipc/irq.h>
52
#include <ipc/irq.h>
54
#include <ipc/ipc.h>
53
#include <ipc/ipc.h>
55
#include <synch/spinlock.h>
54
#include <synch/spinlock.h>
56
#include <mm/tlb.h>
55
#include <mm/tlb.h>
57
 
56
 
-
 
57
#ifdef CONFIG_SYMTAB
-
 
58
#include <symtab.h>
-
 
59
#endif
-
 
60
 
58
#define VECTORS_64_BUNDLE   20
61
#define VECTORS_64_BUNDLE   20
59
#define VECTORS_16_BUNDLE   48
62
#define VECTORS_16_BUNDLE   48
60
#define VECTORS_16_BUNDLE_START 0x5000
63
#define VECTORS_16_BUNDLE_START 0x5000
61
#define VECTOR_MAX      0x7f00
64
#define VECTOR_MAX      0x7f00
62
 
65
 
63
#define BUNDLE_SIZE     16
66
#define BUNDLE_SIZE     16
64
 
67
 
65
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
68
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
66
    "VHPT Translation vector",
69
    "VHPT Translation vector",
67
    "Instruction TLB vector",
70
    "Instruction TLB vector",
68
    "Data TLB vector",
71
    "Data TLB vector",
69
    "Alternate Instruction TLB vector",
72
    "Alternate Instruction TLB vector",
70
    "Alternate Data TLB vector",
73
    "Alternate Data TLB vector",
71
    "Data Nested TLB vector",
74
    "Data Nested TLB vector",
72
    "Instruction Key Miss vector",
75
    "Instruction Key Miss vector",
73
    "Data Key Miss vector",
76
    "Data Key Miss vector",
74
    "Dirty-Bit vector",
77
    "Dirty-Bit vector",
75
    "Instruction Access-Bit vector",
78
    "Instruction Access-Bit vector",
76
    "Data Access-Bit vector"
79
    "Data Access-Bit vector"
77
    "Break Instruction vector",
80
    "Break Instruction vector",
78
    "External Interrupt vector"
81
    "External Interrupt vector"
79
    "Reserved",
82
    "Reserved",
80
    "Reserved",
83
    "Reserved",
81
    "Reserved",
84
    "Reserved",
82
    "Reserved",
85
    "Reserved",
83
    "Reserved",
86
    "Reserved",
84
    "Reserved",
87
    "Reserved",
85
    "Reserved"
88
    "Reserved"
86
};
89
};
87
 
90
 
88
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
91
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
89
    "Page Not Present vector",
92
    "Page Not Present vector",
90
    "Key Permission vector",
93
    "Key Permission vector",
91
    "Instruction Access rights vector",
94
    "Instruction Access rights vector",
92
    "Data Access Rights vector",
95
    "Data Access Rights vector",
93
    "General Exception vector",
96
    "General Exception vector",
94
    "Disabled FP-Register vector",
97
    "Disabled FP-Register vector",
95
    "NaT Consumption vector",
98
    "NaT Consumption vector",
96
    "Speculation vector",
99
    "Speculation vector",
97
    "Reserved",
100
    "Reserved",
98
    "Debug vector",
101
    "Debug vector",
99
    "Unaligned Reference vector",
102
    "Unaligned Reference vector",
100
    "Unsupported Data Reference vector",
103
    "Unsupported Data Reference vector",
101
    "Floating-point Fault vector",
104
    "Floating-point Fault vector",
102
    "Floating-point Trap vector",
105
    "Floating-point Trap vector",
103
    "Lower-Privilege Transfer Trap vector",
106
    "Lower-Privilege Transfer Trap vector",
104
    "Taken Branch Trap vector",
107
    "Taken Branch Trap vector",
105
    "Single Step Trap vector",
108
    "Single Step Trap vector",
106
    "Reserved",
109
    "Reserved",
107
    "Reserved",
110
    "Reserved",
108
    "Reserved",
111
    "Reserved",
109
    "Reserved",
112
    "Reserved",
110
    "Reserved",
113
    "Reserved",
111
    "Reserved",
114
    "Reserved",
112
    "Reserved",
115
    "Reserved",
113
    "Reserved",
116
    "Reserved",
114
    "IA-32 Exception vector",
117
    "IA-32 Exception vector",
115
    "IA-32 Intercept vector",
118
    "IA-32 Intercept vector",
116
    "IA-32 Interrupt vector",
119
    "IA-32 Interrupt vector",
117
    "Reserved",
120
    "Reserved",
118
    "Reserved",
121
    "Reserved",
119
    "Reserved"
122
    "Reserved"
120
};
123
};
121
 
124
 
122
static char *vector_to_string(uint16_t vector);
125
static char *vector_to_string(uint16_t vector);
123
static void dump_interrupted_context(istate_t *istate);
126
static void dump_interrupted_context(istate_t *istate);
124
 
127
 
125
char *vector_to_string(uint16_t vector)
128
char *vector_to_string(uint16_t vector)
126
{
129
{
127
    ASSERT(vector <= VECTOR_MAX);
130
    ASSERT(vector <= VECTOR_MAX);
128
   
131
   
129
    if (vector >= VECTORS_16_BUNDLE_START)
132
    if (vector >= VECTORS_16_BUNDLE_START)
130
        return vector_names_16_bundle[(vector -
133
        return vector_names_16_bundle[(vector -
131
            VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
134
            VECTORS_16_BUNDLE_START) / (16 * BUNDLE_SIZE)];
132
    else
135
    else
133
        return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
136
        return vector_names_64_bundle[vector / (64 * BUNDLE_SIZE)];
134
}
137
}
135
 
138
 
136
void dump_interrupted_context(istate_t *istate)
139
void dump_interrupted_context(istate_t *istate)
137
{
140
{
138
    char *ifa, *iipa, *iip;
141
    char *ifa, *iipa, *iip;
139
 
142
 
-
 
143
#ifdef CONFIG_SYMTAB
140
    ifa = get_symtab_entry(istate->cr_ifa);
144
    ifa = get_symtab_entry(istate->cr_ifa);
141
    iipa = get_symtab_entry(istate->cr_iipa);
145
    iipa = get_symtab_entry(istate->cr_iipa);
142
    iip = get_symtab_entry(istate->cr_iip);
146
    iip = get_symtab_entry(istate->cr_iip);
-
 
147
#else
-
 
148
    ifa = iipa = iip = "n/a";
-
 
149
#endif
143
 
150
 
144
    putchar('\n');
151
    putchar('\n');
145
    printf("Interrupted context dump:\n");
152
    printf("Interrupted context dump:\n");
146
    printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
153
    printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
147
        istate->ar_bspstore);
154
        istate->ar_bspstore);
148
    printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
155
    printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat,
149
        istate->ar_rsc);
156
        istate->ar_rsc);
150
    printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
157
    printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs,
151
        istate->ar_pfs);
158
        istate->ar_pfs);
152
    printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
159
    printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value,
153
        istate->cr_ipsr);
160
        istate->cr_ipsr);
154
   
161
   
155
    printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
162
    printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
156
        istate->cr_isr.ei, iip);
163
        istate->cr_isr.ei, iip);
157
    printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
164
    printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
158
    printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
165
    printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
159
}
166
}
160
 
167
 
161
void general_exception(uint64_t vector, istate_t *istate)
168
void general_exception(uint64_t vector, istate_t *istate)
162
{
169
{
163
    char *desc = "";
170
    char *desc = "";
164
 
171
 
165
    switch (istate->cr_isr.ge_code) {
172
    switch (istate->cr_isr.ge_code) {
166
    case GE_ILLEGALOP:
173
    case GE_ILLEGALOP:
167
        desc = "Illegal Operation fault";
174
        desc = "Illegal Operation fault";
168
        break;
175
        break;
169
    case GE_PRIVOP:
176
    case GE_PRIVOP:
170
        desc = "Privileged Operation fault";
177
        desc = "Privileged Operation fault";
171
        break;
178
        break;
172
    case GE_PRIVREG:
179
    case GE_PRIVREG:
173
        desc = "Privileged Register fault";
180
        desc = "Privileged Register fault";
174
        break;
181
        break;
175
    case GE_RESREGFLD:
182
    case GE_RESREGFLD:
176
        desc = "Reserved Register/Field fault";
183
        desc = "Reserved Register/Field fault";
177
        break;
184
        break;
178
    case GE_DISBLDISTRAN:
185
    case GE_DISBLDISTRAN:
179
        desc = "Disabled Instruction Set Transition fault";
186
        desc = "Disabled Instruction Set Transition fault";
180
        break;
187
        break;
181
    case GE_ILLEGALDEP:
188
    case GE_ILLEGALDEP:
182
        desc = "Illegal Dependency fault";
189
        desc = "Illegal Dependency fault";
183
        break;
190
        break;
184
    default:
191
    default:
185
        desc = "unknown";
192
        desc = "unknown";
186
        break;
193
        break;
187
    }
194
    }
188
 
195
 
189
    fault_if_from_uspace(istate, "General Exception (%s).", desc);
196
    fault_if_from_uspace(istate, "General Exception (%s).", desc);
190
 
197
 
191
    dump_interrupted_context(istate);
198
    dump_interrupted_context(istate);
192
    panic("General Exception (%s).", desc);
199
    panic("General Exception (%s).", desc);
193
}
200
}
194
 
201
 
195
void disabled_fp_register(uint64_t vector, istate_t *istate)
202
void disabled_fp_register(uint64_t vector, istate_t *istate)
196
{
203
{
197
#ifdef CONFIG_FPU_LAZY
204
#ifdef CONFIG_FPU_LAZY
198
    scheduler_fpu_lazy_request();
205
    scheduler_fpu_lazy_request();
199
#else
206
#else
200
    fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
207
    fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
201
        (uint16_t) vector, vector_to_string(vector));
208
        (uint16_t) vector, vector_to_string(vector));
202
    dump_interrupted_context(istate);
209
    dump_interrupted_context(istate);
203
    panic("Interruption: %#hx (%s).", (uint16_t) vector,
210
    panic("Interruption: %#hx (%s).", (uint16_t) vector,
204
        vector_to_string(vector));
211
        vector_to_string(vector));
205
#endif
212
#endif
206
}
213
}
207
 
214
 
208
void nop_handler(uint64_t vector, istate_t *istate)
215
void nop_handler(uint64_t vector, istate_t *istate)
209
{
216
{
210
}
217
}
211
 
218
 
212
/** Handle syscall. */
219
/** Handle syscall. */
213
int break_instruction(uint64_t vector, istate_t *istate)
220
int break_instruction(uint64_t vector, istate_t *istate)
214
{
221
{
215
    /*
222
    /*
216
     * Move to next instruction after BREAK.
223
     * Move to next instruction after BREAK.
217
     */
224
     */
218
    if (istate->cr_ipsr.ri == 2) {
225
    if (istate->cr_ipsr.ri == 2) {
219
        istate->cr_ipsr.ri = 0;
226
        istate->cr_ipsr.ri = 0;
220
        istate->cr_iip += 16;
227
        istate->cr_iip += 16;
221
    } else {
228
    } else {
222
        istate->cr_ipsr.ri++;
229
        istate->cr_ipsr.ri++;
223
    }
230
    }
224
 
231
 
225
    return syscall_handler(istate->in0, istate->in1, istate->in2,
232
    return syscall_handler(istate->in0, istate->in1, istate->in2,
226
        istate->in3, istate->in4, istate->in5, istate->in6);
233
        istate->in3, istate->in4, istate->in5, istate->in6);
227
}
234
}
228
 
235
 
229
void universal_handler(uint64_t vector, istate_t *istate)
236
void universal_handler(uint64_t vector, istate_t *istate)
230
{
237
{
231
    fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
238
    fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
232
        (uint16_t) vector, vector_to_string(vector));
239
        (uint16_t) vector, vector_to_string(vector));
233
    dump_interrupted_context(istate);
240
    dump_interrupted_context(istate);
234
    panic("Interruption: %#hx (%s).", (uint16_t) vector,
241
    panic("Interruption: %#hx (%s).", (uint16_t) vector,
235
        vector_to_string(vector));
242
        vector_to_string(vector));
236
}
243
}
237
 
244
 
238
static void end_of_local_irq(void)
245
static void end_of_local_irq(void)
239
{
246
{
240
    asm volatile ("mov cr.eoi=r0;;");
247
    asm volatile ("mov cr.eoi=r0;;");
241
}
248
}
242
 
249
 
243
 
250
 
244
void external_interrupt(uint64_t vector, istate_t *istate)
251
void external_interrupt(uint64_t vector, istate_t *istate)
245
{
252
{
246
    cr_ivr_t ivr;
253
    cr_ivr_t ivr;
247
    irq_t *irq;
254
    irq_t *irq;
248
   
255
   
249
    ivr.value = ivr_read();
256
    ivr.value = ivr_read();
250
    srlz_d();
257
    srlz_d();
251
 
258
 
252
    switch (ivr.vector) {
259
    switch (ivr.vector) {
253
    case INTERRUPT_SPURIOUS:
260
    case INTERRUPT_SPURIOUS:
254
#ifdef CONFIG_DEBUG
261
#ifdef CONFIG_DEBUG
255
        printf("cpu%d: spurious interrupt\n", CPU->id);
262
        printf("cpu%d: spurious interrupt\n", CPU->id);
256
#endif
263
#endif
257
        break;
264
        break;
258
 
265
 
259
#ifdef CONFIG_SMP
266
#ifdef CONFIG_SMP
260
    case VECTOR_TLB_SHOOTDOWN_IPI:
267
    case VECTOR_TLB_SHOOTDOWN_IPI:
261
        tlb_shootdown_ipi_recv();
268
        tlb_shootdown_ipi_recv();
262
        end_of_local_irq();
269
        end_of_local_irq();
263
        break;
270
        break;
264
#endif
271
#endif
265
 
272
 
266
    case INTERRUPT_TIMER:
273
    case INTERRUPT_TIMER:
267
        irq = irq_dispatch_and_lock(ivr.vector);
274
        irq = irq_dispatch_and_lock(ivr.vector);
268
        if (irq) {
275
        if (irq) {
269
            irq->handler(irq);
276
            irq->handler(irq);
270
            spinlock_unlock(&irq->lock);
277
            spinlock_unlock(&irq->lock);
271
        } else {
278
        } else {
272
            panic("Unhandled Internal Timer Interrupt (%d).",
279
            panic("Unhandled Internal Timer Interrupt (%d).",
273
                ivr.vector);
280
                ivr.vector);
274
        }
281
        }
275
        break;
282
        break;
276
    default:
283
    default:
277
        irq = irq_dispatch_and_lock(ivr.vector);
284
        irq = irq_dispatch_and_lock(ivr.vector);
278
        if (irq) {
285
        if (irq) {
279
            /*
286
            /*
280
             * The IRQ handler was found.
287
             * The IRQ handler was found.
281
             */
288
             */
282
            if (irq->preack) {
289
            if (irq->preack) {
283
                /* Send EOI before processing the interrupt */
290
                /* Send EOI before processing the interrupt */
284
                end_of_local_irq();
291
                end_of_local_irq();
285
            }
292
            }
286
            irq->handler(irq);
293
            irq->handler(irq);
287
            if (!irq->preack)
294
            if (!irq->preack)
288
                end_of_local_irq();
295
                end_of_local_irq();
289
            spinlock_unlock(&irq->lock);
296
            spinlock_unlock(&irq->lock);
290
        } else {
297
        } else {
291
            /*
298
            /*
292
             * Unhandled interrupt.
299
             * Unhandled interrupt.
293
             */
300
             */
294
            end_of_local_irq();
301
            end_of_local_irq();
295
#ifdef CONFIG_DEBUG
302
#ifdef CONFIG_DEBUG
296
            printf("\nUnhandled External Interrupt Vector %d\n",
303
            printf("\nUnhandled External Interrupt Vector %d\n",
297
                ivr.vector);
304
                ivr.vector);
298
#endif
305
#endif
299
        }
306
        }
300
        break;
307
        break;
301
    }
308
    }
302
}
309
}
303
 
310
 
304
void trap_virtual_enable_irqs(uint16_t irqmask)
311
void trap_virtual_enable_irqs(uint16_t irqmask)
305
{
312
{
306
}
313
}
307
 
314
 
308
/** @}
315
/** @}
309
 */
316
 */
310
 
317