1 /* Copyright
(C
) 2000, 2001, 2003, 2004, 2005, 2006
2 Free Software Foundation
, Inc.
3 This file was pretty much copied from newlib.
5 This file is part of GCC.
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 2, or (at your option) any
12 In addition to the permissions
in the GNU General
Public License
, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of
this file
into combinations with other programs
,
15 and to distribute those combinations without any restriction coming
16 from the use of
this file.
(The General
Public License restrictions
17 do apply
in other respects
; for example, they cover modification of
18 the file
, and distribution when
not linked
into a combine
21 GCC is distributed
in the hope that it will be useful
,
22 but WITHOUT ANY WARRANTY
; without even the implied warranty of
23 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General
Public License for more details.
26 You should have received a copy of the GNU General
Public License
27 along with
this program
; see the file COPYING. If not, write to
28 the Free Software Foundation
, 51 Franklin Street
, Fifth Floor
,
29 Boston
, MA
02110-1301, USA.
*/
32 /* Section used for exception
/timer interrupt stack area
*/
33 .
section .data.vbr.stack
,"aw"
37 .zero
1024 * 2 /* ; 2k for VBR handlers */
38 /* Label at the highest stack address where the stack grows from
*/
40 #endif
/* MMU_SUPPORT
*/
42 /* ;----------------------------------------
43 Normal newlib crt1.asm
*/
54 #define ICCR_BASE
0x01600000
55 #define OCCR_BASE
0x01e00000
56 #define MMUIR_BASE
0x00000000
57 #define MMUDR_BASE
0x00800000
60 #define PTE_DISABLED
0
62 #define PTE_SHARED
(1 << 1)
63 #define PTE_NOT_SHARED
0
65 #define PTE_CB_UNCACHEABLE
0
66 #define PTE_CB_DEVICE
1
67 #define PTE_CB_CACHEABLE_WB
2
68 #define PTE_CB_CACHEABLE_WT
3
70 #define PTE_SZ_4KB
(0 << 3)
71 #define PTE_SZ_64KB
(1 << 3)
72 #define PTE_SZ_1MB
(2 << 3)
73 #define PTE_SZ_512MB
(3 << 3)
75 #define PTE_PRR
(1 << 6)
76 #define PTE_PRX
(1 << 7)
77 #define PTE_PRW
(1 << 8)
78 #define PTE_PRU
(1 << 9)
83 #define ALIGN_4KB
(0xfff)
84 #define ALIGN_1MB
(0xfffff)
85 #define ALIGN_512MB
(0x1fffffff)
87 #define DYNACON_BASE
0x0f000000
88 #define DM_CB_DLINK_BASE
0x0c000000
89 #define DM_DB_DLINK_BASE
0x0b000000
91 #define FEMI_AREA_0
0x00000000
92 #define FEMI_AREA_1
0x04000000
93 #define FEMI_AREA_2
0x05000000
94 #define FEMI_AREA_3
0x06000000
95 #define FEMI_AREA_4
0x07000000
96 #define FEMI_CB
0x08000000
98 #define EMI_BASE
0X80000000
100 #define DMA_BASE
0X0e000000
102 #define CPU_BASE
0X0d000000
104 #define PERIPH_BASE
0X09000000
105 #define DMAC_BASE
0x0e000000
106 #define INTC_BASE
0x0a000000
107 #define CPRC_BASE
0x0a010000
108 #define TMU_BASE
0x0a020000
109 #define SCIF_BASE
0x0a030000
110 #define RTC_BASE
0x0a040000
114 #define LOAD_CONST32
(val
, reg
) \
115 movi
((val
) >> 16) & 65535, reg
; \
116 shori
(val
) & 65535, reg
118 #define LOAD_PTEH_VAL
(sym
, align, bits
, scratch_reg
, reg
) \
119 LOAD_ADDR
(sym
, reg
); \
120 LOAD_CONST32
((align), scratch_reg
); \
121 andc reg
, scratch_reg
, reg
; \
122 LOAD_CONST32
((bits
), scratch_reg
); \
123 or reg
, scratch_reg
, reg
125 #define LOAD_PTEL_VAL
(sym
, align, bits
, scratch_reg
, reg
) \
126 LOAD_ADDR
(sym
, reg
); \
127 LOAD_CONST32
((align), scratch_reg
); \
128 andc reg
, scratch_reg
, reg
; \
129 LOAD_CONST32
((bits
), scratch_reg
); \
130 or reg
, scratch_reg
, reg
132 #define SET_PTE
(pte_addr_reg
, pteh_val_reg
, ptel_val_reg
) \
133 putcfg pte_addr_reg
, 0, r63
; \
134 putcfg pte_addr_reg
, 1, ptel_val_reg
; \
135 putcfg pte_addr_reg
, 0, pteh_val_reg
139 #define LOAD_ADDR
(sym
, reg
) \
140 movi
(sym
>> 48) & 65535, reg
; \
141 shori
(sym
>> 32) & 65535, reg
; \
142 shori
(sym
>> 16) & 65535, reg
; \
143 shori sym
& 65535, reg
146 .
section .text..SHmedia32
,"ax"
147 #define LOAD_ADDR
(sym
, reg
) \
148 movi
(sym
>> 16) & 65535, reg
; \
149 shori sym
& 65535, reg
153 LOAD_ADDR
(_stack
, r15
)
156 ! Set up the VM using the MMU
and caches
158 ! .vm_ep is first instruction to execute
159 ! after VM initialization
162 ! Configure instruction cache
(ICCR
)
165 LOAD_ADDR
(ICCR_BASE
, r1
)
169 ! movi
7, r2
! write through
170 ! Configure operand cache
(OCCR
)
171 LOAD_ADDR
(OCCR_BASE
, r1
)
175 ! Disable all PTE translations
176 LOAD_ADDR
(MMUIR_BASE
, r1
)
177 LOAD_ADDR
(MMUDR_BASE
, r2
)
179 pt
/l .disable_ptes_loop
, tr0
188 LOAD_ADDR
(MMUIR_BASE
, r1
)
190 ! FEMI instruction mappings
191 ! Area
0 - 1Mb cacheable at
0x00000000
193 ! Area
2 - 1Mb cacheable at
0x05000000
194 ! - 1Mb cacheable at
0x05100000
198 ! Map a
1Mb
page for instructions at
0x00000000
199 LOAD_PTEH_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
200 LOAD_PTEL_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU
, r25
, r3
)
203 ! Map a
1Mb
page for instructions at
0x05000000
205 LOAD_PTEH_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
206 LOAD_PTEL_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU
, r25
, r3
)
209 ! Map a
1Mb
page for instructions at
0x05100000
211 LOAD_PTEH_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
212 LOAD_PTEL_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU
, r25
, r3
)
215 ! Map a
512M
page for instructions at EMI base
217 LOAD_PTEH_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
218 LOAD_PTEL_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRX | PTE_PRU
, r25
, r3
)
221 ! Map a
4K
page for instructions at DM_DB_DLINK_BASE
223 LOAD_PTEH_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
224 LOAD_PTEL_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRX | PTE_PRU
, r25
, r3
)
227 LOAD_ADDR
(MMUDR_BASE
, r1
)
230 ! Area
0 - 1Mb cacheable at
0x00000000
231 ! Area
1 - 1Mb device at
0x04000000
232 ! Area
2 - 1Mb cacheable at
0x05000000
233 ! - 1Mb cacheable at
0x05100000
236 ! CB
- 1Mb device at
0x08000000
238 ! Map a
1Mb
page for data at
0x00000000
239 LOAD_PTEH_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
240 LOAD_PTEL_VAL
(FEMI_AREA_0
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
243 ! Map a
1Mb
page for data at
0x04000000
245 LOAD_PTEH_VAL
(FEMI_AREA_1
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
246 LOAD_PTEL_VAL
(FEMI_AREA_1
, ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
249 ! Map a
1Mb
page for data at
0x05000000
251 LOAD_PTEH_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
252 LOAD_PTEL_VAL
(FEMI_AREA_2
, ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
255 ! Map a
1Mb
page for data at
0x05100000
257 LOAD_PTEH_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
258 LOAD_PTEL_VAL
((FEMI_AREA_2
+0x100000), ALIGN_1MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
261 ! Map a
4K
page for registers at
0x08000000
263 LOAD_PTEH_VAL
(FEMI_CB
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
264 LOAD_PTEL_VAL
(FEMI_CB
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
267 ! Map a
512M
page for data at EMI
269 LOAD_PTEH_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
270 LOAD_PTEL_VAL
(EMI_BASE
, ALIGN_512MB
, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
273 ! Map a
4K
page for DYNACON at DYNACON_BASE
275 LOAD_PTEH_VAL
(DYNACON_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
276 LOAD_PTEL_VAL
(DYNACON_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
279 ! Map a
4K
page for instructions at DM_DB_DLINK_BASE
281 LOAD_PTEH_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
282 LOAD_PTEL_VAL
(DM_DB_DLINK_BASE
, ALIGN_4KB
, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
285 ! Map a
4K
page for data at DM_DB_DLINK_BASE
+0x1000
287 LOAD_PTEH_VAL
((DM_DB_DLINK_BASE
+0x1000), ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
288 LOAD_PTEL_VAL
((DM_DB_DLINK_BASE
+0x1000), ALIGN_4KB
, PTE_CB_UNCACHEABLE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
291 ! Map a
4K
page for stack DM_DB_DLINK_BASE
+0x2000
293 LOAD_PTEH_VAL
((DM_DB_DLINK_BASE
+0x2000), ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
294 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
)
297 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
298 ! 0x0c000000 - 0x0c0fffff
300 LOAD_PTEH_VAL
(DM_CB_DLINK_BASE
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
301 LOAD_PTEL_VAL
(DM_CB_DLINK_BASE
, ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
304 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
305 ! 0x0c100000 - 0x0c1fffff
307 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
308 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x100000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
311 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
312 ! 0x0c200000 - 0x0c2fffff
314 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x200000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
315 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x200000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
318 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
319 ! 0x0c400000 - 0x0c4fffff
321 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x400000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
322 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x400000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
325 ! Map a
1M
page for DM_CB_BASE2 at DM_CB_DLINK
326 ! 0x0c800000 - 0x0c8fffff
328 LOAD_PTEH_VAL
((DM_CB_DLINK_BASE
+0x800000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
329 LOAD_PTEL_VAL
((DM_CB_DLINK_BASE
+0x800000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
332 ! Map a
4K
page for DMA control registers
334 LOAD_PTEH_VAL
(DMA_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
335 LOAD_PTEL_VAL
(DMA_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
338 ! Map lots of
4K pages for peripherals
342 LOAD_PTEH_VAL
(PERIPH_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
343 LOAD_PTEL_VAL
(PERIPH_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
347 LOAD_PTEH_VAL
(DMAC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
348 LOAD_PTEL_VAL
(DMAC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
352 LOAD_PTEH_VAL
(INTC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
353 LOAD_PTEL_VAL
(INTC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
357 LOAD_PTEH_VAL
(RTC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
358 LOAD_PTEL_VAL
(RTC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
362 LOAD_PTEH_VAL
(TMU_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
363 LOAD_PTEL_VAL
(TMU_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
367 LOAD_PTEH_VAL
(SCIF_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
368 LOAD_PTEL_VAL
(SCIF_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
372 LOAD_PTEH_VAL
(CPRC_BASE
, ALIGN_4KB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
373 LOAD_PTEL_VAL
(CPRC_BASE
, ALIGN_4KB
, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
376 ! Map CPU WPC registers
378 LOAD_PTEH_VAL
(CPU_BASE
, ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
379 LOAD_PTEL_VAL
(CPU_BASE
, ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
383 LOAD_PTEH_VAL
((CPU_BASE
+0x100000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
384 LOAD_PTEL_VAL
((CPU_BASE
+0x100000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
388 LOAD_PTEH_VAL
((CPU_BASE
+0x200000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
389 LOAD_PTEL_VAL
((CPU_BASE
+0x200000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
393 LOAD_PTEH_VAL
((CPU_BASE
+0x400000), ALIGN_1MB
, PTE_ENABLED | PTE_NOT_SHARED
, r25
, r2
)
394 LOAD_PTEL_VAL
((CPU_BASE
+0x400000), ALIGN_1MB
, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU
, r25
, r3
)
397 ! Switch over to virtual addressing
and enabled cache
400 shlli r2
, SR_BL_BIT
, r2
405 shlli r2
, SR_MMU_BIT
, r2
413 ! VM
entry point. From now on
, we are
in VM mode.
416 ! Install the trap handler
, by seeding vbr with the
417 ! correct value
, and by assigning sr.
bl = 0.
419 LOAD_ADDR
(vbr_start
, r1
)
425 #endif
/* MMU_SUPPORT
*/
427 pt
/l .Lzero_bss_loop
, tr0
429 pt
/l ___setup_argv_and_call_main
, tr6
433 LOAD_ADDR
(_edata
, r0
)
440 LOAD_ADDR
(___data
, r26
)
441 LOAD_ADDR
(___rodata
, r27
)
443 #ifdef __SH_FPU_ANY__
445 ! enable the FP unit
, by resetting SR.FD
446 ! also zero
out SR.FR
, SR.SZ
and SR.PR
, as mandated by the ABI
452 pt
/l ___set_fpscr
, tr0
458 ! arrange for exit to
call fini
460 LOAD_ADDR
(_fini
, r2
)
471 ! We should never return from _exit but
in case we do we would
enter the
472 ! the following tight
loop.
This avoids executing any data that might follow.
478 ! All these traps are handled
in the same place.
481 pt
/l handler
, tr0
! tr0 trashed.
485 pt
/l handler
, tr0
! tr0 trashed.
490 pt
/l handler
, tr0
! tr0 trashed.
494 pt
/l handler
, tr0
! tr0 trashed.
497 vbr_400: ! Should be at vbr
+0x400
499 /* If the trap handler is there
call it
*/
500 LOAD_ADDR
(__superh_trap_handler
, r2
)
502 beq r2
, r63
, tr2
/* If zero
, ie
not present branch around to chandler
*/
503 /* Now
call the trap handler with as much of the context unchanged as possible.
504 Move trapping address
into R18 to make it look like the trap point
*/
506 pt
/l __superh_trap_handler
, tr0
514 /* Simulated trap handler
*/
515 .
section .text..SHmedia32
,"ax"
517 .
section .debug_abbrev
519 .
section .text..SHmedia32
525 .
section .text..SHmedia32
,"ax"
527 .
global __superh_trap_handler
528 .
type __superh_trap_handler
,@function
529 __superh_trap_handler:
545 .
size __superh_trap_handler
,.Lfe1
-__superh_trap_handler
547 .
section .text..SHmedia32
553 .ualong .Ldebug_abbrev0
556 .ualong .Ldebug_line0
559 .string
"trap_handler.c"
561 .string
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
563 .string
"GNU C 2.97-sh5-010522"
569 .string
"_superh_trap_handler"
579 .string
"trap_reason"
589 .string
"unsigned int"
595 .
section .debug_abbrev
662 .
section .debug_pubnames
665 .ualong .Ldebug_info0
668 .string
"_superh_trap_handler"
672 .
section .debug_aranges
675 .ualong .Ldebug_info0
680 .ualong .Letext0
-.Ltext0
683 .ident
"GCC: (GNU) 2.97-sh5-010522"
684 #endif
/* MMU_SUPPORT
*/
685 #else
/* ! __SH5__
*/
687 ! make a place to keep any previous value of the vbr register
688 ! this will only have a value if it has been set by redboot
(for example
)
700 .
import ___rtos_profiler_start_timer
701 .weak ___rtos_profiler_start_timer
705 #if defined
(__SH3__
) ||
(defined
(__SH_FPU_ANY__
) && ! defined
(__SH2A__
)) || defined
(__SH4_NOFPU__
)
707 ! before zeroing the bss ...
708 ! if the vbr is already set to vbr_start then the program has been restarted
709 ! (i.e. it is
not the first time the program has been run since reset
)
710 ! reset the vbr to its old value before old_vbr
(in bss
) is wiped
711 ! this ensures that the later code does
not create a circular vbr chain
713 mov.l vbr_start_k
, r2
716 ! reset the old vbr value
721 #endif
/* VBR_SETUP
*/
733 #if defined
(__SH_FPU_ANY__
)
734 mov.l set_fpscr_k
, r1
737 shll16 r4
! Set DN bit
(flush denormal inputs to zero
)
738 lds r3
,fpscr
! Switch to default precision
739 #endif
/* defined
(__SH_FPU_ANY__
) */
742 ! save the existing contents of the vbr
743 ! there will only be a prior value when using something like redboot
744 ! otherwise it will be zero
749 mov.l vbr_start_k
, r1
751 #endif
/* VBR_SETUP
*/
753 ! if an rtos is exporting a timer start fn
,
754 ! then pick up an SR which does
not enable ints
755 ! (the rtos will take care of
this)
756 mov.l rtos_start_fn
, r0
757 mov.l sr_initial_bare
, r1
761 mov.l sr_initial_rtos
, r1
764 ! Set status register
(sr
)
767 ! arrange for exit to
call fini
774 ! arrange for exit to
call _mcleanup
(via stop_profiling
)
775 mova stop_profiling
,r0
780 ! Call profiler startup code
781 mov.l monstartup_k
, r0
787 ! enable profiling trap
788 ! until now any trap
33s will have been ignored
789 ! This means that all library functions called before
this point
790 ! (directly
or indirectly
) may have the profiling trap at the start.
791 ! Therefore
, only mcount itself may
not have the extra header.
792 mov.l profiling_enabled_k2
, r0
816 # stop mcount counting
817 mov.l profiling_enabled_k2
, r0
831 profiling_enabled_k2:
832 .long profiling_enabled
840 #if defined
(__SH_FPU_ANY__
)
843 #endif
/* defined
(__SH_FPU_ANY__
) */
852 .long ___setup_argv_and_call_main
866 #endif
/* VBR_SETUP
*/
869 ! Privileged mode RB
1 BL 0. Keep
BL 0 to allow default trap handlers to work.
870 ! Whether profiling
or not, keep interrupts masked
,
871 ! the RTOS will enable these if required.
875 .long ___rtos_profiler_start_timer
879 ! Privileged mode RB
1 BL 0. Keep
BL 0 to allow default trap handlers to work.
880 ! For bare machine
, we need to enable interrupts to get profiling working
885 ! Privileged mode RB
1 BL 0. Keep
BL 0 to allow default trap handlers to work.
886 ! Keep interrupts disabled
- the application will enable as required.
890 ! supplied for backward compatibility only
, in case of linking
891 ! code whose main
() was compiled with an older version of GCC.
898 .
section .text.vbr
, "ax"
904 ! Note on register usage.
905 ! we use r0..r3 as scratch
in this code. If we are here due to a trapa for profiling
906 ! then
this is OK as we are just before executing any function code.
907 ! The other r4..r7 we save explicityl on the stack
908 ! Remaining registers are saved by normal ABI conventions
and we assert we do
not
909 ! use floating point registers.
917 bra handler_100
! if
not a trapa
, go to default handler
922 shlr2 r0
! trapa code is shifted by
2.
929 ! If here then it looks like we have trap #
33
930 ! Now we need to
call mcount with the following convention
931 ! Save
and restore r4..r7
940 ! r0 is the branch back address.
941 ! The code sequence emitted by gcc for the profiling trap is
945 ! .long lab Where lab is planted by the compiler.
This is the address
946 ! of a datum that needs to be incremented.
950 not r2
, r2
! pattern to
align to
4
951 and r2
, r5
! r5 now has aligned address
952 ! add #
4, r5
! r5 now has address of address
953 mov r5
, r2
! Remember it.
954 ! mov.l
@r5, r5
! r5 has value of lable
(lab
in above example
)
956 ldc r2
, spc
! our return address avoiding address
word
958 ! only
call mcount if profiling is enabled
959 mov.l profiling_enabled_k
, r0
981 .long
0xff000024 ! Address of expevt
987 .long profiling_enabled
989 ! Non profiling case.
991 mov.l
2f
, r0
! load the old vbr setting
(if any
)
995 ! no previous vbr
- jump to own generic handler
998 1: ! there was a previous handler
- chain them
1000 add #
0x7f, r0
! 0xfe
1001 add #
0x2, r0
! add 0x100 without corrupting another register
1009 vbr_400: ! Should be at vbr
+0x400
1010 mov.l
2f
, r0
! load the old vbr setting
(if any
)
1013 ! no previous vbr
- jump to own generic handler
1015 ! there was a previous handler
- chain them
1018 add #
0x7f, r0
! 0x1fc
1019 add #
0x7f, r0
! 0x3f8
1020 add #
0x02, r0
! 0x400
1022 rotcl r0
! Add 0x400 without corrupting another register
1029 /* If the trap handler is there
call it
*/
1030 mov.l superh_trap_handler_k
, r0
1031 cmp/eq #
0, r0
! True if zero.
1036 ! Here handler available
, call it.
1037 /* Now
call the trap handler with as much of the context unchanged as possible.
1038 Move trapping address
into PR to make it look like the trap point
*/
1042 mov.l
@r4, r4
! r4 is value of expevt
, first parameter.
1043 mov r1
, r5
! Remember trapping pc.
1044 mov r1
, r6
! Remember trapping pc.
1045 mov.l chandler_k
, r1
1046 mov.l superh_trap_handler_k
, r2
1047 ! jmp to trap handler to avoid disturbing pr.
1054 ! Should be at vbr
+0x600
1055 ! Now we are
in the land of interrupts so need to save more state.
1056 ! Save register state
1057 mov.l interrupt_stack_k
, r15
! r15 has been saved to sgr.
1069 #if defined
(__SH_FPU_ANY__
)
1070 ! Save fpul
and fpscr
, save fr0
-fr7
in 64 bit mode
1071 ! and set the pervading precision for the timer_handler
1075 lds r0
,fpscr
! Clear fpscr
1080 mov.l pervading_precision_k
,r0
1087 #endif
/* __SH_FPU_ANY__
*/
1088 ! Pass interrupted pc to timer_handler as first parameter
(r4
).
1090 mov.l timer_handler_k
, r0
1093 #if defined
(__SH_FPU_ANY__
)
1095 lds r0
,fpscr
! Clear the fpscr
1106 #endif
/* __SH_FPU_ANY__
*/
1118 stc sgr
, r15
! Restore r15
, destroyed by
this sequence.
1121 #if defined
(__SH_FPU_ANY__
)
1123 pervading_precision_k:
1124 #define CONCAT1
(A
,B
) A##B
1125 #define CONCAT
(A
,B
) CONCAT1
(A
,B
)
1126 .long CONCAT
(__USER_LABEL_PREFIX__
,__fpscr_values
)+4
1129 mov.l
2f
, r0
! Load the old vbr setting
(if any
).
1132 ! no previous vbr
- jump to own handler
1134 ! there was a previous handler
- chain them
1137 add #
0x7f, r0
! 0x1fc
1138 add #
0x7f, r0
! 0x3f8
1139 add #
0x7f, r0
! 0x5f4
1140 add #
0x03, r0
! 0x600
1142 rotcl r0
! Add 0x600 without corrupting another register
1148 #endif
/* PROFILE code
*/
1151 mov.l
@r4, r4
! r4 is value of expevt hence making
this the return code
1152 mov.l handler_exit_k
,r0
1155 ! We should never return from _exit but
in case we do we would
enter the
1156 ! the following tight
loop
1163 .long __timer_stack
! The
high end of the stack
1165 .long __profil_counter
1168 .long
0xff000024 ! Address of expevt
1171 superh_trap_handler_k:
1172 .long __superh_trap_handler
1176 ! Simulated compile of trap handler.
1177 .
section .debug_abbrev
,"",@progbits
1179 .
section .debug_info
,"",@progbits
1181 .
section .debug_line
,"",@progbits
1186 .
type __superh_trap_handler
,@function
1187 __superh_trap_handler:
1204 .
size __superh_trap_handler
,.Lfe1
-__superh_trap_handler
1205 .
section .debug_frame
,"",@progbits
1207 .ualong .LECIE0
-.LSCIE0
1221 .ualong .LEFDE0
-.LASFDE0
1227 .ualong .LCFI0
-.LFB1
1231 .ualong .LCFI1
-.LCFI0
1237 .ualong .LCFI2
-.LCFI1
1244 .
section .debug_info
1247 .ualong .Ldebug_abbrev0
1250 .ualong .Ldebug_line0
1253 .string
"trap_handler.c"
1254 .string
"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1255 .string
"GNU C 3.2 20020529 (experimental)"
1260 .string
"_superh_trap_handler"
1269 .string
"trap_reason"
1278 .string
"unsigned int"
1282 .
section .debug_abbrev
1352 .
section .debug_pubnames
,"",@progbits
1355 .ualong .Ldebug_info0
1358 .string
"_superh_trap_handler"
1360 .
section .debug_aranges
,"",@progbits
1363 .ualong .Ldebug_info0
1369 .ualong .Letext0
-.Ltext0
1372 #endif
/* VBR_SETUP
*/
1373 #endif
/* ! __SH5__
*/