Subversion Repositories HelenOS

Rev

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

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