Subversion Repositories HelenOS

Rev

Rev 4220 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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