Home | History | Annotate | Line # | Download | only in sh
crt1.S revision 1.1
      1 /* Copyright (C) 2000-2013 Free Software Foundation, Inc.
      2    This file was pretty much copied from newlib.
      3 
      4 This file is part of GCC.
      5 
      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
      9 later version.
     10 
     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.
     15 
     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.
     19 
     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/>.  */
     24 
     25 
     26 #ifdef MMU_SUPPORT
     27 	/* Section used for exception/timer interrupt stack area */
     28 	.section .data.vbr.stack,"aw"
     29 	.align 4
     30 	.global __ST_VBR
     31 __ST_VBR:
     32 	.zero 1024 * 2          /* ; 2k for VBR handlers */
     33 /* Label at the highest stack address where the stack grows from */
     34 __timer_stack:
     35 #endif /* MMU_SUPPORT */
     36 
     37 	/* ;----------------------------------------
     38 	Normal newlib crt1.S */
     39 
     40 #ifdef __SH5__
     41 	.section .data,"aw"
     42 	.global ___data
     43 ___data:
     44 
     45 	.section .rodata,"a"
     46 	.global ___rodata
     47 ___rodata:
     48 
     49 #define ICCR_BASE  0x01600000
     50 #define OCCR_BASE  0x01e00000
     51 #define MMUIR_BASE 0x00000000
     52 #define MMUDR_BASE 0x00800000
     53 
     54 #define PTE_ENABLED     1
     55 #define PTE_DISABLED    0
     56 
     57 #define PTE_SHARED (1 << 1)
     58 #define PTE_NOT_SHARED  0
     59 
     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
     64 
     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)
     69 
     70 #define PTE_PRR      (1 << 6)
     71 #define PTE_PRX      (1 << 7)
     72 #define PTE_PRW      (1 << 8)
     73 #define PTE_PRU      (1 << 9)
     74 
     75 #define SR_MMU_BIT          31
     76 #define SR_BL_BIT           28
     77 
     78 #define ALIGN_4KB  (0xfff)
     79 #define ALIGN_1MB  (0xfffff)
     80 #define ALIGN_512MB (0x1fffffff)
     81 
     82 #define DYNACON_BASE               0x0f000000
     83 #define DM_CB_DLINK_BASE           0x0c000000
     84 #define DM_DB_DLINK_BASE           0x0b000000
     85 
     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
     92 
     93 #define EMI_BASE                   0X80000000
     94 
     95 #define DMA_BASE                   0X0e000000
     96 
     97 #define CPU_BASE                   0X0d000000
     98 
     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
    106 
    107 
    108 
    109 #define LOAD_CONST32(val, reg) \
    110 	movi	((val) >> 16) & 65535, reg; \
    111 	shori	(val) & 65535, reg
    112 
    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
    119 
    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
    126 
    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
    131 
    132 #if __SH5__ == 64
    133 	.section .text,"ax"
    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
    139 #else
    140 	.mode	SHmedia
    141 	.section .text..SHmedia32,"ax"
    142 #define LOAD_ADDR(sym, reg) \
    143 	movi	(sym >> 16) & 65535, reg; \
    144 	shori	sym & 65535, reg
    145 #endif
    146 	.global start
    147 start:
    148 	LOAD_ADDR (_stack, r15)
    149 
    150 #ifdef MMU_SUPPORT
    151 	! Set up the VM using the MMU and caches
    152 
    153 	! .vm_ep is first instruction to execute
    154 	! after VM initialization
    155 	pt/l	.vm_ep, tr1
    156 
    157 	! Configure instruction cache (ICCR)
    158 	movi	3, r2
    159 	movi	0, r3
    160 	LOAD_ADDR (ICCR_BASE, r1)
    161 	putcfg	r1, 0, r2
    162 	putcfg	r1, 1, r3
    163 
    164 	! movi	7, r2 ! write through
    165 	! Configure operand cache (OCCR)
    166 	LOAD_ADDR (OCCR_BASE, r1)
    167 	putcfg	r1, 0, r2
    168 	putcfg	r1, 1, r3
    169 
    170 	! Disable all PTE translations
    171 	LOAD_ADDR (MMUIR_BASE, r1)
    172 	LOAD_ADDR (MMUDR_BASE, r2)
    173 	movi	64, r3
    174 	pt/l	.disable_ptes_loop, tr0
    175 .disable_ptes_loop:
    176 	putcfg	r1, 0, r63
    177 	putcfg	r2, 0, r63
    178 	addi	r1, 16, r1
    179 	addi	r2, 16, r2
    180 	addi	r3, -1, r3
    181 	bgt	r3, r63, tr0
    182 
    183 	LOAD_ADDR (MMUIR_BASE, r1)
    184 
    185 	! FEMI instruction mappings
    186 	!   Area 0 - 1Mb cacheable at 0x00000000
    187 	!   Area 1 - None
    188 	!   Area 2 - 1Mb cacheable at 0x05000000
    189 	!          - 1Mb cacheable at 0x05100000
    190 	!   Area 3 - None
    191 	!   Area 4 - None
    192 
    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)
    196 	SET_PTE (r1, r2, r3)
    197 
    198 	! Map a 1Mb page for instructions at 0x05000000
    199 	addi	r1, 16, r1
    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)
    202 	SET_PTE (r1, r2, r3)
    203 
    204 	! Map a 1Mb page for instructions at 0x05100000
    205 	addi	r1, 16, r1
    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)
    208 	SET_PTE (r1, r2, r3)
    209 
    210 	! Map a 512M page for instructions at EMI base
    211 	addi	r1, 16, r1
    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)
    214 	SET_PTE (r1, r2, r3)
    215 
    216 	! Map a 4K page for instructions at DM_DB_DLINK_BASE
    217 	addi	r1, 16, r1
    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)
    220 	SET_PTE (r1, r2, r3)
    221 
    222 	LOAD_ADDR (MMUDR_BASE, r1)
    223 
    224 	! FEMI data mappings
    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
    229 	!   Area 3 - None
    230 	!   Area 4 - None
    231 	!   CB     - 1Mb device at 0x08000000
    232 
    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)
    236 	SET_PTE (r1, r2, r3)
    237 
    238 	! Map a 1Mb page for data at 0x04000000
    239 	addi	r1, 16, r1
    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)
    242 	SET_PTE (r1, r2, r3)
    243 
    244 	! Map a 1Mb page for data at 0x05000000
    245 	addi	r1, 16, r1
    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)
    248 	SET_PTE (r1, r2, r3)
    249 
    250 	! Map a 1Mb page for data at 0x05100000
    251 	addi	r1, 16, r1
    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)
    254 	SET_PTE (r1, r2, r3)
    255 
    256 	! Map a 4K page for registers at 0x08000000
    257 	addi	r1, 16, r1
    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)
    260 	SET_PTE (r1, r2, r3)
    261 
    262 	! Map a 512M page for data at EMI
    263 	addi	r1, 16, r1
    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)
    266 	SET_PTE (r1, r2, r3)
    267 
    268 	! Map a 4K page for DYNACON at DYNACON_BASE
    269 	addi	r1, 16, r1
    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)
    272 	SET_PTE (r1, r2, r3)
    273 
    274 	! Map a 4K page for instructions at DM_DB_DLINK_BASE
    275 	addi	r1, 16, r1
    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)
    278 	SET_PTE (r1, r2, r3)
    279 
    280 	! Map a 4K page for data at DM_DB_DLINK_BASE+0x1000
    281 	addi	r1, 16, r1
    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)
    284 	SET_PTE (r1, r2, r3)
    285 
    286 	! Map a 4K page for stack DM_DB_DLINK_BASE+0x2000
    287 	addi	r1, 16, r1
    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)
    290 	SET_PTE (r1, r2, r3)
    291 
    292 	! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
    293 	! 0x0c000000 - 0x0c0fffff
    294 	addi	r1, 16, r1
    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)
    297 	SET_PTE (r1, r2, r3)
    298 
    299 	! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
    300 	! 0x0c100000 - 0x0c1fffff
    301 	addi	r1, 16, r1
    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)
    304 	SET_PTE (r1, r2, r3)
    305 
    306 	! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
    307 	! 0x0c200000 - 0x0c2fffff
    308 	addi	r1, 16, r1
    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)
    311 	SET_PTE (r1, r2, r3)
    312 
    313 	! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
    314 	! 0x0c400000 - 0x0c4fffff
    315 	addi	r1, 16, r1
    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)
    318 	SET_PTE (r1, r2, r3)
    319 
    320 	! Map a 1M page for DM_CB_BASE2 at DM_CB_DLINK
    321 	! 0x0c800000 - 0x0c8fffff
    322 	addi	r1, 16, r1
    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)
    325 	SET_PTE (r1, r2, r3)
    326 
    327 	! Map a 4K page for DMA control registers
    328 	addi	r1, 16, r1
    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)
    331 	SET_PTE (r1, r2, r3)
    332 
    333 	! Map lots of 4K pages for peripherals
    334 
    335 	! /* peripheral */
    336 	addi	r1, 16, r1
    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)
    339 	SET_PTE (r1, r2, r3)
    340 	! /* dmac */
    341 	addi	r1, 16, r1
    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)
    344 	SET_PTE (r1, r2, r3)
    345 	! /* intc */
    346 	addi	r1, 16, r1
    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)
    349 	SET_PTE (r1, r2, r3)
    350 	! /* rtc */
    351 	addi	r1, 16, r1
    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)
    354 	SET_PTE (r1, r2, r3)
    355 	! /* dmac */
    356 	addi	r1, 16, r1
    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)
    359 	SET_PTE (r1, r2, r3)
    360 	! /* scif */
    361 	addi	r1, 16, r1
    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)
    364 	SET_PTE (r1, r2, r3)
    365 	! /* cprc */
    366 	addi	r1, 16, r1
    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)
    369 	SET_PTE (r1, r2, r3)
    370 
    371 	! Map CPU WPC registers
    372 	addi	r1, 16, r1
    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)
    375 	SET_PTE (r1, r2, r3)
    376 	addi	r1, 16, r1
    377 
    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)
    380 	SET_PTE (r1, r2, r3)
    381 
    382 	addi	r1, 16, r1
    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)
    385 	SET_PTE (r1, r2, r3)
    386 
    387 	addi	r1, 16, r1
    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)
    390 	SET_PTE (r1, r2, r3)
    391 
    392 	! Switch over to virtual addressing and enabled cache
    393 	getcon	sr, r1
    394 	movi	1, r2
    395 	shlli	r2, SR_BL_BIT, r2
    396 	or	r1, r2, r1
    397 	putcon	r1, ssr
    398 	getcon	sr, r1
    399 	movi	1, r2
    400 	shlli	r2, SR_MMU_BIT, r2
    401 	or	r1, r2, r1
    402 	putcon	r1, ssr
    403 	gettr	tr1, r1
    404 	putcon	r1, spc
    405 	synco
    406 	rte
    407 
    408 	! VM entry point.  From now on, we are in VM mode.
    409 .vm_ep:
    410 
    411 	! Install the trap handler, by seeding vbr with the
    412 	! correct value, and by assigning sr.bl = 0.
    413 
    414 	LOAD_ADDR (vbr_start, r1)
    415 	putcon	r1, vbr
    416 	movi	~(1<<28), r1
    417 	getcon	sr, r2
    418 	and     r1, r2, r2
    419 	putcon	r2, sr
    420 #endif /* MMU_SUPPORT */
    421 
    422 	pt/l	.Lzero_bss_loop, tr0
    423 	pt/l	_init, tr5
    424 	pt/l	___setup_argv_and_call_main, tr6
    425 	pt/l	_exit, tr7
    426 
    427 	! zero out bss
    428 	LOAD_ADDR (_edata, r0)
    429 	LOAD_ADDR (_end, r1)
    430 .Lzero_bss_loop:
    431 	stx.q	r0, r63, r63
    432 	addi	r0, 8, r0
    433 	bgt/l	r1, r0, tr0
    434 
    435 	LOAD_ADDR (___data, r26)
    436 	LOAD_ADDR (___rodata, r27)
    437 
    438 #ifdef __SH_FPU_ANY__
    439 	getcon	sr, r0
    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
    442 	movi	0, r1
    443 	shori	0xf000, r1
    444 	andc	r0, r1, r0
    445 	putcon	r0, sr
    446 #if __SH5__ == 32
    447 	pt/l ___set_fpscr, tr0
    448 	movi	0, r4
    449 	blink	tr0, r18
    450 #endif
    451 #endif
    452 
    453 	! arrange for exit to call fini
    454 	pt/l	_atexit, tr1
    455 	LOAD_ADDR (_fini, r2)
    456 	blink	tr1, r18
    457 
    458 	! call init
    459 	blink	tr5, r18
    460 
    461 	! call the mainline
    462 	blink	tr6, r18
    463 
    464 	! call exit
    465 	blink	tr7, r18
    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.
    468 limbo:
    469 	pt/l limbo, tr0
    470 	blink tr0, r63
    471 
    472 #ifdef MMU_SUPPORT
    473 	! All these traps are handled in the same place.
    474 	.balign 256
    475 vbr_start:
    476 	pt/l handler, tr0	! tr0 trashed.
    477 	blink tr0, r63
    478 	.balign 256
    479 vbr_100:
    480 	pt/l handler, tr0	! tr0 trashed.
    481 	blink tr0, r63
    482 vbr_100_end:
    483 	.balign 256
    484 vbr_200:
    485 	pt/l handler, tr0	! tr0 trashed.
    486 	blink tr0, r63
    487 	.balign 256
    488 vbr_300:
    489 	pt/l handler, tr0	! tr0 trashed.
    490 	blink tr0, r63
    491 	.balign 256
    492 vbr_400:	! Should be at vbr+0x400
    493 handler:
    494 	/* If the trap handler is there call it */
    495 	LOAD_ADDR (__superh_trap_handler, r2)
    496 	pta chandler,tr2
    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 */
    500 	getcon spc, r18
    501 	pt/l __superh_trap_handler, tr0
    502 	blink tr0, r7
    503 chandler:
    504 	getcon	spc, r62
    505 	getcon expevt, r2
    506 	pt/l	_exit, tr0
    507 	blink	tr0, r63
    508 
    509 	/* Simulated trap handler */
    510 	.section	.text..SHmedia32,"ax"
    511 gcc2_compiled.:
    512 	.section	.debug_abbrev
    513 .Ldebug_abbrev0:
    514 	.section	.text..SHmedia32
    515 .Ltext0:
    516 	.section	.debug_info
    517 .Ldebug_info0:
    518 	.section	.debug_line
    519 .Ldebug_line0:
    520 	.section	.text..SHmedia32,"ax"
    521 	.align 5
    522 	.global	__superh_trap_handler
    523 	.type	__superh_trap_handler,@function
    524 __superh_trap_handler:
    525 .LFB1:
    526 	ptabs	r18, tr0
    527 	addi.l	r15, -8, r15
    528 	st.l	r15, 4, r14
    529 	addi.l	r15, -8, r15
    530 	add.l	r15, r63, r14
    531 	st.l	r14, 0, r2
    532 	 ptabs r7, tr0
    533 	addi.l	r14, 8, r14
    534 	add.l	r14, r63, r15
    535 	ld.l	r15, 4, r14
    536 	addi.l	r15, 8, r15
    537 	blink	tr0, r63
    538 .LFE1:
    539 .Lfe1:
    540 	.size	__superh_trap_handler,.Lfe1-__superh_trap_handler
    541 
    542 	.section	.text..SHmedia32
    543 .Letext0:
    544 
    545 	.section	.debug_info
    546 	.ualong	0xa7
    547 	.uaword	0x2
    548 	.ualong	.Ldebug_abbrev0
    549 	.byte	0x4
    550 	.byte	0x1
    551 	.ualong	.Ldebug_line0
    552 	.ualong	.Letext0
    553 	.ualong	.Ltext0
    554 	.string	"trap_handler.c"
    555 
    556 	.string	"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    557 
    558 	.string	"GNU C 2.97-sh5-010522"
    559 
    560 	.byte	0x1
    561 	.byte	0x2
    562 	.ualong	0x9a
    563 	.byte	0x1
    564 	.string	"_superh_trap_handler"
    565 
    566 	.byte	0x1
    567 	.byte	0x2
    568 	.byte	0x1
    569 	.ualong	.LFB1
    570 	.ualong	.LFE1
    571 	.byte	0x1
    572 	.byte	0x5e
    573 	.byte	0x3
    574 	.string	"trap_reason"
    575 
    576 	.byte	0x1
    577 	.byte	0x1
    578 	.ualong	0x9a
    579 	.byte	0x2
    580 	.byte	0x91
    581 	.byte	0x0
    582 	.byte	0x0
    583 	.byte	0x4
    584 	.string	"unsigned int"
    585 
    586 	.byte	0x4
    587 	.byte	0x7
    588 	.byte	0x0
    589 
    590 	.section	.debug_abbrev
    591 	.byte	0x1
    592 	.byte	0x11
    593 	.byte	0x1
    594 	.byte	0x10
    595 	.byte	0x6
    596 	.byte	0x12
    597 	.byte	0x1
    598 	.byte	0x11
    599 	.byte	0x1
    600 	.byte	0x3
    601 	.byte	0x8
    602 	.byte	0x1b
    603 	.byte	0x8
    604 	.byte	0x25
    605 	.byte	0x8
    606 	.byte	0x13
    607 	.byte	0xb
    608 	.byte	0,0
    609 	.byte	0x2
    610 	.byte	0x2e
    611 	.byte	0x1
    612 	.byte	0x1
    613 	.byte	0x13
    614 	.byte	0x3f
    615 	.byte	0xc
    616 	.byte	0x3
    617 	.byte	0x8
    618 	.byte	0x3a
    619 	.byte	0xb
    620 	.byte	0x3b
    621 	.byte	0xb
    622 	.byte	0x27
    623 	.byte	0xc
    624 	.byte	0x11
    625 	.byte	0x1
    626 	.byte	0x12
    627 	.byte	0x1
    628 	.byte	0x40
    629 	.byte	0xa
    630 	.byte	0,0
    631 	.byte	0x3
    632 	.byte	0x5
    633 	.byte	0x0
    634 	.byte	0x3
    635 	.byte	0x8
    636 	.byte	0x3a
    637 	.byte	0xb
    638 	.byte	0x3b
    639 	.byte	0xb
    640 	.byte	0x49
    641 	.byte	0x13
    642 	.byte	0x2
    643 	.byte	0xa
    644 	.byte	0,0
    645 	.byte	0x4
    646 	.byte	0x24
    647 	.byte	0x0
    648 	.byte	0x3
    649 	.byte	0x8
    650 	.byte	0xb
    651 	.byte	0xb
    652 	.byte	0x3e
    653 	.byte	0xb
    654 	.byte	0,0
    655 	.byte	0
    656 
    657 	.section	.debug_pubnames
    658 	.ualong	0x27
    659 	.uaword	0x2
    660 	.ualong	.Ldebug_info0
    661 	.ualong	0xab
    662 	.ualong	0x5b
    663 	.string	"_superh_trap_handler"
    664 
    665 	.ualong	0x0
    666 
    667 	.section	.debug_aranges
    668 	.ualong	0x1c
    669 	.uaword	0x2
    670 	.ualong	.Ldebug_info0
    671 	.byte	0x4
    672 	.byte	0x0
    673 	.uaword	0x0,0
    674 	.ualong	.Ltext0
    675 	.ualong	.Letext0-.Ltext0
    676 	.ualong	0x0
    677 	.ualong	0x0
    678 	.ident	"GCC: (GNU) 2.97-sh5-010522"
    679 #endif /* MMU_SUPPORT */
    680 #else /* ! __SH5__ */
    681 
    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)
    684 	.section .bss
    685 old_vbr:
    686 	.long 0
    687 #ifdef PROFILE
    688 profiling_enabled:
    689 	.long 0
    690 #endif
    691 
    692 
    693 	.section .text
    694 	.global	start
    695 	.import ___rtos_profiler_start_timer
    696 	.weak   ___rtos_profiler_start_timer
    697 start:
    698 	mov.l	stack_k,r15
    699 
    700 #if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__)
    701 #define VBR_SETUP
    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
    707 	stc	vbr, r1
    708 	mov.l	vbr_start_k, r2
    709 	cmp/eq	r1, r2
    710 	bf	0f
    711 	! reset the old vbr value
    712 	mov.l	old_vbr_k, r1
    713 	mov.l	@r1, r2
    714 	ldc	r2, vbr
    715 0:
    716 #endif /* VBR_SETUP */
    717 
    718 	! zero out bss
    719 	mov.l	edata_k,r0
    720 	mov.l	end_k,r1
    721 	mov	#0,r2
    722 start_l:
    723 	mov.l	r2,@r0
    724 	add	#4,r0
    725 	cmp/ge	r0,r1
    726 	bt	start_l
    727 
    728 #if defined (__SH_FPU_ANY__)
    729 	mov.l set_fpscr_k, r1
    730 	mov #4,r4
    731 	jsr @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__) */
    735 
    736 #ifdef VBR_SETUP
    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
    740 	stc	vbr, r1
    741 	mov.l	old_vbr_k, r2
    742 	mov.l	r1, @r2
    743 	! setup vbr
    744 	mov.l	vbr_start_k, r1
    745 	ldc	r1,vbr
    746 #endif /* VBR_SETUP */
    747 
    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
    753 	tst	r0, r0
    754 	bt	set_sr
    755 
    756 	mov.l sr_initial_rtos, r1
    757 
    758 set_sr:
    759 	! Set status register (sr)
    760 	ldc	r1, sr
    761 
    762 	! arrange for exit to call fini
    763 	mov.l	atexit_k,r0
    764 	mov.l	fini_k,r4
    765 	jsr	@r0
    766 	nop
    767 
    768 #ifdef PROFILE
    769 	! arrange for exit to call _mcleanup (via stop_profiling)
    770 	mova    stop_profiling,r0
    771 	mov.l   atexit_k,r1
    772 	jsr     @r1
    773 	mov	r0, r4
    774 
    775 	! Call profiler startup code
    776 	mov.l monstartup_k, r0
    777 	mov.l start_k, r4
    778 	mov.l etext_k, r5
    779 	jsr @r0
    780 	nop
    781 
    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
    788 	mov	#1, r1
    789 	mov.l	r1, @r0
    790 #endif /* PROFILE */
    791 
    792 	! call init
    793 	mov.l	init_k,r0
    794 	jsr	@r0
    795 	nop
    796 
    797 	! call the mainline
    798 	mov.l	main_k,r0
    799 	jsr	@r0
    800 	nop
    801 
    802 	! call exit
    803 	mov	r0,r4
    804 	mov.l	exit_k,r0
    805 	jsr	@r0
    806 	nop
    807 
    808 		.balign 4
    809 #ifdef PROFILE
    810 stop_profiling:
    811 	# stop mcount counting
    812 	mov.l	profiling_enabled_k2, r0
    813 	mov	#0, r1
    814 	mov.l	r1, @r0
    815 
    816 	# call mcleanup
    817 	mov.l	mcleanup_k, r0
    818 	jmp	@r0
    819 	nop
    820 
    821 		.balign 4
    822 mcleanup_k:
    823 	.long __mcleanup
    824 monstartup_k:
    825 	.long ___monstartup
    826 profiling_enabled_k2:
    827 	.long profiling_enabled
    828 start_k:
    829 	.long _start
    830 etext_k:
    831 	.long __etext
    832 #endif /* PROFILE */
    833 
    834 	.align 2
    835 #if defined (__SH_FPU_ANY__)
    836 set_fpscr_k:
    837 	.long	___set_fpscr
    838 #endif /*  defined (__SH_FPU_ANY__) */
    839 
    840 stack_k:
    841 	.long	_stack
    842 edata_k:
    843 	.long	_edata
    844 end_k:
    845 	.long	_end
    846 main_k:
    847 	.long	___setup_argv_and_call_main
    848 exit_k:
    849 	.long	_exit
    850 atexit_k:
    851 	.long	_atexit
    852 init_k:
    853 	.long	_init
    854 fini_k:
    855 	.long	_fini
    856 #ifdef VBR_SETUP
    857 old_vbr_k:
    858 	.long	old_vbr
    859 vbr_start_k:
    860 	.long	vbr_start
    861 #endif /* VBR_SETUP */
    862 
    863 sr_initial_rtos:
    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.
    867 	.long 0x600000f1
    868 
    869 rtos_start_fn:
    870 	.long ___rtos_profiler_start_timer
    871 
    872 #ifdef PROFILE
    873 sr_initial_bare:
    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
    876 	.long 0x60000001
    877 #else
    878 
    879 sr_initial_bare:
    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.
    882 	.long 0x600000f1
    883 #endif
    884 
    885 	! supplied for backward compatibility only, in case of linking
    886 	! code whose main() was compiled with an older version of GCC.
    887 	.global ___main
    888 ___main:
    889 	rts
    890 	nop
    891 #ifdef VBR_SETUP
    892 ! Exception handlers
    893 	.section .text.vbr, "ax"
    894 vbr_start:
    895 
    896 	.org 0x100
    897 vbr_100:
    898 #ifdef PROFILE
    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.
    905 	mov.l expevt_k1, r1
    906 	mov.l @r1, r1
    907 	mov.l event_mask, r0
    908 	and r0,r1
    909 	mov.l trapcode_k, r2
    910 	cmp/eq r1,r2
    911 	bt 1f
    912 	bra handler_100   ! if not a trapa, go to default handler
    913 	nop
    914 1:
    915 	mov.l trapa_k, r0
    916 	mov.l @r0, r0
    917 	shlr2 r0      ! trapa code is shifted by 2.
    918 	cmp/eq #33, r0
    919 	bt 2f
    920 	bra handler_100
    921 	nop
    922 2:
    923 
    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
    927 	mov.l	r4,@-r15
    928 	mov.l	r5,@-r15
    929 	mov.l	r6,@-r15
    930 	mov.l	r7,@-r15
    931 	sts.l	pr,@-r15
    932 
    933 	! r4 is frompc.
    934 	! r5 is selfpc
    935 	! r0 is the branch back address.
    936 	! The code sequence emitted by gcc for the profiling trap is
    937 	! .align 2
    938 	! trapa #33
    939 	! .align 2
    940 	! .long lab Where lab is planted by the compiler. This is the address
    941 	! of a datum that needs to be incremented.
    942 	sts pr,  r4     ! frompc
    943 	stc spc, r5	! selfpc
    944 	mov #2, r2
    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)
    950 	add #8, r2
    951 	ldc r2, spc     ! our return address avoiding address word
    952 
    953 	! only call mcount if profiling is enabled
    954 	mov.l profiling_enabled_k, r0
    955 	mov.l @r0, r0
    956 	cmp/eq #0, r0
    957 	bt 3f
    958 	! call mcount
    959 	mov.l mcount_k, r2
    960 	jsr @r2
    961 	nop
    962 3:
    963 	lds.l @r15+,pr
    964 	mov.l @r15+,r7
    965 	mov.l @r15+,r6
    966 	mov.l @r15+,r5
    967 	mov.l @r15+,r4
    968 	rte
    969 	nop
    970 	.balign 4
    971 event_mask:
    972 	.long 0xfff
    973 trapcode_k:
    974 	.long 0x160
    975 expevt_k1:
    976 	.long 0xff000024 ! Address of expevt
    977 trapa_k:
    978 	.long 0xff000020
    979 mcount_k:
    980 	.long __call_mcount
    981 profiling_enabled_k:
    982 	.long profiling_enabled
    983 #endif
    984 	! Non profiling case.
    985 handler_100:
    986 	mov.l 2f, r0     ! load the old vbr setting (if any)
    987 	mov.l @r0, r0
    988 	cmp/eq #0, r0
    989 	bf 1f
    990 	! no previous vbr - jump to own generic handler
    991 	bra handler
    992 	nop
    993 1:	! there was a previous handler - chain them
    994 	add #0x7f, r0	 ! 0x7f
    995 	add #0x7f, r0	 ! 0xfe
    996 	add #0x2, r0     ! add 0x100 without corrupting another register
    997 	jmp @r0
    998 	nop
    999 	.balign 4
   1000 2:
   1001 	.long old_vbr
   1002 
   1003 	.org 0x400
   1004 vbr_400:	! Should be at vbr+0x400
   1005 	mov.l 2f, r0     ! load the old vbr setting (if any)
   1006 	mov.l @r0, r0
   1007 	cmp/eq #0, r0
   1008 	! no previous vbr - jump to own generic handler
   1009 	bt handler
   1010 	! there was a previous handler - chain them
   1011 	rotcr r0
   1012 	rotcr r0
   1013 	add #0x7f, r0	 ! 0x1fc
   1014 	add #0x7f, r0	 ! 0x3f8
   1015 	add #0x02, r0	 ! 0x400
   1016 	rotcl r0
   1017 	rotcl r0	 ! Add 0x400 without corrupting another register
   1018 	jmp @r0
   1019 	nop
   1020 	.balign 4
   1021 2:
   1022 	.long old_vbr
   1023 handler:
   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.
   1027 	bf 3f
   1028 	bra   chandler
   1029 	nop
   1030 3:
   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 */
   1034 	stc spc, r1
   1035 	lds r1, pr
   1036 	mov.l expevt_k, r4
   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.
   1043 	jmp @r2
   1044 	nop
   1045 
   1046 	.org 0x600
   1047 vbr_600:
   1048 #ifdef PROFILE
   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.
   1053 	mov.l	r0,@-r15
   1054 	mov.l	r1,@-r15
   1055 	mov.l	r2,@-r15
   1056 	mov.l	r3,@-r15
   1057 	mov.l	r4,@-r15
   1058 	mov.l	r5,@-r15
   1059 	mov.l	r6,@-r15
   1060 	mov.l	r7,@-r15
   1061 	sts.l	pr,@-r15
   1062 	sts.l	mach,@-r15
   1063 	sts.l	macl,@-r15
   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
   1067 	mov	#0,r0
   1068 	sts.l	fpul,@-r15
   1069 	sts.l	fpscr,@-r15
   1070 	lds	r0,fpscr	! Clear fpscr
   1071 	fmov	fr0,@-r15
   1072 	fmov	fr1,@-r15
   1073 	fmov	fr2,@-r15
   1074 	fmov	fr3,@-r15
   1075 	mov.l	pervading_precision_k,r0
   1076 	fmov	fr4,@-r15
   1077 	fmov	fr5,@-r15
   1078 	mov.l	@r0,r0
   1079 	fmov	fr6,@-r15
   1080 	fmov	fr7,@-r15
   1081 	lds	r0,fpscr
   1082 #endif /* __SH_FPU_ANY__ */
   1083 	! Pass interrupted pc to timer_handler as first parameter (r4).
   1084 	stc    spc, r4
   1085 	mov.l timer_handler_k, r0
   1086 	jsr @r0
   1087 	nop
   1088 #if defined(__SH_FPU_ANY__)
   1089 	mov	#0,r0
   1090 	lds	r0,fpscr	! Clear the fpscr
   1091 	fmov	@r15+,fr7
   1092 	fmov	@r15+,fr6
   1093 	fmov	@r15+,fr5
   1094 	fmov	@r15+,fr4
   1095 	fmov	@r15+,fr3
   1096 	fmov	@r15+,fr2
   1097 	fmov	@r15+,fr1
   1098 	fmov	@r15+,fr0
   1099 	lds.l	@r15+,fpscr
   1100 	lds.l	@r15+,fpul
   1101 #endif /* __SH_FPU_ANY__ */
   1102 	lds.l @r15+,macl
   1103 	lds.l @r15+,mach
   1104 	lds.l @r15+,pr
   1105 	mov.l @r15+,r7
   1106 	mov.l @r15+,r6
   1107 	mov.l @r15+,r5
   1108 	mov.l @r15+,r4
   1109 	mov.l @r15+,r3
   1110 	mov.l @r15+,r2
   1111 	mov.l @r15+,r1
   1112 	mov.l @r15+,r0
   1113 	stc sgr, r15    ! Restore r15, destroyed by this sequence.
   1114 	rte
   1115 	nop
   1116 #if defined(__SH_FPU_ANY__)
   1117 	.balign 4
   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
   1122 #endif
   1123 #else
   1124 	mov.l 2f, r0     ! Load the old vbr setting (if any).
   1125 	mov.l @r0, r0
   1126 	cmp/eq #0, r0
   1127 	! no previous vbr - jump to own handler
   1128 	bt chandler
   1129 	! there was a previous handler - chain them
   1130 	rotcr r0
   1131 	rotcr r0
   1132 	add #0x7f, r0	 ! 0x1fc
   1133 	add #0x7f, r0	 ! 0x3f8
   1134 	add #0x7f, r0	 ! 0x5f4
   1135 	add #0x03, r0	 ! 0x600
   1136 	rotcl r0
   1137 	rotcl r0	 ! Add 0x600 without corrupting another register
   1138 	jmp @r0
   1139 	nop
   1140 	.balign 4
   1141 2:
   1142 	.long old_vbr
   1143 #endif	 /* PROFILE code */
   1144 chandler:
   1145 	mov.l expevt_k, r4
   1146 	mov.l @r4, r4 ! r4 is value of expevt hence making this the return code
   1147 	mov.l handler_exit_k,r0
   1148 	jsr   @r0
   1149 	nop
   1150 	! We should never return from _exit but in case we do we would enter the
   1151 	! the following tight loop
   1152 limbo:
   1153 	bra limbo
   1154 	nop
   1155 	.balign 4
   1156 #ifdef PROFILE
   1157 interrupt_stack_k:
   1158 	.long __timer_stack	! The high end of the stack
   1159 timer_handler_k:
   1160 	.long __profil_counter
   1161 #endif
   1162 expevt_k:
   1163 	.long 0xff000024 ! Address of expevt
   1164 chandler_k:
   1165 	.long chandler
   1166 superh_trap_handler_k:
   1167 	.long	__superh_trap_handler
   1168 handler_exit_k:
   1169 	.long _exit
   1170 	.align 2
   1171 ! Simulated compile of trap handler.
   1172 	.section	.debug_abbrev,"",@progbits
   1173 .Ldebug_abbrev0:
   1174 	.section	.debug_info,"",@progbits
   1175 .Ldebug_info0:
   1176 	.section	.debug_line,"",@progbits
   1177 .Ldebug_line0:
   1178 	.text
   1179 .Ltext0:
   1180 	.align 5
   1181 	.type	__superh_trap_handler,@function
   1182 __superh_trap_handler:
   1183 .LFB1:
   1184 	mov.l	r14,@-r15
   1185 .LCFI0:
   1186 	add	#-4,r15
   1187 .LCFI1:
   1188 	mov	r15,r14
   1189 .LCFI2:
   1190 	mov.l	r4,@r14
   1191 	lds	r1, pr
   1192 	add	#4,r14
   1193 	mov	r14,r15
   1194 	mov.l	@r15+,r14
   1195 	rts
   1196 	nop
   1197 .LFE1:
   1198 .Lfe1:
   1199 	.size	__superh_trap_handler,.Lfe1-__superh_trap_handler
   1200 	.section	.debug_frame,"",@progbits
   1201 .Lframe0:
   1202 	.ualong	.LECIE0-.LSCIE0
   1203 .LSCIE0:
   1204 	.ualong	0xffffffff
   1205 	.byte	0x1
   1206 	.string	""
   1207 	.uleb128 0x1
   1208 	.sleb128 -4
   1209 	.byte	0x11
   1210 	.byte	0xc
   1211 	.uleb128 0xf
   1212 	.uleb128 0x0
   1213 	.align 2
   1214 .LECIE0:
   1215 .LSFDE0:
   1216 	.ualong	.LEFDE0-.LASFDE0
   1217 .LASFDE0:
   1218 	.ualong	.Lframe0
   1219 	.ualong	.LFB1
   1220 	.ualong	.LFE1-.LFB1
   1221 	.byte	0x4
   1222 	.ualong	.LCFI0-.LFB1
   1223 	.byte	0xe
   1224 	.uleb128 0x4
   1225 	.byte	0x4
   1226 	.ualong	.LCFI1-.LCFI0
   1227 	.byte	0xe
   1228 	.uleb128 0x8
   1229 	.byte	0x8e
   1230 	.uleb128 0x1
   1231 	.byte	0x4
   1232 	.ualong	.LCFI2-.LCFI1
   1233 	.byte	0xd
   1234 	.uleb128 0xe
   1235 	.align 2
   1236 .LEFDE0:
   1237 	.text
   1238 .Letext0:
   1239 	.section	.debug_info
   1240 	.ualong	0xb3
   1241 	.uaword	0x2
   1242 	.ualong	.Ldebug_abbrev0
   1243 	.byte	0x4
   1244 	.uleb128 0x1
   1245 	.ualong	.Ldebug_line0
   1246 	.ualong	.Letext0
   1247 	.ualong	.Ltext0
   1248 	.string	"trap_handler.c"
   1249 	.string	"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
   1250 	.string	"GNU C 3.2 20020529 (experimental)"
   1251 	.byte	0x1
   1252 	.uleb128 0x2
   1253 	.ualong	0xa6
   1254 	.byte	0x1
   1255 	.string	"_superh_trap_handler"
   1256 	.byte	0x1
   1257 	.byte	0x2
   1258 	.byte	0x1
   1259 	.ualong	.LFB1
   1260 	.ualong	.LFE1
   1261 	.byte	0x1
   1262 	.byte	0x5e
   1263 	.uleb128 0x3
   1264 	.string	"trap_reason"
   1265 	.byte	0x1
   1266 	.byte	0x1
   1267 	.ualong	0xa6
   1268 	.byte	0x2
   1269 	.byte	0x91
   1270 	.sleb128 0
   1271 	.byte	0x0
   1272 	.uleb128 0x4
   1273 	.string	"unsigned int"
   1274 	.byte	0x4
   1275 	.byte	0x7
   1276 	.byte	0x0
   1277 	.section	.debug_abbrev
   1278 	.uleb128 0x1
   1279 	.uleb128 0x11
   1280 	.byte	0x1
   1281 	.uleb128 0x10
   1282 	.uleb128 0x6
   1283 	.uleb128 0x12
   1284 	.uleb128 0x1
   1285 	.uleb128 0x11
   1286 	.uleb128 0x1
   1287 	.uleb128 0x3
   1288 	.uleb128 0x8
   1289 	.uleb128 0x1b
   1290 	.uleb128 0x8
   1291 	.uleb128 0x25
   1292 	.uleb128 0x8
   1293 	.uleb128 0x13
   1294 	.uleb128 0xb
   1295 	.byte	0x0
   1296 	.byte	0x0
   1297 	.uleb128 0x2
   1298 	.uleb128 0x2e
   1299 	.byte	0x1
   1300 	.uleb128 0x1
   1301 	.uleb128 0x13
   1302 	.uleb128 0x3f
   1303 	.uleb128 0xc
   1304 	.uleb128 0x3
   1305 	.uleb128 0x8
   1306 	.uleb128 0x3a
   1307 	.uleb128 0xb
   1308 	.uleb128 0x3b
   1309 	.uleb128 0xb
   1310 	.uleb128 0x27
   1311 	.uleb128 0xc
   1312 	.uleb128 0x11
   1313 	.uleb128 0x1
   1314 	.uleb128 0x12
   1315 	.uleb128 0x1
   1316 	.uleb128 0x40
   1317 	.uleb128 0xa
   1318 	.byte	0x0
   1319 	.byte	0x0
   1320 	.uleb128 0x3
   1321 	.uleb128 0x5
   1322 	.byte	0x0
   1323 	.uleb128 0x3
   1324 	.uleb128 0x8
   1325 	.uleb128 0x3a
   1326 	.uleb128 0xb
   1327 	.uleb128 0x3b
   1328 	.uleb128 0xb
   1329 	.uleb128 0x49
   1330 	.uleb128 0x13
   1331 	.uleb128 0x2
   1332 	.uleb128 0xa
   1333 	.byte	0x0
   1334 	.byte	0x0
   1335 	.uleb128 0x4
   1336 	.uleb128 0x24
   1337 	.byte	0x0
   1338 	.uleb128 0x3
   1339 	.uleb128 0x8
   1340 	.uleb128 0xb
   1341 	.uleb128 0xb
   1342 	.uleb128 0x3e
   1343 	.uleb128 0xb
   1344 	.byte	0x0
   1345 	.byte	0x0
   1346 	.byte	0x0
   1347 	.section	.debug_pubnames,"",@progbits
   1348 	.ualong	0x27
   1349 	.uaword	0x2
   1350 	.ualong	.Ldebug_info0
   1351 	.ualong	0xb7
   1352 	.ualong	0x67
   1353 	.string	"_superh_trap_handler"
   1354 	.ualong	0x0
   1355 	.section	.debug_aranges,"",@progbits
   1356 	.ualong	0x1c
   1357 	.uaword	0x2
   1358 	.ualong	.Ldebug_info0
   1359 	.byte	0x4
   1360 	.byte	0x0
   1361 	.uaword	0x0
   1362 	.uaword	0x0
   1363 	.ualong	.Ltext0
   1364 	.ualong	.Letext0-.Ltext0
   1365 	.ualong	0x0
   1366 	.ualong	0x0
   1367 #endif /* VBR_SETUP */
   1368 #endif /* ! __SH5__ */
   1369