Subversion Repositories HelenOS-historic

Rev

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

Rev 1096 Rev 1100
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
#include <syscall/syscall.h>
-
 
44
 
43
 
45
static char * exctable[] = {
44
static char * exctable[] = {
46
    "Interrupt","TLB Modified","TLB Invalid","TLB Invalid Store",
45
    "Interrupt","TLB Modified","TLB Invalid","TLB Invalid Store",
47
        "Address Error - load/instr. fetch",
46
        "Address Error - load/instr. fetch",
48
        "Address Error - store",
47
        "Address Error - store",
49
        "Bus Error - fetch instruction",
48
        "Bus Error - fetch instruction",
50
        "Bus Error - data reference",
49
        "Bus Error - data reference",
51
        "Syscall",
50
        "Syscall",
52
        "BreakPoint",
51
        "BreakPoint",
53
        "Reserved Instruction",
52
        "Reserved Instruction",
54
        "Coprocessor Unusable",
53
        "Coprocessor Unusable",
55
        "Arithmetic Overflow",
54
        "Arithmetic Overflow",
56
        "Trap",
55
        "Trap",
57
        "Virtual Coherency - instruction",
56
        "Virtual Coherency - instruction",
58
        "Floating Point",
57
        "Floating Point",
59
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
58
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
60
        "WatchHi/WatchLo", /* 23 */
59
        "WatchHi/WatchLo", /* 23 */
61
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
60
        NULL, NULL, NULL, NULL, NULL, NULL, NULL,
62
        "Virtual Coherency - data",
61
        "Virtual Coherency - data",
63
};
62
};
64
 
63
 
65
static void print_regdump(istate_t *istate)
64
static void print_regdump(istate_t *istate)
66
{
65
{
67
    char *pcsymbol = "";
66
    char *pcsymbol = "";
68
    char *rasymbol = "";
67
    char *rasymbol = "";
69
 
68
 
70
    char *s = get_symtab_entry(istate->epc);
69
    char *s = get_symtab_entry(istate->epc);
71
    if (s)
70
    if (s)
72
        pcsymbol = s;
71
        pcsymbol = s;
73
    s = get_symtab_entry(istate->ra);
72
    s = get_symtab_entry(istate->ra);
74
    if (s)
73
    if (s)
75
        rasymbol = s;
74
        rasymbol = s;
76
   
75
   
77
    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,
78
           istate->ra,rasymbol, istate->sp);
77
           istate->ra,rasymbol, istate->sp);
79
}
78
}
80
 
79
 
81
static void unhandled_exception(int n, istate_t *istate)
80
static void unhandled_exception(int n, istate_t *istate)
82
{
81
{
83
    print_regdump(istate);
82
    print_regdump(istate);
84
    panic("unhandled exception %s\n", exctable[n]);
83
    panic("unhandled exception %s\n", exctable[n]);
85
}
84
}
86
 
85
 
87
static void breakpoint_exception(int n, istate_t *istate)
86
static void breakpoint_exception(int n, istate_t *istate)
88
{
87
{
89
#ifdef CONFIG_DEBUG
88
#ifdef CONFIG_DEBUG
90
    debugger_bpoint(istate);
89
    debugger_bpoint(istate);
91
#else
90
#else
92
    /* it is necessary to not re-execute BREAK instruction after
91
    /* it is necessary to not re-execute BREAK instruction after
93
       returning from Exception handler
92
       returning from Exception handler
94
       (see page 138 in R4000 Manual for more information) */
93
       (see page 138 in R4000 Manual for more information) */
95
    istate->epc += 4;
94
    istate->epc += 4;
96
#endif
95
#endif
97
}
96
}
98
 
97
 
99
static void tlbmod_exception(int n, istate_t *istate)
98
static void tlbmod_exception(int n, istate_t *istate)
100
{
99
{
101
    tlb_modified(istate);
100
    tlb_modified(istate);
102
}
101
}
103
 
102
 
104
static void tlbinv_exception(int n, istate_t *istate)
103
static void tlbinv_exception(int n, istate_t *istate)
105
{
104
{
106
    tlb_invalid(istate);
105
    tlb_invalid(istate);
107
}
106
}
108
 
107
 
109
#ifdef CONFIG_FPU_LAZY
108
#ifdef CONFIG_FPU_LAZY
110
static void cpuns_exception(int n, istate_t *istate)
109
static void cpuns_exception(int n, istate_t *istate)
111
{
110
{
112
    if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
111
    if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
113
        scheduler_fpu_lazy_request();
112
        scheduler_fpu_lazy_request();
114
    else
113
    else
115
        panic("unhandled Coprocessor Unusable Exception\n");
114
        panic("unhandled Coprocessor Unusable Exception\n");
116
}
115
}
117
#endif
116
#endif
118
 
117
 
119
static void interrupt_exception(int n, istate_t *istate)
118
static void interrupt_exception(int n, istate_t *istate)
120
{
119
{
121
    __u32 cause;
120
    __u32 cause;
122
    int i;
121
    int i;
123
   
122
   
124
    /* decode interrupt number and process the interrupt */
123
    /* decode interrupt number and process the interrupt */
125
    cause = (cp0_cause_read() >> 8) &0xff;
124
    cause = (cp0_cause_read() >> 8) &0xff;
126
   
125
   
127
    for (i = 0; i < 8; i++)
126
    for (i = 0; i < 8; i++)
128
        if (cause & (1 << i))
127
        if (cause & (1 << i))
129
            exc_dispatch(i+INT_OFFSET, istate);
128
            exc_dispatch(i+INT_OFFSET, istate);
130
}
129
}
131
 
-
 
132
__native syscall_handler(__native a0, __native a1, __native a2,
-
 
133
             __native a3, __native sysnum)
-
 
134
{
-
 
135
    if (sysnum < SYSCALL_END)
-
 
136
        return syscall_table[sysnum](a0,a1,a2,a3);
-
 
137
    panic("Undefined syscall %d", sysnum);
-
 
138
}
-
 
139
 
130
 
140
/** Handle syscall userspace call */
131
/** Handle syscall userspace call */
141
static void syscall_exception(int n, istate_t *istate)
132
static void syscall_exception(int n, istate_t *istate)
142
{
133
{
143
    panic("Syscall is handled through shortcut");
134
    panic("Syscall is handled through shortcut");
144
}
135
}
145
 
136
 
146
void exception_init(void)
137
void exception_init(void)
147
{
138
{
148
    int i;
139
    int i;
149
 
140
 
150
    /* Clear exception table */
141
    /* Clear exception table */
151
    for (i=0;i < IVT_ITEMS; i++)
142
    for (i=0;i < IVT_ITEMS; i++)
152
        exc_register(i, "undef", (iroutine) unhandled_exception);
143
        exc_register(i, "undef", (iroutine) unhandled_exception);
153
    exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
144
    exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
154
    exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
145
    exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
155
    exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
146
    exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
156
    exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
147
    exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
157
    exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
148
    exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
158
#ifdef CONFIG_FPU_LAZY
149
#ifdef CONFIG_FPU_LAZY
159
    exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
150
    exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
160
#endif
151
#endif
161
    exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
152
    exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
162
}
153
}
163
 
154