Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/sh/crt1.asm @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2009 | |
2 Free Software Foundation, Inc. | |
3 This file was pretty much copied from newlib. | |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 3, or (at your option) any | |
10 later version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 General Public License for more details. | |
16 | |
17 Under Section 7 of GPL version 3, you are granted additional | |
18 permissions described in the GCC Runtime Library Exception, version | |
19 3.1, as published by the Free Software Foundation. | |
20 | |
21 You should have received a copy of the GNU General Public License and | |
22 a copy of the GCC Runtime Library Exception along with this program; | |
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 <http://www.gnu.org/licenses/>. */ | |
25 | |
26 | |
27 #ifdef MMU_SUPPORT | |
28 /* Section used for exception/timer interrupt stack area */ | |
29 .section .data.vbr.stack,"aw" | |
30 .align 4 | |
31 .global __ST_VBR | |
32 __ST_VBR: | |
33 .zero 1024 * 2 /* ; 2k for VBR handlers */ | |
34 /* Label at the highest stack address where the stack grows from */ | |
35 __timer_stack: | |
36 #endif /* MMU_SUPPORT */ | |
37 | |
38 /* ;---------------------------------------- | |
39 Normal newlib crt1.asm */ | |
40 | |
41 #ifdef __SH5__ | |
42 .section .data,"aw" | |
43 .global ___data | |
44 ___data: | |
45 | |
46 .section .rodata,"a" | |
47 .global ___rodata | |
48 ___rodata: | |
49 | |
50 #define ICCR_BASE 0x01600000 | |
51 #define OCCR_BASE 0x01e00000 | |
52 #define MMUIR_BASE 0x00000000 | |
53 #define MMUDR_BASE 0x00800000 | |
54 | |
55 #define PTE_ENABLED 1 | |
56 #define PTE_DISABLED 0 | |
57 | |
58 #define PTE_SHARED (1 << 1) | |
59 #define PTE_NOT_SHARED 0 | |
60 | |
61 #define PTE_CB_UNCACHEABLE 0 | |
62 #define PTE_CB_DEVICE 1 | |
63 #define PTE_CB_CACHEABLE_WB 2 | |
64 #define PTE_CB_CACHEABLE_WT 3 | |
65 | |
66 #define PTE_SZ_4KB (0 << 3) | |
67 #define PTE_SZ_64KB (1 << 3) | |
68 #define PTE_SZ_1MB (2 << 3) | |
69 #define PTE_SZ_512MB (3 << 3) | |
70 | |
71 #define PTE_PRR (1 << 6) | |
72 #define PTE_PRX (1 << 7) | |
73 #define PTE_PRW (1 << 8) | |
74 #define PTE_PRU (1 << 9) | |
75 | |
76 #define SR_MMU_BIT 31 | |
77 #define SR_BL_BIT 28 | |
78 | |
79 #define ALIGN_4KB (0xfff) | |
80 #define ALIGN_1MB (0xfffff) | |
81 #define ALIGN_512MB (0x1fffffff) | |
82 | |
83 #define DYNACON_BASE 0x0f000000 | |
84 #define DM_CB_DLINK_BASE 0x0c000000 | |
85 #define DM_DB_DLINK_BASE 0x0b000000 | |
86 | |
87 #define FEMI_AREA_0 0x00000000 | |
88 #define FEMI_AREA_1 0x04000000 | |
89 #define FEMI_AREA_2 0x05000000 | |
90 #define FEMI_AREA_3 0x06000000 | |
91 #define FEMI_AREA_4 0x07000000 | |
92 #define FEMI_CB 0x08000000 | |
93 | |
94 #define EMI_BASE 0X80000000 | |
95 | |
96 #define DMA_BASE 0X0e000000 | |
97 | |
98 #define CPU_BASE 0X0d000000 | |
99 | |
100 #define PERIPH_BASE 0X09000000 | |
101 #define DMAC_BASE 0x0e000000 | |
102 #define INTC_BASE 0x0a000000 | |
103 #define CPRC_BASE 0x0a010000 | |
104 #define TMU_BASE 0x0a020000 | |
105 #define SCIF_BASE 0x0a030000 | |
106 #define RTC_BASE 0x0a040000 | |
107 | |
108 | |
109 | |
110 #define LOAD_CONST32(val, reg) \ | |
111 movi ((val) >> 16) & 65535, reg; \ | |
112 shori (val) & 65535, reg | |
113 | |
114 #define LOAD_PTEH_VAL(sym, align, bits, scratch_reg, reg) \ | |
115 LOAD_ADDR (sym, reg); \ | |
116 LOAD_CONST32 ((align), scratch_reg); \ | |
117 andc reg, scratch_reg, reg; \ | |
118 LOAD_CONST32 ((bits), scratch_reg); \ | |
119 or reg, scratch_reg, reg | |
120 | |
121 #define LOAD_PTEL_VAL(sym, align, bits, scratch_reg, reg) \ | |
122 LOAD_ADDR (sym, reg); \ | |
123 LOAD_CONST32 ((align), scratch_reg); \ | |
124 andc reg, scratch_reg, reg; \ | |
125 LOAD_CONST32 ((bits), scratch_reg); \ | |
126 or reg, scratch_reg, reg | |
127 | |
128 #define SET_PTE(pte_addr_reg, pteh_val_reg, ptel_val_reg) \ | |
129 putcfg pte_addr_reg, 0, r63; \ | |
130 putcfg pte_addr_reg, 1, ptel_val_reg; \ | |
131 putcfg pte_addr_reg, 0, pteh_val_reg | |
132 | |
133 #if __SH5__ == 64 | |
134 .section .text,"ax" | |
135 #define LOAD_ADDR(sym, reg) \ | |
136 movi (sym >> 48) & 65535, reg; \ | |
137 shori (sym >> 32) & 65535, reg; \ | |
138 shori (sym >> 16) & 65535, reg; \ | |
139 shori sym & 65535, reg | |
140 #else | |
141 .mode SHmedia | |
142 .section .text..SHmedia32,"ax" | |
143 #define LOAD_ADDR(sym, reg) \ | |
144 movi (sym >> 16) & 65535, reg; \ | |
145 shori sym & 65535, reg | |
146 #endif | |
147 .global start | |
148 start: | |
149 LOAD_ADDR (_stack, r15) | |
150 | |
151 #ifdef MMU_SUPPORT | |
152 ! Set up the VM using the MMU and caches | |
153 | |
154 ! .vm_ep is first instruction to execute | |
155 ! after VM initialization | |
156 pt/l .vm_ep, tr1 | |
157 | |
158 ! Configure instruction cache (ICCR) | |
159 movi 3, r2 | |
160 movi 0, r3 | |
161 LOAD_ADDR (ICCR_BASE, r1) | |
162 putcfg r1, 0, r2 | |
163 putcfg r1, 1, r3 | |
164 | |
165 ! movi 7, r2 ! write through | |
166 ! Configure operand cache (OCCR) | |
167 LOAD_ADDR (OCCR_BASE, r1) | |
168 putcfg r1, 0, r2 | |
169 putcfg r1, 1, r3 | |
170 | |
171 ! Disable all PTE translations | |
172 LOAD_ADDR (MMUIR_BASE, r1) | |
173 LOAD_ADDR (MMUDR_BASE, r2) | |
174 movi 64, r3 | |
175 pt/l .disable_ptes_loop, tr0 | |
176 .disable_ptes_loop: | |
177 putcfg r1, 0, r63 | |
178 putcfg r2, 0, r63 | |
179 addi r1, 16, r1 | |
180 addi r2, 16, r2 | |
181 addi r3, -1, r3 | |
182 bgt r3, r63, tr0 | |
183 | |
184 LOAD_ADDR (MMUIR_BASE, r1) | |
185 | |
186 ! FEMI instruction mappings | |
187 ! Area 0 - 1Mb cacheable at 0x00000000 | |
188 ! Area 1 - None | |
189 ! Area 2 - 1Mb cacheable at 0x05000000 | |
190 ! - 1Mb cacheable at 0x05100000 | |
191 ! Area 3 - None | |
192 ! Area 4 - None | |
193 | |
194 ! Map a 1Mb page for instructions at 0x00000000 | |
195 LOAD_PTEH_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
196 LOAD_PTEL_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3) | |
197 SET_PTE (r1, r2, r3) | |
198 | |
199 ! Map a 1Mb page for instructions at 0x05000000 | |
200 addi r1, 16, r1 | |
201 LOAD_PTEH_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
202 LOAD_PTEL_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3) | |
203 SET_PTE (r1, r2, r3) | |
204 | |
205 ! Map a 1Mb page for instructions at 0x05100000 | |
206 addi r1, 16, r1 | |
207 LOAD_PTEH_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
208 LOAD_PTEL_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3) | |
209 SET_PTE (r1, r2, r3) | |
210 | |
211 ! Map a 512M page for instructions at EMI base | |
212 addi r1, 16, r1 | |
213 LOAD_PTEH_VAL (EMI_BASE, ALIGN_512MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
214 LOAD_PTEL_VAL (EMI_BASE, ALIGN_512MB, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRX | PTE_PRU, r25, r3) | |
215 SET_PTE (r1, r2, r3) | |
216 | |
217 ! Map a 4K page for instructions at DM_DB_DLINK_BASE | |
218 addi r1, 16, r1 | |
219 LOAD_PTEH_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
220 LOAD_PTEL_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRX | PTE_PRU, r25, r3) | |
221 SET_PTE (r1, r2, r3) | |
222 | |
223 LOAD_ADDR (MMUDR_BASE, r1) | |
224 | |
225 ! FEMI data mappings | |
226 ! Area 0 - 1Mb cacheable at 0x00000000 | |
227 ! Area 1 - 1Mb device at 0x04000000 | |
228 ! Area 2 - 1Mb cacheable at 0x05000000 | |
229 ! - 1Mb cacheable at 0x05100000 | |
230 ! Area 3 - None | |
231 ! Area 4 - None | |
232 ! CB - 1Mb device at 0x08000000 | |
233 | |
234 ! Map a 1Mb page for data at 0x00000000 | |
235 LOAD_PTEH_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
236 LOAD_PTEL_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
237 SET_PTE (r1, r2, r3) | |
238 | |
239 ! Map a 1Mb page for data at 0x04000000 | |
240 addi r1, 16, r1 | |
241 LOAD_PTEH_VAL (FEMI_AREA_1, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
242 LOAD_PTEL_VAL (FEMI_AREA_1, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
243 SET_PTE (r1, r2, r3) | |
244 | |
245 ! Map a 1Mb page for data at 0x05000000 | |
246 addi r1, 16, r1 | |
247 LOAD_PTEH_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
248 LOAD_PTEL_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
249 SET_PTE (r1, r2, r3) | |
250 | |
251 ! Map a 1Mb page for data at 0x05100000 | |
252 addi r1, 16, r1 | |
253 LOAD_PTEH_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
254 LOAD_PTEL_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
255 SET_PTE (r1, r2, r3) | |
256 | |
257 ! Map a 4K page for registers at 0x08000000 | |
258 addi r1, 16, r1 | |
259 LOAD_PTEH_VAL (FEMI_CB, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
260 LOAD_PTEL_VAL (FEMI_CB, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
261 SET_PTE (r1, r2, r3) | |
262 | |
263 ! Map a 512M page for data at EMI | |
264 addi r1, 16, r1 | |
265 LOAD_PTEH_VAL (EMI_BASE, ALIGN_512MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
266 LOAD_PTEL_VAL (EMI_BASE, ALIGN_512MB, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
267 SET_PTE (r1, r2, r3) | |
268 | |
269 ! Map a 4K page for DYNACON at DYNACON_BASE | |
270 addi r1, 16, r1 | |
271 LOAD_PTEH_VAL (DYNACON_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
272 LOAD_PTEL_VAL (DYNACON_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
273 SET_PTE (r1, r2, r3) | |
274 | |
275 ! Map a 4K page for instructions at DM_DB_DLINK_BASE | |
276 addi r1, 16, r1 | |
277 LOAD_PTEH_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
278 LOAD_PTEL_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
279 SET_PTE (r1, r2, r3) | |
280 | |
281 ! Map a 4K page for data at DM_DB_DLINK_BASE+0x1000 | |
282 addi r1, 16, r1 | |
283 LOAD_PTEH_VAL ((DM_DB_DLINK_BASE+0x1000), ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
284 LOAD_PTEL_VAL ((DM_DB_DLINK_BASE+0x1000), ALIGN_4KB, PTE_CB_UNCACHEABLE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
285 SET_PTE (r1, r2, r3) | |
286 | |
287 ! Map a 4K page for stack DM_DB_DLINK_BASE+0x2000 | |
288 addi r1, 16, r1 | |
289 LOAD_PTEH_VAL ((DM_DB_DLINK_BASE+0x2000), ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
290 LOAD_PTEL_VAL ((DM_DB_DLINK_BASE+0x2000), ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
291 SET_PTE (r1, r2, r3) | |
292 | |
293 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK | |
294 ! 0x0c000000 - 0x0c0fffff | |
295 addi r1, 16, r1 | |
296 LOAD_PTEH_VAL (DM_CB_DLINK_BASE, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
297 LOAD_PTEL_VAL (DM_CB_DLINK_BASE, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
298 SET_PTE (r1, r2, r3) | |
299 | |
300 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK | |
301 ! 0x0c100000 - 0x0c1fffff | |
302 addi r1, 16, r1 | |
303 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
304 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x100000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
305 SET_PTE (r1, r2, r3) | |
306 | |
307 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK | |
308 ! 0x0c200000 - 0x0c2fffff | |
309 addi r1, 16, r1 | |
310 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x200000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
311 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x200000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
312 SET_PTE (r1, r2, r3) | |
313 | |
314 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK | |
315 ! 0x0c400000 - 0x0c4fffff | |
316 addi r1, 16, r1 | |
317 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x400000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
318 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x400000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
319 SET_PTE (r1, r2, r3) | |
320 | |
321 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK | |
322 ! 0x0c800000 - 0x0c8fffff | |
323 addi r1, 16, r1 | |
324 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x800000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
325 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x800000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
326 SET_PTE (r1, r2, r3) | |
327 | |
328 ! Map a 4K page for DMA control registers | |
329 addi r1, 16, r1 | |
330 LOAD_PTEH_VAL (DMA_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
331 LOAD_PTEL_VAL (DMA_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
332 SET_PTE (r1, r2, r3) | |
333 | |
334 ! Map lots of 4K pages for peripherals | |
335 | |
336 ! /* peripheral */ | |
337 addi r1, 16, r1 | |
338 LOAD_PTEH_VAL (PERIPH_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
339 LOAD_PTEL_VAL (PERIPH_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
340 SET_PTE (r1, r2, r3) | |
341 ! /* dmac */ | |
342 addi r1, 16, r1 | |
343 LOAD_PTEH_VAL (DMAC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
344 LOAD_PTEL_VAL (DMAC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
345 SET_PTE (r1, r2, r3) | |
346 ! /* intc */ | |
347 addi r1, 16, r1 | |
348 LOAD_PTEH_VAL (INTC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
349 LOAD_PTEL_VAL (INTC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
350 SET_PTE (r1, r2, r3) | |
351 ! /* rtc */ | |
352 addi r1, 16, r1 | |
353 LOAD_PTEH_VAL (RTC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
354 LOAD_PTEL_VAL (RTC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
355 SET_PTE (r1, r2, r3) | |
356 ! /* dmac */ | |
357 addi r1, 16, r1 | |
358 LOAD_PTEH_VAL (TMU_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
359 LOAD_PTEL_VAL (TMU_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
360 SET_PTE (r1, r2, r3) | |
361 ! /* scif */ | |
362 addi r1, 16, r1 | |
363 LOAD_PTEH_VAL (SCIF_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
364 LOAD_PTEL_VAL (SCIF_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
365 SET_PTE (r1, r2, r3) | |
366 ! /* cprc */ | |
367 addi r1, 16, r1 | |
368 LOAD_PTEH_VAL (CPRC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
369 LOAD_PTEL_VAL (CPRC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
370 SET_PTE (r1, r2, r3) | |
371 | |
372 ! Map CPU WPC registers | |
373 addi r1, 16, r1 | |
374 LOAD_PTEH_VAL (CPU_BASE, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
375 LOAD_PTEL_VAL (CPU_BASE, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
376 SET_PTE (r1, r2, r3) | |
377 addi r1, 16, r1 | |
378 | |
379 LOAD_PTEH_VAL ((CPU_BASE+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
380 LOAD_PTEL_VAL ((CPU_BASE+0x100000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
381 SET_PTE (r1, r2, r3) | |
382 | |
383 addi r1, 16, r1 | |
384 LOAD_PTEH_VAL ((CPU_BASE+0x200000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
385 LOAD_PTEL_VAL ((CPU_BASE+0x200000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
386 SET_PTE (r1, r2, r3) | |
387 | |
388 addi r1, 16, r1 | |
389 LOAD_PTEH_VAL ((CPU_BASE+0x400000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2) | |
390 LOAD_PTEL_VAL ((CPU_BASE+0x400000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3) | |
391 SET_PTE (r1, r2, r3) | |
392 | |
393 ! Switch over to virtual addressing and enabled cache | |
394 getcon sr, r1 | |
395 movi 1, r2 | |
396 shlli r2, SR_BL_BIT, r2 | |
397 or r1, r2, r1 | |
398 putcon r1, ssr | |
399 getcon sr, r1 | |
400 movi 1, r2 | |
401 shlli r2, SR_MMU_BIT, r2 | |
402 or r1, r2, r1 | |
403 putcon r1, ssr | |
404 gettr tr1, r1 | |
405 putcon r1, spc | |
406 synco | |
407 rte | |
408 | |
409 ! VM entry point. From now on, we are in VM mode. | |
410 .vm_ep: | |
411 | |
412 ! Install the trap handler, by seeding vbr with the | |
413 ! correct value, and by assigning sr.bl = 0. | |
414 | |
415 LOAD_ADDR (vbr_start, r1) | |
416 putcon r1, vbr | |
417 movi ~(1<<28), r1 | |
418 getcon sr, r2 | |
419 and r1, r2, r2 | |
420 putcon r2, sr | |
421 #endif /* MMU_SUPPORT */ | |
422 | |
423 pt/l .Lzero_bss_loop, tr0 | |
424 pt/l _init, tr5 | |
425 pt/l ___setup_argv_and_call_main, tr6 | |
426 pt/l _exit, tr7 | |
427 | |
428 ! zero out bss | |
429 LOAD_ADDR (_edata, r0) | |
430 LOAD_ADDR (_end, r1) | |
431 .Lzero_bss_loop: | |
432 stx.q r0, r63, r63 | |
433 addi r0, 8, r0 | |
434 bgt/l r1, r0, tr0 | |
435 | |
436 LOAD_ADDR (___data, r26) | |
437 LOAD_ADDR (___rodata, r27) | |
438 | |
439 #ifdef __SH_FPU_ANY__ | |
440 getcon sr, r0 | |
441 ! enable the FP unit, by resetting SR.FD | |
442 ! also zero out SR.FR, SR.SZ and SR.PR, as mandated by the ABI | |
443 movi 0, r1 | |
444 shori 0xf000, r1 | |
445 andc r0, r1, r0 | |
446 putcon r0, sr | |
447 #if __SH5__ == 32 | |
448 pt/l ___set_fpscr, tr0 | |
449 movi 0, r4 | |
450 blink tr0, r18 | |
451 #endif | |
452 #endif | |
453 | |
454 ! arrange for exit to call fini | |
455 pt/l _atexit, tr1 | |
456 LOAD_ADDR (_fini, r2) | |
457 blink tr1, r18 | |
458 | |
459 ! call init | |
460 blink tr5, r18 | |
461 | |
462 ! call the mainline | |
463 blink tr6, r18 | |
464 | |
465 ! call exit | |
466 blink tr7, r18 | |
467 ! We should never return from _exit but in case we do we would enter the | |
468 ! the following tight loop. This avoids executing any data that might follow. | |
469 limbo: | |
470 pt/l limbo, tr0 | |
471 blink tr0, r63 | |
472 | |
473 #ifdef MMU_SUPPORT | |
474 ! All these traps are handled in the same place. | |
475 .balign 256 | |
476 vbr_start: | |
477 pt/l handler, tr0 ! tr0 trashed. | |
478 blink tr0, r63 | |
479 .balign 256 | |
480 vbr_100: | |
481 pt/l handler, tr0 ! tr0 trashed. | |
482 blink tr0, r63 | |
483 vbr_100_end: | |
484 .balign 256 | |
485 vbr_200: | |
486 pt/l handler, tr0 ! tr0 trashed. | |
487 blink tr0, r63 | |
488 .balign 256 | |
489 vbr_300: | |
490 pt/l handler, tr0 ! tr0 trashed. | |
491 blink tr0, r63 | |
492 .balign 256 | |
493 vbr_400: ! Should be at vbr+0x400 | |
494 handler: | |
495 /* If the trap handler is there call it */ | |
496 LOAD_ADDR (__superh_trap_handler, r2) | |
497 pta chandler,tr2 | |
498 beq r2, r63, tr2 /* If zero, ie not present branch around to chandler */ | |
499 /* Now call the trap handler with as much of the context unchanged as possible. | |
500 Move trapping address into R18 to make it look like the trap point */ | |
501 getcon spc, r18 | |
502 pt/l __superh_trap_handler, tr0 | |
503 blink tr0, r7 | |
504 chandler: | |
505 getcon spc, r62 | |
506 getcon expevt, r2 | |
507 pt/l _exit, tr0 | |
508 blink tr0, r63 | |
509 | |
510 /* Simulated trap handler */ | |
511 .section .text..SHmedia32,"ax" | |
512 gcc2_compiled.: | |
513 .section .debug_abbrev | |
514 .Ldebug_abbrev0: | |
515 .section .text..SHmedia32 | |
516 .Ltext0: | |
517 .section .debug_info | |
518 .Ldebug_info0: | |
519 .section .debug_line | |
520 .Ldebug_line0: | |
521 .section .text..SHmedia32,"ax" | |
522 .align 5 | |
523 .global __superh_trap_handler | |
524 .type __superh_trap_handler,@function | |
525 __superh_trap_handler: | |
526 .LFB1: | |
527 ptabs r18, tr0 | |
528 addi.l r15, -8, r15 | |
529 st.l r15, 4, r14 | |
530 addi.l r15, -8, r15 | |
531 add.l r15, r63, r14 | |
532 st.l r14, 0, r2 | |
533 ptabs r7, tr0 | |
534 addi.l r14, 8, r14 | |
535 add.l r14, r63, r15 | |
536 ld.l r15, 4, r14 | |
537 addi.l r15, 8, r15 | |
538 blink tr0, r63 | |
539 .LFE1: | |
540 .Lfe1: | |
541 .size __superh_trap_handler,.Lfe1-__superh_trap_handler | |
542 | |
543 .section .text..SHmedia32 | |
544 .Letext0: | |
545 | |
546 .section .debug_info | |
547 .ualong 0xa7 | |
548 .uaword 0x2 | |
549 .ualong .Ldebug_abbrev0 | |
550 .byte 0x4 | |
551 .byte 0x1 | |
552 .ualong .Ldebug_line0 | |
553 .ualong .Letext0 | |
554 .ualong .Ltext0 | |
555 .string "trap_handler.c" | |
556 | |
557 .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
558 | |
559 .string "GNU C 2.97-sh5-010522" | |
560 | |
561 .byte 0x1 | |
562 .byte 0x2 | |
563 .ualong 0x9a | |
564 .byte 0x1 | |
565 .string "_superh_trap_handler" | |
566 | |
567 .byte 0x1 | |
568 .byte 0x2 | |
569 .byte 0x1 | |
570 .ualong .LFB1 | |
571 .ualong .LFE1 | |
572 .byte 0x1 | |
573 .byte 0x5e | |
574 .byte 0x3 | |
575 .string "trap_reason" | |
576 | |
577 .byte 0x1 | |
578 .byte 0x1 | |
579 .ualong 0x9a | |
580 .byte 0x2 | |
581 .byte 0x91 | |
582 .byte 0x0 | |
583 .byte 0x0 | |
584 .byte 0x4 | |
585 .string "unsigned int" | |
586 | |
587 .byte 0x4 | |
588 .byte 0x7 | |
589 .byte 0x0 | |
590 | |
591 .section .debug_abbrev | |
592 .byte 0x1 | |
593 .byte 0x11 | |
594 .byte 0x1 | |
595 .byte 0x10 | |
596 .byte 0x6 | |
597 .byte 0x12 | |
598 .byte 0x1 | |
599 .byte 0x11 | |
600 .byte 0x1 | |
601 .byte 0x3 | |
602 .byte 0x8 | |
603 .byte 0x1b | |
604 .byte 0x8 | |
605 .byte 0x25 | |
606 .byte 0x8 | |
607 .byte 0x13 | |
608 .byte 0xb | |
609 .byte 0,0 | |
610 .byte 0x2 | |
611 .byte 0x2e | |
612 .byte 0x1 | |
613 .byte 0x1 | |
614 .byte 0x13 | |
615 .byte 0x3f | |
616 .byte 0xc | |
617 .byte 0x3 | |
618 .byte 0x8 | |
619 .byte 0x3a | |
620 .byte 0xb | |
621 .byte 0x3b | |
622 .byte 0xb | |
623 .byte 0x27 | |
624 .byte 0xc | |
625 .byte 0x11 | |
626 .byte 0x1 | |
627 .byte 0x12 | |
628 .byte 0x1 | |
629 .byte 0x40 | |
630 .byte 0xa | |
631 .byte 0,0 | |
632 .byte 0x3 | |
633 .byte 0x5 | |
634 .byte 0x0 | |
635 .byte 0x3 | |
636 .byte 0x8 | |
637 .byte 0x3a | |
638 .byte 0xb | |
639 .byte 0x3b | |
640 .byte 0xb | |
641 .byte 0x49 | |
642 .byte 0x13 | |
643 .byte 0x2 | |
644 .byte 0xa | |
645 .byte 0,0 | |
646 .byte 0x4 | |
647 .byte 0x24 | |
648 .byte 0x0 | |
649 .byte 0x3 | |
650 .byte 0x8 | |
651 .byte 0xb | |
652 .byte 0xb | |
653 .byte 0x3e | |
654 .byte 0xb | |
655 .byte 0,0 | |
656 .byte 0 | |
657 | |
658 .section .debug_pubnames | |
659 .ualong 0x27 | |
660 .uaword 0x2 | |
661 .ualong .Ldebug_info0 | |
662 .ualong 0xab | |
663 .ualong 0x5b | |
664 .string "_superh_trap_handler" | |
665 | |
666 .ualong 0x0 | |
667 | |
668 .section .debug_aranges | |
669 .ualong 0x1c | |
670 .uaword 0x2 | |
671 .ualong .Ldebug_info0 | |
672 .byte 0x4 | |
673 .byte 0x0 | |
674 .uaword 0x0,0 | |
675 .ualong .Ltext0 | |
676 .ualong .Letext0-.Ltext0 | |
677 .ualong 0x0 | |
678 .ualong 0x0 | |
679 .ident "GCC: (GNU) 2.97-sh5-010522" | |
680 #endif /* MMU_SUPPORT */ | |
681 #else /* ! __SH5__ */ | |
682 | |
683 ! make a place to keep any previous value of the vbr register | |
684 ! this will only have a value if it has been set by redboot (for example) | |
685 .section .bss | |
686 old_vbr: | |
687 .long 0 | |
688 #ifdef PROFILE | |
689 profiling_enabled: | |
690 .long 0 | |
691 #endif | |
692 | |
693 | |
694 .section .text | |
695 .global start | |
696 .import ___rtos_profiler_start_timer | |
697 .weak ___rtos_profiler_start_timer | |
698 start: | |
699 mov.l stack_k,r15 | |
700 | |
701 #if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__) | |
702 #define VBR_SETUP | |
703 ! before zeroing the bss ... | |
704 ! if the vbr is already set to vbr_start then the program has been restarted | |
705 ! (i.e. it is not the first time the program has been run since reset) | |
706 ! reset the vbr to its old value before old_vbr (in bss) is wiped | |
707 ! this ensures that the later code does not create a circular vbr chain | |
708 stc vbr, r1 | |
709 mov.l vbr_start_k, r2 | |
710 cmp/eq r1, r2 | |
711 bf 0f | |
712 ! reset the old vbr value | |
713 mov.l old_vbr_k, r1 | |
714 mov.l @r1, r2 | |
715 ldc r2, vbr | |
716 0: | |
717 #endif /* VBR_SETUP */ | |
718 | |
719 ! zero out bss | |
720 mov.l edata_k,r0 | |
721 mov.l end_k,r1 | |
722 mov #0,r2 | |
723 start_l: | |
724 mov.l r2,@r0 | |
725 add #4,r0 | |
726 cmp/ge r0,r1 | |
727 bt start_l | |
728 | |
729 #if defined (__SH_FPU_ANY__) | |
730 mov.l set_fpscr_k, r1 | |
731 mov #4,r4 | |
732 jsr @r1 | |
733 shll16 r4 ! Set DN bit (flush denormal inputs to zero) | |
734 lds r3,fpscr ! Switch to default precision | |
735 #endif /* defined (__SH_FPU_ANY__) */ | |
736 | |
737 #ifdef VBR_SETUP | |
738 ! save the existing contents of the vbr | |
739 ! there will only be a prior value when using something like redboot | |
740 ! otherwise it will be zero | |
741 stc vbr, r1 | |
742 mov.l old_vbr_k, r2 | |
743 mov.l r1, @r2 | |
744 ! setup vbr | |
745 mov.l vbr_start_k, r1 | |
746 ldc r1,vbr | |
747 #endif /* VBR_SETUP */ | |
748 | |
749 ! if an rtos is exporting a timer start fn, | |
750 ! then pick up an SR which does not enable ints | |
751 ! (the rtos will take care of this) | |
752 mov.l rtos_start_fn, r0 | |
753 mov.l sr_initial_bare, r1 | |
754 tst r0, r0 | |
755 bt set_sr | |
756 | |
757 mov.l sr_initial_rtos, r1 | |
758 | |
759 set_sr: | |
760 ! Set status register (sr) | |
761 ldc r1, sr | |
762 | |
763 ! arrange for exit to call fini | |
764 mov.l atexit_k,r0 | |
765 mov.l fini_k,r4 | |
766 jsr @r0 | |
767 nop | |
768 | |
769 #ifdef PROFILE | |
770 ! arrange for exit to call _mcleanup (via stop_profiling) | |
771 mova stop_profiling,r0 | |
772 mov.l atexit_k,r1 | |
773 jsr @r1 | |
774 mov r0, r4 | |
775 | |
776 ! Call profiler startup code | |
777 mov.l monstartup_k, r0 | |
778 mov.l start_k, r4 | |
779 mov.l etext_k, r5 | |
780 jsr @r0 | |
781 nop | |
782 | |
783 ! enable profiling trap | |
784 ! until now any trap 33s will have been ignored | |
785 ! This means that all library functions called before this point | |
786 ! (directly or indirectly) may have the profiling trap at the start. | |
787 ! Therefore, only mcount itself may not have the extra header. | |
788 mov.l profiling_enabled_k2, r0 | |
789 mov #1, r1 | |
790 mov.l r1, @r0 | |
791 #endif /* PROFILE */ | |
792 | |
793 ! call init | |
794 mov.l init_k,r0 | |
795 jsr @r0 | |
796 nop | |
797 | |
798 ! call the mainline | |
799 mov.l main_k,r0 | |
800 jsr @r0 | |
801 nop | |
802 | |
803 ! call exit | |
804 mov r0,r4 | |
805 mov.l exit_k,r0 | |
806 jsr @r0 | |
807 nop | |
808 | |
809 .balign 4 | |
810 #ifdef PROFILE | |
811 stop_profiling: | |
812 # stop mcount counting | |
813 mov.l profiling_enabled_k2, r0 | |
814 mov #0, r1 | |
815 mov.l r1, @r0 | |
816 | |
817 # call mcleanup | |
818 mov.l mcleanup_k, r0 | |
819 jmp @r0 | |
820 nop | |
821 | |
822 .balign 4 | |
823 mcleanup_k: | |
824 .long __mcleanup | |
825 monstartup_k: | |
826 .long ___monstartup | |
827 profiling_enabled_k2: | |
828 .long profiling_enabled | |
829 start_k: | |
830 .long _start | |
831 etext_k: | |
832 .long __etext | |
833 #endif /* PROFILE */ | |
834 | |
835 .align 2 | |
836 #if defined (__SH_FPU_ANY__) | |
837 set_fpscr_k: | |
838 .long ___set_fpscr | |
839 #endif /* defined (__SH_FPU_ANY__) */ | |
840 | |
841 stack_k: | |
842 .long _stack | |
843 edata_k: | |
844 .long _edata | |
845 end_k: | |
846 .long _end | |
847 main_k: | |
848 .long ___setup_argv_and_call_main | |
849 exit_k: | |
850 .long _exit | |
851 atexit_k: | |
852 .long _atexit | |
853 init_k: | |
854 .long _init | |
855 fini_k: | |
856 .long _fini | |
857 #ifdef VBR_SETUP | |
858 old_vbr_k: | |
859 .long old_vbr | |
860 vbr_start_k: | |
861 .long vbr_start | |
862 #endif /* VBR_SETUP */ | |
863 | |
864 sr_initial_rtos: | |
865 ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. | |
866 ! Whether profiling or not, keep interrupts masked, | |
867 ! the RTOS will enable these if required. | |
868 .long 0x600000f1 | |
869 | |
870 rtos_start_fn: | |
871 .long ___rtos_profiler_start_timer | |
872 | |
873 #ifdef PROFILE | |
874 sr_initial_bare: | |
875 ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. | |
876 ! For bare machine, we need to enable interrupts to get profiling working | |
877 .long 0x60000001 | |
878 #else | |
879 | |
880 sr_initial_bare: | |
881 ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. | |
882 ! Keep interrupts disabled - the application will enable as required. | |
883 .long 0x600000f1 | |
884 #endif | |
885 | |
886 ! supplied for backward compatibility only, in case of linking | |
887 ! code whose main() was compiled with an older version of GCC. | |
888 .global ___main | |
889 ___main: | |
890 rts | |
891 nop | |
892 #ifdef VBR_SETUP | |
893 ! Exception handlers | |
894 .section .text.vbr, "ax" | |
895 vbr_start: | |
896 | |
897 .org 0x100 | |
898 vbr_100: | |
899 #ifdef PROFILE | |
900 ! Note on register usage. | |
901 ! we use r0..r3 as scratch in this code. If we are here due to a trapa for profiling | |
902 ! then this is OK as we are just before executing any function code. | |
903 ! The other r4..r7 we save explicityl on the stack | |
904 ! Remaining registers are saved by normal ABI conventions and we assert we do not | |
905 ! use floating point registers. | |
906 mov.l expevt_k1, r1 | |
907 mov.l @r1, r1 | |
908 mov.l event_mask, r0 | |
909 and r0,r1 | |
910 mov.l trapcode_k, r2 | |
911 cmp/eq r1,r2 | |
912 bt 1f | |
913 bra handler_100 ! if not a trapa, go to default handler | |
914 nop | |
915 1: | |
916 mov.l trapa_k, r0 | |
917 mov.l @r0, r0 | |
918 shlr2 r0 ! trapa code is shifted by 2. | |
919 cmp/eq #33, r0 | |
920 bt 2f | |
921 bra handler_100 | |
922 nop | |
923 2: | |
924 | |
925 ! If here then it looks like we have trap #33 | |
926 ! Now we need to call mcount with the following convention | |
927 ! Save and restore r4..r7 | |
928 mov.l r4,@-r15 | |
929 mov.l r5,@-r15 | |
930 mov.l r6,@-r15 | |
931 mov.l r7,@-r15 | |
932 sts.l pr,@-r15 | |
933 | |
934 ! r4 is frompc. | |
935 ! r5 is selfpc | |
936 ! r0 is the branch back address. | |
937 ! The code sequence emitted by gcc for the profiling trap is | |
938 ! .align 2 | |
939 ! trapa #33 | |
940 ! .align 2 | |
941 ! .long lab Where lab is planted by the compiler. This is the address | |
942 ! of a datum that needs to be incremented. | |
943 sts pr, r4 ! frompc | |
944 stc spc, r5 ! selfpc | |
945 mov #2, r2 | |
946 not r2, r2 ! pattern to align to 4 | |
947 and r2, r5 ! r5 now has aligned address | |
948 ! add #4, r5 ! r5 now has address of address | |
949 mov r5, r2 ! Remember it. | |
950 ! mov.l @r5, r5 ! r5 has value of lable (lab in above example) | |
951 add #8, r2 | |
952 ldc r2, spc ! our return address avoiding address word | |
953 | |
954 ! only call mcount if profiling is enabled | |
955 mov.l profiling_enabled_k, r0 | |
956 mov.l @r0, r0 | |
957 cmp/eq #0, r0 | |
958 bt 3f | |
959 ! call mcount | |
960 mov.l mcount_k, r2 | |
961 jsr @r2 | |
962 nop | |
963 3: | |
964 lds.l @r15+,pr | |
965 mov.l @r15+,r7 | |
966 mov.l @r15+,r6 | |
967 mov.l @r15+,r5 | |
968 mov.l @r15+,r4 | |
969 rte | |
970 nop | |
971 .balign 4 | |
972 event_mask: | |
973 .long 0xfff | |
974 trapcode_k: | |
975 .long 0x160 | |
976 expevt_k1: | |
977 .long 0xff000024 ! Address of expevt | |
978 trapa_k: | |
979 .long 0xff000020 | |
980 mcount_k: | |
981 .long __call_mcount | |
982 profiling_enabled_k: | |
983 .long profiling_enabled | |
984 #endif | |
985 ! Non profiling case. | |
986 handler_100: | |
987 mov.l 2f, r0 ! load the old vbr setting (if any) | |
988 mov.l @r0, r0 | |
989 cmp/eq #0, r0 | |
990 bf 1f | |
991 ! no previous vbr - jump to own generic handler | |
992 bra handler | |
993 nop | |
994 1: ! there was a previous handler - chain them | |
995 add #0x7f, r0 ! 0x7f | |
996 add #0x7f, r0 ! 0xfe | |
997 add #0x2, r0 ! add 0x100 without corrupting another register | |
998 jmp @r0 | |
999 nop | |
1000 .balign 4 | |
1001 2: | |
1002 .long old_vbr | |
1003 | |
1004 .org 0x400 | |
1005 vbr_400: ! Should be at vbr+0x400 | |
1006 mov.l 2f, r0 ! load the old vbr setting (if any) | |
1007 mov.l @r0, r0 | |
1008 cmp/eq #0, r0 | |
1009 ! no previous vbr - jump to own generic handler | |
1010 bt handler | |
1011 ! there was a previous handler - chain them | |
1012 rotcr r0 | |
1013 rotcr r0 | |
1014 add #0x7f, r0 ! 0x1fc | |
1015 add #0x7f, r0 ! 0x3f8 | |
1016 add #0x02, r0 ! 0x400 | |
1017 rotcl r0 | |
1018 rotcl r0 ! Add 0x400 without corrupting another register | |
1019 jmp @r0 | |
1020 nop | |
1021 .balign 4 | |
1022 2: | |
1023 .long old_vbr | |
1024 handler: | |
1025 /* If the trap handler is there call it */ | |
1026 mov.l superh_trap_handler_k, r0 | |
1027 cmp/eq #0, r0 ! True if zero. | |
1028 bf 3f | |
1029 bra chandler | |
1030 nop | |
1031 3: | |
1032 ! Here handler available, call it. | |
1033 /* Now call the trap handler with as much of the context unchanged as possible. | |
1034 Move trapping address into PR to make it look like the trap point */ | |
1035 stc spc, r1 | |
1036 lds r1, pr | |
1037 mov.l expevt_k, r4 | |
1038 mov.l @r4, r4 ! r4 is value of expevt, first parameter. | |
1039 mov r1, r5 ! Remember trapping pc. | |
1040 mov r1, r6 ! Remember trapping pc. | |
1041 mov.l chandler_k, r1 | |
1042 mov.l superh_trap_handler_k, r2 | |
1043 ! jmp to trap handler to avoid disturbing pr. | |
1044 jmp @r2 | |
1045 nop | |
1046 | |
1047 .org 0x600 | |
1048 vbr_600: | |
1049 #ifdef PROFILE | |
1050 ! Should be at vbr+0x600 | |
1051 ! Now we are in the land of interrupts so need to save more state. | |
1052 ! Save register state | |
1053 mov.l interrupt_stack_k, r15 ! r15 has been saved to sgr. | |
1054 mov.l r0,@-r15 | |
1055 mov.l r1,@-r15 | |
1056 mov.l r2,@-r15 | |
1057 mov.l r3,@-r15 | |
1058 mov.l r4,@-r15 | |
1059 mov.l r5,@-r15 | |
1060 mov.l r6,@-r15 | |
1061 mov.l r7,@-r15 | |
1062 sts.l pr,@-r15 | |
1063 sts.l mach,@-r15 | |
1064 sts.l macl,@-r15 | |
1065 #if defined(__SH_FPU_ANY__) | |
1066 ! Save fpul and fpscr, save fr0-fr7 in 64 bit mode | |
1067 ! and set the pervading precision for the timer_handler | |
1068 mov #0,r0 | |
1069 sts.l fpul,@-r15 | |
1070 sts.l fpscr,@-r15 | |
1071 lds r0,fpscr ! Clear fpscr | |
1072 fmov fr0,@-r15 | |
1073 fmov fr1,@-r15 | |
1074 fmov fr2,@-r15 | |
1075 fmov fr3,@-r15 | |
1076 mov.l pervading_precision_k,r0 | |
1077 fmov fr4,@-r15 | |
1078 fmov fr5,@-r15 | |
1079 mov.l @r0,r0 | |
1080 fmov fr6,@-r15 | |
1081 fmov fr7,@-r15 | |
1082 lds r0,fpscr | |
1083 #endif /* __SH_FPU_ANY__ */ | |
1084 ! Pass interrupted pc to timer_handler as first parameter (r4). | |
1085 stc spc, r4 | |
1086 mov.l timer_handler_k, r0 | |
1087 jsr @r0 | |
1088 nop | |
1089 #if defined(__SH_FPU_ANY__) | |
1090 mov #0,r0 | |
1091 lds r0,fpscr ! Clear the fpscr | |
1092 fmov @r15+,fr7 | |
1093 fmov @r15+,fr6 | |
1094 fmov @r15+,fr5 | |
1095 fmov @r15+,fr4 | |
1096 fmov @r15+,fr3 | |
1097 fmov @r15+,fr2 | |
1098 fmov @r15+,fr1 | |
1099 fmov @r15+,fr0 | |
1100 lds.l @r15+,fpscr | |
1101 lds.l @r15+,fpul | |
1102 #endif /* __SH_FPU_ANY__ */ | |
1103 lds.l @r15+,macl | |
1104 lds.l @r15+,mach | |
1105 lds.l @r15+,pr | |
1106 mov.l @r15+,r7 | |
1107 mov.l @r15+,r6 | |
1108 mov.l @r15+,r5 | |
1109 mov.l @r15+,r4 | |
1110 mov.l @r15+,r3 | |
1111 mov.l @r15+,r2 | |
1112 mov.l @r15+,r1 | |
1113 mov.l @r15+,r0 | |
1114 stc sgr, r15 ! Restore r15, destroyed by this sequence. | |
1115 rte | |
1116 nop | |
1117 #if defined(__SH_FPU_ANY__) | |
1118 .balign 4 | |
1119 pervading_precision_k: | |
1120 #define CONCAT1(A,B) A##B | |
1121 #define CONCAT(A,B) CONCAT1(A,B) | |
1122 .long CONCAT(__USER_LABEL_PREFIX__,__fpscr_values)+4 | |
1123 #endif | |
1124 #else | |
1125 mov.l 2f, r0 ! Load the old vbr setting (if any). | |
1126 mov.l @r0, r0 | |
1127 cmp/eq #0, r0 | |
1128 ! no previous vbr - jump to own handler | |
1129 bt chandler | |
1130 ! there was a previous handler - chain them | |
1131 rotcr r0 | |
1132 rotcr r0 | |
1133 add #0x7f, r0 ! 0x1fc | |
1134 add #0x7f, r0 ! 0x3f8 | |
1135 add #0x7f, r0 ! 0x5f4 | |
1136 add #0x03, r0 ! 0x600 | |
1137 rotcl r0 | |
1138 rotcl r0 ! Add 0x600 without corrupting another register | |
1139 jmp @r0 | |
1140 nop | |
1141 .balign 4 | |
1142 2: | |
1143 .long old_vbr | |
1144 #endif /* PROFILE code */ | |
1145 chandler: | |
1146 mov.l expevt_k, r4 | |
1147 mov.l @r4, r4 ! r4 is value of expevt hence making this the return code | |
1148 mov.l handler_exit_k,r0 | |
1149 jsr @r0 | |
1150 nop | |
1151 ! We should never return from _exit but in case we do we would enter the | |
1152 ! the following tight loop | |
1153 limbo: | |
1154 bra limbo | |
1155 nop | |
1156 .balign 4 | |
1157 #ifdef PROFILE | |
1158 interrupt_stack_k: | |
1159 .long __timer_stack ! The high end of the stack | |
1160 timer_handler_k: | |
1161 .long __profil_counter | |
1162 #endif | |
1163 expevt_k: | |
1164 .long 0xff000024 ! Address of expevt | |
1165 chandler_k: | |
1166 .long chandler | |
1167 superh_trap_handler_k: | |
1168 .long __superh_trap_handler | |
1169 handler_exit_k: | |
1170 .long _exit | |
1171 .align 2 | |
1172 ! Simulated compile of trap handler. | |
1173 .section .debug_abbrev,"",@progbits | |
1174 .Ldebug_abbrev0: | |
1175 .section .debug_info,"",@progbits | |
1176 .Ldebug_info0: | |
1177 .section .debug_line,"",@progbits | |
1178 .Ldebug_line0: | |
1179 .text | |
1180 .Ltext0: | |
1181 .align 5 | |
1182 .type __superh_trap_handler,@function | |
1183 __superh_trap_handler: | |
1184 .LFB1: | |
1185 mov.l r14,@-r15 | |
1186 .LCFI0: | |
1187 add #-4,r15 | |
1188 .LCFI1: | |
1189 mov r15,r14 | |
1190 .LCFI2: | |
1191 mov.l r4,@r14 | |
1192 lds r1, pr | |
1193 add #4,r14 | |
1194 mov r14,r15 | |
1195 mov.l @r15+,r14 | |
1196 rts | |
1197 nop | |
1198 .LFE1: | |
1199 .Lfe1: | |
1200 .size __superh_trap_handler,.Lfe1-__superh_trap_handler | |
1201 .section .debug_frame,"",@progbits | |
1202 .Lframe0: | |
1203 .ualong .LECIE0-.LSCIE0 | |
1204 .LSCIE0: | |
1205 .ualong 0xffffffff | |
1206 .byte 0x1 | |
1207 .string "" | |
1208 .uleb128 0x1 | |
1209 .sleb128 -4 | |
1210 .byte 0x11 | |
1211 .byte 0xc | |
1212 .uleb128 0xf | |
1213 .uleb128 0x0 | |
1214 .align 2 | |
1215 .LECIE0: | |
1216 .LSFDE0: | |
1217 .ualong .LEFDE0-.LASFDE0 | |
1218 .LASFDE0: | |
1219 .ualong .Lframe0 | |
1220 .ualong .LFB1 | |
1221 .ualong .LFE1-.LFB1 | |
1222 .byte 0x4 | |
1223 .ualong .LCFI0-.LFB1 | |
1224 .byte 0xe | |
1225 .uleb128 0x4 | |
1226 .byte 0x4 | |
1227 .ualong .LCFI1-.LCFI0 | |
1228 .byte 0xe | |
1229 .uleb128 0x8 | |
1230 .byte 0x8e | |
1231 .uleb128 0x1 | |
1232 .byte 0x4 | |
1233 .ualong .LCFI2-.LCFI1 | |
1234 .byte 0xd | |
1235 .uleb128 0xe | |
1236 .align 2 | |
1237 .LEFDE0: | |
1238 .text | |
1239 .Letext0: | |
1240 .section .debug_info | |
1241 .ualong 0xb3 | |
1242 .uaword 0x2 | |
1243 .ualong .Ldebug_abbrev0 | |
1244 .byte 0x4 | |
1245 .uleb128 0x1 | |
1246 .ualong .Ldebug_line0 | |
1247 .ualong .Letext0 | |
1248 .ualong .Ltext0 | |
1249 .string "trap_handler.c" | |
1250 .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
1251 .string "GNU C 3.2 20020529 (experimental)" | |
1252 .byte 0x1 | |
1253 .uleb128 0x2 | |
1254 .ualong 0xa6 | |
1255 .byte 0x1 | |
1256 .string "_superh_trap_handler" | |
1257 .byte 0x1 | |
1258 .byte 0x2 | |
1259 .byte 0x1 | |
1260 .ualong .LFB1 | |
1261 .ualong .LFE1 | |
1262 .byte 0x1 | |
1263 .byte 0x5e | |
1264 .uleb128 0x3 | |
1265 .string "trap_reason" | |
1266 .byte 0x1 | |
1267 .byte 0x1 | |
1268 .ualong 0xa6 | |
1269 .byte 0x2 | |
1270 .byte 0x91 | |
1271 .sleb128 0 | |
1272 .byte 0x0 | |
1273 .uleb128 0x4 | |
1274 .string "unsigned int" | |
1275 .byte 0x4 | |
1276 .byte 0x7 | |
1277 .byte 0x0 | |
1278 .section .debug_abbrev | |
1279 .uleb128 0x1 | |
1280 .uleb128 0x11 | |
1281 .byte 0x1 | |
1282 .uleb128 0x10 | |
1283 .uleb128 0x6 | |
1284 .uleb128 0x12 | |
1285 .uleb128 0x1 | |
1286 .uleb128 0x11 | |
1287 .uleb128 0x1 | |
1288 .uleb128 0x3 | |
1289 .uleb128 0x8 | |
1290 .uleb128 0x1b | |
1291 .uleb128 0x8 | |
1292 .uleb128 0x25 | |
1293 .uleb128 0x8 | |
1294 .uleb128 0x13 | |
1295 .uleb128 0xb | |
1296 .byte 0x0 | |
1297 .byte 0x0 | |
1298 .uleb128 0x2 | |
1299 .uleb128 0x2e | |
1300 .byte 0x1 | |
1301 .uleb128 0x1 | |
1302 .uleb128 0x13 | |
1303 .uleb128 0x3f | |
1304 .uleb128 0xc | |
1305 .uleb128 0x3 | |
1306 .uleb128 0x8 | |
1307 .uleb128 0x3a | |
1308 .uleb128 0xb | |
1309 .uleb128 0x3b | |
1310 .uleb128 0xb | |
1311 .uleb128 0x27 | |
1312 .uleb128 0xc | |
1313 .uleb128 0x11 | |
1314 .uleb128 0x1 | |
1315 .uleb128 0x12 | |
1316 .uleb128 0x1 | |
1317 .uleb128 0x40 | |
1318 .uleb128 0xa | |
1319 .byte 0x0 | |
1320 .byte 0x0 | |
1321 .uleb128 0x3 | |
1322 .uleb128 0x5 | |
1323 .byte 0x0 | |
1324 .uleb128 0x3 | |
1325 .uleb128 0x8 | |
1326 .uleb128 0x3a | |
1327 .uleb128 0xb | |
1328 .uleb128 0x3b | |
1329 .uleb128 0xb | |
1330 .uleb128 0x49 | |
1331 .uleb128 0x13 | |
1332 .uleb128 0x2 | |
1333 .uleb128 0xa | |
1334 .byte 0x0 | |
1335 .byte 0x0 | |
1336 .uleb128 0x4 | |
1337 .uleb128 0x24 | |
1338 .byte 0x0 | |
1339 .uleb128 0x3 | |
1340 .uleb128 0x8 | |
1341 .uleb128 0xb | |
1342 .uleb128 0xb | |
1343 .uleb128 0x3e | |
1344 .uleb128 0xb | |
1345 .byte 0x0 | |
1346 .byte 0x0 | |
1347 .byte 0x0 | |
1348 .section .debug_pubnames,"",@progbits | |
1349 .ualong 0x27 | |
1350 .uaword 0x2 | |
1351 .ualong .Ldebug_info0 | |
1352 .ualong 0xb7 | |
1353 .ualong 0x67 | |
1354 .string "_superh_trap_handler" | |
1355 .ualong 0x0 | |
1356 .section .debug_aranges,"",@progbits | |
1357 .ualong 0x1c | |
1358 .uaword 0x2 | |
1359 .ualong .Ldebug_info0 | |
1360 .byte 0x4 | |
1361 .byte 0x0 | |
1362 .uaword 0x0 | |
1363 .uaword 0x0 | |
1364 .ualong .Ltext0 | |
1365 .ualong .Letext0-.Ltext0 | |
1366 .ualong 0x0 | |
1367 .ualong 0x0 | |
1368 #endif /* VBR_SETUP */ | |
1369 #endif /* ! __SH5__ */ |