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.
This commit is contained in:
Joel Sherrill
2005-07-06 18:46:04 +00:00
parent e9b4f29a40
commit 3c7ed6b8cd
32 changed files with 5336 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
mkinstalldirs
+12
View File
@@ -0,0 +1,12 @@
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.
+177
View File
@@ -0,0 +1,177 @@
##
## $Id$
##
ACLOCAL_AMFLAGS = -I ../../../../aclocal
include $(top_srcdir)/../../../../automake/compile.am
include $(top_srcdir)/../../bsp.am
dist_project_lib_DATA = bsp_specs
include_HEADERS = include/bsp.h
include_HEADERS += include/arm_mode_bits.h
include_HEADERS += include/asm_macros.h
include_HEADERS += include/gba_registers.h
include_HEADERS += include/conio.h
include_HEADERS += include/tm27.h
include_HEADERS += include/gba.h
nodist_include_HEADERS = include/bspopts.h
nodist_include_HEADERS += ../../shared/include/coverhd.h
DISTCLEANFILES = include/bspopts.h
noinst_PROGRAMS =
EXTRA_DIST = start/start.S
start$(LIB_VARIANT).$(OBJEXT): start/start.S
$(CPPASCOMPILE) -DASM -o $@ -c $<
project_lib_DATA = start$(LIB_VARIANT).$(OBJEXT)
dist_project_lib_DATA += startup/linkcmds
noinst_PROGRAMS += startup.rel
startup_rel_SOURCES = ../../shared/bsplibc.c ../../shared/bsppost.c \
startup/bspstart.c startup/exit.c startup/cpu.c startup/cpu_asm.S \
../../shared/bootcard.c ../../shared/main.c ../../shared/sbrk.c \
../../shared/gnatinstallhandler.c
startup_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += startup_g.rel
startup_g_rel_SOURCES = $(startup_rel_SOURCES)
startup_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
startup_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += clock.rel
clock_rel_SOURCES = clock/clockdrv.c
clock_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += clock_g.rel
clock_g_rel_SOURCES = $(clock_rel_SOURCES)
clock_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
clock_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += console.rel
console_rel_SOURCES = console/conio.c console/console.c console/defaultfont.c
console_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
console_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += console_g.rel
console_g_rel_SOURCES = $(console_rel_SOURCES)
console_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
console_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += timer.rel
timer_rel_SOURCES = timer/timer.c
timer_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += timer_g.rel
timer_g_rel_SOURCES = $(timer_rel_SOURCES)
timer_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
timer_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
include_HEADERS += irq/irq.h
noinst_PROGRAMS += irq.rel
irq_rel_SOURCES = irq/irq.c irq/bsp_irq_init.c \
irq/irq_init.c irq/bsp_irq_asm.S \
irq/irq_asm.S
irq_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_PROGRAMS += irq_g.rel
irq_g_rel_SOURCES = $(irq_rel_SOURCES)
irq_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
irq_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
if HAS_NETWORKING
##
endif
noinst_LIBRARIES = libbsp.a
libbsp_a_SOURCES =
libbsp_a_LIBADD = clock$(LIB_VARIANT).rel console$(LIB_VARIANT).rel \
startup$(LIB_VARIANT).rel irq$(LIB_VARIANT).rel timer$(LIB_VARIANT).rel
if HAS_NETWORKING
##
endif
noinst_LIBRARIES += libbsp_g.a
libbsp_g_a_SOURCES = $(libbsp_a_SOURCES)
libbsp_g_a_LIBADD = $(libbsp_a_LIBADD)
all-local: $(PREINSTALL_FILES) $(TMPINSTALL_FILES)
PREINSTALL_DIRS =
PREINSTALL_FILES =
TMPINSTALL_FILES =
$(PROJECT_INCLUDE)/$(dirstamp):
@$(mkdir_p) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
$(PROJECT_LIB)/$(dirstamp):
@$(mkdir_p) $(PROJECT_LIB)
@: > $(PROJECT_LIB)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp)
$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
$(PROJECT_INCLUDE)/arm_mode_bits.h: include/arm_mode_bits.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/arm_mode_bits.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/arm_mode_bits.h
$(PROJECT_INCLUDE)/asm_macros.h: include/asm_macros.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/asm_macros.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/asm_macros.h
$(PROJECT_INCLUDE)/gba_registers.h: include/gba_registers.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/gba_registers.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/gba_registers.h
$(PROJECT_INCLUDE)/conio.h: include/conio.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/conio.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/conio.h
$(PROJECT_INCLUDE)/tm27.h: include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tm27.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h
$(PROJECT_INCLUDE)/gba.h: include/gba.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/gba.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/gba.h
$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bspopts.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h
$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/coverhd.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h
$(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT): start$(LIB_VARIANT).$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT)
TMPINSTALL_FILES += $(PROJECT_LIB)/start$(LIB_VARIANT).$(OBJEXT)
$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds
PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds
$(PROJECT_INCLUDE)/irq.h: irq/irq.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/irq.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/irq.h
CLEANFILES = $(PREINSTALL_FILES)
DISTCLEANFILES += $(PREINSTALL_DIRS)
CLEANFILES += $(TMPINSTALL_FILES)
include $(top_srcdir)/../../../../automake/local.am
+7
View File
@@ -0,0 +1,7 @@
#
# $Id$
#
This is the BSP for Nintendo's GBA and GBA SP. The RTEMS Wiki
has more detailed information on this BSP.
+26
View File
@@ -0,0 +1,26 @@
%rename cpp old_cpp
%rename lib old_lib
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*cpp:
%(old_cpp) %{qrtems: -D__embedded__ -D__USE_INIT_FINI__} -Asystem(embedded)
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group \
%{!qrtems_debug: -lrtemsbsp -lrtemscpu} %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
-lc -lgcc --end-group \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:
%{!qrtems: %(old_startfile)} %{!nostdlib: %{qrtems: \
%{!qrtems_debug: start.o%s crti.o%s crtbegin.o%s} \
%{qrtems_debug: start_g.o%s crti.o%s crtbegin.o%s}}}
*link:
%{!qrtems: %(old_link)} %{qrtems: -Qy -dc -dp -Bstatic -N -e _start}
*endfile:
%{!qrtems: *(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s }
+130
View File
@@ -0,0 +1,130 @@
/**
* @file clockdrv.c
*
* Game Boy Advance Clock driver.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <irq.h>
#include <gba.h>
/*-------------------------------------------------------------------------+
| Clock isr variables
+--------------------------------------------------------------------------*/
rtems_isr Clock_isr(rtems_vector_number vector);
static void clock_isr_on(const rtems_irq_connect_data *unused);
static void clock_isr_off(const rtems_irq_connect_data *unused);
static int clock_isr_is_on(const rtems_irq_connect_data *irq);
rtems_irq_connect_data clock_isr_data = {BSP_IRQ_TIMER3,
(rtems_irq_hdl)Clock_isr,
clock_isr_on,
clock_isr_off,
clock_isr_is_on,
0,
0 };
#define CLOCK_VECTOR 0
#define Clock_driver_support_at_tick()
#define Clock_driver_support_install_isr( _new, _old ) \
do { \
BSP_install_rtems_irq_handler(&clock_isr_data); \
} while(0)
#define Clock_driver_support_shutdown_hardware() \
do { \
BSP_remove_rtems_irq_handler(&clock_isr_data); \
} while (0)
/*-------------------------------------------------------------------------+
| Calculate Tick Times
| 1 / 16.78Mhz => 59.595 ns
| 64 / 16.78Mhz => 3.814 us
| 256 / 16.78Mhz => 15.256 us
| 1024 / 16.78Mhz => 61.025 us
+--------------------------------------------------------------------------*/
#define __TimTickTime_us ((1000000L/__ClockFrequency)*__TimPreScaler)
#define __TimTickTime_ns ((1000000000L/__ClockFrequency)*__TimPreScaler)
#if (__TimPreScaler==1)
#define GBA_TMCNT_PS 0x0000
#elif (__TimPreScaler==64)
#define GBA_TMCNT_PS 0x0001
#elif (__TimPreScaler==256)
#define GBA_TMCNT_PS 0x0002
#elif (__TimPreScaler==1024)
#define GBA_TMCNT_PS 0x0003
#else
#define GBA_TMCNT_PS 0x0003
#endif
extern rtems_configuration_table BSP_Configuration;
/**
* @brief This function set up the clock hardware
*
* @param None
* @return None
*/
void Clock_driver_support_initialize_hardware()
{
int tmreload = ((BSP_Configuration.microseconds_per_tick*1000)/__TimTickTime_ns);
if (tmreload>0xFFFF) tmreload = 0xFFFF;
GBA_REG_TM3CNT = (GBA_TMCNT_PS);
GBA_REG_TM3D = (0x0000-tmreload);
GBA_REG_TM3CNT = (0x00c0|GBA_TMCNT_PS);
}
/**
* @brief This function is empty
*
* @param unused an unused parameter
* @return None
*/
static void clock_isr_on(const rtems_irq_connect_data *unused)
{
return;
}
/**
* @brief This function is empty
*
* @param unused an unused parameter
* @return None
*/
static void clock_isr_off(const rtems_irq_connect_data *unused)
{
return;
}
/**
* @brief This function is empty
*
* @param irq unused
* @return constant 1
*/
static int clock_isr_is_on(const rtems_irq_connect_data *irq)
{
return 1;
}
#include "../../../shared/clockdrv_shell.c"
+23
View File
@@ -0,0 +1,23 @@
## Process this file with autoconf to produce a configure script.
##
## $Id$
AC_PREREQ(2.59)
AC_INIT([rtems-c-src-lib-libbsp-arm-gba],[_RTEMS_VERSION],[rtems-bugs@rtems.com])
AC_CONFIG_SRCDIR([bsp_specs])
RTEMS_TOP(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.9])
RTEMS_BSP_CONFIGURE
RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm])
RTEMS_CANONICALIZE_TOOLS
RTEMS_PROG_CCAS
RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
+428
View File
@@ -0,0 +1,428 @@
/**
* @file conio.c
*
* This file contains the GBA conio I/O package.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
* based on MyLib by Rafael Vuijk (aka Dark Fader)
*
* The license and distribution terms for this file may be
* found in 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 Rafael Vuijk (aka Dark Fader)
*****************************************************************************
*****************************************************************************
* MyLib by Rafael Vuijk (aka Dark Fader)
* :
* This file is released into the public domain for commercial
* or non-commercial usage with no restrictions placed upon it.
*****************************************************************************/
/*---------------------------------------------------------------------------*
* Includes *
*---------------------------------------------------------------------------*/
#include <stdint.h>
#include <rtems/score/types.h>
#include <gba.h>
#include <conio.h>
#include <stdio.h>
#include <stdarg.h>
/*---------------------------------------------------------------------------*
* Defines *
*---------------------------------------------------------------------------*/
#define W 60 /**< Screen width */
#define H 26 /**< Screen height */
#define CLRSCR_SIZE (W*4 * H*6) /**< Screen size */
#define DEFAULT_FONT_WIDTH 4 /**< Font width */
#define DEFAULT_FONT_HEIGHT 6 /**< Font height */
typedef unsigned short Palette[256]; /**< 256 colors */
typedef unsigned short Palettes[16][16]; /**< 16 palettes with each 16 colors */
typedef unsigned short Bitmap3[GBA_LCD_HEIGHT][GBA_LCD_WIDTH]; /**< 16 bits, single buffered */
typedef unsigned char Bitmap4[GBA_LCD_HEIGHT][GBA_LCD_WIDTH]; /**< 8 bits, double buffered */
typedef unsigned short Bitmap5[GBA_MODE5_HEIGHT][GBA_MODE5_WIDTH];/**< double buffered */
#define VRAM GBA_VRAM_ADDR /**< VRAM address */
#define VRAM_END (VRAM + 0x18000) /**< VRAM end */
#define BG_BITMAP0_VRAM (VRAM + 0x0) /**< BG Bitmap 0 RAM */
#define BG_BITMAP1_VRAM (VRAM + 0xa000) /**< BG Bitmap 1 RAM */
#define bg_bitmap0 (*(Bitmap4 *)BG_BITMAP0_VRAM)
#define bg_bitmap1 (*(Bitmap4 *)BG_BITMAP1_VRAM)
#define bg_bitmap3 (*(Bitmap3 *)BG_BITMAP0_VRAM)
#define bg_bitmap4a (*(Bitmap4 *)BG_BITMAP0_VRAM)
#define bg_bitmap4b (*(Bitmap4 *)BG_BITMAP1_VRAM)
#define bg_bitmap5a (*(Bitmap5 *)BG_BITMAP0_VRAM)
#define bg_bitmap5b (*(Bitmap5 *)BG_BITMAP1_VRAM)
/** Color conversion macro */
#define RGB(r,g,b) ( (r)<<0 | (g)<<5 | (b)<<10 )
/** BG Affine Transformation Destination Data Structure */
typedef struct {
int16_t H_DiffX; /**< Line Direction X Coordinate Difference */
int16_t V_DiffX; /**< Vertical Direction X Coordinate Difference */
int16_t H_DiffY; /**< Line Direction Y Coordinate Difference */
int16_t V_DiffY; /**< Vertical Direction Y Coordinate Difference */
int32_t StartX; /**< Start X Coordinate */
int32_t StartY; /**< Start Y Coordinate */
} BgAffineDestData;
typedef volatile BgAffineDestData vBgAffineDestData;
#define rBg2Affine (*(vBgAffineDestData *)0x4000020)
/** 256 colors for background(s) */
#define bg_palette (*(Palette *)(GBA_PAL_RAM_ADDR))
int _wherex; /**< Screen X coordinate */
int _wherey; /**< Screen Y coordinate */
int _textattr; /**< Text attribute */
/*---------------------------------------------------------------------------*
* Defaultfont *
*---------------------------------------------------------------------------*/
#include "defaultfont.c"
/**
* @brief gba_gotoxy function set screeen xy-coordinates
*
* @param _x screen x coordinate
* @param _y screen y coordinate
* @return None
*/
void gba_gotoxy(int _x, int _y)
{
_wherex = _x;
_wherey = _y;
}
/**
* @brief gba_putchar function writes char-data to screen memory.
*
* Char code is index to font table.
*
* Input parameters: char, attribute and cordinates
* @param c character code
* @param textattr text attribute
* @param x screen x coordinate
* @param y screen y coordinate
* @return None
*/
void gba_putchar(char c, int textattr, int x, int y)
{
int f = textattr & 0x0F;
int b = textattr >> 4;
uint32_t fmask = f | f<<8 | f<<16 | f<<24;
uint32_t bmask = b | b<<8 | b<<16 | b<<24;
uint32_t *dest = (uint32_t *)&bg_bitmap4a[((y<<1) + y) << 1][x<<2];
const uint32_t *src = (uint32_t *)&(font3x5[(int)c]);
uint32_t s;
s = *src++; *dest = (fmask&s) | (bmask&~s); dest += GBA_LCD_WIDTH/sizeof(uint32_t);
s = *src++; *dest = (fmask&s) | (bmask&~s); dest += GBA_LCD_WIDTH/sizeof(uint32_t);
s = *src++; *dest = (fmask&s) | (bmask&~s); dest += GBA_LCD_WIDTH/sizeof(uint32_t);
s = *src++; *dest = (fmask&s) | (bmask&~s); dest += GBA_LCD_WIDTH/sizeof(uint32_t);
s = *src++; *dest = (fmask&s) | (bmask&~s); dest += GBA_LCD_WIDTH/sizeof(uint32_t);
s = *src++; *dest = (fmask&s) | (bmask&~s); dest += GBA_LCD_WIDTH/sizeof(uint32_t);
}
/**
* @brief gba_textattr function set textattribute
*
* @param _attr text attribute
* @return None
*/
void gba_textattr(int _attr)
{
_textattr = _attr;
}
/**
* @brief gba_textbackground function set text background color
*
* @param _color backround color
* @return None
*/
void gba_textbackground(int _color)
{
_textattr = (_textattr & 0x0F) | (_color << 4);
}
/**
* @brief gba_textcolor function set text color
*
* @param _colour text color
* @return None
*/
void gba_textcolor(int _color)
{
_textattr = (_textattr & 0xF0) | (_color);
}
/**
* @brief gba_clearline function clear line nro y
*
* Line is filled with spaces
*
* @param y line number
* @return None
*/
void gba_clearline(int y)
{
int x;
for (x=0 ; x<=W ; x++) {
gba_putchar(0, _textattr, x, y);
}
}
/**
* @brief gba_nextline function moves cursor to next line and clears it
*
* @param None
* @return None
*/
void gba_nextline(void)
{
_wherex = 0;
if (++_wherey >= H) {
_wherey = 0;
}
gba_clearline(_wherey);
}
/**
* @brief gba_clrscr function clear screen
*
* @param None
* @return None
*/
void gba_clrscr(void)
{
int y;
for (y=0 ; y<=H ; y++) {
gba_clearline(y);
}
gba_gotoxy(0,0);
}
/**
* @brief gba_put function convert ascii char to font index and
* write char to screen memory
*
* @param _c character code
* @return None
*/
void gba_put(char _c)
{
/* We have save some memory with reduced fonts */
_c = _c & 0x7F; /* no extened chars */
_c = _c - 0x20; /* no cntr chars */
gba_putchar(_c, _textattr, _wherex, _wherey);
}
/**
* @brief gba_putch function write ascii chars to screen
*
* @param _c character code
* @return None
*/
void gba_putch(char _c)
{
switch (_c) {
case ASCII_LF:
gba_nextline();
break;
case ASCII_CR:
gba_gotoxy(0, _wherey);
break;
default:
gba_put(_c);
if (++_wherex >= W)
{
gba_nextline();
}
break;
}
return;
}
/**
* @brief gba_puts function write ascii string to screen
*
* @param _str ASCII string
* @return None
*/
void gba_puts(const char *_str)
{
while (*_str) {
gba_putch(*_str++);
}
return;
}
/**
* @brief gba_printf function do formated printf
*
* @param _format printf format string
* @param ... parameters specified in format string
* @return None
*/
int gba_printf(const char *_format, ...)
{
char s[256];
va_list marker;
va_start(marker, _format);
int r = vsprintf(s, _format, marker);
va_end(marker);
gba_puts(s);
return r;
}
/**
* @brief gba_initconio function initialize console
*
* @param None
* @return None
*/
void gba_initconio(void)
{
GBA_REG_DISPCNT = GBA_DISP_MODE_4 | GBA_DISP_BG2_ON;/* 256 color bitmapped mode */
const BgAffineDestData bgAffineReset = {256,0,0,256,0,-256*2};
rBg2Affine = bgAffineReset;
bg_palette[BLACK ] = RGB( 0, 0, 0); /* BLACK */
bg_palette[BLUE ] = RGB( 0, 0,16); /* BLUE */
bg_palette[GREEN ] = RGB( 0,16, 0); /* GREEN */
bg_palette[CYAN ] = RGB( 0,16,16); /* CYAN */
bg_palette[RED ] = RGB(16, 0, 0); /* RED */
bg_palette[MAGENTA ] = RGB(16, 0,16); /* MAGENTA */
bg_palette[BROWN ] = RGB(16,16, 0); /* BROWN */
bg_palette[LIGHTGRAY ] = RGB(24,24,24); /* LIGHTGRAY */
bg_palette[DARKGRAY ] = RGB(16,16,16); /* DARKGRAY */
bg_palette[LIGHTBLUE ] = RGB( 0, 0,31); /* LIGHTBLUE */
bg_palette[LIGHTGREEN ] = RGB( 0,31, 0); /* LIGHTGREEN */
bg_palette[LIGHTCYAN ] = RGB( 0,31,31); /* LIGHTCYAN */
bg_palette[LIGHTRED ] = RGB(31, 0, 0); /* LIGHTRED */
bg_palette[LIGHTMAGENTA] = RGB(31, 0,31); /* LIGHTMAGENTA */
bg_palette[YELLOW ] = RGB(31,31, 0); /* YELLOW */
bg_palette[WHITE ] = RGB(31,31,31); /* WHITE */
gba_textattr(0);
gba_textcolor(DEF_TEXTCOLOR);
gba_textbackground(DEF_TEXTBACKGROUND);
gba_clrscr();
}
/**
* @brief gba_textmode function set console mode
*
* @param _mode console mode code
* @return None
*/
void gba_textmode(int _mode)
{
switch (_mode) {
case CO60:
{
gba_initconio();
break;
}
}
}
/**
* @brief delay_loop function is simple delay loop
*
* @param count loop counter
* @return None
*/
void delay_loop(unsigned int count)
{
int i;
for (i = 0; i<count; i++) i = i;
}
static unsigned char inputch = ASCII_CR; /**< input character value */
/**
* @brief gba_getch function read char from game pad keys
*
* Character input is done with GBA buttons, up-down-left-right/A/B/R/L/Select/Start
* - Select-key accept selected character
* - Start-key read CR (Enter)
* - A-key select 'A' character
* - B-key select 'Z' character
* - R-key select '1' character
* - L-key select '9' character
* - up-key increment character ('A'->'B')
* - down-key decrement character ('B'-'A')
* - left-key change set of character ('!'->'A'->'a')
* - right-key change set of character ('a'->'A'->'!')
*
* @param None
* @return Selected char code
*/
char gba_getch(void)
{
int keyx, key = 0;
while(1) {
key = GBA_KEY();
while ( (keyx=GBA_KEY())==key );
switch (key)
{
case GBA_KEY_SELECT:
gba_put(inputch);
return inputch;
break;
case GBA_KEY_START:
gba_put(' ');
inputch = ASCII_CR;
return inputch;
break;
case GBA_KEY_A:
inputch = 'A';
break;
case GBA_KEY_B:
inputch = 'Z';
break;
case GBA_KEY_UP:
if ((inputch-1) >= 0x20) inputch--;
break;
case GBA_KEY_DOWN:
if ((inputch+1) <= 0x7E) inputch++;
break;
case GBA_KEY_LEFT:
if ((inputch - 0x20) >= 0x20) inputch -= 0x20;
break;
case GBA_KEY_RIGHT:
if ((inputch + 0x20) <= 0x7E) inputch += 0x20;
break;
case GBA_KEY_R:
inputch = '1';
break;
case GBA_KEY_L:
inputch = '9';
break;
default:
break;
}
gba_put(inputch);
delay_loop(1000);
}
}
+286
View File
@@ -0,0 +1,286 @@
/**
* @file console.c
*
* This file contains the GBA console I/O package.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <rtems/termiostypes.h>
#include <termios.h>
#include <irq.h>
#include <gba.h>
#include <conio.h>
#undef __assert
void __assert (const char *file, int line, const char *msg);
extern void rtemsReboot(void);
/**
* @brief gba_pollRead function read char
*
* @param minor unused
* @return character code
*/
static int gba_pollRead(int minor)
{
return(gba_getch());
}
/**
* @brief gba_write function writes chars
*
* Input parameters: minor code, buffer pointer and lenght
* @param minor unused
* @param *buf buffer pointer
* @param len lenght of buffer
* @return character code
*
*/
static int gba_write(int minor, const char *buf, int len)
{
int i;
for (i=0;i<len;i++) {
gba_putch((unsigned short)buf[i]);
}
return len;
}
/**
* @brief gba_setAttributes function is empty
*
* @param minor unused
* @param *t unused
* @return constant 0
*/
static int gba_setAttributes(int minor, const struct termios *t)
{
return 0;
}
/** BSP_output_char for printk support */
BSP_output_char_function_type BSP_output_char = (BSP_output_char_function_type) gba_putch;
/** BSP_poll_char for printk support */
BSP_polling_getchar_function_type BSP_poll_char = (BSP_polling_getchar_function_type) gba_getch;
/**
* @brief assert function
*
* @param *file file name
* @param line line number
* @param *msg assert message
* @return None
*/
void __assert (const char *file, int line, const char *msg)
{
static const char exit_msg[] = "EXECUTIVE SHUTDOWN! Any button to reboot...";
/*
* Note we cannot call exit or printf from here,
* assert can fail inside ISR too
*/
close(2); /* Close console */
close(1);
close(0);
printk("\nassert failed: %s: ", file);
printk("%d: ", line);
printk("%s\n\n", msg);
printk("%s",exit_msg);
while ( !GBA_ANY_KEY(GBA_KEY_ALL) );
printk("\n\n");
rtemsReboot();
}
/**
* @brief Console device driver INITIALIZE entry point
*
* Initilizes the I/O console driver.
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
rtems_device_driver
console_initialize(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
/* Set up TERMIOS */
rtems_termios_initialize ();
/* Do device-specific initialization */
/* Allready done in bspstart.c -> gba_textmode(CO60); */
/* Register the device */
status = rtems_io_register_name ("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL) {
printk("Error registering console device!\n");
rtems_fatal_error_occurred (status);
}
printk("Initialized GBA console\n\n");
return RTEMS_SUCCESSFUL;
}
/**
* @brief console_first_open function is empty
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
static int console_first_open(int major, int minor, void *arg)
{
return 0;
}
/**
* @brief console_last_close function is empty
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
static int console_last_close(int major, int minor, void *arg)
{
return 0;
}
/**
* @brief Console device driver OPEN entry point
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
rtems_device_driver
console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_status_code status;
static rtems_termios_callbacks cb =
{
console_first_open, /* firstOpen */
console_last_close, /* lastClose */
gba_pollRead, /* pollRead */
gba_write, /* write */
gba_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
TERMIOS_POLLED /* 1 = outputUsesInterrupts */
};
status = rtems_termios_open (major, minor, arg, &cb);
if (status != RTEMS_SUCCESSFUL) {
printk("Error openning console device\n");
return status;
}
return RTEMS_SUCCESSFUL;
}
/**
* @brief Console device driver CLOSE entry point
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
rtems_device_driver
console_close(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
rtems_device_driver res = RTEMS_SUCCESSFUL;
res = rtems_termios_close (arg);
return res;
}
/**
* @brief Console device driver READ entry point.
*
* Read characters from the I/O console.
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
rtems_device_driver
console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return rtems_termios_read (arg);
}
/**
* @brief Console device driver WRITE entry point.
*
* Write characters to the I/O console.
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
rtems_device_driver
console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return rtems_termios_write (arg);
}
/**
* @brief Handle ioctl request.
*
* @param major diver major number
* @param minor driver minor mumber
* @param *arg pointer to parameters
* @return status code
*/
rtems_device_driver
console_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_ioctl (arg);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
/**
* @file arm_mode_bits.h
*
* ARM statusregister mode bits.
*
* This include file contains definitions related to the ARM BSP.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef __ARMMODEBITS_H
#define __ARMMODEBITS_H
/*-----------------------------------------------------------------------------
* Definitions
----------------------------------------------------------------------------*/
#define Mode_USR 0x10
#define Mode_FIQ 0x11
#define Mode_IRQ 0x12
#define Mode_SVC 0x13
#define Mode_ABT 0x17
#define Mode_ABORT 0x17
#define Mode_UNDEF 0x1B
#define Mode_SYS 0x1F /**< only available on ARM Arch v4 */
#define Mode_Bits 0x1F /**< mask for mode bits */
#define ModePriv Mode_SVC /**< used supervisor mode */
#define I_Bit 0x80
#define F_Bit 0x40
#define Int_Bits 0xC0
#define Mode_SVC_MIRQ (Mode_SVC | I_Bit | F_Bit)
#define Mode_SVC_UIRQ (Mode_SVC)
#define Mode_IRQ_MIRQ (Mode_SVC | I_Bit | F_Bit)
#define Mode_IRQ_UIRQ (Mode_SVC)
#endif // __ARMMODEBITS_H
@@ -0,0 +1,54 @@
/**
* @file asm_macros.h
*
* This include file contains definitions related to the GBA BSP.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
/*-----------------------------------------------------------------------------*
* Macros
*-----------------------------------------------------------------------------*/
#ifdef __asm__
#define PUBLIC_ARM_FUNCTION(label) .global label ; \
.type label, function ; \
.arm ; \
label:
#define PUBLIC_THUMB_FUNCTION(label) .global label ; \
.type label, function ; \
.thumb_func ; \
label:
#define STATIC_ARM_FUNCTION(label) .type label, function ; \
.arm ; \
label:
#define STATIC_THUMB_FUNCTION(label) .type label, function ; \
.thumb_func ; \
label:
#define OBJECT(label) .global label ; \
.type label, object ; \
label:
#define STATIC_OBJECT(label) .type label, object ; \
label:
#define WEAK_OBJECT(label) .weak label ; \
.type label, object ; \
label:
#define LABEL_END(label) .L##label##_end: ; \
.size label, .L##label##_end - label
#endif
+67
View File
@@ -0,0 +1,67 @@
/**
* @file bsp.h
*
* This include file contains definitions related to the GBA BSP.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004
* Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef __BSP_H_
#define __BSP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <bspopts.h>
#include <rtems.h>
#include <rtems/iosupp.h>
#include <rtems/console.h>
#include <rtems/clockdrv.h>
#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 1
/** Define operation count for Tests */
#define OPERATION_COUNT 10
/**
* Simple spin delay in microsecond units for device drivers.
* This is very dependent on the clock speed of the target.
*/
#define rtems_bsp_delay( microseconds ) \
{ \
uint32_t i; \
for(i = 0; i<microseconds;) {i++;} \
uint32_t _cnt = _microseconds; \
asm volatile ("0: nop; sub %0, %0, #1; cmp %0,#0; bne 0b" : "=c"(_cnt) : "0"(_cnt)); \
}
/** Our copy of BSP configuration table from the application. */
extern rtems_configuration_table BSP_Configuration;
/** gba_zero_memory library function in start.S */
extern void gba_zero_memory(int start, int stop);
/** gba_move_memory library function in start.S */
extern void gba_move_memory(int from, int toStart, int toEnd);
/** gba_set_memory library function in start.S */
extern void gba_set_memory(int start, int stop, int data);
#ifdef __cplusplus
}
#endif
#endif /* __BSP_H_ */
@@ -0,0 +1,16 @@
/* include/bspopts.h.in. Generated from configure.ac by autoheader. */
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
+92
View File
@@ -0,0 +1,92 @@
/**
* @file conio.h
*
* This file contains the GBA conio I/O package.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _CONIO_H
#define _CONIO_H
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------*
* Includes *
*---------------------------------------------------------------------------*/
#include <gba.h>
/*---------------------------------------------------------------------------*
* Defines *
*---------------------------------------------------------------------------*/
#define ASCII_BEL 0x07 /**< bell */
#define ASCII_BS 0x08 /**< backspace */
#define ASCII_TAB 0x09 /**< horizontal tab */
#define ASCII_LF 0x0A /**< line feed */
#define ASCII_CR 0x0D /**< carriage return */
#define ASCII_XON 0x11 /**< control-Q */
#define ASCII_XOFF 0x13 /**< control-S */
#define ASCII_ESC 0x1B /**< escape */
enum TEXT_MODES
{
CO60 = 0, /**< 60x26 (3x5 font) */
MAXMODES
};
enum COLORS
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE,
MAXCOLORS
};
#define DEF_TEXTCOLOR BLACK
#define DEF_TEXTBACKGROUND WHITE
/*---------------------------------------------------------------------------*
* Prototypes *
*---------------------------------------------------------------------------*/
void gba_textmode(int _mode);
void gba_clrscr(void);
void gba_textattr(int _attr);
void gba_textbackground(int _color);
void gba_textcolor(int _color);
void gba_putch(char _c);
void gba_puts(const char *_str);
int gba_printf(const char *_format, ...);
void gba_gotoxy(int _x, int _y);
char gba_getch(void);
#ifdef __cplusplus
}
#endif
#endif /* _CONIO_H */
+106
View File
@@ -0,0 +1,106 @@
/**
* @file gba.h
*
* This include file contains definitions related to the ARM BSP.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _GBA_H
#define _GBA_H
#ifdef __cplusplus
extern "C" {
#endif
#include <gba_registers.h>
/*---------------------------------------------------------------------------*
* Clock *
*---------------------------------------------------------------------------*/
#define __ClockFrequency 16780000L /**< ClockFreguency in Hz */
#define __TimPreScaler 1024L /**< Prescaler value 1,64,256,1024 */
/*---------------------------------------------------------------------------*
* Activation defines *
*---------------------------------------------------------------------------*/
/**
* Multiboot/Cart boot Selection.
*
* If the variable __gba_multiboot is defined
* (probably should be in your main project file) then code
* is generated which will run as a multiboot image (code starts
* at 0x02000000) or as a normal flash cart / emulator image.
* (i.e. start.S copies code from ROM to EWRAM if started in cart
* or emulator.) If this variable is not defined then code is
* generated for flash cart / emulator only operation (code starts
* at 0x08000000).
*/
#define MULTIBOOT volatile const unsigned short __gba_multiboot;
/**
* IWRAM/EWRAM data Selection.
*
* If the variable __gba_iwram_data is defined
* (probably should be in your main project file) then code
* is generated which will allocate data section in IWRAM
* (data starts at 0x03000080).
* If this variable is not defined then data sections is
* allocated in EWRAM (data starts at 0x02000000).
*/
#define IWRAMDATA volatile const unsigned short __gba_iwram_data;
/**
* IWRAM/EWRAM bss Selection.
*
* If the variable __gba_iwram_bss is defined
* (probably should be in your main project file) then code
* is generated which will allocate bss section in IWRAM
* (data starts at 0x03000080).
* If this variable is not defined then bss sections is
* allocated in EWRAM (data starts at 0x02000000).
*/
#define IWRAMBSS volatile const unsigned short __gba_iwram_bss;
/*---------------------------------------------------------------------------*
* Attributes *
*---------------------------------------------------------------------------*/
#define CODE_IN_ROM __attribute__ ((section (".text"), long_call))
#define CODE_IN_IWRAM __attribute__ ((section (".iwram"), long_call))
#define IN_IWRAM __attribute__ ((section (".iwram")))
#define IN_EWRAM __attribute__ ((section (".ewram")))
/*---------------------------------------------------------------------------*
* Console Keypad *
*---------------------------------------------------------------------------*/
#define OK_KEY (0==0) /**< TRUE */
#define NO_KEY (0==1) /**< FALSE */
#define GBA_KEYS_PRESSED(keys) (( ((~GBA_REG_P1) & (keys)) == (keys)) ? (OK_KEY) : (NO_KEY))
#define GBA_ANY_KEY(keys) (( ((~GBA_REG_P1) & (keys)) != 0) ? (OK_KEY) : (NO_KEY))
#define GBA_KEY() ((~GBA_REG_P1)&GBA_KEY_ALL)
/*---------------------------------------------------------------------------*
* Console Screen *
*---------------------------------------------------------------------------*/
#define GBA_LCD_WIDTH 240
#define GBA_LCD_HEIGHT 160
#define GBA_MODE5_WIDTH 160
#define GBA_MODE5_HEIGHT 128
#define GBA_LCD_ASPECT ((float)(GBA_LCD_WIDTH / GBA_LCD_HEIGHT))
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
+35
View File
@@ -0,0 +1,35 @@
/**
* @file tm27.h
*
* This include file contains definitions related to Time Test 27.
*/
/*
* 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$
*/
#ifndef _RTEMS_TMTEST27
#error "This is an RTEMS internal file you must not include directly."
#endif
#ifndef __tm27_h
#define __tm27_h
/**
* Define the interrupt mechanism for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) /* empty */
#define Cause_tm27_intr() /* empty */
#define Clear_tm27_intr() /* empty */
#define Lower_tm27_intr() /* empty */
#endif
+179
View File
@@ -0,0 +1,179 @@
/**
* @file bsp_irq_asm.S
*
* Intererrupt handler for GameBoy Advance.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#define __asm__
#include <asm_macros.h>
#include <gba_registers.h>
#include <arm_mode_bits.h>
/* @cond INCLUDE_ASM */
/**
* Execute interrupt handler
* function void ExecuteITHandler(void)
*
* Look at interrupt status register to determine source.
* From source, determine offset into expanded vector table
* and load handler address into r0.
* irq_vector_table is defined in linkcmds
*
*/
.align
/* .section .iwram */
PUBLIC_ARM_FUNCTION(ExecuteITHandler)
ldr r1, =GBA_REG_IE_ADDR
ldrh r1, [r1]
ldr r2, =GBA_REG_IF_ADDR
ldrh r2, [r2]
and r3, r1, r2 /* only look at interrupts which are enabled */
check_lcdv:
tst r3, #0x0001
beq check_lcdh
ldr r0, =(irq_vector_table + (4 * 0)) /* load the vector number */
ldr r3,=0x0001
b get_handler
check_lcdh:
tst r3, #0x0002
beq check_lcdvc
ldr r0, =(irq_vector_table + (4 * 1)) /* load the vector number */
ldr r3,=0x0002
b get_handler
check_lcdvc:
tst r3, #0x0004
beq check_t0
ldr r0, =(irq_vector_table + (4 * 2)) /* load the vector number */
ldr r3,=0x0004
b get_handler
check_t0:
tst r3, #0x0008
beq check_t1
ldr r0, =(irq_vector_table + (4 * 3)) /* load the vector number */
ldr r3,=0x0008
b get_handler
check_t1:
tst r3, #0x0010
beq check_t2
ldr r0, =(irq_vector_table + (4 * 4)) /* load the vector number */
ldr r3,=0x0010
b get_handler
check_t2:
tst r3, #0x0020
beq check_t3
ldr r0, =(irq_vector_table + (4 * 5)) /* load the vector number */
ldr r3,=0x0020
b get_handler
check_t3:
tst r3, #0x0040
beq check_ser
ldr r0, =(irq_vector_table + (4 * 6)) /* load the vector number */
ldr r3,=0x0040
b get_handler
check_ser:
tst r3, #0x0080
beq check_dma0
ldr r0, =(irq_vector_table + (4 * 7)) /* load the vector number */
ldr r3,=0x0080
b get_handler
check_dma0:
tst r3, #0x0100
beq check_dma1
ldr r0, =(irq_vector_table + (4 * 8)) /* load the vector number */
ldr r3,=0x0100
b get_handler
check_dma1:
tst r3, #0x0200
beq check_dma2
ldr r0, =(irq_vector_table + (4 * 9)) /* load the vector number */
ldr r3,=0x0200
b get_handler
check_dma2:
tst r3, #0x0400
beq check_dma3
ldr r0, =(irq_vector_table + (4 * 10)) /* load the vector number */
ldr r3,=0x0400
b get_handler
check_dma3:
tst r3, #0x0800
beq check_keypad
ldr r0, =(irq_vector_table + (4 * 11)) /* load the vector number */
ldr r3,=0x0800
b get_handler
check_keypad:
tst r3, #0x1000
beq check_gamepak
ldr r0, =(irq_vector_table + (4 * 12)) /* load the vector number */
ldr r3,=0x1000
b get_handler
check_gamepak:
tst r3, #0x2000
beq IRQ_NoInterrupt
ldr r0, =(irq_vector_table + (4 * 13)) /* load the vector number */
ldr r3,=0x2000
b get_handler
unknown_irq:
ldr r0, =(default_int_handler) /* Unknown Interrupt? */
ldr r3,=0x0000
get_handler:
ldr r0, [r0] /* extract the IT handler */
ldr r2, =GBA_REG_IF_ADDR /* Clear IF */
strh r3, [r2]
/*
* re-enable interrupts at processor level
*/
mrs r1, cpsr
bic r1, r1, #Int_Bits
msr cpsr, r1
stmdb sp!,{lr}
ldr lr, =IRQ_return /* prepare the return from handler */
mov pc, r0 /* EXECUTE INT HANDLER */
IRQ_return:
ldmia sp!,{lr}
/*
* disable interrupts_again
*/
mrs r0, cpsr
orr r0, r0, #Int_Bits
msr cpsr, r0
IRQ_NoInterrupt:
/* return to the "main" interrupt handler */
mov pc, lr
LABEL_END(ExecuteITHandler)
/* @endcond */
@@ -0,0 +1,38 @@
/**
* @file bsp_irq_init.c
*
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <irq.h>
#include <bsp.h>
#include <gba_registers.h>
/**
* @brief BSP_rtems_irq_mngt_init BSP routine initialize irq registers
*
* @param None
* @return None
*/
void BSP_rtems_irq_mngt_init(void)
{
/* clear all interrupt status flags */
GBA_REG_IF = 0xffff;
/* disable all interrupts */
GBA_REG_IE = 0;
/* set master interrupt enable */
GBA_REG_IME = 1;
}
+161
View File
@@ -0,0 +1,161 @@
/**
* @file irq.c
*
* This file contains the implementation of the function described in irq.h.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
*
* Copyright (c) 2002 by Charlie Steader <charlies@poliac.com>
*
* Copyright (c) 2004 by Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <bsp.h>
#include <irq.h>
#include <gba_registers.h>
#include <rtems/score/thread.h>
#include <rtems/score/apiext.h>
/**
* @brief isValidInterrupt function check that the value given for the irq line is valid.
*
* @param irq irq number
* @return status code TRUE/FALSE (0/1)
*/
static int isValidInterrupt(int irq)
{
if ( (irq < 0) || (irq > BSP_MAX_INT)) {
return 0;
}
return 1;
}
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
/**
* @brief BSP_install_rtems_irq_handler function install rtems irq handler.
*
* @param irq irq connect data
* @return status code TRUE/FALSE (0/1)
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_irq_hdl *HdlTable;
rtems_interrupt_level level;
if (!isValidInterrupt(irq->name)) {
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
*/
HdlTable = (rtems_irq_hdl *) (unsigned32)VECTOR_TABLE;
if (*(HdlTable + irq->name) != default_int_handler) {
return 0;
}
_CPU_ISR_Disable(level);
/*
* store the new handler
*/
*(HdlTable + irq->name) = irq->hdl;
/*
* ack pending interrupt
*/
GBA_REG_IF |= (1 << (irq->name));
/*
* initialize the control register for the concerned interrupt
*/
GBA_REG_IE |= (1 << (irq->name));
/*
* Enable interrupt on device
*/
irq->on(irq);
_CPU_ISR_Enable(level);
return 1;
}
/**
* @brief BSP_remove_rtems_irq_handler function removes rtems irq handler.
*
* @param irq irq connect data
* @return status code TRUE/FALSE (0/1)
*/
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_irq_hdl *HdlTable;
rtems_interrupt_level level;
if (!isValidInterrupt(irq->name)) {
return 0;
}
/*
* Check if the handler is actually connected. If not issue an error.
*/
HdlTable = (rtems_irq_hdl *) (unsigned32)VECTOR_TABLE;
if (*(HdlTable + irq->name) != irq->hdl) {
return 0;
}
_CPU_ISR_Disable(level);
/*
* mask at INT controller level
*/
GBA_REG_IE &= ~(1 << irq->name);
/*
* Disable interrupt on device
*/
irq->off(irq);
/*
* restore the default irq value
*/
*(HdlTable + irq->name) = default_int_handler;
_CPU_ISR_Enable(level);
return 1;
}
/**
* @brief _ThreadProcessSignalsFromIrq function check that the value given for the irq line is valid.
*
* @param cxt exeption frame
* @return None
*/
void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx)
{
/*
* Process pending signals that have not already been
* processed by _Thread_Dispatch. This happens quite
* unfrequently : the ISR must have posted an action
* to the current running thread.
*/
if ( _Thread_Do_post_task_switch_extension ||
_Thread_Executing->do_post_task_switch_extension )
{
_Thread_Executing->do_post_task_switch_extension = FALSE;
_API_extensions_Run_postswitch();
}
}
+196
View File
@@ -0,0 +1,196 @@
/**
* @file irq.h
*
* This include file describe the data structure and the functions implemented
* by rtems to write interrupt handlers.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifndef _IRQ_H_
#define _IRQ_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Include some preprocessor value also used by assember code
*/
#define VECTOR_TABLE (&irq_vector_table[0])
#include <stdint.h>
#include <rtems.h>
extern void default_int_handler();
/*---------------------------------------------------------------------------*
* MACROS *
*---------------------------------------------------------------------------*/
#define ENABLE_IRQ() GBA_REG_IME = 1;
#define DISABLE_IRQ() GBA_REG_IME = 0;
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
typedef enum {
BSP_IRQ_VBLANK = 0,
BSP_IRQ_HBLANK = 1,
BSP_IRQ_VCOUNTER = 2,
BSP_IRQ_TIMER0 = 3,
BSP_IRQ_TIMER1 = 4,
BSP_IRQ_TIMER2 = 5,
BSP_IRQ_TIMER3 = 6,
BSP_IRQ_SERIAL = 7,
BSP_IRQ_DMA0 = 8,
BSP_IRQ_DMA1 = 9,
BSP_IRQ_DMA2 = 10,
BSP_IRQ_DMA3 = 11,
BSP_IRQ_KEY = 12,
BSP_IRQ_CART = 13,
BSP_IRQ_NA14 = 14,
BSP_IRQ_NA15 = 15,
BSP_MAX_INT = 16 /**< BSP_MAX_INT <= _irq_max_vector in linkcmds */
} rtems_irq_symbolic_name;
/*
* Type definition for RTEMS managed interrupts
*/
typedef unsigned char rtems_irq_level;
typedef unsigned char rtems_irq_trigger;
extern void _irq_max_vector; /**< defined in lincmds */
extern uint32_t irq_vector_table[BSP_MAX_INT]; /**< allocated in linkcmds */
struct __rtems_irq_connect_data__; /* forward declaratiuon */
typedef void (*rtems_irq_hdl) (void);
typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
/** irq connection data structure */
typedef struct __rtems_irq_connect_data__ {
/**
* IRQ line
*/
rtems_irq_symbolic_name name;
/**
* handler. See comment on handler properties below in function prototype.
*/
rtems_irq_hdl hdl;
/**
* function for enabling interrupts at device level (ONLY!).
* The BSP code will automatically enable it at PIC level.
* RATIONALE : anyway such code has to exist in current driver code.
* It is usually called immediately AFTER connecting the interrupt handler.
* RTEMS may well need such a function when restoring normal interrupt
* processing after a debug session.
*
*/
rtems_irq_enable on;
/**
* function for disabling interrupts at device level (ONLY!).
* The code will disable it at PIC level. RATIONALE : anyway
* such code has to exist for clean shutdown. It is usually called
* BEFORE disconnecting the interrupt. RTEMS may well need such
* a function when disabling normal interrupt processing for
* a debug session. May well be a NOP function.
*/
rtems_irq_disable off;
/**
* function enabling to know what interrupt may currently occur
* if someone manipulates the PIC interrupt mask without care...
*/
rtems_irq_is_enabled isOn;
/**
* irq priority level
*/
rtems_irq_level irqLevel;
/**
* Trigger way : Rising or falling edge or High or low level
*/
rtems_irq_trigger irqTrigger;
} rtems_irq_connect_data;
/*-------------------------------------------------------------------------+
| Function Prototypes.
+--------------------------------------------------------------------------*/
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
/**
* @brief function to initialize the interrupt for a specific BSP
*/
void BSP_rtems_irq_mngt_init();
/**
* @brief function to connect a particular irq handler.
* This hanlder will NOT be called directly as the result of the corresponding interrupt.
* Instead, a RTEMS irq prologue will be called that will :
* 1) save the C scratch registers,
* 2) switch to a interrupt stack if the interrupt is not nested,
* 3) store the current i8259s' interrupt masks
* 4) modify them to disable the current interrupt at 8259 level (and may
* be others depending on software priorities)
* 5) aknowledge the i8259s',
* 6) demask the processor,
* 7) call the application handler
*
* As a result the hdl function provided
* a) can perfectly be written is C,
* b) may also well directly call the part of the RTEMS API that can be used
* from interrupt level,
* c) It only responsible for handling the jobs that need to be done at
* the device level including (aknowledging/re-enabling the interrupt at device,
* level, getting the data,...)
*
* When returning from the function, the following will be performed by
* the RTEMS irq epilogue :
*
* 1) masks the interrupts again,
* 2) restore the original i8259s' interrupt masks
* 3) switch back on the orinal stack if needed,
* 4) perform rescheduling when necessary,
* 5) restore the C scratch registers...
* 6) restore initial execution flow
*
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
/**
* function to get the current RTEMS irq handler for ptr->name. It enables to
* define hanlder chain...
*/
int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
/**
* @brief function to get disconnect the RTEMS irq handler for ptr->name.
* This function checks that the value given is the current one for safety reason.
* The user can use the previous function to get it.
*/
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
#ifdef __cplusplus
}
#endif
#endif /* _IRQ_H_ */
+183
View File
@@ -0,0 +1,183 @@
/**
* @file irq_asm.S
*
* This file contains the implementation of the IRQ handler.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2002 Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* Copyright (C) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Modified Andy Dachs <a.dachs@sstl.co.uk>
* Copyright (c) 2001 Surrey Satellite Technolgy Limited
*
* Modified Markku Puro <markku.puro@kopteri.net>
* Copyright (c) 2004
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#define __asm__
#include <rtems/asm.h>
#include <asm_macros.h>
#include <arm_mode_bits.h>
/* @cond INCLUDE_ASM */
/**
* Interrupt handler
* function void _ISR_Handler(void)
*
*/
.align
/* .section .iwram */
PUBLIC_ARM_FUNCTION(_ISR_Handler)
stmdb sp!, {r0, r1, r2, r3, r12} /* save regs on INT stack */
stmdb sp!, {lr} /* now safe to call C funcs */
/* one nest level deeper */
ldr r0, =_ISR_Nest_level
ldr r1, [r0]
add r1, r1,#1
str r1, [r0]
/* disable multitasking */
ldr r0, =_Thread_Dispatch_disable_level
ldr r1, [r0]
add r1, r1,#1
str r1, [r0]
/* BSP specific function to INT handler */
bl ExecuteITHandler
/* one less nest level */
ldr r0, =_ISR_Nest_level
ldr r1, [r0]
sub r1, r1,#1
str r1, [r0]
/* unnest multitasking */
ldr r0, =_Thread_Dispatch_disable_level
ldr r1, [r0]
sub r1, r1,#1
str r1, [r0]
/* check to see if we interrupted (no FIQ in GBA) */
mrs r0, spsr
and r0, r0, #Mode_Bits
cmp r0, #Mode_IRQ /* is it INT mode? */
beq exitit
/* If thread dispatching is disabled, exit */
cmp r1, #0
bne exitit
/* If a task switch is necessary, call scheduler */
ldr r0, =_Context_Switch_necessary
ldr r1, [r0]
cmp r1, #0
/* since bframe is going to clear _ISR_Signals_to_thread_executing, */
/* we need to load it here */
ldr r0, =_ISR_Signals_to_thread_executing
ldr r1, [r0]
bne bframe
/* If a signals to be sent (_ISR_Signals_to_thread_executing != 0), */
/* call scheduler */
cmp r1, #0
beq exitit
/* _ISR_Signals_to_thread_executing = FALSE */
mov r1, #0
str r1, [r0]
bframe:
/* Now we need to set up the return from this ISR to be _ISR_Dispatch */
/* To do that, we need to save the current lr_int and spsr_int on the */
/* SVC stack */
mrs r0, spsr
ldmia sp!, {r1} /* get lr off stack */
stmdb sp!, {r1}
mrs r2, cpsr
bic r3, r2, #Mode_Bits
orr r3, r3, #ModePriv /* change to SVC mode */
msr cpsr_c, r3
/* now in SVC mode */
stmdb sp!, {r0, r1} /* put spsr_int and lr_int on SVC stack */
msr cpsr_c, r2 /* change back to INT mode */
/* now in INT mode */
/* replace lr with address of _ISR_Dispatch */
ldr lr, =_ISR_Dispatch_p_4 /* On entry to an ISR, the lr is */
/* the return address + 4, so */
/* we have to emulate that */
ldmia sp!, {r1} /* out with the old */
stmdb sp!, {lr} /* in with the new (lr) */
orr r0, r0, #Int_Bits
msr spsr, r0
exitit:
ldmia sp!, {lr} /* restore regs from INT stack */
ldmia sp!, {r0, r1, r2, r3, r12} /* restore regs from INT stack */
subs pc, lr , #4 /* return */
LABEL_END(_ISR_Handler)
/* on entry to _ISR_Dispatch, we're in SVC mode */
PUBLIC_ARM_FUNCTION(_ISR_Dispatch)
stmdb sp!, {r0-r3, r12,lr} /* save regs on SVC stack */
/* (now safe to call C funcs) */
/* we don't save lr, since */
/* it's just going to get */
/* overwritten */
_ISR_Dispatch_p_4:
bl _Thread_Dispatch
ldmia sp!, {r0-r3, r12, lr}
stmdb sp!, {r0-r2}
/* Now we have to screw with the stack */
mov r0, sp /* copy the SVC stack pointer */
mrs r1, cpsr
bic r2, r1, #Mode_Bits /* clear mode bits */
orr r2, r2, #(Mode_IRQ | Int_Bits) /* change to INT mode */
msr cpsr_c, r2 /* disable interrupts */
/* now in INT mode */
stmdb sp!, {r4, r5, r6} /* save temp vars on INT stack */
ldmia r0!, {r4, r5, r6} /* Get r0-r3 from SVC stack */
stmdb sp!, {r4, r5, r6} /* and save them on INT stack */
ldmia r0!, {r4, r5} /* get saved values from SVC stack */
/* r4=spsr, r5=lr */
mov lr, r5 /* restore lr_int */
msr spsr, r4 /* restore spsr_int */
/* switch to SVC mode, update sp, then return to INT mode */
msr cpsr_c, r1 /* switch to SVC mode */
mov sp, r0 /* update sp_svc */
msr cpsr_c, r2 /* switch back to INT mode */
/* pop all the registers from the stack */
ldmia sp!, {r0, r1, r2}
ldmia sp!, {r4, r5, r6}
/* Finally, we can return to the interrupted task */
subs pc, lr, #4
LABEL_END(_ISR_Dispatch)
/* @endcond */
+71
View File
@@ -0,0 +1,71 @@
/**
* @file irq_init.c
*
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*/
/*
* RTEMS GBA BSP
*
* CopyRight (C) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <stdint.h>
#include <bsp.h>
#include <irq.h>
#include <rtems/bspIo.h>
/** default int vector */
extern void _ISR_Handler(void);
/** max number of vectors, defined in linkcmds */
extern void _irq_max_vector;
/**
* @brief default_int_handler BSP routine is default int_handler
*
* @param None
* @return None
*/
void default_int_handler(void)
{
printk("raw_idt_notify has been called \n");
}
/**
* @brief rtems_irq_mngt_init BSP routine initialize rtems_irq_mngt
*
* @param None
* @return None
*/
void rtems_irq_mngt_init(void)
{
int i;
uint32_t *vectorTable;
rtems_interrupt_level level;
vectorTable = (uint32_t *)VECTOR_TABLE;
_CPU_ISR_Disable(level);
/* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS */
/* First, connect the ISR_Handler for IRQ and FIQ interrupts */
/*_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ISR_Handler, NULL);*/
/*_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _ISR_Handler, NULL);*/
/* Initialize the vector table contents with default handler */
for (i=0 ; i < (uint32_t)&_irq_max_vector ; i++) {
*(vectorTable + i) = (uint32_t)(default_int_handler);
}
/* Initialize the INT at the BSP level */
BSP_rtems_irq_mngt_init();
}
+27
View File
@@ -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 */
+398
View File
@@ -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 */
+197
View File
@@ -0,0 +1,197 @@
/**
* @file bspstart.c
*
* This file contains the GBA BSP startup package.
* It includes application, board, and monitor specific initialization and
* configuration. The generic CPU dependent initialization has been
* performed before this routine is invoked.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <stdio.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <rtems/libcsupport.h>
#include <gba.h>
#include <conio.h>
#define BSP_DEBUG 0
/* Global Variables, Defined in 'linkcmds' */
extern void _end;
extern void _stack_size;
extern void _irq_max_vector;
extern void __heap_limit;
extern void __ro_start;
extern void __ro_end;
extern void __data_start;
extern void __data_end;
extern void __load_start_data;
extern void __load_stop_data;
extern void __ewram_start;
extern void __ewram_end;
extern void __load_start_ewram;
extern void __load_stop_ewram;
extern void __iwram_start;
extern void __iwram_end;
extern void __load_start_iwram;
extern void __load_stop_iwram;
extern void __bss_start;
extern void __bss_end;
/** The original BSP configuration table from the application. */
extern rtems_configuration_table Configuration;
/** Our copy of BSP configuration table from the application. */
rtems_configuration_table BSP_Configuration;
/* External Prototypes */
extern void bsp_cleanup( void );
extern void rtems_irq_mngt_init(void);
extern void bsp_libc_init( void *, rtems_unsigned32, int );
extern void bsp_postdriver_hook(void);
/** Chip registers */
volatile unsigned int *Regs = (unsigned int *)GBA_IO_REGS_ADDR;
/**
* Size of heap if it is 0 it will be dynamically defined by memory size,
* otherwise the value should be changed by binary patch
*/
rtems_unsigned32 _heap_size = 0;
/** Address of start of free memory - should be updated after creating new partitions or regions.*/
rtems_unsigned32 rtemsFreeMemStart;
/** CPU configuration table. */
rtems_cpu_table Cpu_table;
/** Program name - from main(). */
char *rtems_progname;
/**
* @brief BSP pretasking hook.
*
* Called just before drivers are initialized.
* Used to setup libc and install any BSP extensions.
*
* NOTE: Must not use libc (to do io) from here, since drivers are not yet initialized.
*
* @param None
* @return None
*/
void bsp_pretasking_hook(void)
{
if (_heap_size == 0) {
_heap_size = (rtems_unsigned32)&__heap_limit - rtemsFreeMemStart;
}
bsp_libc_init((void *)rtemsFreeMemStart, _heap_size, 0);
rtemsFreeMemStart += _heap_size;
#ifdef RTEMS_DEBUG
rtems_debug_enable(RTEMS_DEBUG_ALL_MASK);
#endif /* RTEMS_DEBUG */
#if BSP_DEBUG
/* The following information is very useful when debugging. */
printk("[bsp_pretasking_hook]\n");
printk("_heap_size = 0x%x\n", _heap_size);
printk("_stack_size = 0x%x\n", (rtems_unsigned32)&_stack_size);
printk("_irq_max_vector = 0x%x\n", (rtems_unsigned32)&_irq_max_vector);
printk("__ro_start = 0x%x : __ro_end = 0x%x\n", (rtems_unsigned32)&__ro_start, (rtems_unsigned32)&__ro_end);
printk("__ewram_start = 0x%x : __ewram_end = 0x%x\n", (rtems_unsigned32)&__ewram_start, (rtems_unsigned32)&__ewram_end);
printk("__data_start = 0x%x : __data_end = 0x%x\n", (rtems_unsigned32)&__data_start, (rtems_unsigned32)&__data_end);
printk("__bss_start = 0x%x : __bss_end = 0x%x\n", (rtems_unsigned32)&__bss_start,(rtems_unsigned32)&__bss_end);
printk("__iwram_start = 0x%x : __iwram_end = 0x%x\n", (rtems_unsigned32)&__iwram_start,(rtems_unsigned32)&__iwram_end);
printk("__load_start_iwram = 0x%x\n", (rtems_unsigned32)&__load_start_iwram);
printk("__load_stop_iwram = 0x%x\n", (rtems_unsigned32)&__load_stop_iwram);
printk("__load_start_ewram = 0x%x\n", (rtems_unsigned32)&__load_start_ewram);
printk("__load_stop_ewram = 0x%x\n", (rtems_unsigned32)&__load_stop_ewram);
printk("__load_start_data = 0x%x\n", (rtems_unsigned32)&__load_start_data);
printk("__load_stop_data = 0x%x\n", (rtems_unsigned32)&__load_stop_data);
#endif
}
/**
* @brief BSP Start
*
* Called before main is invoked.
*
* @param None
* @return None
*/
void bsp_start_default( void )
{
/* set the value of start of free memory. */
rtemsFreeMemStart = (rtems_unsigned32)&_end;
/* If we don't have command line arguments set default program name. */
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.predriver_hook = NULL; /* use system's */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
Cpu_table.idle_task = NULL; /* don't override system IDLE task */
Cpu_table.do_zero_of_workspace = TRUE;
Cpu_table.interrupt_stack_size = 0;
Cpu_table.extra_mpci_receive_server_stack = 0;
/* Place RTEMS workspace at beginning of free memory. */
BSP_Configuration.work_space_start = (void *)rtemsFreeMemStart;
rtemsFreeMemStart += BSP_Configuration.work_space_size;
/* Init conio */
gba_textmode(CO60);
/* Init rtems exceptions management */
/*!!!!!GBA - Can't use exception vectors in GBA because they are already in GBA ROM BIOS */
/* rtems_exception_init_mngt(); */
/* Init rtems interrupt management */
rtems_irq_mngt_init();
#if BSP_DEBUG
/* The following information is very useful when debugging. */
printk("[bsp_start]\n");
printk("rtemsFreeMemStart= 0x%x\n", rtemsFreeMemStart);
printk("__heap_limit = 0x%x\n", (rtems_unsigned32)&__heap_limit);
printk("work_space_start = 0x%x size = 0x%x\n", BSP_Configuration.work_space_start,BSP_Configuration.work_space_size);
printk("maximum_extensions = 0x%x\n", BSP_Configuration.maximum_extensions);
printk("microseconds_per_tick = 0x%x\n", BSP_Configuration.microseconds_per_tick);
printk("ticks_per_timeslice = 0x%x\n", BSP_Configuration.ticks_per_timeslice);
printk("maximum_devices = 0x%x\n", BSP_Configuration.maximum_devices);
printk("number_of_device_drivers = 0x%x\n", BSP_Configuration.number_of_device_drivers);
printk("Device_driver_table = 0x%x\n", BSP_Configuration.Device_driver_table);
#endif
/* Do we have enough memory */
if ((rtems_unsigned32)&__heap_limit < rtemsFreeMemStart) {
printk("\nFatal Error: Memory overflow[0x%x]!\n",rtemsFreeMemStart);
bsp_cleanup();
}
}
/**
* @brief weak alias for bsp_start_default
*
* By making this a weak alias for bsp_start_default, a brave soul
* can override the actual bsp_start routine used.
*/
void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
+170
View File
@@ -0,0 +1,170 @@
/**
* @file cpu.c
*
* ARM CPU Dependent Source.
*/
/*
* RTEMS GBA BSP
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2002 Advent Networks, Inc
* Jay Monkman <jmonkman@adventnetworks.com>
*
* Copyright (c) 2004
* Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <stdint.h>
#include <rtems/system.h>
#include <rtems.h>
#include <rtems/bspIo.h>
#include <rtems/score/isr.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
#include <arm_mode_bits.h>
/**
* @brief _CPU_Initialize routine performs processor dependent initialization
*
* @param cpu_table CPU table to initialize
* @param thread_dispatch address of ISR disptaching routine (unused)
* @return None
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
_CPU_Table = *cpu_table;
}
/**
* @brief _CPU_ISR_Get_level returns the current interrupt level
*
* @param None
* @return int level
*/
uint32_t _CPU_ISR_Get_level( void )
{
uint32_t reg = 0; /* to avoid warning */
asm volatile ("mrs %0, cpsr \n" \
"and %0, %0, #0xc0 \n" \
: "=r" (reg) \
: "0" (reg) );
return reg;
}
/**
* @brief _CPU_ISR_install_vector kernel routine installs the RTEMS handler for the
* specified vector
*
* @param vector interrupt vector number
* @param new_handler replacement ISR for this vector number
* @param old_handler pointer to store former ISR for this vector number
* @return None
*
* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!!
*/
extern __inline__ void _CPU_ISR_install_vector(uint32_t vector, proc_ptr new_handler, proc_ptr *old_handler);
/**
* @brief _CPU_Context_Initialize kernel routine initialize the specified context
*
* @param the_context
* @param stack_base
* @param size
* @param new_level
* @param entry_point
* @param is_fp
* @return None
*/
void _CPU_Context_Initialize(
Context_Control *the_context,
uint32_t *stack_base,
uint32_t size,
uint32_t new_level,
void *entry_point,
boolean is_fp
)
{
the_context->register_sp = (uint32_t)stack_base + size ;
the_context->register_lr = (uint32_t)entry_point;
the_context->register_cpsr = new_level | ModePriv;
}
/**
* @brief _CPU_Install_interrupt_stack function is empty since the BSP must set up the interrupt stacks.
*
* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!!
*/
extern __inline__ void _CPU_Install_interrupt_stack( void );
/**
* @brief _defaultExcHandler function is empty
*
* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!!
*/
extern void _defaultExcHandler (CPU_Exception_frame *ctx);
/**
* @brief _currentExcHandler function is empty (_defaultExcHandler)
*
* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!!
*/
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
/*
extern void _Exception_Handler_Undef_Swi();
extern void _Exception_Handler_Abort();
extern void _exc_data_abort();
*/
/**
* @brief rtems_exception_init_mngt function is empty since the BSP must set up the interrupt stacks.
*
* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!!
*/
extern __inline__ void rtems_exception_init_mngt();
/**
* @brief do_data_abort function is empty
*
* This function figure out what caused the data abort
*
* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!!
* This function is supposed to figure out what caused the data abort, do that, then return.
* All unhandled instructions cause the system to hang.
*/
extern __inline__ void do_data_abort(uint32_t insn, uint32_t spsr, CPU_Exception_frame *ctx);
/* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS!! */
/* @todo Remove dummy functions needed by linker
****************************************************************************************/
/* @cond INCLUDE_ASM */
asm (" .text");
asm (" .arm");
asm (" .global _CPU_ISR_install_vector");
asm ("_CPU_ISR_install_vector:");
asm (" .global _CPU_Install_interrupt_stack");
asm ("_CPU_Install_interrupt_stack:");
asm (" .global _defaultExcHandler");
asm ("_defaultExcHandler:");
asm (" .global rtems_exception_init_mngt");
asm ("rtems_exception_init_mngt:");
asm (" .global do_data_abort");
asm ("do_data_abort:");
asm (" mov pc, lr");
/* @endcond */
@@ -0,0 +1,86 @@
/**
* @file cpu_asm.S
*
* This file contains the implementation of exception handlers.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2002 by Advent Networks, Inc.
* Jay Monkman <jmonkman@adventnetworks.com>
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* Copyright (c) 2004
* Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#define __asm__
#include <rtems/asm.h>
#include <rtems/score/cpu_asm.h>
#include <asm_macros.h>
/* @cond INCLUDE_ASM */
/**
* This routine performs a normal non-FP context.
* function void _CPU_Context_switch( run_context, heir_context )
* R0 = run_context R1 = heir_context
*
* This function copies the current registers to where r0 points, then
* restores the ones from where r1 points.
*
* Using the ldm/stm opcodes save 2-3 us on 100 MHz ARM9TDMI with
* a 16 bit data bus.
*
*/
.align
/* .section .iwram */
PUBLIC_ARM_FUNCTION(_CPU_Context_switch)
/* Start saving context */
mrs r2, cpsr
stmia r0, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
/* Start restoring context */
_restore:
ldmia r1, {r2, r4, r5, r6, r7, r8, r9, r10, r11, r13, r14}
msr cpsr, r2
mov pc, lr
LABEL_END(_CPU_Context_switch)
/**
* This function copies the restores the registers from where r0 points.
* function void _CPU_Context_restore( new_context )
* It must match _CPU_Context_switch()
*
*/
PUBLIC_ARM_FUNCTION(_CPU_Context_restore)
mov r1, r0
b _restore
LABEL_END(_CPU_Context_restore)
/**
* function _Exception_Handler_Undef_Swi
* Can't use exception vectors in GBA
* @todo _Exception_Handler_Undef_Swi: Unused handler needed by ../score/cpu_asm.S
*
*/
.global _Exception_Handler_Undef_Swi
_Exception_Handler_Undef_Swi:
mov pc, lr
/**
* function _Exception_Handler_Abort
* Can't use exception vectors in GBA
* @todo _Exception_Handler_Abort: Unused handler needed by ../score/cpu_asm.S
*
*/
.global _Exception_Handler_Abort
_Exception_Handler_Abort:
mov pc, lr
/* @endcond */
+54
View File
@@ -0,0 +1,54 @@
/**
* @file exit.c
*
* Routines to shutdown and reboot the BSP.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <stdio.h>
#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/libio.h>
#include <gba.h>
/**
* @brief rtemsReboot BSP routine reboot rtems
*
* Input parameters: None
*
* Output parameters: None
*/
void rtemsReboot (void)
{
asm volatile ("ldr r0, =_gba_reset");
asm volatile ("bx r0");
}
/**
* @brief bsp_cleanup BSP routine wait input from user for rebooting
*
* Normally at this point, the console driver is disconnected => we must
* use polled output/input. This is exactly what printk does.
*
* @param None
* @return None
*/
void bsp_cleanup(void)
{
static const char line[]="\nEXECUTIVE SHUTDOWN! Press button to reboot...";
printk("\n");
printk("%s",line);
while ( !GBA_ANY_KEY(GBA_KEY_ALL) );
rtemsReboot();
}
+348
View File
@@ -0,0 +1,348 @@
/**
* @file linkcmds
*
* GBA BSP linker script
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) Jeff Frohwein
*
* Copyright (c) 2003 Jason Wilkins
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* 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 Linker Script is based on work by Jeff Frohwein and Jason Wilkins
*****************************************************************************
* Linker Script v1.3 by Jeff Frohwein
* :
* This file is released into the public domain
* for commercial or non-commercial use 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. There are absolutely no restrictions on use of
* object code generated from this source, but the disclaimers remain in force.
*
* 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.
*
*****************************************************************************/
/* @cond INCLUDE_ASM */
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
/*************************************************************************
The linker script MEMORY directive is not used here due to the fact
that __ro_start is not always a fixed value.
*************************************************************************
MEMORY
{
rom : ORIGIN = 0x08000000 , LENGTH = 96M
iwram : ORIGIN = 0x03000000 , LENGTH = 32K
ewram : ORIGIN = 0x02000000 , LENGTH = 256K
sram : ORIGIN = 0x0E000000 , LENGTH = 64K
}
*************************************************************************/
__gba_ewram_start = 0x02000000;
__gba_ewram_end = 0x02040000;
__gba_iwram_start = 0x03000000;
__gba_iwram_end = 0x03008000;
__gba_rom_start = 0x08000000;
__gba_rom_end = 0x0E000000;
__gba_sram_start = 0x0E000000;
__gba_sram_end = 0x0E010000;
__sp_irq_size = 0x2A0;
_stack_size = 0xA00;
__irq_vector = __gba_iwram_end - 0x0004; /* 0x03007FFC */
__sp_svc = __gba_iwram_end - 0x0020; /* 0x03007FE0 */
__sp_irq = __gba_iwram_end - 0x0060; /* 0x03007FA0 */
__sp_usr = __sp_irq - __sp_irq_size; /* 0x03007D00 */
__sp_limit = __sp_usr - _stack_size; /* 0x03007300 */
__heap_limit = DEFINED(__gba_multiboot) ? __gba_ewram_end : ( DEFINED(__gba_iwram_bss) ? __sp_limit : __gba_ewram_end ) ;
SECTIONS
{
/*** read-only sections ***/
/*************************************************************************
if 'multiboot' allocate prog in __gba_ewram_start (0x02000000-0x0207FFFF)
else allocate prog in __gba_rom_start (0x08000000-0x0DFFFFFF)
*************************************************************************/
__ro_start = DEFINED(__gba_multiboot) ? __gba_ewram_start : __gba_rom_start ;
PROVIDE(__text_start__ = __ro_start );
.text __ro_start :
{
CREATE_OBJECT_SYMBOLS
*/start.o(.text)
*(EXCLUDE_FILE(*.rodata.* *.ewram.o *.iwram.o) .text)
*(.stub .text.* .gnu.linkonce.t*)
/*
* Special FreeBSD sysctl sections.
*/
. = ALIGN (16);
__start_set_sysctl_set = .;
*(set_sysctl_*);
__stop_set_sysctl_set = ABSOLUTE(.);
*(set_domain_*);
*(set_pseudo_*);
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
} =0xFF
.init :
{
*(.init)
. = ALIGN(4);
} =0xFF
.fini :
{
*(.fini)
. = ALIGN(4);
} =0xFF
__rodata_start = . ;
.rodata :
{
*(.rodata1)
*(EXCLUDE_FILE(*.rodata.* *.ewram.o *.iwram.o) .rodata)
*(.rodata.* .gnu.linkonce.r*)
*(.roda) /* deprecated: for compatibility with objcopyroda */
SORT(CONSTRUCTORS)
. = ALIGN(4);
} =0xFF
__rodata_end = . ;
.eh_frame :
{
KEEP(*(.eh_frame))
. = ALIGN(4);
} =0xFF
.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4);
} =0xFF
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is first.
Because this is a wildcard, it doesn't matter
if the user does not actually link against crtbegin.o;
the linker won't look for a file to match a wildcard.
The wildcard also means that it doesn't matter which
directory crtbegin.o is in.
*/
KEEP(*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last
*/
KEEP(*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
. = ALIGN(4);
} =0xFF
.dtors :
{
KEEP(*crtbegin.o(.dtors))
KEEP(*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
. = ALIGN(4);
} =0xFF
.jcr :
{
*(.jcr)
. = ALIGN(4);
} =0xFF
/*************************************************************************
calculate __ro_end
*************************************************************************/
__ro_end =
ADDR(.text) +
SIZEOF(.text) +
SIZEOF(.init) +
SIZEOF(.fini) +
SIZEOF(.rodata) +
SIZEOF(.eh_frame) +
SIZEOF(.gcc_except_table) +
SIZEOF(.ctors) +
SIZEOF(.dtors) +
SIZEOF(.jcr);
PROVIDE(__text_end__ = __ro_end );
/*** IWRAM ***/
/*************************************************************************
allocate iwram in __gba_iwram_start (0x03000000-0x03003FFF)
*************************************************************************/
__load_start_iwram = __ro_end;
. = __gba_iwram_start ;
__iwram_start = . ;
PROVIDE(__iwram_start__ = . );
.iwram : AT(__load_start_iwram)
{
/* put irq_vector_table in stat of iwram */
CREATE_OBJECT_SYMBOLS
_irq_vector_table = .;
PROVIDE(irq_vector_table = .);
. += 4;
. = ALIGN(16 * 4);
PROVIDE(irq_vector_table_end = .);
_irq_vector_table_end = .;
*(.iwram .iwram.*)
*.iwram.o (.text .rodata .data)
. = ALIGN(4);
} =0xFF
__iwram_end = . ;
PROVIDE(__iwram_end__ = . );
__load_stop_iwram = __load_start_iwram + SIZEOF(.iwram);
_irq_vector_table_size = _irq_vector_table_end - _irq_vector_table;
PROVIDE(_irq_max_vector = _irq_vector_table_size / 4 );
/*** EWRAM ***/
/*************************************************************************
if 'multiboot' allocate prog+ewram in __gba_ewram
else allocate only ewram in __gba_ewram_start
*************************************************************************/
. = DEFINED(__gba_multiboot) ? __load_stop_iwram : __gba_ewram_start ;
__load_start_ewram = __load_stop_iwram;
__ewram_start = . ;
PROVIDE(__ewram_start__ = . );
.ewram : AT(__load_start_ewram)
{
*(.ewram .ewram.*)
*.ewram.o (.text .rodata .data)
. = ALIGN(4);
} =0xFF
__ewram_end = . ;
PROVIDE(__ewram_end__ = . );
__load_stop_ewram = __load_start_ewram + SIZEOF(.ewram) ;
/*************************************************************************
if 'multiboot' allocate prog+ewram+data+bss in __gba_ewram
else if 'iwram_data' allocate data in __gba_iwram
else allocate data in __gba_ewram
*************************************************************************/
. = DEFINED(__gba_multiboot) ? __load_stop_ewram : (DEFINED(__gba_iwram_data) ? __iwram_end : __ewram_end) ;
__load_start_data = __load_stop_ewram;
__data_start = . ;
PROVIDE(__data_start__ = . );
.data : AT(__load_start_data)
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
*(EXCLUDE_FILE(*.rodata.* *.ewram.o *.iwram.o) .data)
*(.data.* .gnu.linkonce.d.*)
*(.data1)
*(.tdata .tdata.* .gnu.linkonce.td.*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
. = ALIGN(4);
} =0xFF
__data_end = . ;
PROVIDE(__data_end__ = . );
__load_stop_data = __load_start_data + SIZEOF(.data);
/*** BSS ***/
/*************************************************************************
if 'multiboot' allocate prog+ewram+data+bss in __gba_ewram
else if 'iwram_data' and 'iwram_bss' allocate iwram+data+bss in __gba_iwram
else if !'iwram_data' and 'iwram_bss' allocate iwram+bss in __gba_iwram
else allocate data+ewram+bss in __gba_ewram
*************************************************************************/
. = DEFINED(__gba_multiboot) ? __load_stop_data : ( DEFINED(__gba_iwram_data) ? (DEFINED(__gba_iwram_bss) ? __data_end : __ewram_end) : (DEFINED(__gba_iwram_bss) ? __iwram_end : __data_end) ) ;
__bss_start = . ;
PROVIDE(__bss_start__ = . );
.bss :
{
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.bss .bss.* .gnu.linkonce.b*)
*(COMMON)
. = ALIGN(4);
}
__bss_end = . ;
PROVIDE(__bss_end__ = . );
PROVIDE(_bss_end__ = . );
PROVIDE(_end = . );
PROVIDE(__end__ = _end);
PROVIDE(end = _end);
/*** debugging info ***/
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.comment 0 : { *(.comment) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
/* @endcond */
+149
View File
@@ -0,0 +1,149 @@
/**
* @file timer.c
*
* GBA Timer driver.
*/
/*
* RTEMS GBA BSP
*
* Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
*
* Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
*
* Notes:
* This file manages the benchmark timer used by the RTEMS Timing Test
* Suite. Each measured time period is demarcated by calls to
* Timer_initialize() and Read_timer(). Read_timer() usually returns
* the number of microseconds since Timer_initialize() exitted.
*
* It is important that the timer start/stop overhead be determined
* when porting or modifying this code.
*
* $Id$
*/
#include <rtems.h>
#include <bsp.h>
#include <irq.h>
#include <gba.h>
/*
* Set up the timer hardware
* 1 / 16.78Mhz => 59.595 ns
* 64 / 16.78Mhz => 3.814 us
* 256 / 16.78Mhz => 15.256 us
* 1024 / 16.78Mhz => 61.025 us
*/
#define __TimePreScaler 1
#define __TickTime_ns ((1000000000L/__ClockFrequency)*__TimePreScaler)
#define __TickTime_us ((1000000L/__ClockFrequency)*__TimePreScaler)
#if (__TimePreScaler==1)
#define GBA_TM0CNT_PS 0x0000
#elif (__TimePreScaler==64)
#define GBA_TM0CNT_PS 0x0001
#elif (__TimePreScaler==256)
#define GBA_TM0CNT_PS 0x0002
#elif (__TimePreScaler==1024)
#define GBA_TM0CNT_PS 0x0003
#else
#define GBA_TM0CNT_PS 0x0003
#endif
rtems_boolean Timer_driver_Find_average_overhead;
/**
* @brief Timer_initialize start TM0 and TM1
*
* @param None
* @return None
*/
void Timer_initialize( void )
{
GBA_REG_TM1CNT = 0x0000; /* Stop Counters */
GBA_REG_TM0CNT = 0x0000;
GBA_REG_TM1D = 0x0000; /* Reset Counters */
GBA_REG_TM0D = 0x0000;
/* Start Counters */
GBA_REG_TM1CNT = 0x0084; /* Start Count Up timing */
GBA_REG_TM0CNT = (0x0080|GBA_TM0CNT_PS); /* Start Count */
}
/*
* The following controls the behavior of Read_timer().
*
* AVG_OVEREHAD is the overhead for starting and stopping the timer. It
* is usually deducted from the number returned.
*
* LEAST_VALID is the lowest number this routine should trust. Numbers
* below this are "noise" and zero is returned.
*/
#define AVG_OVERHEAD 3 /**< It typically takes 3 microseconds */
#define LEAST_VALID 1 /**< Don't trust a clicks value lower than this */
/**
* @brief Read_timer return timer countervalue in microseconds.
*
* Used in Timing Test Suite.
*
* @param None
* @return Timer value in microseconds
*/
uint32_t Read_timer( void )
{
uint32_t ticks;
uint32_t total;
/* Stop Counters */
GBA_REG_TM0CNT = 0x0000;
GBA_REG_TM1CNT = 0x0000;
/* Read Counters */
ticks = (GBA_REG_TM1D<<16) | GBA_REG_TM0D;
if ( ticks < LEAST_VALID ) {
return 0; /* below timer resolution */
}
/* convert to uS */
total = ((ticks * __TickTime_ns) / 1000);
if ( Timer_driver_Find_average_overhead == 1 ) {
return total; /* in microseconds */
}
else {
if ( total < AVG_OVERHEAD ) {
return 0;
}
return (total - AVG_OVERHEAD);
}
}
/**
* @brief Empty function
*
* Empty function call used in loops to measure basic cost of looping
* in Timing Test Suite.
*
* @param None
* @return RTEMS_SUCCESSFUL
*/
rtems_status_code Empty_function( void )
{
return RTEMS_SUCCESSFUL;
}
/**
* @brief Set Timer_driver_Find_average_overhead flag.
*
* Used in Timing Test Suite.
*
* @param find_flag boolean find_flag
* @return None
*/
void Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
}