source: mainline/arch/mips32/src/exception.c@ 78a95d6f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 78a95d6f was 052da81, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Fixes in memory allocator

  • proper kernel blacklisting, when kernel not loaded on page boundary
  • correct zone adding in zone list (how could this work??)
  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (C) 2003-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
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
15 * derived from this software without specific prior written permission.
16 *
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
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <arch/exception.h>
30#include <arch/interrupt.h>
31#include <panic.h>
32#include <arch/cp0.h>
33#include <arch/types.h>
34#include <arch.h>
35#include <debug.h>
36#include <proc/thread.h>
37#include <symtab.h>
38#include <print.h>
39#include <interrupt.h>
40#include <func.h>
41#include <console/kconsole.h>
42#include <arch/debugger.h>
43#include <syscall/syscall.h>
44
45static char * exctable[] = {
46 "Interrupt","TLB Modified","TLB Invalid","TLB Invalid Store",
47 "Address Error - load/instr. fetch",
48 "Address Error - store",
49 "Bus Error - fetch instruction",
50 "Bus Error - data reference",
51 "Syscall",
52 "BreakPoint",
53 "Reserved Instruction",
54 "Coprocessor Unusable",
55 "Arithmetic Overflow",
56 "Trap",
57 "Virtual Coherency - instruction",
58 "Floating Point",
59 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
60 "WatchHi/WatchLo", /* 23 */
61 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
62 "Virtual Coherency - data",
63};
64
65static void print_regdump(struct exception_regdump *pstate)
66{
67 char *pcsymbol = "";
68 char *rasymbol = "";
69
70 char *s = get_symtab_entry(pstate->epc);
71 if (s)
72 pcsymbol = s;
73 s = get_symtab_entry(pstate->ra);
74 if (s)
75 rasymbol = s;
76
77 printf("PC: %X(%s) RA: %X(%s), SP(%P)\n",pstate->epc,pcsymbol,
78 pstate->ra,rasymbol, pstate->sp);
79}
80
81static void unhandled_exception(int n, struct exception_regdump *pstate)
82{
83 print_regdump(pstate);
84 panic("unhandled exception %s\n", exctable[n]);
85}
86
87static void breakpoint_exception(int n, struct exception_regdump *pstate)
88{
89#ifdef CONFIG_DEBUG
90 debugger_bpoint(pstate);
91#else
92 /* it is necessary to not re-execute BREAK instruction after
93 returning from Exception handler
94 (see page 138 in R4000 Manual for more information) */
95 pstate->epc += 4;
96#endif
97}
98
99static void tlbmod_exception(int n, struct exception_regdump *pstate)
100{
101 tlb_modified(pstate);
102}
103
104static void tlbinv_exception(int n, struct exception_regdump *pstate)
105{
106 tlb_invalid(pstate);
107}
108
109#ifdef CONFIG_FPU_LAZY
110static void cpuns_exception(int n, struct exception_regdump *pstate)
111{
112 if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
113 scheduler_fpu_lazy_request();
114 else
115 panic("unhandled Coprocessor Unusable Exception\n");
116}
117#endif
118
119static void interrupt_exception(int n, struct exception_regdump *pstate)
120{
121 __u32 cause;
122 int i;
123
124 /* decode interrupt number and process the interrupt */
125 cause = (cp0_cause_read() >> 8) &0xff;
126
127 for (i = 0; i < 8; i++)
128 if (cause & (1 << i))
129 exc_dispatch(i+INT_OFFSET, pstate);
130}
131
132#include <debug.h>
133/** Handle syscall userspace call */
134static void syscall_exception(int n, struct exception_regdump *pstate)
135{
136 if (pstate->a3 < SYSCALL_END)
137 pstate->v0 = syscall_table[pstate->a3](pstate->a0,
138 pstate->a1,
139 pstate->a2);
140 else
141 panic("Undefined syscall %d", pstate->a3);
142 pstate->epc += 4;
143}
144
145
146void exception(struct exception_regdump *pstate)
147{
148 int cause;
149 int excno;
150
151 ASSERT(CPU != NULL);
152
153 /*
154 * NOTE ON OPERATION ORDERING
155 *
156 * On entry, interrupts_disable() must be called before
157 * exception bit is cleared.
158 */
159
160 interrupts_disable();
161 cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit |
162 cp0_status_um_bit));
163
164 /* Save pstate so that the threads can access it */
165 /* If THREAD->pstate is set, this is nested exception,
166 * do not rewrite it
167 */
168 if (THREAD && !THREAD->pstate)
169 THREAD->pstate = pstate;
170
171 cause = cp0_cause_read();
172 excno = cp0_cause_excno(cause);
173 /* Dispatch exception */
174 exc_dispatch(excno, pstate);
175
176 /* Set to NULL, so that we can still support nested
177 * exceptions
178 * TODO: We should probably set EXL bit before this command,
179 * nesting. On the other hand, if some exception occurs between
180 * here and ERET, it won't set anything on the pstate anyway.
181 */
182 if (THREAD)
183 THREAD->pstate = NULL;
184}
185
186void exception_init(void)
187{
188 int i;
189
190 /* Clear exception table */
191 for (i=0;i < IVT_ITEMS; i++)
192 exc_register(i, "undef", (iroutine) unhandled_exception);
193 exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
194 exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
195 exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
196 exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
197 exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
198#ifdef CONFIG_FPU_LAZY
199 exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
200#endif
201 exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
202}
Note: See TracBrowser for help on using the repository browser.