Subversion Repositories HelenOS

Rev

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

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