1 /* Copyright (C) 2000-2013 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 3, or (at your option) any
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
27 /* Section used for exception/timer interrupt stack area */
28 .section .data.vbr.stack,"aw"
32 .zero 1024 * 2 /* ; 2k for VBR handlers */
33 /* Label at the highest stack address where the stack grows from */
35 #endif /* MMU_SUPPORT */
37 /* ;----------------------------------------
38 Normal newlib crt1.S */
49 #define ICCR_BASE 0x01600000
50 #define OCCR_BASE 0x01e00000
51 #define MMUIR_BASE 0x00000000
52 #define MMUDR_BASE 0x00800000
55 #define PTE_DISABLED 0
57 #define PTE_SHARED (1 << 1)
58 #define PTE_NOT_SHARED 0
60 #define PTE_CB_UNCACHEABLE 0
61 #define PTE_CB_DEVICE 1
62 #define PTE_CB_CACHEABLE_WB 2
63 #define PTE_CB_CACHEABLE_WT 3
65 #define PTE_SZ_4KB (0 << 3)
66 #define PTE_SZ_64KB (1 << 3)
67 #define PTE_SZ_1MB (2 << 3)
68 #define PTE_SZ_512MB (3 << 3)
70 #define PTE_PRR (1 << 6)
71 #define PTE_PRX (1 << 7)
72 #define PTE_PRW (1 << 8)
73 #define PTE_PRU (1 << 9)
78 #define ALIGN_4KB (0xfff)
79 #define ALIGN_1MB (0xfffff)
80 #define ALIGN_512MB (0x1fffffff)
82 #define DYNACON_BASE 0x0f000000
83 #define DM_CB_DLINK_BASE 0x0c000000
84 #define DM_DB_DLINK_BASE 0x0b000000
86 #define FEMI_AREA_0 0x00000000
87 #define FEMI_AREA_1 0x04000000
88 #define FEMI_AREA_2 0x05000000
89 #define FEMI_AREA_3 0x06000000
90 #define FEMI_AREA_4 0x07000000
91 #define FEMI_CB 0x08000000
93 #define EMI_BASE 0X80000000
95 #define DMA_BASE 0X0e000000
97 #define CPU_BASE 0X0d000000
99 #define PERIPH_BASE 0X09000000
100 #define DMAC_BASE 0x0e000000
101 #define INTC_BASE 0x0a000000
102 #define CPRC_BASE 0x0a010000
103 #define TMU_BASE 0x0a020000
104 #define SCIF_BASE 0x0a030000
105 #define RTC_BASE 0x0a040000
109 #define LOAD_CONST32(val, reg) \
110 movi ((val) >> 16) & 65535, reg; \
111 shori (val) & 65535, reg
113 #define LOAD_PTEH_VAL(sym, align, bits, scratch_reg, reg) \
114 LOAD_ADDR (sym, reg); \
115 LOAD_CONST32 ((align), scratch_reg); \
116 andc reg, scratch_reg, reg; \
117 LOAD_CONST32 ((bits), scratch_reg); \
118 or reg, scratch_reg, reg
120 #define LOAD_PTEL_VAL(sym, align, bits, scratch_reg, reg) \
121 LOAD_ADDR (sym, reg); \
122 LOAD_CONST32 ((align), scratch_reg); \
123 andc reg, scratch_reg, reg; \
124 LOAD_CONST32 ((bits), scratch_reg); \
125 or reg, scratch_reg, reg
127 #define SET_PTE(pte_addr_reg, pteh_val_reg, ptel_val_reg) \
128 putcfg pte_addr_reg, 0, r63; \
129 putcfg pte_addr_reg, 1, ptel_val_reg; \
130 putcfg pte_addr_reg, 0, pteh_val_reg
134 #define LOAD_ADDR(sym, reg) \
135 movi (sym >> 48) & 65535, reg; \
136 shori (sym >> 32) & 65535, reg; \
137 shori (sym >> 16) & 65535, reg; \
138 shori sym & 65535, reg
141 .section .text..SHmedia32,"ax"
142 #define LOAD_ADDR(sym, reg) \
143 movi (sym >> 16) & 65535, reg; \
144 shori sym & 65535, reg
148 LOAD_ADDR (_stack, r15)
151 ! Set up the VM using the MMU and caches
153 ! .vm_ep is first instruction to execute
154 ! after VM initialization
157 ! Configure instruction cache (ICCR)
160 LOAD_ADDR (ICCR_BASE, r1)
164 ! movi 7, r2 ! write through
165 ! Configure operand cache (OCCR)
166 LOAD_ADDR (OCCR_BASE, r1)
170 ! Disable all PTE translations
171 LOAD_ADDR (MMUIR_BASE, r1)
172 LOAD_ADDR (MMUDR_BASE, r2)
174 pt/l .disable_ptes_loop, tr0
183 LOAD_ADDR (MMUIR_BASE, r1)
185 ! FEMI instruction mappings
186 ! Area 0 - 1Mb cacheable at 0x00000000
188 ! Area 2 - 1Mb cacheable at 0x05000000
189 ! - 1Mb cacheable at 0x05100000
193 ! Map a 1Mb page for instructions at 0x00000000
194 LOAD_PTEH_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
195 LOAD_PTEL_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3)
198 ! Map a 1Mb page for instructions at 0x05000000
200 LOAD_PTEH_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
201 LOAD_PTEL_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3)
204 ! Map a 1Mb page for instructions at 0x05100000
206 LOAD_PTEH_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
207 LOAD_PTEL_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRX | PTE_PRU, r25, r3)
210 ! Map a 512M page for instructions at EMI base
212 LOAD_PTEH_VAL (EMI_BASE, ALIGN_512MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
213 LOAD_PTEL_VAL (EMI_BASE, ALIGN_512MB, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRX | PTE_PRU, r25, r3)
216 ! Map a 4K page for instructions at DM_DB_DLINK_BASE
218 LOAD_PTEH_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
219 LOAD_PTEL_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRX | PTE_PRU, r25, r3)
222 LOAD_ADDR (MMUDR_BASE, r1)
225 ! Area 0 - 1Mb cacheable at 0x00000000
226 ! Area 1 - 1Mb device at 0x04000000
227 ! Area 2 - 1Mb cacheable at 0x05000000
228 ! - 1Mb cacheable at 0x05100000
231 ! CB - 1Mb device at 0x08000000
233 ! Map a 1Mb page for data at 0x00000000
234 LOAD_PTEH_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
235 LOAD_PTEL_VAL (FEMI_AREA_0, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
238 ! Map a 1Mb page for data at 0x04000000
240 LOAD_PTEH_VAL (FEMI_AREA_1, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
241 LOAD_PTEL_VAL (FEMI_AREA_1, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
244 ! Map a 1Mb page for data at 0x05000000
246 LOAD_PTEH_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
247 LOAD_PTEL_VAL (FEMI_AREA_2, ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
250 ! Map a 1Mb page for data at 0x05100000
252 LOAD_PTEH_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
253 LOAD_PTEL_VAL ((FEMI_AREA_2+0x100000), ALIGN_1MB, PTE_CB_CACHEABLE_WB | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
256 ! Map a 4K page for registers at 0x08000000
258 LOAD_PTEH_VAL (FEMI_CB, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
259 LOAD_PTEL_VAL (FEMI_CB, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
262 ! Map a 512M page for data at EMI
264 LOAD_PTEH_VAL (EMI_BASE, ALIGN_512MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
265 LOAD_PTEL_VAL (EMI_BASE, ALIGN_512MB, PTE_CB_CACHEABLE_WB | PTE_SZ_512MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
268 ! Map a 4K page for DYNACON at DYNACON_BASE
270 LOAD_PTEH_VAL (DYNACON_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
271 LOAD_PTEL_VAL (DYNACON_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
274 ! Map a 4K page for instructions at DM_DB_DLINK_BASE
276 LOAD_PTEH_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
277 LOAD_PTEL_VAL (DM_DB_DLINK_BASE, ALIGN_4KB, PTE_CB_CACHEABLE_WB | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
280 ! Map a 4K page for data at DM_DB_DLINK_BASE+0x1000
282 LOAD_PTEH_VAL ((DM_DB_DLINK_BASE+0x1000), ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
283 LOAD_PTEL_VAL ((DM_DB_DLINK_BASE+0x1000), ALIGN_4KB, PTE_CB_UNCACHEABLE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
286 ! Map a 4K page for stack DM_DB_DLINK_BASE+0x2000
288 LOAD_PTEH_VAL ((DM_DB_DLINK_BASE+0x2000), ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
289 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)
292 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
293 ! 0x0c000000 - 0x0c0fffff
295 LOAD_PTEH_VAL (DM_CB_DLINK_BASE, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
296 LOAD_PTEL_VAL (DM_CB_DLINK_BASE, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
299 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
300 ! 0x0c100000 - 0x0c1fffff
302 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
303 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x100000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
306 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
307 ! 0x0c200000 - 0x0c2fffff
309 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x200000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
310 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x200000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
313 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
314 ! 0x0c400000 - 0x0c4fffff
316 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x400000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
317 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x400000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
320 ! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
321 ! 0x0c800000 - 0x0c8fffff
323 LOAD_PTEH_VAL ((DM_CB_DLINK_BASE+0x800000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
324 LOAD_PTEL_VAL ((DM_CB_DLINK_BASE+0x800000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
327 ! Map a 4K page for DMA control registers
329 LOAD_PTEH_VAL (DMA_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
330 LOAD_PTEL_VAL (DMA_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
333 ! Map lots of 4K pages for peripherals
337 LOAD_PTEH_VAL (PERIPH_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
338 LOAD_PTEL_VAL (PERIPH_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
342 LOAD_PTEH_VAL (DMAC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
343 LOAD_PTEL_VAL (DMAC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
347 LOAD_PTEH_VAL (INTC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
348 LOAD_PTEL_VAL (INTC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
352 LOAD_PTEH_VAL (RTC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
353 LOAD_PTEL_VAL (RTC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
357 LOAD_PTEH_VAL (TMU_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
358 LOAD_PTEL_VAL (TMU_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
362 LOAD_PTEH_VAL (SCIF_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
363 LOAD_PTEL_VAL (SCIF_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
367 LOAD_PTEH_VAL (CPRC_BASE, ALIGN_4KB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
368 LOAD_PTEL_VAL (CPRC_BASE, ALIGN_4KB, PTE_CB_DEVICE | PTE_SZ_4KB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
371 ! Map CPU WPC registers
373 LOAD_PTEH_VAL (CPU_BASE, ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
374 LOAD_PTEL_VAL (CPU_BASE, ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
378 LOAD_PTEH_VAL ((CPU_BASE+0x100000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
379 LOAD_PTEL_VAL ((CPU_BASE+0x100000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
383 LOAD_PTEH_VAL ((CPU_BASE+0x200000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
384 LOAD_PTEL_VAL ((CPU_BASE+0x200000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
388 LOAD_PTEH_VAL ((CPU_BASE+0x400000), ALIGN_1MB, PTE_ENABLED | PTE_NOT_SHARED, r25, r2)
389 LOAD_PTEL_VAL ((CPU_BASE+0x400000), ALIGN_1MB, PTE_CB_DEVICE | PTE_SZ_1MB | PTE_PRR | PTE_PRW | PTE_PRU, r25, r3)
392 ! Switch over to virtual addressing and enabled cache
395 shlli r2, SR_BL_BIT, r2
400 shlli r2, SR_MMU_BIT, r2
408 ! VM entry point. From now on, we are in VM mode.
411 ! Install the trap handler, by seeding vbr with the
412 ! correct value, and by assigning sr.bl = 0.
414 LOAD_ADDR (vbr_start, r1)
420 #endif /* MMU_SUPPORT */
422 pt/l .Lzero_bss_loop, tr0
424 pt/l ___setup_argv_and_call_main, tr6
428 LOAD_ADDR (_edata, r0)
435 LOAD_ADDR (___data, r26)
436 LOAD_ADDR (___rodata, r27)
438 #ifdef __SH_FPU_ANY__
440 ! enable the FP unit, by resetting SR.FD
441 ! also zero out SR.FR, SR.SZ and SR.PR, as mandated by the ABI
447 pt/l ___set_fpscr, tr0
453 ! arrange for exit to call fini
455 LOAD_ADDR (_fini, r2)
466 ! We should never return from _exit but in case we do we would enter the
467 ! the following tight loop. This avoids executing any data that might follow.
473 ! All these traps are handled in the same place.
476 pt/l handler, tr0 ! tr0 trashed.
480 pt/l handler, tr0 ! tr0 trashed.
485 pt/l handler, tr0 ! tr0 trashed.
489 pt/l handler, tr0 ! tr0 trashed.
492 vbr_400: ! Should be at vbr+0x400
494 /* If the trap handler is there call it */
495 LOAD_ADDR (__superh_trap_handler, r2)
497 beq r2, r63, tr2 /* If zero, ie not present branch around to chandler */
498 /* Now call the trap handler with as much of the context unchanged as possible.
499 Move trapping address into R18 to make it look like the trap point */
501 pt/l __superh_trap_handler, tr0
509 /* Simulated trap handler */
510 .section .text..SHmedia32,"ax"
512 .section .debug_abbrev
514 .section .text..SHmedia32
520 .section .text..SHmedia32,"ax"
522 .global __superh_trap_handler
523 .type __superh_trap_handler,@function
524 __superh_trap_handler:
540 .size __superh_trap_handler,.Lfe1-__superh_trap_handler
542 .section .text..SHmedia32
548 .ualong .Ldebug_abbrev0
551 .ualong .Ldebug_line0
554 .string "trap_handler.c"
556 .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
558 .string "GNU C 2.97-sh5-010522"
564 .string "_superh_trap_handler"
574 .string "trap_reason"
584 .string "unsigned int"
590 .section .debug_abbrev
657 .section .debug_pubnames
660 .ualong .Ldebug_info0
663 .string "_superh_trap_handler"
667 .section .debug_aranges
670 .ualong .Ldebug_info0
675 .ualong .Letext0-.Ltext0
678 .ident "GCC: (GNU) 2.97-sh5-010522"
679 #endif /* MMU_SUPPORT */
680 #else /* ! __SH5__ */
682 ! make a place to keep any previous value of the vbr register
683 ! this will only have a value if it has been set by redboot (for example)
695 .import ___rtos_profiler_start_timer
696 .weak ___rtos_profiler_start_timer
700 #if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__)
702 ! before zeroing the bss ...
703 ! if the vbr is already set to vbr_start then the program has been restarted
704 ! (i.e. it is not the first time the program has been run since reset)
705 ! reset the vbr to its old value before old_vbr (in bss) is wiped
706 ! this ensures that the later code does not create a circular vbr chain
708 mov.l vbr_start_k, r2
711 ! reset the old vbr value
716 #endif /* VBR_SETUP */
728 #if defined (__SH_FPU_ANY__)
729 mov.l set_fpscr_k, r1
732 shll16 r4 ! Set DN bit (flush denormal inputs to zero)
733 lds r3,fpscr ! Switch to default precision
734 #endif /* defined (__SH_FPU_ANY__) */
737 ! save the existing contents of the vbr
738 ! there will only be a prior value when using something like redboot
739 ! otherwise it will be zero
744 mov.l vbr_start_k, r1
746 #endif /* VBR_SETUP */
748 ! if an rtos is exporting a timer start fn,
749 ! then pick up an SR which does not enable ints
750 ! (the rtos will take care of this)
751 mov.l rtos_start_fn, r0
752 mov.l sr_initial_bare, r1
756 mov.l sr_initial_rtos, r1
759 ! Set status register (sr)
762 ! arrange for exit to call fini
769 ! arrange for exit to call _mcleanup (via stop_profiling)
770 mova stop_profiling,r0
775 ! Call profiler startup code
776 mov.l monstartup_k, r0
782 ! enable profiling trap
783 ! until now any trap 33s will have been ignored
784 ! This means that all library functions called before this point
785 ! (directly or indirectly) may have the profiling trap at the start.
786 ! Therefore, only mcount itself may not have the extra header.
787 mov.l profiling_enabled_k2, r0
811 # stop mcount counting
812 mov.l profiling_enabled_k2, r0
826 profiling_enabled_k2:
827 .long profiling_enabled
835 #if defined (__SH_FPU_ANY__)
838 #endif /* defined (__SH_FPU_ANY__) */
847 .long ___setup_argv_and_call_main
861 #endif /* VBR_SETUP */
864 ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work.
865 ! Whether profiling or not, keep interrupts masked,
866 ! the RTOS will enable these if required.
870 .long ___rtos_profiler_start_timer
874 ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work.
875 ! For bare machine, we need to enable interrupts to get profiling working
880 ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work.
881 ! Keep interrupts disabled - the application will enable as required.
885 ! supplied for backward compatibility only, in case of linking
886 ! code whose main() was compiled with an older version of GCC.
893 .section .text.vbr, "ax"
899 ! Note on register usage.
900 ! we use r0..r3 as scratch in this code. If we are here due to a trapa for profiling
901 ! then this is OK as we are just before executing any function code.
902 ! The other r4..r7 we save explicityl on the stack
903 ! Remaining registers are saved by normal ABI conventions and we assert we do not
904 ! use floating point registers.
912 bra handler_100 ! if not a trapa, go to default handler
917 shlr2 r0 ! trapa code is shifted by 2.
924 ! If here then it looks like we have trap #33
925 ! Now we need to call mcount with the following convention
926 ! Save and restore r4..r7
935 ! r0 is the branch back address.
936 ! The code sequence emitted by gcc for the profiling trap is
940 ! .long lab Where lab is planted by the compiler. This is the address
941 ! of a datum that needs to be incremented.
945 not r2, r2 ! pattern to align to 4
946 and r2, r5 ! r5 now has aligned address
947 ! add #4, r5 ! r5 now has address of address
948 mov r5, r2 ! Remember it.
949 ! mov.l @r5, r5 ! r5 has value of lable (lab in above example)
951 ldc r2, spc ! our return address avoiding address word
953 ! only call mcount if profiling is enabled
954 mov.l profiling_enabled_k, r0
976 .long 0xff000024 ! Address of expevt
982 .long profiling_enabled
984 ! Non profiling case.
986 mov.l 2f, r0 ! load the old vbr setting (if any)
990 ! no previous vbr - jump to own generic handler
993 1: ! there was a previous handler - chain them
996 add #0x2, r0 ! add 0x100 without corrupting another register
1004 vbr_400: ! Should be at vbr+0x400
1005 mov.l 2f, r0 ! load the old vbr setting (if any)
1008 ! no previous vbr - jump to own generic handler
1010 ! there was a previous handler - chain them
1013 add #0x7f, r0 ! 0x1fc
1014 add #0x7f, r0 ! 0x3f8
1015 add #0x02, r0 ! 0x400
1017 rotcl r0 ! Add 0x400 without corrupting another register
1024 /* If the trap handler is there call it */
1025 mov.l superh_trap_handler_k, r0
1026 cmp/eq #0, r0 ! True if zero.
1031 ! Here handler available, call it.
1032 /* Now call the trap handler with as much of the context unchanged as possible.
1033 Move trapping address into PR to make it look like the trap point */
1037 mov.l @r4, r4 ! r4 is value of expevt, first parameter.
1038 mov r1, r5 ! Remember trapping pc.
1039 mov r1, r6 ! Remember trapping pc.
1040 mov.l chandler_k, r1
1041 mov.l superh_trap_handler_k, r2
1042 ! jmp to trap handler to avoid disturbing pr.
1049 ! Should be at vbr+0x600
1050 ! Now we are in the land of interrupts so need to save more state.
1051 ! Save register state
1052 mov.l interrupt_stack_k, r15 ! r15 has been saved to sgr.
1064 #if defined(__SH_FPU_ANY__)
1065 ! Save fpul and fpscr, save fr0-fr7 in 64 bit mode
1066 ! and set the pervading precision for the timer_handler
1070 lds r0,fpscr ! Clear fpscr
1075 mov.l pervading_precision_k,r0
1082 #endif /* __SH_FPU_ANY__ */
1083 ! Pass interrupted pc to timer_handler as first parameter (r4).
1085 mov.l timer_handler_k, r0
1088 #if defined(__SH_FPU_ANY__)
1090 lds r0,fpscr ! Clear the fpscr
1101 #endif /* __SH_FPU_ANY__ */
1113 stc sgr, r15 ! Restore r15, destroyed by this sequence.
1116 #if defined(__SH_FPU_ANY__)
1118 pervading_precision_k:
1119 #define CONCAT1(A,B) A##B
1120 #define CONCAT(A,B) CONCAT1(A,B)
1121 .long CONCAT(__USER_LABEL_PREFIX__,__fpscr_values)+4
1124 mov.l 2f, r0 ! Load the old vbr setting (if any).
1127 ! no previous vbr - jump to own handler
1129 ! there was a previous handler - chain them
1132 add #0x7f, r0 ! 0x1fc
1133 add #0x7f, r0 ! 0x3f8
1134 add #0x7f, r0 ! 0x5f4
1135 add #0x03, r0 ! 0x600
1137 rotcl r0 ! Add 0x600 without corrupting another register
1143 #endif /* PROFILE code */
1146 mov.l @r4, r4 ! r4 is value of expevt hence making this the return code
1147 mov.l handler_exit_k,r0
1150 ! We should never return from _exit but in case we do we would enter the
1151 ! the following tight loop
1158 .long __timer_stack ! The high end of the stack
1160 .long __profil_counter
1163 .long 0xff000024 ! Address of expevt
1166 superh_trap_handler_k:
1167 .long __superh_trap_handler
1171 ! Simulated compile of trap handler.
1172 .section .debug_abbrev,"",@progbits
1174 .section .debug_info,"",@progbits
1176 .section .debug_line,"",@progbits
1181 .type __superh_trap_handler,@function
1182 __superh_trap_handler:
1199 .size __superh_trap_handler,.Lfe1-__superh_trap_handler
1200 .section .debug_frame,"",@progbits
1202 .ualong .LECIE0-.LSCIE0
1216 .ualong .LEFDE0-.LASFDE0
1222 .ualong .LCFI0-.LFB1
1226 .ualong .LCFI1-.LCFI0
1232 .ualong .LCFI2-.LCFI1
1239 .section .debug_info
1242 .ualong .Ldebug_abbrev0
1245 .ualong .Ldebug_line0
1248 .string "trap_handler.c"
1249 .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1250 .string "GNU C 3.2 20020529 (experimental)"
1255 .string "_superh_trap_handler"
1264 .string "trap_reason"
1273 .string "unsigned int"
1277 .section .debug_abbrev
1347 .section .debug_pubnames,"",@progbits
1350 .ualong .Ldebug_info0
1353 .string "_superh_trap_handler"
1355 .section .debug_aranges,"",@progbits
1358 .ualong .Ldebug_info0
1364 .ualong .Letext0-.Ltext0
1367 #endif /* VBR_SETUP */
1368 #endif /* ! __SH5__ */