Subversion Repositories HelenOS

Rev

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

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