Subversion Repositories HelenOS

Rev

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

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