Annotation of sys/arch/sh/sh/vectors.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: vectors.S,v 1.2 2007/05/14 07:05:49 art Exp $ */
2: /* $NetBSD: exception_vector.S,v 1.19 2006/08/22 21:47:57 uwe Exp $ */
3:
4: /*-
5: * Copyright (c) 2002 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the NetBSD
19: * Foundation, Inc. and its contributors.
20: * 4. Neither the name of The NetBSD Foundation nor the names of its
21: * contributors may be used to endorse or promote products derived
22: * from this software without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34: * POSSIBILITY OF SUCH DAMAGE.
35: */
36:
37: #include "assym.h"
38:
39: #include <sh/param.h>
40: #include <sh/asm.h>
41: #include <sh/locore.h>
42: #include <sh/trap.h>
43: #include <sh/ubcreg.h>
44: #include <sh/mmu_sh3.h>
45: #include <sh/mmu_sh4.h>
46:
47: /*
48: * Exception vectors. The following routines are copied to vector addreses.
49: * sh_vector_generic: VBR + 0x100
50: * sh_vector_tlbmiss: VBR + 0x400
51: * sh_vector_interrupt: VBR + 0x600
52: */
53:
54: #define VECTOR_END_MARKER(sym) \
55: .globl _C_LABEL(sym); \
56: _C_LABEL(sym):
57:
58:
59: /*
60: * LINTSTUB: Var: char sh_vector_generic[1];
61: *
62: * void sh_vector_generic(void) __attribute__((__noreturn__))
63: * Copied to VBR+0x100. This code should be position independent
64: * and no more than 786 bytes long (== 0x400 - 0x100).
65: */
66: NENTRY(sh_vector_generic)
67: __EXCEPTION_ENTRY
68: __INTR_MASK(r0, r1)
69: /* Identify exception cause */
70: MOV (EXPEVT, r0)
71: mov.l @r0, r0
72: mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
73: /* Get curproc */
74: mov.l _L.curproc, r1
75: mov.l @r1, r4 /* 1st arg */
76: /* Get TEA */
77: MOV (TEA, r1)
78: mov.l @r1, r6 /* 3rd arg */
79: /* Check TLB exception or not */
80: mov.l _L.TLB_PROT_ST, r1
81: cmp/hi r1, r0
82: bt 1f
83:
84: /* tlb_exception(curproc, trapframe, trunc_page(TEA)); */
85: mov.l _L.VPN_MASK, r1
86: and r1, r6 /* va = trunc_page(va) */
87: __EXCEPTION_UNBLOCK(r0, r1)
88: mov.l _L.tlb, r0
89: jsr @r0
90: mov r14, r5 /* 2nd arg */
91: bra 2f
92: nop
93:
94: /* general_exception(curproc, trapframe, TEA); */
95: 1: mov r4, r8
96: #ifdef DDB
97: mov #0, r2
98: MOV (BBRA, r1)
99: mov.w r2, @r1 /* disable UBC */
100: mov.l r2, @(TF_UBC, r14) /* clear trapframe->tf_ubc */
101: #endif /* DDB */
102: __EXCEPTION_UNBLOCK(r0, r1)
103: mov.l _L.general, r0
104: jsr @r0
105: mov r14, r5 /* 2nd arg */
106:
107: /* Check for ASTs on exit to user mode. */
108: mov r8, r4
109: mov.l _L.ast, r0
110: jsr @r0
111: mov r14, r5
112: #ifdef DDB /* BBRA = trapframe->tf_ubc */
113: __EXCEPTION_BLOCK(r0, r1)
114: mov.l @(TF_UBC, r14), r0
115: MOV (BBRA, r1)
116: mov.w r0, @r1
117: #endif /* DDB */
118: 2: __EXCEPTION_RETURN
119: /* NOTREACHED */
120: .align 2
121: _L.curproc: .long _C_LABEL(cpu_info_store) + CI_CURPROC
122: REG_SYMBOL(EXPEVT)
123: REG_SYMBOL(BBRA)
124: REG_SYMBOL(TEA)
125: _L.tlb: .long _C_LABEL(tlb_exception)
126: _L.general: .long _C_LABEL(general_exception)
127: _L.ast: .long _C_LABEL(ast)
128: _L.TLB_PROT_ST: .long 0xc0
129: _L.VPN_MASK: .long 0xfffff000
130:
131: /* LINTSTUB: Var: char sh_vector_generic_end[1]; */
132: VECTOR_END_MARKER(sh_vector_generic_end)
133: SET_ENTRY_SIZE(sh_vector_generic)
134:
135:
136: #ifdef SH3
137: /*
138: * LINTSTUB: Var: char sh3_vector_tlbmiss[1];
139: *
140: * void sh3_vector_tlbmiss(void) __attribute__((__noreturn__))
141: * Copied to VBR+0x400. This code should be position independent
142: * and no more than 512 bytes long (== 0x600 - 0x400).
143: */
144: NENTRY(sh3_vector_tlbmiss)
145: __EXCEPTION_ENTRY
146: mov #(SH3_TEA & 0xff), r0
147: mov.l @r0, r6 /* 3rd arg: va = TEA */
148: #if !defined(P1_STACK)
149: /* Load kernel stack */
150: mov.l __L.VPN_MASK, r0
151: and r6, r0
152: tst r0, r0 /* check VPN == 0 */
153: bt 6f
154: mov.l _L.CURUPTE, r1
155: mov.l @r1, r1
156: mov #UPAGES,r3
157: mov #1, r2
158: 4: mov.l @r1+, r7
159: cmp/eq r7, r0 /* md_upte.addr: u-area VPN */
160: bt 5f
161: add #4, r1 /* skip md_upte.data */
162: cmp/eq r2, r3
163: bf/s 4b
164: add #1, r2
165: bra 7f /* pull insn at 6f into delay slot */
166: mov #(SH3_EXPEVT & 0xff), r0
167: 5: mov.l @r1, r2 /* md_upte.data: u-area PTE */
168: mov #(SH3_PTEL & 0xff), r1
169: mov.l r2, @r1
170: mov #(SH3_PTEH & 0xff), r1
171: mov.l @r1, r2
172: mov.l __L.VPN_MASK, r0
173: and r2, r0
174: mov.l r0, @r1 /* ASID 0 */
175: ldtlb
176: bra 3f
177: mov.l r2, @r1 /* restore ASID */
178: #endif /* !P1_STACK */
179: 6: mov #(SH3_EXPEVT & 0xff), r0
180: 7: mov.l @r0, r0
181: mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
182: mov.l 2f, r0
183: mov.l @r0, r4 /* 1st arg */
184: __INTR_MASK(r0, r1)
185: __EXCEPTION_UNBLOCK(r0, r1)
186: mov.l 1f, r0
187: jsr @r0
188: mov r14, r5 /* 2nd arg */
189: 3: __EXCEPTION_RETURN
190: .align 2
191: 2: .long _C_LABEL(cpu_info_store) + CI_CURPROC
192: 1: .long _C_LABEL(tlb_exception)
193: __L.VPN_MASK: .long 0xfffff000
194: _L.CURUPTE: .long _C_LABEL(curupte)
195:
196: /* LINTSTUB: Var: char sh3_vector_tlbmiss_end[1]; */
197: VECTOR_END_MARKER(sh3_vector_tlbmiss_end)
198: SET_ENTRY_SIZE(sh3_vector_tlbmiss)
199: #endif /* SH3 */
200:
201:
202: #ifdef SH4
203: /*
204: * LINTSTUB: Var: char sh4_vector_tlbmiss[1];
205: *
206: * void sh4_vector_tlbmiss(void) __attribute__((__noreturn__))
207: * Copied to VBR+0x400. This code should be position independent
208: * and no more than 512 bytes long (== 0x600 - 0x400).
209: */
210: NENTRY(sh4_vector_tlbmiss)
211: __EXCEPTION_ENTRY
212: mov.l _L.TEA4, r0
213: mov.l @r0, r6
214: mov.l _L.EXPEVT4, r0
215: mov.l @r0, r0
216: mov.l r0, @(TF_EXPEVT, r14) /* trapframe->tf_expevt = EXPEVT */
217: mov.l 2f, r0
218: mov.l @r0, r4 /* 1st arg */
219: __INTR_MASK(r0, r1)
220: __EXCEPTION_UNBLOCK(r0, r1)
221: mov.l 1f, r0
222: jsr @r0
223: mov r14, r5 /* 2nd arg */
224: __EXCEPTION_RETURN
225: .align 2
226: 1: .long _C_LABEL(tlb_exception)
227: 2: .long _C_LABEL(cpu_info_store) + CI_CURPROC
228: _L.EXPEVT4: .long SH4_EXPEVT
229: _L.TEA4: .long SH4_TEA
230:
231: /* LINTSTUB: Var: char sh4_vector_tlbmiss_end[1]; */
232: VECTOR_END_MARKER(sh4_vector_tlbmiss_end)
233: SET_ENTRY_SIZE(sh4_vector_tlbmiss)
234: #endif /* SH4 */
235:
236:
237: /*
238: * LINTSTUB: Var: char sh_vector_interrupt[1];
239: *
240: * void sh_vector_interrupt(void) __attribute__((__noreturn__)):
241: * copied to VBR+0x600. This code should be relocatable.
242: */
243: NENTRY(sh_vector_interrupt)
244: __EXCEPTION_ENTRY
245: xor r0, r0
246: mov.l r0, @(TF_EXPEVT, r14) /* (for debug) */
247: stc r0_bank,r6 /* ssp */
248: /* Enable exception for P3 access */
249: __INTR_MASK(r0, r1)
250: __EXCEPTION_UNBLOCK(r0, r1)
251: /* uvmexp.intrs++ */
252: mov.l __L.uvmexp.intrs, r0
253: mov.l @r0, r1
254: add #1 r1
255: mov.l r1, @r0
256: /* Dispatch interrupt handler */
257: mov.l __L.intc_intr, r0
258: jsr @r0 /* intc_intr(ssr, spc, ssp) */
259: nop
260: /* Check for ASTs on exit to user mode. */
261: mov.l 1f, r0
262: mov.l @r0, r4 /* 1st arg */
263: mov.l __L.ast, r0
264: jsr @r0
265: mov r14, r5 /* 2nd arg */
266: __EXCEPTION_RETURN
267: .align 2
268: 1: .long _C_LABEL(cpu_info_store) + CI_CURPROC
269: __L.intc_intr: .long _C_LABEL(intc_intr)
270: __L.ast: .long _C_LABEL(ast)
271: __L.uvmexp.intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS
272:
273: /* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
274: VECTOR_END_MARKER(sh_vector_interrupt_end)
275: SET_ENTRY_SIZE(sh_vector_interrupt)
CVSweb