Subversion Repositories HelenOS-historic

Rev

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

Rev 1100 Rev 1119
1
/*
1
/*
2
 * Copyright (C) 2003-2004 Jakub Jermar
2
 * Copyright (C) 2003-2004 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
#include <arch/exception.h>
29
#include <arch/exception.h>
30
#include <arch/interrupt.h>
30
#include <arch/interrupt.h>
31
#include <panic.h>
31
#include <panic.h>
32
#include <arch/cp0.h>
32
#include <arch/cp0.h>
33
#include <arch/types.h>
33
#include <arch/types.h>
34
#include <arch.h>
34
#include <arch.h>
35
#include <debug.h>
35
#include <debug.h>
36
#include <proc/thread.h>
36
#include <proc/thread.h>
37
#include <symtab.h>
37
#include <symtab.h>
38
#include <print.h>
38
#include <print.h>
39
#include <interrupt.h>
39
#include <interrupt.h>
40
#include <func.h>
40
#include <func.h>
41
#include <console/kconsole.h>
41
#include <console/kconsole.h>
42
#include <arch/debugger.h>
42
#include <arch/debugger.h>
43
 
43
 
44
static char * exctable[] = {
44
static char * exctable[] = {
45
    "Interrupt","TLB Modified","TLB Invalid","TLB Invalid Store",
45
    "Interrupt","TLB Modified","TLB Invalid","TLB Invalid Store",
46
        "Address Error - load/instr. fetch",
46
        "Address Error - load/instr. fetch",
47
        "Address Error - store",
47
        "Address Error - store",
48
        "Bus Error - fetch instruction",
48
        "Bus Error - fetch instruction",
49
        "Bus Error - data reference",
49
        "Bus Error - data reference",
50
        "Syscall",
50
        "Syscall",
51
        "BreakPoint",
51
        "BreakPoint",
52
        "Reserved Instruction",
52
        "Reserved Instruction",
53
        "Coprocessor Unusable",
53
        "Coprocessor Unusable",
54
        "Arithmetic Overflow",
54
        "Arithmetic Overflow",
55
        "Trap",
55
        "Trap",
56
        "Virtual Coherency - instruction",
56
        "Virtual Coherency - instruction",
57
        "Floating Point",
57
        "Floating Point",
58
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
58
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
59
        "WatchHi/WatchLo", /* 23 */
59
        "WatchHi/WatchLo", /* 23 */
60
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
60
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
61
        "Virtual Coherency - data",
61
        "Virtual Coherency - data",
62
};
62
};
63
 
63
 
64
static void print_regdump(istate_t *istate)
64
static void print_regdump(istate_t *istate)
65
{
65
{
66
    char *pcsymbol = "";
66
    char *pcsymbol = "";
67
    char *rasymbol = "";
67
    char *rasymbol = "";
68
 
68
 
69
    char *s = get_symtab_entry(istate->epc);
69
    char *s = get_symtab_entry(istate->epc);
70
    if (s)
70
    if (s)
71
        pcsymbol = s;
71
        pcsymbol = s;
72
    s = get_symtab_entry(istate->ra);
72
    s = get_symtab_entry(istate->ra);
73
    if (s)
73
    if (s)
74
        rasymbol = s;
74
        rasymbol = s;
75
   
75
   
76
    printf("PC: %X(%s) RA: %X(%s), SP(%P)\n",istate->epc,pcsymbol,
76
    printf("PC: %X(%s) RA: %X(%s), SP(%P)\n",istate->epc,pcsymbol,
77
           istate->ra,rasymbol, istate->sp);
77
           istate->ra,rasymbol, istate->sp);
78
}
78
}
79
 
79
 
80
static void unhandled_exception(int n, istate_t *istate)
80
static void unhandled_exception(int n, istate_t *istate)
81
{
81
{
82
    print_regdump(istate);
82
    print_regdump(istate);
83
    panic("unhandled exception %s\n", exctable[n]);
83
    panic("unhandled exception %s\n", exctable[n]);
84
}
84
}
85
 
85
 
-
 
86
static void reserved_instr_exception(int n, istate_t *istate)
-
 
87
{
-
 
88
    if (*((__u32 *)istate->epc) == 0x7c03e83b) {
-
 
89
        ASSERT(THREAD);
-
 
90
        istate->epc += 4;
-
 
91
        istate->v1 = istate->k1;
-
 
92
    } else {
-
 
93
        print_regdump(istate);
-
 
94
        panic("reserved instruction");
-
 
95
    }
-
 
96
}
-
 
97
 
86
static void breakpoint_exception(int n, istate_t *istate)
98
static void breakpoint_exception(int n, istate_t *istate)
87
{
99
{
88
#ifdef CONFIG_DEBUG
100
#ifdef CONFIG_DEBUG
89
    debugger_bpoint(istate);
101
    debugger_bpoint(istate);
90
#else
102
#else
91
    /* it is necessary to not re-execute BREAK instruction after
103
    /* it is necessary to not re-execute BREAK instruction after
92
       returning from Exception handler
104
       returning from Exception handler
93
       (see page 138 in R4000 Manual for more information) */
105
       (see page 138 in R4000 Manual for more information) */
94
    istate->epc += 4;
106
    istate->epc += 4;
95
#endif
107
#endif
96
}
108
}
97
 
109
 
98
static void tlbmod_exception(int n, istate_t *istate)
110
static void tlbmod_exception(int n, istate_t *istate)
99
{
111
{
100
    tlb_modified(istate);
112
    tlb_modified(istate);
101
}
113
}
102
 
114
 
103
static void tlbinv_exception(int n, istate_t *istate)
115
static void tlbinv_exception(int n, istate_t *istate)
104
{
116
{
105
    tlb_invalid(istate);
117
    tlb_invalid(istate);
106
}
118
}
107
 
119
 
108
#ifdef CONFIG_FPU_LAZY
120
#ifdef CONFIG_FPU_LAZY
109
static void cpuns_exception(int n, istate_t *istate)
121
static void cpuns_exception(int n, istate_t *istate)
110
{
122
{
111
    if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
123
    if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
112
        scheduler_fpu_lazy_request();
124
        scheduler_fpu_lazy_request();
113
    else
125
    else
114
        panic("unhandled Coprocessor Unusable Exception\n");
126
        panic("unhandled Coprocessor Unusable Exception\n");
115
}
127
}
116
#endif
128
#endif
117
 
129
 
118
static void interrupt_exception(int n, istate_t *istate)
130
static void interrupt_exception(int n, istate_t *istate)
119
{
131
{
120
    __u32 cause;
132
    __u32 cause;
121
    int i;
133
    int i;
122
   
134
   
123
    /* decode interrupt number and process the interrupt */
135
    /* decode interrupt number and process the interrupt */
124
    cause = (cp0_cause_read() >> 8) &0xff;
136
    cause = (cp0_cause_read() >> 8) &0xff;
125
   
137
   
126
    for (i = 0; i < 8; i++)
138
    for (i = 0; i < 8; i++)
127
        if (cause & (1 << i))
139
        if (cause & (1 << i))
128
            exc_dispatch(i+INT_OFFSET, istate);
140
            exc_dispatch(i+INT_OFFSET, istate);
129
}
141
}
130
 
142
 
131
/** Handle syscall userspace call */
143
/** Handle syscall userspace call */
132
static void syscall_exception(int n, istate_t *istate)
144
static void syscall_exception(int n, istate_t *istate)
133
{
145
{
134
    panic("Syscall is handled through shortcut");
146
    panic("Syscall is handled through shortcut");
135
}
147
}
136
 
148
 
137
void exception_init(void)
149
void exception_init(void)
138
{
150
{
139
    int i;
151
    int i;
140
 
152
 
141
    /* Clear exception table */
153
    /* Clear exception table */
142
    for (i=0;i < IVT_ITEMS; i++)
154
    for (i=0;i < IVT_ITEMS; i++)
143
        exc_register(i, "undef", (iroutine) unhandled_exception);
155
        exc_register(i, "undef", (iroutine) unhandled_exception);
144
    exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
156
    exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
-
 
157
    exc_register(EXC_RI, "resinstr", (iroutine) reserved_instr_exception);
145
    exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
158
    exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
146
    exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
159
    exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
147
    exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
160
    exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
148
    exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
161
    exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
149
#ifdef CONFIG_FPU_LAZY
162
#ifdef CONFIG_FPU_LAZY
150
    exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
163
    exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
151
#endif
164
#endif
152
    exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
165
    exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
153
}
166
}
154
 
167