Subversion Repositories HelenOS-historic

Rev

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

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