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

4.104.114.84.9
Last change on this file since 3c7ed6b was 3c7ed6b, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 6, 2005 at 6:46:04 PM

2005-07-06 Markku Puro <markku.puro@…>

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