Subversion Repositories HelenOS-historic

Rev

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

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