1 /* Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2009
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 3, or (at your option) any
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.
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.
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/>. */
28 /* Section used for exception/timer interrupt stack area */
29 .section .data.vbr.stack,"aw"
33 .zero 1024 * 2 /* ; 2k for VBR handlers */
34 /* Label at the highest stack address where the stack grows from */
36 #endif /* MMU_SUPPORT */
38 /* ;----------------------------------------
39 Normal newlib crt1.asm */
50 #define ICCR_BASE 0x01600000
51 #define OCCR_BASE 0x01e00000
52 #define MMUIR_BASE 0x00000000
53 #define MMUDR_BASE 0x00800000
56 #define PTE_DISABLED 0
58 #define PTE_SHARED (1 << 1)
59 #define PTE_NOT_SHARED 0
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
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)
71 #define PTE_PRR (1 << 6)
72 #define PTE_PRX (1 << 7)
73 #define PTE_PRW (1 << 8)
74 #define PTE_PRU (1 << 9)
79 #define ALIGN_4KB (0xfff)
80 #define ALIGN_1MB (0xfffff)
81 #define ALIGN_512MB (0x1fffffff)
83 #define DYNACON_BASE 0x0f000000
84 #define DM_CB_DLINK_BASE 0x0c000000
85 #define DM_DB_DLINK_BASE 0x0b000000
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
94 #define EMI_BASE 0X80000000
96 #define DMA_BASE 0X0e000000
98 #define CPU_BASE 0X0d000000
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
110 #define LOAD_CONST32(val, reg) \
111 movi ((val) >> 16) & 65535, reg; \
112 shori (val) & 65535, reg
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
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
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
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
142 .section .text..SHmedia32,"ax"
143 #define LOAD_ADDR(sym, reg) \
144 movi (sym >> 16) & 65535, reg; \
145 shori sym & 65535, reg
149 LOAD_ADDR (_stack, r15)
152 ! Set up the VM using the MMU and caches
154 ! .vm_ep is first instruction to execute
155 ! after VM initialization
158 ! Configure instruction cache (ICCR)
161 LOAD_ADDR (ICCR_BASE, r1)
165 ! movi 7, r2 ! write through
166 ! Configure operand cache (OCCR)
167 LOAD_ADDR (OCCR_BASE, r1)
171 ! Disable all PTE translations
172 LOAD_ADDR (MMUIR_BASE, r1)
173 LOAD_ADDR (MMUDR_BASE, r2)
175 pt/l .disable_ptes_loop, tr0
184 LOAD_ADDR (MMUIR_BASE, r1)
186 ! FEMI instruction mappings
187 ! Area 0 - 1Mb cacheable at 0x00000000
189 ! Area 2 - 1Mb cacheable at 0x05000000
190 ! - 1Mb cacheable at 0x05100000
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)
199 ! Map a 1Mb page for instructions at 0x05000000
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)
205 ! Map a 1Mb page for instructions at 0x05100000
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)
211 ! Map a 512M page for instructions at EMI base
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)
217 ! Map a 4K page for instructions at DM_DB_DLINK_BASE
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)
223 LOAD_ADDR (MMUDR_BASE, r1)
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
232 ! CB - 1Mb device at 0x08000000
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)
239 ! Map a 1Mb page for data at 0x04000000
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)
245 ! Map a 1Mb page for data at 0x05000000
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)
251 ! Map a 1Mb page for data at 0x05100000
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)
257 ! Map a 4K page for registers at 0x08000000
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)
263 ! Map a 512M page for data at EMI
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)
269 ! Map a 4K page for DYNACON at DYNACON_BASE
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)
275 ! Map a 4K page for instructions at DM_DB_DLINK_BASE
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)
281 ! Map a 4K page for data at DM_DB_DLINK_BASE+0x1000
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)
287 ! Map a 4K page for stack DM_DB_DLINK_BASE+0x2000
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)
293 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
294 ! 0x0c000000 - 0x0c0fffff
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)
300 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
301 ! 0x0c100000 - 0x0c1fffff
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)
307 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
308 ! 0x0c200000 - 0x0c2fffff
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)
314 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
315 ! 0x0c400000 - 0x0c4fffff
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)
321 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
322 ! 0x0c800000 - 0x0c8fffff
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)
328 ! Map a 4K page for DMA control registers
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)
334 ! Map lots of 4K pages for peripherals
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)
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)
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)
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)
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)
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)
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)
372 ! Map CPU WPC registers
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)
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)
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)
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)
393 ! Switch over to virtual addressing and enabled cache
396 shlli r2, SR_BL_BIT, r2
401 shlli r2, SR_MMU_BIT, r2
409 ! VM entry point. From now on, we are in VM mode.
412 ! Install the trap handler, by seeding vbr with the
413 ! correct value, and by assigning sr.bl = 0.
415 LOAD_ADDR (vbr_start, r1)
421 #endif /* MMU_SUPPORT */
423 pt/l .Lzero_bss_loop, tr0
425 pt/l ___setup_argv_and_call_main, tr6
429 LOAD_ADDR (_edata, r0)
436 LOAD_ADDR (___data, r26)
437 LOAD_ADDR (___rodata, r27)
439 #ifdef __SH_FPU_ANY__
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
448 pt/l ___set_fpscr, tr0
454 ! arrange for exit to call fini
456 LOAD_ADDR (_fini, r2)
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.
474 ! All these traps are handled in the same place.
477 pt/l handler, tr0 ! tr0 trashed.
481 pt/l handler, tr0 ! tr0 trashed.
486 pt/l handler, tr0 ! tr0 trashed.
490 pt/l handler, tr0 ! tr0 trashed.
493 vbr_400: ! Should be at vbr+0x400
495 /* If the trap handler is there call it */
496 LOAD_ADDR (__superh_trap_handler, r2)
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 */
502 pt/l __superh_trap_handler, tr0
510 /* Simulated trap handler */
511 .section .text..SHmedia32,"ax"
513 .section .debug_abbrev
515 .section .text..SHmedia32
521 .section .text..SHmedia32,"ax"
523 .global __superh_trap_handler
524 .type __superh_trap_handler,@function
525 __superh_trap_handler:
541 .size __superh_trap_handler,.Lfe1-__superh_trap_handler
543 .section .text..SHmedia32
549 .ualong .Ldebug_abbrev0
552 .ualong .Ldebug_line0
555 .string "trap_handler.c"
557 .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
559 .string "GNU C 2.97-sh5-010522"
565 .string "_superh_trap_handler"
575 .string "trap_reason"
585 .string "unsigned int"
591 .section .debug_abbrev
658 .section .debug_pubnames
661 .ualong .Ldebug_info0
664 .string "_superh_trap_handler"
668 .section .debug_aranges
671 .ualong .Ldebug_info0
676 .ualong .Letext0-.Ltext0
679 .ident "GCC: (GNU) 2.97-sh5-010522"
680 #endif /* MMU_SUPPORT */
681 #else /* ! __SH5__ */
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)
696 .import ___rtos_profiler_start_timer
697 .weak ___rtos_profiler_start_timer
701 #if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__)
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
709 mov.l vbr_start_k, r2
712 ! reset the old vbr value
717 #endif /* VBR_SETUP */
729 #if defined (__SH_FPU_ANY__)
730 mov.l set_fpscr_k, 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__) */
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
745 mov.l vbr_start_k, r1
747 #endif /* VBR_SETUP */
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
757 mov.l sr_initial_rtos, r1
760 ! Set status register (sr)
763 ! arrange for exit to call fini
770 ! arrange for exit to call _mcleanup (via stop_profiling)
771 mova stop_profiling,r0
776 ! Call profiler startup code
777 mov.l monstartup_k, r0
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
812 # stop mcount counting
813 mov.l profiling_enabled_k2, r0
827 profiling_enabled_k2:
828 .long profiling_enabled
836 #if defined (__SH_FPU_ANY__)
839 #endif /* defined (__SH_FPU_ANY__) */
848 .long ___setup_argv_and_call_main
862 #endif /* VBR_SETUP */
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.
871 .long ___rtos_profiler_start_timer
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
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.
886 ! supplied for backward compatibility only, in case of linking
887 ! code whose main() was compiled with an older version of GCC.
894 .section .text.vbr, "ax"
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.
913 bra handler_100 ! if not a trapa, go to default handler
918 shlr2 r0 ! trapa code is shifted by 2.
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
936 ! r0 is the branch back address.
937 ! The code sequence emitted by gcc for the profiling trap is
941 ! .long lab Where lab is planted by the compiler. This is the address
942 ! of a datum that needs to be incremented.
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)
952 ldc r2, spc ! our return address avoiding address word
954 ! only call mcount if profiling is enabled
955 mov.l profiling_enabled_k, r0
977 .long 0xff000024 ! Address of expevt
983 .long profiling_enabled
985 ! Non profiling case.
987 mov.l 2f, r0 ! load the old vbr setting (if any)
991 ! no previous vbr - jump to own generic handler
994 1: ! there was a previous handler - chain them
997 add #0x2, r0 ! add 0x100 without corrupting another register
1005 vbr_400: ! Should be at vbr+0x400
1006 mov.l 2f, r0 ! load the old vbr setting (if any)
1009 ! no previous vbr - jump to own generic handler
1011 ! there was a previous handler - chain them
1014 add #0x7f, r0 ! 0x1fc
1015 add #0x7f, r0 ! 0x3f8
1016 add #0x02, r0 ! 0x400
1018 rotcl r0 ! Add 0x400 without corrupting another register
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.
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 */
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.
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.
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
1071 lds r0,fpscr ! Clear fpscr
1076 mov.l pervading_precision_k,r0
1083 #endif /* __SH_FPU_ANY__ */
1084 ! Pass interrupted pc to timer_handler as first parameter (r4).
1086 mov.l timer_handler_k, r0
1089 #if defined(__SH_FPU_ANY__)
1091 lds r0,fpscr ! Clear the fpscr
1102 #endif /* __SH_FPU_ANY__ */
1114 stc sgr, r15 ! Restore r15, destroyed by this sequence.
1117 #if defined(__SH_FPU_ANY__)
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
1125 mov.l 2f, r0 ! Load the old vbr setting (if any).
1128 ! no previous vbr - jump to own handler
1130 ! there was a previous handler - chain them
1133 add #0x7f, r0 ! 0x1fc
1134 add #0x7f, r0 ! 0x3f8
1135 add #0x7f, r0 ! 0x5f4
1136 add #0x03, r0 ! 0x600
1138 rotcl r0 ! Add 0x600 without corrupting another register
1144 #endif /* PROFILE code */
1147 mov.l @r4, r4 ! r4 is value of expevt hence making this the return code
1148 mov.l handler_exit_k,r0
1151 ! We should never return from _exit but in case we do we would enter the
1152 ! the following tight loop
1159 .long __timer_stack ! The high end of the stack
1161 .long __profil_counter
1164 .long 0xff000024 ! Address of expevt
1167 superh_trap_handler_k:
1168 .long __superh_trap_handler
1172 ! Simulated compile of trap handler.
1173 .section .debug_abbrev,"",@progbits
1175 .section .debug_info,"",@progbits
1177 .section .debug_line,"",@progbits
1182 .type __superh_trap_handler,@function
1183 __superh_trap_handler:
1200 .size __superh_trap_handler,.Lfe1-__superh_trap_handler
1201 .section .debug_frame,"",@progbits
1203 .ualong .LECIE0-.LSCIE0
1217 .ualong .LEFDE0-.LASFDE0
1223 .ualong .LCFI0-.LFB1
1227 .ualong .LCFI1-.LCFI0
1233 .ualong .LCFI2-.LCFI1
1240 .section .debug_info
1243 .ualong .Ldebug_abbrev0
1246 .ualong .Ldebug_line0
1249 .string "trap_handler.c"
1250 .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1251 .string "GNU C 3.2 20020529 (experimental)"
1256 .string "_superh_trap_handler"
1265 .string "trap_reason"
1274 .string "unsigned int"
1278 .section .debug_abbrev
1348 .section .debug_pubnames,"",@progbits
1351 .ualong .Ldebug_info0
1354 .string "_superh_trap_handler"
1356 .section .debug_aranges,"",@progbits
1359 .ualong .Ldebug_info0
1365 .ualong .Letext0-.Ltext0
1368 #endif /* VBR_SETUP */
1369 #endif /* ! __SH5__ */