summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/gba/start/start.S
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2005-07-06 18:46:04 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2005-07-06 18:46:04 +0000
commit3c7ed6b8cd505f696c9c2b6d90723094f334b348 (patch)
tree30da596d32865c2d042ece5735d16baeade7d17d /c/src/lib/libbsp/arm/gba/start/start.S
parentAdd PR. (diff)
downloadrtems-3c7ed6b8cd505f696c9c2b6d90723094f334b348.tar.bz2
2005-07-06 Markku Puro <markku.puro@kopteri.net>
* .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.
Diffstat (limited to 'c/src/lib/libbsp/arm/gba/start/start.S')
-rw-r--r--c/src/lib/libbsp/arm/gba/start/start.S398
1 files changed, 398 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/gba/start/start.S b/c/src/lib/libbsp/arm/gba/start/start.S
new file mode 100644
index 0000000000..659e722d47
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/start/start.S
@@ -0,0 +1,398 @@
+/**
+ * @file start.S
+ *
+ * RTEMS entry point.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) by Jeff Frohwein.
+ *
+ * Copyright (c) 2003, Jason Wilkins.
+ *
+ * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
+ * based on crt0.S v1.28 by Jeff Frohwein
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+/*****************************************************************************
+ * This source file is based on work by Jeff Frohwein and Jason Wilkins
+ *****************************************************************************
+ *****************************************************************************
+ * crt0.S v1.28 by Jeff Frohwein
+ * :
+ * This file is released into the public domain for commercial
+ * or non-commercial usage with no restrictions placed upon it.
+ *****************************************************************************
+ * Copyright 2003, Jason Wilkins. This source code is free for any use except
+ * that this copyright notice and the following disclaimers remain intact when
+ * the source is distributed. Object code and binary distributions may be made
+ * as if the code were in the public domain.
+ *
+ * THIS CODE WAS NOT MADE IN ASSOCIATION WITH NINTENDO AND DOES NOT MAKE USE
+ * OF ANY INTELLECTUAL PROPERTY CLAIMED BY NINTENDO.
+ *
+ * GAMEBOY ADVANCE IS A TRADEMARK OF NINTENDO.
+ *
+ * THIS CODE HAS BEEN PROVIDED "AS-IS" WITHOUT A WARRANTY OF ANY KIND, EITHER
+ * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED WARRANTIES OF
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. THE ENTIRE RISK AS TO THE
+ * QUALITY OR PERFORMANCE OF THE CODE IS WITH YOU.
+ *
+ * IN NO EVENT, UNLESS AGREED TO IN WRITING, WILL ANY COPYRIGHT HOLDER, OR ANY
+ * OTHER PARTY, BE HELD LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OR
+ * INABILITY TO USE THIS CODE.
+ *****************************************************************************/
+
+#define __asm__
+#include <rtems/asm.h>
+#include <asm_macros.h>
+#include <arm_mode_bits.h>
+/* @cond INCLUDE_ASM */
+
+#ifndef NINTENDO_LOGO
+#define NINTENDO_LOGO 1
+#endif
+
+#ifndef GBA_MULTIBOOT
+#define GBA_MULTIBOOT 1
+#endif
+
+#ifndef GAME_TITLE
+#define GAME_TITLE "RTEMS-RTOS "
+#endif
+
+#ifdef GBA_MULTIBOOT
+ #ifndef GAME_CODE
+ #define GAME_CODE "MB "
+ #endif
+ #ifndef COMPLEMENT_CHECK
+ #define COMPLEMENT_CHECK 0xE2
+ #endif
+#else
+ #ifndef GAME_CODE
+ #define GAME_CODE "GBA "
+ #endif
+ #ifndef COMPLEMENT_CHECK
+ #define COMPLEMENT_CHECK 0xC7
+ #endif
+#endif
+
+#ifndef MAKER_CODE
+#define MAKER_CODE "00"
+#endif
+
+/**
+ * RTEMS entry point
+ * function void _start(void)
+ *
+ */
+/*****************************************************************************\
+ ROM Header
+\*****************************************************************************/
+
+.text
+.align
+.arm
+
+/*---------------------------------------------------------------------------+
+| Nintendo Header:
+| A special header is required or the GBA will refuse to run your code.
+|
+| File offsets from 0x0200000 or 0x08000000.
++----------------------------------------------------------------------------*/
+ PUBLIC_ARM_FUNCTION(_start)
+ b SYM(_real_start) /* 0x00 Entry Point */
+ SYM(_gba_rom_header):
+#if NINTENDO_LOGO /* 0x04 Nintendo Logo Character Data */
+#include "logo.S"
+#else
+ .fill 156, 1, 0 /* 0x04 Nintendo Logo Character Data */
+#endif
+ .ascii GAME_TITLE /* 0xA0 Game Title */
+ .ascii GAME_CODE /* 0xAC Game Code */
+ .ascii MAKER_CODE /* 0xB0 Maker Code */
+ .byte 0x96 /* 0xB2 Fixed Value */
+ .byte 0 /* 0xB3 Main Unit Code */
+ .byte 0 /* 0xB4 Device Type */
+ .byte 0, 0, 0, 0, 0, 0, 0 /* 0xB5 Reserved (7 Bytes) */
+ .byte 0 /* 0xBC Software Version No. */
+ .byte COMPLEMENT_CHECK /* 0xBD Complement Check */
+ .byte 0, 0 /* 0xBE Reserved */
+ .Lheader_end:
+
+
+#if GBA_MULTIBOOT
+/*---------------------------------------------------------------------------+
+| Multiboot Header:
+| The following header is required if the code is meant for Multiboot.
+|
+| If the code has been downloaded through the serial port, then the GBA BIOS
+| will set offset 0xC0 depending on the boot method:
+| 1 = JoyBus, 3 = Multiboot
+| It remains 0 for cartridges.
+|
+| offset 0xC4 will be set to the GBA's assigned slave number 1-3.
+| This header also defines the symbols _boot_method and _slave_number for
+| easy reference to these values. Some libraries may depend on them whether
+| or not the code is meant for Multiboot.
+|
++----------------------------------------------------------------------------*/
+ SYM(_gba_multiboot_start):
+ b SYM(_real_start) /* 0xC0 Multiboot Entry Point */
+ OBJECT(_boot_method)
+ .byte 0 /* 0xC4 Boot Method */
+ OBJECT(_slave_number)
+ .byte 0 /* 0xC5 Slave Number (1-3) */
+ .align
+ STATIC_OBJECT(_gba_mb_reserved)
+ .word 0, 0, 0, 0, 0, 0 /* 0xC8 Reserved (6 words) */
+ SYM(_gba_joybus_start):
+ b SYM(_real_start) /* 0xE0 JoyBus Entry Point */
+ .Lmultiboot_header_end:
+#endif
+
+/*---------------------------------------------------------------------------+
+| Restore registers and stack from GBA bios IRQ frame and call ISR_Handler
++----------------------------------------------------------------------------*/
+ EXTERN(_ISR_Handler)
+ .align
+ PUBLIC_ARM_FUNCTION(_gba_ISR_handler)
+ ldmfd r13!,{r0-r3,r12,r14}
+ b _ISR_Handler
+ LABEL_END(_gba_ISR_handler)
+
+
+/*---------------------------------------------------------------------------+
+| Code to initialize the low-level BSP environment
++----------------------------------------------------------------------------*/
+ SYM(_real_start):
+ /* Initialize IRQ and USR Stack Pointers */
+ SYM(_gba_init_stacks):
+ mov r0, #(Mode_IRQ | Int_Bits) /* No interrupts */
+ msr cpsr, r0 /* switch to IRQ mode */
+ ldr sp, =__sp_irq /* defined in linkcmds */
+ mov r0, #(ModePriv | Int_Bits) /* No interrupts */
+ msr cpsr, r0 /* switch to System Mode */
+ ldr sp, =__sp_usr /* defined in linkcmds */
+
+ /* Switch to Thumb Mode */
+ SYM(_gba_bx_thumb):
+ adr r0, .Lthumb + 1
+ bx r0
+ .thumb
+ .Lthumb:
+ /* Reduce gameboy waitstates */
+ SYM(_reduce_waitstates):
+ ldr r1, =0x4000204
+ ldrh r0, =0x4490
+ strh r0, [r1]
+
+
+#if GBA_MULTIBOOT
+/*---------------------------------------------------------------------------+
+| Load Multiboot Image from ROM into RAM:
+| Check to see if the image is meant for Multiboot or GamePak. If it is for
+| Multiboot then check if it is currently running from EWRAM or from CARTROM.
+| If it is running from CARTROM, then it needs to be copied to EWRAM and
+| re-executed from the beginning.
+|
+| The reason for all this is to allow a program to be used "as-is" with a
+| flash-cart, emulator, or MBV2-style Multiboot cable without rebuilding.
+|
+| NOTE: Any branchs used above this code need to be relative.
++----------------------------------------------------------------------------*/
+ STATIC_THUMB_FUNCTION(_gba_load_multiboot)
+ ldr r0, =_start /* 8000000h=GamePak 2000000h=Multiboot*/
+ ldr r1, =__gba_rom_start /* defined in linkcmds */
+ cmp r0, r1
+ beq SYM(_no_load_multiboot)/* skip if GamePak */
+ mov r3, pc
+ cmp r1, r3 /* check program counter */
+ bhi SYM(_no_load_multiboot)/* skip if already running from EWRAM */
+ sub r3, r1, r0 /* diff between _start and CARTROM */
+ ldr r2, =__load_stop_data /* defined in linkcmds */
+ add r2, r2, r3 /* adjust pointer into ROM */
+ bl SYM(gba_move_memory)
+
+ /* patch multiboot header */
+ ldr r0, =SYM(_boot_method)
+ mov r1, #3
+ str r1, [r0]
+
+ /* remember that multiboot image came from GamePak */
+ ldr r0, =SYM(_gba_flash_loaded_multiboot)
+ mov r1, #0
+ str r1, [r0]
+
+ ldr r0, =SYM(_start)
+ bx r0 /* restart */
+ LABEL_END(_gba_load_multiboot)
+
+ .align 4
+ OBJECT(_gba_flash_loaded_multiboot)
+ .word -1
+ LABEL_END(_gba_flash_loaded_multiboot)
+ SYM(_no_load_multiboot):
+#endif
+
+/* Initialize Standard Sections */
+ STATIC_THUMB_FUNCTION(_gba_init_std_sections)
+ /* Copy internal work ram (iwram section ROM to RAM)*/
+ ldr r0,=__iwram_start
+ ldr r1,=__load_start_iwram
+ ldr r2,=__load_stop_iwram
+ bl SYM(gba_move_memory)
+
+ /* Copy external work ram (ewram section ROM to RAM) */
+ ldr r0,=__ewram_start
+ ldr r1,=__load_start_ewram
+ ldr r2,=__load_stop_ewram
+ bl SYM(gba_move_memory)
+
+ /* load initial values of variables like 'int foo = 42' */
+ ldr r0, =__data_start /* defined in linkcmds */
+ ldr r1, =__load_start_data /* defined in linkcmds */
+ ldr r2, =__load_stop_data /* defined in linkcmds */
+ bl SYM(gba_move_memory)
+
+ /* zero the bss */
+ ldr r0, =__bss_start /* defined in linkcmds */
+ ldr r1, =__bss_end /* defined in linkcmds */
+ bl SYM(gba_zero_memory)
+ LABEL_END(_gba_init_std_sections)
+
+/* Initialize Interrupt Vector */
+ STATIC_THUMB_FUNCTION(_gba_init_intr_vect)
+ ldr r1, =__irq_vector /* defined in linkcmds */
+ ldr r0, =SYM(_gba_ISR_handler)
+ str r0, [r1]
+ LABEL_END(_gba_init_intr_vect)
+
+
+/* Enter the C code. If it returns, then restart */
+ STATIC_THUMB_FUNCTION(_gba_call_arm_boot_card)
+ adr r0, .Larm
+ bx r0
+ .arm
+ .Larm:
+ ldr r0, =boot_card
+ bl SYM(_gba_call_via_r0)
+
+ ldr r0, =SYM(_gba_reset)
+ SYM(_gba_call_via_r0):
+ bx r0
+
+/* GBA Reset */
+ PUBLIC_ARM_FUNCTION(_gba_reset)
+ adr r0, .Lthumb2 + 1
+ bx r0
+ .thumb
+ .Lthumb2:
+ /* disable interrupts */
+ ldr r0, =0x04000208
+ mov r1, #0
+ strb r1, [r0]
+
+ /* reset stack, default free area */
+ ldr r0, =0x03007F00
+ mov sp, r0
+
+#if GBA_MULTIBOOT
+ ldr r0, =SYM(_gba_flash_loaded_multiboot)
+ ldr r0, [r0]
+ cmp r0, #0
+ beq SYM(_reset)
+#endif
+
+ ldr r0, =_start /* defined in linkcmds */
+ ldr r1, =__gba_rom_start /* defined in linkcmds */
+ sub r0, r0, r1
+ lsr r0, r0, #24
+
+ SYM(_reset):
+ /* soft reset (swi 0) parameter: where is _start */
+ ldr r1, =0x03007FFA
+ strb r0, [r1]
+ mov r0, #0xFE /* clear all but EWRAM */
+ swi 1
+ swi 0
+ LABEL_END(_gba_reset)
+
+
+/*---------------------------------------------------------------------------+
+| Library Functions
++----------------------------------------------------------------------------*/
+
+/* gba_zero_memory */
+ PUBLIC_THUMB_FUNCTION(gba_zero_memory)
+ mov r2, #0
+ nop
+ LABEL_END(gba_zero_memory)
+
+/* gba_set_memory */
+ PUBLIC_THUMB_FUNCTION(gba_set_memory)
+ cmp r0, r1
+ bcs .Lset_memory_return
+
+ .Lset_memory_loop:
+ stmia r0!, {r2}
+ cmp r0, r1
+ bcc .Lset_memory_loop
+
+ .Lset_memory_return:
+ bx lr
+ LABEL_END(gba_set_memory)
+
+/* gba_move_memory */
+ .align
+ PUBLIC_THUMB_FUNCTION(gba_move_memory)
+ cmp r0, r1
+ bcc .Lforward_move /* if dst < src then forward copy */
+ bhi .Lreverse_move /* if dst > src then reverse copy */
+ bx lr /* else dst == src, nothing to do */
+
+ .Lforward_move:
+ cmp r1, r2
+ bcs .Lmove_memory_return
+
+ .Lforward_move_loop:
+ ldmia r1!, {r3}
+ stmia r0!, {r3}
+ cmp r1, r2
+ bcc .Lforward_move_loop
+ bx lr
+
+ .Lreverse_move:
+ cmp r2, r1
+ bls .Lmove_memory_return
+ sub r3, r2, r1
+ add r0, r0, r3
+
+ .Lreverse_move_loop:
+ sub r2, r2, #4
+ ldr r3, [r2]
+ sub r0, r0, #4
+ str r3, [r0]
+ cmp r2, r1
+ bhi .Lreverse_move_loop
+
+ .Lmove_memory_return:
+ bx lr
+ LABEL_END(gba_move_memory)
+
+
+/* @todo FIXME: Remove unused handler needed by ../score/cpu_asm.S
+ *****************************************************************************/
+ .arm
+ .global SWI_Handler
+SWI_Handler:
+ mov pc, lr
+/* @endcond */
+