source: trunk/libs/newlib/src/libgloss/mep/sim-crt0.S @ 546

Last change on this file since 546 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 10.3 KB
Line 
1# Copyright (c) 2003  Red Hat, Inc. All rights reserved.
2#
3# This copyrighted material is made available to anyone wishing to use, modify,
4# copy, or redistribute it subject to the terms and conditions of the BSD
5# License.   This program is distributed in the hope that it will be useful,
6# but WITHOUT ANY WARRANTY expressed or implied, including the implied
7# warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  A copy of
8# this license is available at http://www.opensource.org/licenses. Any Red Hat
9# trademarks that are incorporated in the source code or documentation are not
10# subject to the BSD License and may only be used or replicated with the express
11# permission of Red Hat, Inc.
12#
13# Toshiba Media Processor startup file (crt0.S)
14#
15# Designed for user programs running in the 0-2Mb startup section.
16# Designed for the simulator by default.
17#
18# Exception/Interrupt Handler Locations
19# CFG.EVM  CFG.EVA  CFG.IVA   Exception     INTn
20## 0         -        -        0x0000_0000  0x0000_0030 rom
21## 1         0        0        0x0020_0000  0x0020_0030 local RAM / local RAM
22## 1         1        0        0x0080_0000  0x0020_0000 ext RAM / local RAM
23## 1         0        1        0x0020_0000  0x0080_0000 local RAM / ext RAM
24## 1         1        1        0x0080_0000  0x0080_0030 ext RAM / ext RAM
25#
26# Exceptions           
27# Reset 0x0000_0000
28# NMI   0x0000_0000+4
29# RI    (Base Address) +0x08
30# ZDIV  (Base Address) +0x0C
31# BRK   (Base Address) +0x10
32# SWI   (Base Address) +0x14
33# DSP   (Base Address) +0x1C
34# COP   (Base Address) +0x20
35
36        .set _local_ram_base, 0x00200000
37        .set _ext_ram_base, 0x00800000
38        .set _int_base_offset, 0x30
39
40#include "syscall.h"
41
42.macro  if_bitfield_zero reg, start, length, label
43        ldc     $0, \reg
44        srl     $0, \start
45        and3    $0, $0, (1 << \length) - 1
46        beqz    $0,\label
47.endm
48
49.macro  if_bitfield_notN reg, start, length, N, label
50        ldc     $0, \reg
51        srl     $0, \start
52        and3    $0, $0, (1 << \length) - 1
53        bnei    $0,\N, \label
54.endm
55       
56.macro  if_bitfield_eqN reg, start, length, N, label
57        ldc     $0, \reg
58        srl     $0, \start
59        and3    $0, $0, (1 << \length) - 1
60        beqi    $0,\N, \label
61.endm
62
63.macro  if_bitfield_ltN reg, start, length, N, label
64        ldc     $0, \reg
65        srl     $0, \start
66        and3    $0, $0, (1 << \length) - 1
67        blti    $0,\N, \label
68.endm
69
70        .section  .hwinit, "ax"
71        # CCFG.ICSZ
72        if_bitfield_zero reg=$ccfg, start=16, length=7, label=.Lend_enable_icache
73__enable_icache:
74        # set ICE(cfg[1])
75        ldc     $1,$cfg
76        or3     $1,$1,2
77        stc     $1,$cfg
78        nop
79        nop
80        nop
81        nop
82        nop
83.Lend_enable_icache:
84        ret
85
86__enable_dcache:
87        # CCFG.DCSZ
88        if_bitfield_zero reg=$ccfg, start=0, length=7, label=.Lend_enable_dcache
89        # set DCE(cfg[0])
90        ldc     $1,$cfg
91        or3     $1,$1,1
92        stc     $1,$cfg
93        nop
94        nop
95        nop
96        nop
97        nop
98        ret
99.Lend_enable_dcache:           
100
101        .text
102
103#ifdef NOVEC
104        .global _reset
105_reset:
106#endif
107
108        .global _start
109_start:
110        mov     $fp, 0                  # for unwinding
111
112        # $sp set
113        movh    $sp, %uhi(__stack_table)
114        or3     $sp, $sp, %lo(__stack_table)
115
116        # initialize sp, gp, tp
117        # get CPU ID
118        ldc     $0, $id
119        srl     $0, 16
120
121        # load ID-specific stack pointer       
122        sl2ad3  $0, $0, $sp              # $0 = ($0 << 2) + $sp
123        lw      $sp,($0)                 # $sp = *($0)
124        mov     $0,0xfffffff8
125        and     $sp, $0
126
127#ifndef NOVEC
128        # copy exception vector table
129
130        # RCFG.IRSZ
131        if_bitfield_zero reg=$rcfg, start=16, length=7, label=.Lend_ev_imem
132        # handle imem
133        movh    $11,%uhi(_local_ram_base)
134        or3     $11,$11,%lo(_local_ram_base)
135        # clear CFG.EVA ([23])
136        ldc     $0,$cfg
137        movh    $1, %uhi(0xff7fffff)
138        or3     $1, $1, %lo(0xff7fffff)
139        and     $0,$1
140        stc     $0,$cfg
141        bra     .Ldo_repeat_ev
142.Lend_ev_imem: 
143#ifdef     UseSDRAM
144        movh    $11,%uhi(_ext_ram_base)
145        or3     $11,$11,%lo(_ext_ram_base)
146        # set CFG.EVA ([23])
147        ldc     $0,$cfg
148        movh    $1,%uhi(1<<23)
149        or3     $1,$1,%lo(1<<23)
150        or      $0,$1
151        stc     $0,$cfg
152#else
153        # handle ROM
154        bra     .Lend_ev
155#endif
156.Ldo_repeat_ev:
157        # set CFG.EVM ([4])
158        ldc     $0,$cfg
159        or3     $0,$0,(1<<4)
160        stc     $0,$cfg
161        # copy _exception_table to $11
162        movh    $12,%uhi(_exception_table)
163        or3     $12,$12,%lo(_exception_table)
164        mov     $13,8
165        repeat  $13,.Lrepeat_ev
166        lw      $1,0($12)
167        add     $12,4
168.Lrepeat_ev:
169        sw      $1,0($11)
170        add     $11,4
171.Lend_ev:       
172
173        # copy interrupt vector table
174        # RCFG.IRSZ
175        if_bitfield_zero reg=$rcfg, start=16, length=7, label=.Lend_iv_imem
176        # handle imem
177        movh    $11,%uhi(_local_ram_base)
178        or3     $11,$11,%lo(_int_base_offset)
179        # clear CFG.IVA ([22])
180        ldc     $0,$cfg
181        movh    $1,%uhi(0xffbfffff)  # ~(1<<22)
182        or3     $1,$1,%lo(0xffbfffff)
183        and     $0,$1
184        stc     $0,$cfg
185        bra     .Ldo_repeat_iv
186.Lend_iv_imem: 
187#ifdef UseSDRAM
188        movh    $11,%uhi(_ext_ram_base)
189        or3     $11,$11,%lo(_int_base_offset)
190        # set CFG. IVA ([22])
191        ldc     $0,$cfg
192        movh    $1,%uhi(1<<22)
193        or3     $1,$1,%lo(1<<22)
194        or      $0,$1
195        stc     $0,$cfg
196#else
197        # handle ROM
198        bra     .Lend_iv
199#endif
200.Ldo_repeat_iv:
201        # set CFG.IVM ([3])
202        ldc     $0,$cfg
203        or3     $0,$0,(1<<3)
204        stc     $0,$cfg
205        # copy _interrupt_table to $11
206        movh    $12,%uhi(_interrupt_table)
207        or3     $12,$12,%lo(_interrupt_table)
208        mov     $13,32
209        add     $13,-1
210        and3    $13,$13,127
211        repeat  $13,.Lrepeat_iv
212        lw      $1,0($12)
213        add     $12,4
214.Lrepeat_iv:
215        sw      $1,0($11)
216        add     $11,4
217.Lend_iv:       
218
219        # initialize instruction cache
220        # Icache Size CCFG.ICSZ ([22..16]) KByte
221        if_bitfield_zero reg=$ccfg, start=16, length=7, label=.Lend_ic
222        mov     $3,$0                   # cache size in KB
223        # ID.ID
224        if_bitfield_ltN reg=$ID, start=8, length=8, N=3, label=.Lend_mepc3_ic
225        # Line Size CCFG.ICSZ ([26..24]) Byte
226        if_bitfield_ltN reg=$ccfg, start=24, length=3, N=2, label=.Lend_ic
227        bgei    $0,5,.Lend_ic
228
229        add3    $1,$0,3                 # bit width of line size
230        mov     $0,$3
231        # clear tag
232        mov     $2,10
233        sub     $2,$1
234        sll     $0,$2                   # *KByte/(line size)   
235        add     $0,-1
236        mov     $2,1
237        sll     $2,$1                   # line size
238        bra     .Ldo_repeat_icache
239.Lend_mepc3_ic:
240        # ICache: $0 KByte
241        mov     $0,$3
242        # clear tag
243        sll     $0,(10-5)               # *KByte/(32byte=linesize)
244        add     $0,-1
245        mov     $2,32
246.Ldo_repeat_icache:     
247        mov     $1,0
248        bra     0f
249        # Align this code on an 8 byte boundary in order to keep the repeat
250        # loop entirely within the instruction fetch buffer.
251        .p2align 3
2520:
253        movh    $3,%hi(0x00310000)      # for tag
254        repeat  $0,.Lrepeat_icache
255        add     $0,-1
256.Lrepeat_icache:
257        sw      $1,0($3)
258        add3    $3,$3,$2
259.Lenable_icache:
260        movh    $1,%hi(__enable_icache)
261        add3    $1,$1,%lo(__enable_icache)
262        jsr     $1
263.Lend_ic:
264
265        # initialize data cache
266        # Dcache Size CCFG.DCSZ ([6..0]) KByte
267        if_bitfield_zero reg=$ccfg, start=0, length=7, label=.Lend_dc
268        mov     $3,$0                   # cache size in KB
269        # ID.ID
270        if_bitfield_ltN reg=$ID, start=8, length=8, N=3, label=.Lend_mepc3_dc
271        # Line Size CCFG.DCSZ ([10..8]) Byte
272        if_bitfield_ltN reg=$ccfg, start=8, length=3, N=2, label=.Lend_dc
273        bgei    $0,5,.Lend_dc
274
275        add3    $1,$0,3                 # bit width of line size
276        mov     $0,$3
277        # clear tag
278        mov     $2,10
279        sub     $2,$1
280        sll     $0,$2                   # *KByte/(line size)   
281        add     $0,-1
282        mov     $2,1
283        sll     $2,$1                   # line size
284        bra     .Ldo_repeat_dcache
285.Lend_mepc3_dc:
286        # DCache: $0 KByte
287        mov     $0,$3
288        # clear tag
289        sll     $0,(10-5)               # *KByte/(32byte=linesize)
290        add     $0,-1
291        mov     $2,32
292.Ldo_repeat_dcache:
293        mov     $1,0
294        movh    $3,%hi(0x00330000)              # for tag
295
296        repeat  $0,.Lrepeat_dcache
297        add     $0,-1
298.Lrepeat_dcache:
299        sw      $1,0($3)
300        add3    $3,$3,$2
301.Lenable_dcache:
302        movh    $1,%hi(__enable_dcache)
303        add3    $1,$1,%lo(__enable_dcache)
304        jsr             $1
305.Lend_dc:       
306        # NOVEC
307#endif
308        mov     $0, 0
309       
310        movh    $gp, %uhi(__sdabase)
311        or3     $gp, $gp, %lo(__sdabase)
312
313        movh    $tp, %uhi(__tpbase)
314        or3     $tp, $tp, %lo(__tpbase)
315
316        # zero out BSS
317        movh    $1, %uhi(__bss_start)
318        or3     $1, $1, %lo(__bss_start)
319        mov     $2, 0
320        movh    $3, %uhi(_end)
321        or3     $3, $3, %lo(_end)
322        sub     $3, $1
323        bsr     memset
324
325        movh    $1, %uhi(__sbss_start)
326        or3     $1, $1, %lo(__sbss_start)
327        mov     $2, 0
328        movh    $3, %uhi(__sbss_end)
329        or3     $3, $3, %lo(__sbss_end)
330        sub     $3, $1
331        bsr     memset
332
333        movh    $1, %uhi(__farbss_start)
334        or3     $1, $1, %lo(__farbss_start)
335        mov     $2, 0
336        movh    $3, %uhi(__farbss_end)
337        or3     $3, $3, %lo(__farbss_end)
338        sub     $3, $1
339        bsr     memset
340
341    # enable interrupts
342    ei
343
344    # construct global class variables
345        bsr     __invoke_init_section
346
347    # invoke main
348        mov     $1, 0                   # argc, argv, envp
349        mov     $2, 0
350        mov     $3, 0
351        bsr     main
352        mov     $1, $0
353        bsr     exit
354
355        .global _exit
356_exit:
357        # Prevent _exit recursion
358        movh    $3, %uhi(_exit_in_progress)
359        or3     $3, $3, %lo(_exit_in_progress)
360        lw      $5, ($3)
361        bnez    $5, _skip_fini
362        mov     $5, 1   
363        sw      $5, ($3)
364       
365        # We don't need to preserve $5 because we're going to exit anyway.
366        mov     $5,$1
367
368    # destruct global class variables
369        bsr     __invoke_fini_section
370        mov     $1,$5
371
372_skip_fini:
373
374#ifdef NOSIM
375_exit_loop:
376        bra     _exit_loop
377#else
378        .2byte 0x7800 | ((SYS_exit & 0xe) << 7) | ((SYS_exit & 1) << 4)
379        ret
380#endif
381
382        .data
383_exit_in_progress:      .word 0
384
385               
386       
387# For these two, the epilogue is in crtn.S
388
389        .section        .init
390__invoke_init_section:
391        add     $sp, -8
392        ldc     $0, $lp
393        sw      $0, ($sp)
394
395        .section .fini
396__invoke_fini_section:
397        add     $sp, -8
398        ldc     $0, $lp
399        sw      $0, ($sp)
400
401#ifndef NOVEC
402        .section .vec, "ax"
403        .core
404        .org 0x0, 0
405    .global _exception_table
406.type   _exception_table,@function     
407_exception_table:       
408        .p2align 2
409    .org 0x0000, 0
410        .global _reset
411_reset:
412        jmp  _handler_RESET
413    .org 0x0004, 0
414        jmp  _handler_NMI
415    .org 0x0008, 0
416        jmp  _handler_RI
417    .org 0x000c, 0
418        jmp  _handler_ZDIV
419    .org 0x0010, 0
420        jmp  _handler_BRK
421    .org 0x0014, 0
422        jmp  _handler_SWI
423    .org 0x0018, 0
424        jmp  _handler_DEBUG
425    .org 0x001c, 0
426        jmp  _handler_DSP
427    .org 0x0020, 0
428        jmp  _handler_COP
429
430        .org 0x30, 0
431        .global _interrupt_table
432.type   _interrupt_table,@function     
433_interrupt_table:               
434    .org 0x0030
435        jmp  _handler_INT0
436    .org 0x0034
437        jmp  _handler_INT1
438    .org 0x0038
439        jmp  _handler_INT2
440    .org 0x003c
441        jmp  _handler_INT3
442    .org 0x0040
443        jmp  _handler_INT4
444    .org 0x0044
445        jmp  _handler_INT5
446    .org 0x0048
447        jmp  _handler_INT6
448    .org 0x004c
449        jmp  _handler_INT7
450    .org 0x0050
451        jmp  _handler_INT8
452    .org 0x0054
453        jmp  _handler_INT9
454    .org 0x0058
455        jmp  _handler_INT10
456    .org 0x005c
457        jmp  _handler_INT11
458    .org 0x0060
459        jmp  _handler_INT12
460    .org 0x0064
461        jmp  _handler_INT13
462    .org 0x0068
463        jmp  _handler_INT14
464    .org 0x006c
465        jmp  _handler_INT15
466    .org 0x0070
467        jmp  _handler_INT16
468    .org 0x0074
469        jmp  _handler_INT17
470    .org 0x0078
471        jmp  _handler_INT18
472    .org 0x007c
473        jmp  _handler_INT19
474    .org 0x0080
475        jmp  _handler_INT20
476    .org 0x0084
477        jmp  _handler_INT21
478    .org 0x0088
479        jmp  _handler_INT22
480    .org 0x008c
481        jmp  _handler_INT23
482    .org 0x0090
483        jmp  _handler_INT24
484    .org 0x0094
485        jmp  _handler_INT25
486    .org 0x0098
487        jmp  _handler_INT26
488    .org 0x009c
489        jmp  _handler_INT27
490    .org 0x00a0
491        jmp  _handler_INT28
492    .org 0x00a4
493        jmp  _handler_INT29
494    .org 0x00a8
495        jmp  _handler_INT30
496    .org 0x00ac
497        jmp  _handler_INT31
498        # NOVEC
499#endif
Note: See TracBrowser for help on using the repository browser.