source: rtems/c/src/lib/libbsp/arm/gba/start/start.S @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 13.5 KB
Line 
1/**
2 *  @file start.S
3 *
4 *  RTEMS entry point.
5 */
6/*
7 *  RTEMS GBA BSP
8 *
9 *  Copyright (c) by Jeff Frohwein.
10 *
11 *  Copyright (c) 2003, Jason Wilkins.
12 *
13 *  Copyright (c) 2004  Markku Puro <markku.puro@kopteri.net>
14 *  based on crt0.S v1.28 by Jeff Frohwein
15 *
16 *  The license and distribution terms for this file may be
17 *  found in the file LICENSE in this distribution or at
18 *  http://www.rtems.org/license/LICENSE.
19 */
20
21/*****************************************************************************
22 * This source file is based on work by Jeff Frohwein and Jason Wilkins
23 *****************************************************************************
24 *****************************************************************************
25 * crt0.S v1.28 by Jeff Frohwein
26 * :
27 * This file is released into the public domain for commercial
28 * or non-commercial usage with no restrictions placed upon it.
29 *****************************************************************************
30 * Copyright 2003, Jason Wilkins.  This source code is free for any use except
31 * that this copyright notice and the following disclaimers remain intact when
32 * the source is distributed.  Object code and binary distributions may be made
33 * as if the code were in the public domain.
34 *
35 * THIS CODE WAS NOT MADE IN ASSOCIATION WITH NINTENDO AND DOES NOT MAKE USE
36 * OF ANY INTELLECTUAL PROPERTY CLAIMED BY NINTENDO.
37 *
38 * GAMEBOY ADVANCE IS A TRADEMARK OF NINTENDO.
39 *
40 * THIS CODE HAS BEEN PROVIDED "AS-IS" WITHOUT A WARRANTY OF ANY KIND, EITHER
41 * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED WARRANTIES OF
42 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  THE ENTIRE RISK AS TO THE
43 * QUALITY OR PERFORMANCE OF THE CODE IS WITH YOU.
44 *
45 * IN NO EVENT, UNLESS AGREED TO IN WRITING, WILL ANY COPYRIGHT HOLDER, OR ANY
46 * OTHER PARTY, BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OR
47 * INABILITY TO USE THIS CODE.
48 *****************************************************************************/
49
50#define __asm__
51#include <rtems/asm.h>
52#include <asm_macros.h>
53#include <arm_mode_bits.h>
54/* @cond  INCLUDE_ASM */
55
56#ifndef NINTENDO_LOGO
57#define NINTENDO_LOGO 1
58#endif
59
60#ifndef GBA_MULTIBOOT
61#define GBA_MULTIBOOT 1
62#endif
63
64#ifndef GAME_TITLE
65#define GAME_TITLE "RTEMS-RTOS  "
66#endif
67
68#ifdef GBA_MULTIBOOT
69  #ifndef GAME_CODE
70  #define GAME_CODE "MB  "
71  #endif
72  #ifndef COMPLEMENT_CHECK
73  #define COMPLEMENT_CHECK 0xE2
74  #endif
75#else
76  #ifndef GAME_CODE
77  #define GAME_CODE "GBA "
78  #endif
79  #ifndef COMPLEMENT_CHECK
80  #define COMPLEMENT_CHECK 0xC7
81  #endif
82#endif
83
84#ifndef MAKER_CODE
85#define MAKER_CODE "00"
86#endif
87
88/**
89 *  RTEMS entry point
90 *  function void _start(void)
91 *
92 */
93/*****************************************************************************\
94                           ROM Header
95\*****************************************************************************/
96
97.text
98.align
99.arm
100
101/*---------------------------------------------------------------------------+
102|  Nintendo Header:
103|   A special header is required or the GBA will refuse to run your code.
104|
105|  File offsets from 0x0200000 or 0x08000000.
106+----------------------------------------------------------------------------*/
107    PUBLIC_ARM_FUNCTION(_start)
108         b       SYM(_real_start)    /* 0x00 Entry Point                     */
109    SYM(_gba_rom_header):
110#if NINTENDO_LOGO                    /* 0x04 Nintendo Logo Character Data    */
111#include        "logo.S"
112#else
113        .fill   156, 1, 0            /* 0x04 Nintendo Logo Character Data    */
114#endif
115        .ascii  GAME_TITLE           /* 0xA0 Game Title                      */
116        .ascii  GAME_CODE            /* 0xAC Game Code                       */
117        .ascii  MAKER_CODE           /* 0xB0 Maker Code                      */
118        .byte   0x96                 /* 0xB2 Fixed Value                     */
119        .byte   0                    /* 0xB3 Main Unit Code                  */
120        .byte   0                    /* 0xB4 Device Type                     */
121        .byte   0, 0, 0, 0, 0, 0, 0  /* 0xB5 Reserved (7 Bytes)              */
122        .byte   0                    /* 0xBC Software Version No.            */
123        .byte   COMPLEMENT_CHECK     /* 0xBD Complement Check                */
124        .byte   0, 0                 /* 0xBE Reserved                        */
125    .Lheader_end:
126
127
128#if GBA_MULTIBOOT
129/*---------------------------------------------------------------------------+
130|  Multiboot Header:
131|  The following header is required if the code is meant for Multiboot.
132|
133|  If the code has been downloaded through the serial port, then the GBA BIOS
134|  will set offset 0xC0 depending on the boot method:
135|  1 = JoyBus, 3 = Multiboot
136|  It remains 0 for cartridges.
137|
138|  offset 0xC4 will be set to the GBA's assigned slave number 1-3.
139|  This header also defines the symbols _boot_method and _slave_number for
140|  easy reference to these values.  Some libraries may depend on them whether
141|  or not the code is meant for Multiboot.
142|
143+----------------------------------------------------------------------------*/
144    SYM(_gba_multiboot_start):
145        b       SYM(_real_start)               /* 0xC0 Multiboot Entry Point */
146    OBJECT(_boot_method)
147        .byte   0                              /* 0xC4 Boot Method           */
148    OBJECT(_slave_number)
149        .byte   0                              /* 0xC5 Slave Number (1-3)    */
150        .align
151    STATIC_OBJECT(_gba_mb_reserved)
152        .word   0, 0, 0, 0, 0, 0               /* 0xC8 Reserved (6 words)    */
153    SYM(_gba_joybus_start):
154        b       SYM(_real_start)               /* 0xE0 JoyBus Entry Point    */
155    .Lmultiboot_header_end:
156#endif
157
158/*---------------------------------------------------------------------------+
159|    Restore registers and stack from GBA bios IRQ frame and call ISR_Handler
160+----------------------------------------------------------------------------*/
161    EXTERN(_ISR_Handler)
162    .align
163    PUBLIC_ARM_FUNCTION(_gba_ISR_handler)
164        ldmfd  r13!,{r0-r3,r12,r14}
165        b      _ARMV4_Exception_interrupt
166    LABEL_END(_gba_ISR_handler)
167
168
169/*---------------------------------------------------------------------------+
170|    Code to initialize the low-level BSP environment
171+----------------------------------------------------------------------------*/
172    SYM(_real_start):
173    /* Initialize IRQ and USR Stack Pointers */
174    SYM(_gba_init_stacks):
175        mov     r0, #(Mode_IRQ | Int_Bits)       /* No interrupts            */
176        msr     cpsr, r0                         /* switch to IRQ mode       */
177        ldr     sp, =__sp_irq                    /* defined in linkcmds      */
178        mov     r0, #(ModePriv | Int_Bits)       /* No interrupts            */
179        msr     cpsr, r0                         /* switch to System Mode    */
180        ldr     sp, =__sp_usr                    /* defined in linkcmds      */
181
182    /* Switch to Thumb Mode */
183    SYM(_gba_bx_thumb):
184        adr     r0, .Lthumb + 1
185        bx      r0
186        .thumb
187    .Lthumb:
188    /* Reduce gameboy waitstates */
189    SYM(_reduce_waitstates):
190        ldr     r1, =0x4000204
191        ldrh    r0, =0x4490
192        strh    r0, [r1]
193
194
195#if GBA_MULTIBOOT
196/*---------------------------------------------------------------------------+
197|  Load Multiboot Image from ROM into RAM:
198|  Check to see if the image is meant for Multiboot or GamePak.  If it is for
199|  Multiboot then check if it is currently running from EWRAM or from CARTROM.
200|  If it is running from CARTROM, then it needs to be copied to EWRAM and
201|  re-executed from the beginning.
202|
203|  The reason for all this is to allow a program to be used "as-is" with a
204|  flash-cart, emulator, or MBV2-style Multiboot cable without rebuilding.
205|
206|  NOTE: Any branchs used above this code need to be relative.
207+----------------------------------------------------------------------------*/
208    STATIC_THUMB_FUNCTION(_gba_load_multiboot)
209        ldr     r0, =_start            /* 8000000h=GamePak 2000000h=Multiboot*/
210        ldr     r1, =__gba_rom_start   /* defined in linkcmds                */
211        cmp     r0, r1
212        beq     SYM(_no_load_multiboot)/* skip if GamePak                    */
213        mov     r3, pc
214        cmp     r1, r3                 /* check program counter              */
215        bhi     SYM(_no_load_multiboot)/* skip if already running from EWRAM */
216        sub     r3, r1, r0             /* diff between _start and CARTROM    */
217        ldr     r2, =__load_stop_data  /* defined in linkcmds                */
218        add     r2, r2, r3             /* adjust pointer into ROM            */
219        bl      SYM(gba_move_memory)
220
221        /* patch multiboot header */
222        ldr     r0, =SYM(_boot_method)
223        mov     r1, #3
224        str     r1, [r0]
225
226        /* remember that multiboot image came from GamePak */
227        ldr     r0, =SYM(_gba_flash_loaded_multiboot)
228        mov     r1, #0
229        str     r1, [r0]
230
231        ldr     r0, =SYM(_start)
232        bx      r0                      /* restart                           */
233    LABEL_END(_gba_load_multiboot)
234
235        .align 4
236    OBJECT(_gba_flash_loaded_multiboot)
237        .word -1
238    LABEL_END(_gba_flash_loaded_multiboot)
239    SYM(_no_load_multiboot):
240#endif
241
242/* Initialize Standard Sections */
243    STATIC_THUMB_FUNCTION(_gba_init_std_sections)
244        /* Copy internal work ram (iwram section ROM to RAM)*/
245        ldr     r0,=__iwram_start
246        ldr     r1,=__load_start_iwram
247        ldr     r2,=__load_stop_iwram
248        bl      SYM(gba_move_memory)
249
250        /* Copy external work ram (ewram section ROM to RAM) */
251        ldr     r0,=__ewram_start
252        ldr     r1,=__load_start_ewram
253        ldr     r2,=__load_stop_ewram
254        bl      SYM(gba_move_memory)
255
256        /* load initial values of variables like 'int foo = 42' */
257        ldr     r0, =__data_start      /* defined in linkcmds               */
258        ldr     r1, =__load_start_data /* defined in linkcmds               */
259        ldr     r2, =__load_stop_data  /* defined in linkcmds               */
260        bl      SYM(gba_move_memory)
261
262        /* zero the bss */
263        ldr     r0, =__bss_start       /* defined in linkcmds               */
264        ldr     r1, =__bss_end         /* defined in linkcmds               */
265        bl      SYM(gba_zero_memory)
266    LABEL_END(_gba_init_std_sections)
267
268/* Initialize Interrupt Vector */
269    STATIC_THUMB_FUNCTION(_gba_init_intr_vect)
270        ldr     r1, =__irq_vector    /* defined in linkcmds                 */
271        ldr     r0, =SYM(_gba_ISR_handler)
272        str     r0, [r1]
273    LABEL_END(_gba_init_intr_vect)
274
275
276/* Enter the C code.  If it returns, then restart */
277    STATIC_THUMB_FUNCTION(_gba_call_arm_boot_card)
278        adr     r1, .Larm
279        bx      r1
280        .arm
281    .Larm:
282        ldr     r1, =boot_card
283        mov     r0, #0
284        bl      SYM(_gba_call_via_r1)
285
286        ldr     r0, =SYM(_gba_reset)
287    SYM(_gba_call_via_r1):
288        bx      r1
289
290/* GBA Reset  */
291    PUBLIC_ARM_FUNCTION(_gba_reset)
292        adr     r0, .Lthumb2 + 1
293        bx      r0
294        .thumb
295    .Lthumb2:
296        /* disable interrupts */
297        ldr     r0, =0x04000208
298        mov     r1, #0
299        strb    r1, [r0]
300
301        /* reset stack, default free area */
302        ldr     r0, =0x03007F00
303        mov     sp, r0
304
305#if GBA_MULTIBOOT
306        ldr     r0, =SYM(_gba_flash_loaded_multiboot)
307        ldr     r0, [r0]
308        cmp     r0, #0
309        beq     SYM(_reset)
310#endif
311
312        ldr     r0, =_start            /* defined in linkcmds               */
313        ldr     r1, =__gba_rom_start   /* defined in linkcmds               */
314        sub     r0, r0, r1
315        lsr     r0, r0, #24
316
317   SYM(_reset):
318        /* soft reset (swi 0) parameter: where is _start */
319        ldr     r1, =0x03007FFA
320        strb    r0, [r1]
321        mov     r0, #0xFE              /* clear all but EWRAM               */
322        swi     1
323        swi     0
324    LABEL_END(_gba_reset)
325
326
327/*---------------------------------------------------------------------------+
328|   Library Functions
329+----------------------------------------------------------------------------*/
330
331/* gba_zero_memory */
332    PUBLIC_THUMB_FUNCTION(gba_zero_memory)
333        mov     r2, #0
334        nop
335    LABEL_END(gba_zero_memory)
336
337/* gba_set_memory */
338    PUBLIC_THUMB_FUNCTION(gba_set_memory)
339        cmp     r0, r1
340        bcs     .Lset_memory_return
341
342    .Lset_memory_loop:
343        stmia   r0!, {r2}
344        cmp     r0, r1
345        bcc     .Lset_memory_loop
346
347    .Lset_memory_return:
348        bx      lr
349    LABEL_END(gba_set_memory)
350
351/* gba_move_memory */
352    .align
353    PUBLIC_THUMB_FUNCTION(gba_move_memory)
354        cmp     r0, r1
355        bcc     .Lforward_move  /* if dst < src then forward copy */
356        bhi     .Lreverse_move  /* if dst > src then reverse copy */
357        bx      lr              /* else dst == src, nothing to do */
358
359    .Lforward_move:
360        cmp     r1, r2
361        bcs     .Lmove_memory_return
362
363    .Lforward_move_loop:
364        ldmia   r1!, {r3}
365        stmia   r0!, {r3}
366        cmp     r1, r2
367        bcc     .Lforward_move_loop
368        bx      lr
369
370    .Lreverse_move:
371        cmp     r2, r1
372        bls     .Lmove_memory_return
373        sub     r3, r2, r1
374        add     r0, r0, r3
375
376    .Lreverse_move_loop:
377        sub     r2, r2, #4
378        ldr     r3, [r2]
379        sub     r0, r0, #4
380        str     r3, [r0]
381        cmp     r2, r1
382        bhi     .Lreverse_move_loop
383
384    .Lmove_memory_return:
385        bx      lr
386    LABEL_END(gba_move_memory)
387
388
389/* @todo FIXME: Remove unused handler needed by ../score/cpu_asm.S
390 *****************************************************************************/
391        .arm
392        .global SWI_Handler
393SWI_Handler:
394        mov pc, lr
395/* @endcond     */
396
Note: See TracBrowser for help on using the repository browser.