diff options
Diffstat (limited to 'c/src/lib/libbsp/arm/gba/start')
-rw-r--r-- | c/src/lib/libbsp/arm/gba/start/logo.S | 27 | ||||
-rw-r--r-- | c/src/lib/libbsp/arm/gba/start/start.S | 398 |
2 files changed, 425 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/gba/start/logo.S b/c/src/lib/libbsp/arm/gba/start/logo.S new file mode 100644 index 0000000000..eaeb391594 --- /dev/null +++ b/c/src/lib/libbsp/arm/gba/start/logo.S @@ -0,0 +1,27 @@ +/** + * @file logo.S + * + * Nintendo Logo Character Data [offset 0x04]. + */ +/* + * RTEMS GBA BSP + * + * 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. + * + * $Id$ + */ +/* @cond INCLUDE_ASM */ + .word 0x51AEFF24, 0x21A29A69, 0x0A82843D, 0xAD09E484 + .word 0x988B2411, 0x217F81C0, 0x19BE52A3, 0x20CE0993 + .word 0x4A4A4610, 0xEC3127F8, 0x33E8C758, 0xBFCEE382 + .word 0x94DFF485, 0xC1094BCE, 0xC08A5694, 0xFCA77213 + .word 0x734D849F, 0x619ACAA3, 0x27A39758, 0x769803FC + .word 0x61C71D23, 0x56AE0403, 0x008438BF, 0xFD0EA740 + .word 0x03FE52FF, 0xF130956F, 0x85C0FB97, 0x2580D660 + .word 0x03BE63A9, 0xE2384E01, 0xFF34A2F9, 0x44033EBB + .word 0xCB900078, 0x943A1188, 0x637CC065, 0xAF3CF087 + .word 0x8BE425D6, 0x72AC0A38, 0x07F8D421 +/* @endcond */ 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 */ + |