1 /* Copyright
(C
) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
, Inc.
2 This file was pretty much copied from newlib.
4 This file is part of GCC.
6 GCC is free software
; you can redistribute it and/or modify it
7 under the terms of the GNU General
Public License as published by the
8 Free Software Foundation
; either version 2, or (at your option) any
11 In addition to the permissions
in the GNU General
Public License
, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of
this file
into combinations with other programs
,
14 and to distribute those combinations without any restriction coming
15 from the use of
this file.
(The General
Public License restrictions
16 do apply
in other respects
; for example, they cover modification of
17 the file
, and distribution when
not linked
into a combine
20 GCC is distributed
in the hope that it will be useful
,
21 but WITHOUT ANY WARRANTY
; without even the implied warranty of
22 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General
Public License for more details.
25 You should have received a copy of the GNU General
Public License
26 along with
this program
; see the file COPYING. If not, write to
27 the Free Software Foundation
, 51 Franklin Street
, Fifth Floor
,
28 Boston
, MA
02110-1301, USA.
*/
31 /* Section used for exception
/timer interrupt stack area
*/
32 .
section .data.vbr.stack
,"aw"
36 .zero
1024 * 2 /* ; 2k for VBR handlers */
37 /* Label at the highest stack address where the stack grows from
*/
39 #endif
/* MMU_SUPPORT
*/
41 /* ;----------------------------------------
42 Normal newlib crt1.asm
*/
53 #define ICCR_BASE
0x01600000
54 #define OCCR_BASE
0x01e00000
55 #define MMUIR_BASE
0x00000000
56 #define MMUDR_BASE
0x00800000
59 #define PTE_DISABLED
0
61 #define PTE_SHARED
(1 << 1)
62 #define PTE_NOT_SHARED
0
64 #define PTE_CB_UNCACHEABLE
0
65 #define PTE_CB_DEVICE
1
66 #define PTE_CB_CACHEABLE_WB
2
67 #define PTE_CB_CACHEABLE_WT
3
69 #define PTE_SZ_4KB
(0 << 3)
70 #define PTE_SZ_64KB
(1 << 3)
71 #define PTE_SZ_1MB
(2 << 3)
72 #define PTE_SZ_512MB
(3 << 3)
74 #define PTE_PRR
(1 << 6)
75 #define PTE_PRX
(1 << 7)
76 #define PTE_PRW
(1 << 8)
77 #define PTE_PRU
(1 << 9)
82 #define ALIGN_4KB
(0xfff)
83 #define ALIGN_1MB
(0xfffff)
84 #define ALIGN_512MB
(0x1fffffff)
86 #define DYNACON_BASE
0x0f000000
87 #define DM_CB_DLINK_BASE
0x0c000000
88 #define DM_DB_DLINK_BASE
0x0b000000
90 #define FEMI_AREA_0
0x00000000
91 #define FEMI_AREA_1
0x04000000
92 #define FEMI_AREA_2
0x05000000
93 #define FEMI_AREA_3
0x06000000
94 #define FEMI_AREA_4
0x07000000
95 #define FEMI_CB
0x08000000
97 #define EMI_BASE
0X80000000
99 #define DMA_BASE
0X0e000000
101 #define CPU_BASE
0X0d000000
103 #define PERIPH_BASE
0X09000000
104 #define DMAC_BASE
0x0e000000
105 #define INTC_BASE
0x0a000000
106 #define CPRC_BASE
0x0a010000
107 #define TMU_BASE
0x0a020000
108 #define SCIF_BASE
0x0a030000
109 #define RTC_BASE
0x0a040000
113 #define LOAD_CONST32
(val
, reg
) \
114 movi
((val
) >> 16) & 65535, reg
; \
115 shori
(val
) & 65535, reg
117 #define LOAD_PTEH_VAL
(sym
, align, bits
, scratch_reg
, reg
) \
118 LOAD_ADDR
(sym
, reg
); \
119 LOAD_CONST32
((align), scratch_reg
); \
120 andc reg
, scratch_reg
, reg
; \
121 LOAD_CONST32
((bits
), scratch_reg
); \
122 or reg
, scratch_reg
, reg
124 #define LOAD_PTEL_VAL
(sym
, align, bits
, scratch_reg
, reg
) \
125 LOAD_ADDR
(sym
, reg
); \
126 LOAD_CONST32
((align), scratch_reg
); \
127 andc reg
, scratch_reg
, reg
; \
128 LOAD_CONST32
((bits
), scratch_reg
); \
129 or reg
, scratch_reg
, reg
131 #define SET_PTE
(pte_addr_reg
, pteh_val_reg
, ptel_val_reg
) \
132 putcfg pte_addr_reg
, 0, r63
; \
133 putcfg pte_addr_reg
, 1, ptel_val_reg
; \
134 putcfg pte_addr_reg
, 0, pteh_val_reg
138 #define LOAD_ADDR
(sym
, reg
) \
139 movi
(sym
>> 48) & 65535, reg
; \
140 shori
(sym
>> 32) & 65535, reg
; \
141 shori
(sym
>> 16) & 65535, reg
; \
142 shori sym
& 65535, reg
145 .
section .text..SHmedia32
,"ax"
146 #define LOAD_ADDR
(sym
, reg
) \
147 movi
(sym
>> 16) & 65535, reg
; \
148 shori sym
& 65535, reg
152 LOAD_ADDR
(_stack
, r15
)
155 ! Set up the VM using the MMU
and caches
157 ! .vm_ep is first instruction to execute
158 ! after VM initialization
161 ! Configure instruction cache
(ICCR
)
164 LOAD_ADDR
(ICCR_BASE
, r1
)
168 ! movi
7, r2
! write through
169 ! Configure operand cache
(OCCR
)
170 LOAD_ADDR
(OCCR_BASE
, r1
)
174 ! Disable all PTE translations
175 LOAD_ADDR
(MMUIR_BASE
, r1
)
176 LOAD_ADDR
(MMUDR_BASE
, r2
)
178 pt
/l .disable_ptes_loop
, tr0
187 LOAD_ADDR
(MMUIR_BASE
, r1
)
189 ! FEMI instruction mappings
190 ! Area
0 - 1Mb cacheable at
0x00000000
192 ! Area
2 - 1Mb cacheable at
0x05000000
193 ! - 1Mb cacheable at
0x05100000
197 ! Map a
1Mb
page for instructions at
0x00000000
198 LOAD_PTEH_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
199 LOAD_PTEL_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU
, r25
, r3
)
202 ! Map a
1Mb
page for instructions at
0x05000000
204 LOAD_PTEH_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
205 LOAD_PTEL_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU
, r25
, r3
)
208 ! Map a
1Mb
page for instructions at
0x05100000
210 LOAD_PTEH_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
211 LOAD_PTEL_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU
, r25
, r3
)
214 ! Map a
512M
page for instructions at EMI base
216 LOAD_PTEH_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
217 LOAD_PTEL_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRX | PTE_PRU
, r25
, r3
)
220 ! Map a
4K
page for instructions at DM_DB_DLINK_BASE
222 LOAD_PTEH_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
223 LOAD_PTEL_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRX | PTE_PRU
, r25
, r3
)
226 LOAD_ADDR
(MMUDR_BASE
, r1
)
229 ! Area
0 - 1Mb cacheable at
0x00000000
230 ! Area
1 - 1Mb device at
0x04000000
231 ! Area
2 - 1Mb cacheable at
0x05000000
232 ! - 1Mb cacheable at
0x05100000
235 ! CB
- 1Mb device at
0x08000000
237 ! Map a
1Mb
page for data at
0x00000000
238 LOAD_PTEH_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
239 LOAD_PTEL_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
242 ! Map a
1Mb
page for data at
0x04000000
244 LOAD_PTEH_VAL
(FEMI_AREA_1
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
245 LOAD_PTEL_VAL
(FEMI_AREA_1
, ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
248 ! Map a
1Mb
page for data at
0x05000000
250 LOAD_PTEH_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
251 LOAD_PTEL_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
254 ! Map a
1Mb
page for data at
0x05100000
256 LOAD_PTEH_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
257 LOAD_PTEL_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
260 ! Map a
4K
page for registers at
0x08000000
262 LOAD_PTEH_VAL
(FEMI_CB
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
263 LOAD_PTEL_VAL
(FEMI_CB
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
266 ! Map a
512M
page for data at EMI
268 LOAD_PTEH_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
269 LOAD_PTEL_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
272 ! Map a
4K
page for DYNACON at DYNACON_BASE
274 LOAD_PTEH_VAL
(DYNACON_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
275 LOAD_PTEL_VAL
(DYNACON_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
278 ! Map a
4K
page for instructions at DM_DB_DLINK_BASE
280 LOAD_PTEH_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
281 LOAD_PTEL_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
284 ! Map a
4K
page for data at DM_DB_DLINK_BASE
+0x1000
286 LOAD_PTEH_VAL
((DM_DB_DLINK_BASE
+0x1000), ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
287 LOAD_PTEL_VAL
((DM_DB_DLINK_BASE
+0x1000), ALIGN_4KB
, PTE_CB_UNCACHEABLE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
290 ! Map a
4K
page for stack DM_DB_DLINK_BASE
+0x2000
292 LOAD_PTEH_VAL
((DM_DB_DLINK_BASE
+0x2000), ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
293 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
)
296 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
297 ! 0x0c000000 - 0x0c0fffff
299 LOAD_PTEH_VAL
(DM_CB_DLINK_BASE
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
300 LOAD_PTEL_VAL
(DM_CB_DLINK_BASE
, ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
303 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
304 ! 0x0c100000 - 0x0c1fffff
306 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
307 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x100000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
310 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
311 ! 0x0c200000 - 0x0c2fffff
313 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x200000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
314 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x200000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
317 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
318 ! 0x0c400000 - 0x0c4fffff
320 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x400000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
321 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x400000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
324 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
325 ! 0x0c800000 - 0x0c8fffff
327 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x800000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
328 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x800000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
331 ! Map a
4K
page for DMA control registers
333 LOAD_PTEH_VAL
(DMA_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
334 LOAD_PTEL_VAL
(DMA_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
337 ! Map lots of
4K pages for peripherals
341 LOAD_PTEH_VAL
(PERIPH_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
342 LOAD_PTEL_VAL
(PERIPH_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
346 LOAD_PTEH_VAL
(DMAC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
347 LOAD_PTEL_VAL
(DMAC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
351 LOAD_PTEH_VAL
(INTC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
352 LOAD_PTEL_VAL
(INTC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
356 LOAD_PTEH_VAL
(RTC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
357 LOAD_PTEL_VAL
(RTC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
361 LOAD_PTEH_VAL
(TMU_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
362 LOAD_PTEL_VAL
(TMU_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
366 LOAD_PTEH_VAL
(SCIF_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
367 LOAD_PTEL_VAL
(SCIF_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
371 LOAD_PTEH_VAL
(CPRC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
372 LOAD_PTEL_VAL
(CPRC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
375 ! Map CPU WPC registers
377 LOAD_PTEH_VAL
(CPU_BASE
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
378 LOAD_PTEL_VAL
(CPU_BASE
, ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
382 LOAD_PTEH_VAL
((CPU_BASE
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
383 LOAD_PTEL_VAL
((CPU_BASE
+0x100000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
387 LOAD_PTEH_VAL
((CPU_BASE
+0x200000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
388 LOAD_PTEL_VAL
((CPU_BASE
+0x200000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
392 LOAD_PTEH_VAL
((CPU_BASE
+0x400000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
393 LOAD_PTEL_VAL
((CPU_BASE
+0x400000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
396 ! Switch over to virtual addressing
and enabled cache
399 shlli r2
, SR_BL_BIT
, r2
404 shlli r2
, SR_MMU_BIT
, r2
412 ! VM
entry point. From now on
, we are
in VM mode.
415 ! Install the trap handler
, by seeding vbr with the
416 ! correct value
, and by assigning sr.
bl = 0.
418 LOAD_ADDR
(vbr_start
, r1
)
424 #endif
/* MMU_SUPPORT
*/
426 pt
/l .Lzero_bss_loop
, tr0
428 pt
/l ___setup_argv_and_call_main
, tr6
432 LOAD_ADDR
(_edata
, r0
)
439 LOAD_ADDR
(___data
, r26
)
440 LOAD_ADDR
(___rodata
, r27
)
442 #ifdef __SH_FPU_ANY__
444 ! enable the FP unit
, by resetting SR.FD
445 ! also zero
out SR.FR
, SR.SZ
and SR.PR
, as mandated by the ABI
451 pt
/l ___set_fpscr
, tr0
457 ! arrange for exit to
call fini
459 LOAD_ADDR
(_fini
, r2
)
470 ! We should never return from _exit but
in case we do we would
enter the
471 ! the following tight
loop.
This avoids executing any data that might follow.
477 ! All these traps are handled
in the same place.
480 pt
/l handler
, tr0
! tr0 trashed.
484 pt
/l handler
, tr0
! tr0 trashed.
489 pt
/l handler
, tr0
! tr0 trashed.
493 pt
/l handler
, tr0
! tr0 trashed.
496 vbr_400: ! Should be at vbr
+0x400
498 /* If the trap handler is there
call it
*/
499 LOAD_ADDR
(__superh_trap_handler
, r2
)
501 beq r2
, r63
, tr2
/* If zero
, ie
not present branch around to chandler
*/
502 /* Now
call the trap handler with as much of the context unchanged as possible.
503 Move trapping address
into R18 to make it look like the trap point
*/
505 pt
/l __superh_trap_handler
, tr0
513 /* Simulated trap handler
*/
514 .
section .text..SHmedia32
,"ax"
516 .
section .debug_abbrev
518 .
section .text..SHmedia32
524 .
section .text..SHmedia32
,"ax"
526 .
global __superh_trap_handler
527 .
type __superh_trap_handler
,@function
528 __superh_trap_handler:
544 .
size __superh_trap_handler
,.Lfe1
-__superh_trap_handler
546 .
section .text..SHmedia32
552 .ualong .Ldebug_abbrev0
555 .ualong .Ldebug_line0
558 .string
"trap_handler.c"
560 .string
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
562 .string
"GNU C 2.97-sh5-010522"
568 .string
"_superh_trap_handler"
578 .string
"trap_reason"
588 .string
"unsigned int"
594 .
section .debug_abbrev
661 .
section .debug_pubnames
664 .ualong .Ldebug_info0
667 .string
"_superh_trap_handler"
671 .
section .debug_aranges
674 .ualong .Ldebug_info0
679 .ualong .Letext0
-.Ltext0
682 .ident
"GCC: (GNU) 2.97-sh5-010522"
683 #endif
/* MMU_SUPPORT
*/
684 #else
/* ! __SH5__
*/
686 ! make a place to keep any previous value of the vbr register
687 ! this will only have a value if it has been set by redboot
(for example
)
699 .
import ___rtos_profiler_start_timer
700 .weak ___rtos_profiler_start_timer
704 #if defined
(__SH3__
) ||
(defined
(__SH_FPU_ANY__
) && ! defined
(__SH2A__
)) || defined
(__SH4_NOFPU__
)
706 ! before zeroing the bss ...
707 ! if the vbr is already set to vbr_start then the program has been restarted
708 ! (i.e. it is
not the first time the program has been run since reset
)
709 ! reset the vbr to its old value before old_vbr
(in bss
) is wiped
710 ! this ensures that the later code does
not create a circular vbr chain
712 mov.l vbr_start_k
, r2
715 ! reset the old vbr value
720 #endif
/* VBR_SETUP
*/
732 #if defined
(__SH_FPU_ANY__
)
733 mov.l set_fpscr_k
, r1
736 shll16 r4
! Set DN bit
(flush denormal inputs to zero
)
737 lds r3
,fpscr
! Switch to default precision
738 #endif
/* defined
(__SH_FPU_ANY__
) */
741 ! save the existing contents of the vbr
742 ! there will only be a prior value when using something like redboot
743 ! otherwise it will be zero
748 mov.l vbr_start_k
, r1
750 #endif
/* VBR_SETUP
*/
752 ! if an rtos is exporting a timer start fn
,
753 ! then pick up an SR which does
not enable ints
754 ! (the rtos will take care of
this)
755 mov.l rtos_start_fn
, r0
756 mov.l sr_initial_bare
, r1
760 mov.l sr_initial_rtos
, r1
763 ! Set status register
(sr
)
766 ! arrange for exit to
call fini
773 ! arrange for exit to
call _mcleanup
(via stop_profiling
)
774 mova stop_profiling
,r0
779 ! Call profiler startup code
780 mov.l monstartup_k
, r0
786 ! enable profiling trap
787 ! until now any trap
33s will have been ignored
788 ! This means that all library functions called before
this point
789 ! (directly
or indirectly
) may have the profiling trap at the start.
790 ! Therefore
, only mcount itself may
not have the extra header.
791 mov.l profiling_enabled_k2
, r0
815 # stop mcount counting
816 mov.l profiling_enabled_k2
, r0
830 profiling_enabled_k2:
831 .long profiling_enabled
839 #if defined
(__SH_FPU_ANY__
)
842 #endif
/* defined
(__SH_FPU_ANY__
) */
851 .long ___setup_argv_and_call_main
865 #endif
/* VBR_SETUP
*/
868 ! Privileged mode RB
1 BL 0. Keep
BL 0 to allow default trap handlers to work.
869 ! Whether profiling
or not, keep interrupts masked
,
870 ! the RTOS will enable these if required.
874 .long ___rtos_profiler_start_timer
878 ! Privileged mode RB
1 BL 0. Keep
BL 0 to allow default trap handlers to work.
879 ! For bare machine
, we need to enable interrupts to get profiling working
884 ! Privileged mode RB
1 BL 0. Keep
BL 0 to allow default trap handlers to work.
885 ! Keep interrupts disabled
- the application will enable as required.
889 ! supplied for backward compatibility only
, in case of linking
890 ! code whose main
() was compiled with an older version of GCC.
899 mov.l
2f
, r0
! load the old vbr setting
(if any
)
903 ! no previous vbr
- jump to own generic handler
906 1: ! there was a previous handler
- chain them
916 ! Note on register usage.
917 ! we use r0..r3 as scratch
in this code. If we are here due to a trapa for profiling
918 ! then
this is OK as we are just before executing any function code.
919 ! The other r4..r7 we save explicityl on the stack
920 ! Remaining registers are saved by normal ABI conventions
and we assert we do
not
921 ! use floating point registers.
929 bra handler_100
! if
not a trapa
, go to default handler
934 shlr2 r0
! trapa code is shifted by
2.
941 ! If here then it looks like we have trap #
33
942 ! Now we need to
call mcount with the following convention
943 ! Save
and restore r4..r7
952 ! r0 is the branch back address.
953 ! The code sequence emitted by gcc for the profiling trap is
957 ! .long lab Where lab is planted by the compiler.
This is the address
958 ! of a datum that needs to be incremented.
962 not r2
, r2
! pattern to
align to
4
963 and r2
, r5
! r5 now has aligned address
964 ! add #
4, r5
! r5 now has address of address
965 mov r5
, r2
! Remember it.
966 ! mov.l
@r5, r5
! r5 has value of lable
(lab
in above example
)
968 ldc r2
, spc
! our return address avoiding address
word
970 ! only
call mcount if profiling is enabled
971 mov.l profiling_enabled_k
, r0
993 .long
0xff000024 ! Address of expevt
999 .long profiling_enabled
1001 ! Non profiling case.
1003 mov.l
2f
, r0
! load the old vbr setting
(if any
)
1007 ! no previous vbr
- jump to own generic handler
1010 1: ! there was a previous handler
- chain them
1011 add #
0x7f, r0
! 0x7f
1012 add #
0x7f, r0
! 0xfe
1013 add #
0x2, r0
! add 0x100 without corrupting another register
1022 mov.l
2f
, r0
! load the old vbr setting
(if any
)
1026 ! no previous vbr
- jump to own generic handler
1029 1: ! there was a previous handler
- chain them
1030 add #
0x7f, r0
! 0x7f
1031 add #
0x7f, r0
! 0xfe
1032 add #
0x7f, r0
! 0x17d
1033 add #
0x7f, r0
! 0x1fc
1034 add #
0x4, r0
! add 0x200 without corrupting another register
1043 mov.l
2f
, r0
! load the old vbr setting
(if any
)
1047 ! no previous vbr
- jump to own generic handler
1050 1: ! there was a previous handler
- chain them
1053 add #
0x7f, r0
! 0x1fc
1054 add #
0x41, r0
! 0x300
1056 rotcl r0
! Add 0x300 without corrupting another register
1064 vbr_400: ! Should be at vbr
+0x400
1065 mov.l
2f
, r0
! load the old vbr setting
(if any
)
1068 ! no previous vbr
- jump to own generic handler
1070 ! there was a previous handler
- chain them
1073 add #
0x7f, r0
! 0x1fc
1074 add #
0x7f, r0
! 0x3f8
1075 add #
0x02, r0
! 0x400
1077 rotcl r0
! Add 0x400 without corrupting another register
1084 /* If the trap handler is there
call it
*/
1085 mov.l superh_trap_handler_k
, r0
1086 cmp/eq #
0, r0
! True if zero.
1091 ! Here handler available
, call it.
1092 /* Now
call the trap handler with as much of the context unchanged as possible.
1093 Move trapping address
into PR to make it look like the trap point
*/
1097 mov.l
@r4, r4
! r4 is value of expevt
, first parameter.
1098 mov r1
, r5
! Remember trapping pc.
1099 mov r1
, r6
! Remember trapping pc.
1100 mov.l chandler_k
, r1
1101 mov.l superh_trap_handler_k
, r2
1102 ! jmp to trap handler to avoid disturbing pr.
1108 mov.l
2f
, r0
! load the old vbr setting
(if any
)
1111 ! no previous vbr
- jump to own generic handler
1113 ! there was a previous handler
- chain them
1116 add #
0x7f, r0
! 0x1fc
1117 add #
0x7f, r0
! 0x3f8
1118 add #
0x42, r0
! 0x500
1120 rotcl r0
! Add 0x500 without corrupting another register
1130 ! Should be at vbr
+0x600
1131 ! Now we are
in the land of interrupts so need to save more state.
1132 ! Save register state
1133 mov.l interrupt_stack_k
, r15
! r15 has been saved to sgr.
1143 ! Pass interrupted pc to timer_handler as first parameter
(r4
).
1145 mov.l timer_handler_k
, r0
1157 stc sgr
, r15
! Restore r15
, destroyed by
this sequence.
1161 mov.l
2f
, r0
! Load the old vbr setting
(if any
).
1164 ! no previous vbr
- jump to own handler
1166 ! there was a previous handler
- chain them
1169 add #
0x7f, r0
! 0x1fc
1170 add #
0x7f, r0
! 0x3f8
1171 add #
0x7f, r0
! 0x5f4
1172 add #
0x03, r0
! 0x600
1174 rotcl r0
! Add 0x600 without corrupting another register
1180 #endif
/* PROFILE code
*/
1183 mov.l
@r4, r4
! r4 is value of expevt hence making
this the return code
1184 mov.l handler_exit_k
,r0
1187 ! We should never return from _exit but
in case we do we would
enter the
1188 ! the following tight
loop
1195 .long __timer_stack
! The
high end of the stack
1197 .long __profil_counter
1200 .long
0xff000024 ! Address of expevt
1203 superh_trap_handler_k:
1204 .long __superh_trap_handler
1208 ! Simulated compile of trap handler.
1209 .
section .debug_abbrev
,"",@progbits
1211 .
section .debug_info
,"",@progbits
1213 .
section .debug_line
,"",@progbits
1218 .
type __superh_trap_handler
,@function
1219 __superh_trap_handler:
1236 .
size __superh_trap_handler
,.Lfe1
-__superh_trap_handler
1237 .
section .debug_frame
,"",@progbits
1239 .ualong .LECIE0
-.LSCIE0
1253 .ualong .LEFDE0
-.LASFDE0
1259 .ualong .LCFI0
-.LFB1
1263 .ualong .LCFI1
-.LCFI0
1269 .ualong .LCFI2
-.LCFI1
1276 .
section .debug_info
1279 .ualong .Ldebug_abbrev0
1282 .ualong .Ldebug_line0
1285 .string
"trap_handler.c"
1286 .string
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1287 .string
"GNU C 3.2 20020529 (experimental)"
1292 .string
"_superh_trap_handler"
1301 .string
"trap_reason"
1310 .string
"unsigned int"
1314 .
section .debug_abbrev
1384 .
section .debug_pubnames
,"",@progbits
1387 .ualong .Ldebug_info0
1390 .string
"_superh_trap_handler"
1392 .
section .debug_aranges
,"",@progbits
1395 .ualong .Ldebug_info0
1401 .ualong .Letext0
-.Ltext0
1404 #endif
/* VBR_SETUP
*/
1405 #endif
/* ! __SH5__
*/