Subversion Repositories HelenOS-historic

Rev

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

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