Port of RTEMS to the ARM processor family by Eric Valette

<valette@crf.canon.fr> and Emmanuel Raguet <raguet@crf.canon.fr>
of Canon CRF - Communication Dept.  This port includes a
basic BSP that is sufficient to link hello world.
This commit is contained in:
Joel Sherrill
2000-07-27 01:04:11 +00:00
parent db9ae7078d
commit 08330bf0be
80 changed files with 6598 additions and 21 deletions

View File

@@ -159,11 +159,11 @@ The following persons/organizations have made contributions:
+ Eric Valette <valette@crf.canon.fr> and Emmanuel Raguet <raguet@crf.canon.fr>
of Canon CRF - Communication Dept for numerous submissions including
remote debugging on the i386 and PowerPC, port of RPC, port of the
GoAhead web server, BSP for the Motorola MCP750 PowerPC board, and
numerous improvements to the i386 and PowerPC ports of RTEMS
including a new enhanced interrupt management API that reduces
interrupt latency while making it easier to support external interrupt
controllers.
GoAhead web server, port of RTEMS to the ARM architecture,
BSP for the Motorola MCP750 PowerPC board, and numerous improvements
to the i386 and PowerPC ports of RTEMS including a new enhanced
interrupt management API that reduces interrupt latency while making
it easier to support external interrupt controllers.
+ Mark Bronson <mark@ramix.com> of RAMIX for submitting i960RP
support and the rxgen960 board support package.

View File

@@ -0,0 +1,13 @@
Makefile
Makefile.in
aclocal.m4
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
mkinstalldirs

View File

@@ -0,0 +1,48 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
SUBDIRS = rtems
C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_FILES = cpu_asm.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
H_FILES = asm.h
REL = $(ARCH)/rtems-cpu.rel
rtems_cpu_rel_OBJECTS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_RELEASE)/lib/rtems$(LIB_VARIANT).o: $(ARCH)/rtems.o
$(INSTALL_DATA) $< $@
$(REL): $(rtems_cpu_rel_OBJECTS)
$(make-rel)
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(H_FILES:%=$(PROJECT_INCLUDE)/%)
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/rtems$(LIB_VARIANT).o
all: $(ARCH) $(PREINSTALL_FILES) $(rtems_cpu_rel_OBJECTS) $(REL) $(TMPINSTALL_FILES)
.PRECIOUS: $(REL)
EXTRA_DIST = asm.h cpu.c cpu_asm.S
include $(top_srcdir)/../../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,125 @@
/* asm.h
*
* This include file attempts to address the problems
* caused by incompatible flavors of assemblers and
* toolsets. It primarily addresses variations in the
* use of leading underscores on symbols and the requirement
* that register names be preceded by a %.
*
*
* NOTE: The spacing in the use of these macros
* is critical to them working as advertised.
*
* COPYRIGHT:
*
* This file is based on similar code found in newlib available
* from ftp.cygnus.com. The file which was used had no copyright
* notice. This file is freely distributable as long as the source
* of the file is noted. This file is:
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __ARM_ASM_h
#define __ARM_ASM_h
/*
* Indicate we are in an assembly file and get the basic CPU definitions.
*/
#ifndef ASM
#define ASM
#endif
#include <rtems/score/targopts.h>
#include <rtems/score/arm.h>
/*
* Recent versions of GNU cpp define variables which indicate the
* need for underscores and percents. If not using GNU cpp or
* the version does not support this, then you will obviously
* have to define these as appropriate.
*/
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
#ifndef __REGISTER_PREFIX__
#define __REGISTER_PREFIX__
#endif
/* ANSI concatenation macros. */
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
/* Use the right prefix for global labels. */
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
/* Use the right prefix for registers. */
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
/*
* define macros for all of the registers on this CPU
*
* EXAMPLE: #define d0 REG (d0)
*/
#define r0 REG(r0)
#define r1 REG(r1)
#define r2 REG(r2)
#define r3 REG(r3)
#define r4 REG(r4)
#define r5 REG(r5)
#define r6 REG(r6)
#define r7 REG(r7)
#define r8 REG(r8)
#define r9 REG(r9)
#define r10 REG(r10)
#define r11 REG(r11)
#define r12 REG(r12)
#define r13 REG(r13)
#define r14 REG(r14)
#define r15 REG(r15)
#define CPSR REG(CPSR)
#define SPSR REG(SPSR)
/*
* Define macros to handle section beginning and ends.
*/
#define BEGIN_CODE_DCL .text
#define END_CODE_DCL
#define BEGIN_DATA_DCL .data
#define END_DATA_DCL
#define BEGIN_CODE .text
#define END_CODE
#define BEGIN_DATA
#define END_DATA
#define BEGIN_BSS
#define END_BSS
#define END
/*
* Following must be tailor for a particular flavor of the C compiler.
* They may need to put underscores in front of the symbols.
*/
#define PUBLIC(sym) .globl SYM (sym)
#define EXTERN(sym) .globl SYM (sym)
#endif
/* end of include file */

View File

@@ -0,0 +1,34 @@
dnl Process this file with autoconf to produce a configure script.
dnl
dnl $Id$
AC_PREREQ(2.13)
AC_INIT(cpu_asm.S)
RTEMS_TOP(../../../../../..)
AC_CONFIG_AUX_DIR(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE(rtems-c-src-exec-score-cpu-arm,$RTEMS_VERSION,no)
AM_MAINTAINER_MODE
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_CPU
RTEMS_CANONICAL_HOST
RTEMS_PROJECT_ROOT
RTEMS_PROG_CC_FOR_TARGET
RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_NEWLIB
# Check if there is custom/*.cfg for this BSP
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
# Explicitly list all Makefiles here
AC_OUTPUT(
Makefile
rtems/Makefile
rtems/score/Makefile)

View File

@@ -0,0 +1,169 @@
/*
* ARM CPU Dependent Source
*
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#include <rtems/system.h>
#include <rtems.h>
#include <bspio.h>
#include <rtems/score/isr.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
_CPU_Table = *cpu_table;
}
/*PAGE
*
* _CPU_ISR_Get_level
*/
unsigned32 _CPU_ISR_Get_level( void )
{
/*
* This routine returns the current interrupt level.
*/
return 0;
}
/*
* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
*
* Output parameters: NONE
*
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/* pointer on the redirection table in RAM */
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
if (old_handler != NULL)
old_handler = *(proc_ptr *)(VectorTable + vector);
*(VectorTable + vector) = (long)new_handler ;
}
/*PAGE
*
* _CPU_Install_interrupt_stack
*/
void _CPU_Install_interrupt_stack( void )
{
}
/*PAGE
*
* _CPU_Thread_Idle_body
*
* NOTES:
*
* 1. This is the same as the regular CPU independent algorithm.
*
* 2. If you implement this using a "halt", "idle", or "shutdown"
* instruction, then don't forget to put it in an infinite loop.
*
* 3. Be warned. Some processors with onboard DMA have been known
* to stop the DMA if the CPU were put in IDLE mode. This might
* also be a problem with other on-chip peripherals. So use this
* hook with caution.
*/
void _CPU_Thread_Idle_body( void )
{
while(1);
/* insert your "halt" instruction here */ ;
}
void _defaultExcHandler (CPU_Exception_frame *ctx)
{
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->register_pc, ctx->register_lr - 4,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n",
ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3);
printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n",
ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7);
printk(" r8 = %x r9 = %x r10 = %x\n",
ctx->register_r8, ctx->register_r9, ctx->register_r10);
printk(" fp = %x ip = %x sp = %x pc = %x\n",
ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4);
printk("----------------------------------------------------------\n");
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as
* it has nothing to do with the fault. We cannot return either
* because the eip points to the faulty instruction so...
*/
printk("Exception while executing ISR!!!. System locked\n");
while(1);
}
else {
printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
rtems_task_delete(_Thread_Executing->Object.id);
}
}
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
extern void _Exception_Handler_Undef_Swi();
extern void _Exception_Handler_Abort();
void rtems_exception_init_mngt()
{
_CPU_ISR_Disable(level);
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_Enable(level);
}

View File

@@ -0,0 +1,193 @@
/* cpu_asm.s
*
* This file contains all assembly code for the ARM implementation
* of RTEMS.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#include <asm.h>
/*
* Format of ARM Register structure
*/
.set REG_R0, 0
.set REG_R1, 4
.set REG_R2, 8
.set REG_R3, 12
.set REG_R4, 16
.set REG_R5, 20
.set REG_R6, 24
.set REG_R7, 28
.set REG_R8, 32
.set REG_R9, 36
.set REG_R10, 40
.set REG_FP, 44
.set REG_IP, 48
.set REG_SP, 52
.set REG_LR, 56
.set REG_PC, 60
.set SIZE_REGS, REG_PC + 4
/*
* void _CPU_Context_switch( run_context, heir_context )
*
* This routine performs a normal non-FP context.
*
* R0 = run_context R1 = heir_context
*
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
str r2, [r0, #REG_R2]
str r3, [r0, #REG_R3]
str r4, [r0, #REG_R4]
str r5, [r0, #REG_R5]
str r6, [r0, #REG_R6]
str r7, [r0, #REG_R7]
str r8, [r0, #REG_R8]
str r9, [r0, #REG_R9]
str r10, [r0, #REG_R10]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC]
ldr r2, [r1, #REG_R2]
ldr r3, [r1, #REG_R3]
ldr r4, [r1, #REG_R4]
ldr r5, [r1, #REG_R5]
ldr r6, [r1, #REG_R6]
ldr r7, [r1, #REG_R7]
ldr r8, [r1, #REG_R8]
ldr r9, [r1, #REG_R9]
ldr r10, [r1, #REG_R10]
ldr sp, [r1, #REG_SP]
ldr lr, [r1, #REG_PC]
mov pc, lr
/*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* void _CPU_Context_restore( new_context )
*
* This routine performs a normal non-FP context.
*/
.globl _CPU_Context_restore
_CPU_Context_restore:
ldr r2, [r0, #REG_R2]
ldr r3, [r0, #REG_R3]
ldr r4, [r0, #REG_R4]
ldr r5, [r0, #REG_R5]
ldr r6, [r0, #REG_R6]
ldr r7, [r0, #REG_R7]
ldr r8, [r0, #REG_R8]
ldr r9, [r0, #REG_R9]
ldr r10, [r0, #REG_R10]
ldr sp, [r0, #REG_SP]
ldr lr, [r0, #REG_PC]
mov pc, lr
.globl _Exception_Handler_Undef_Swi
_Exception_Handler_Undef_Swi:
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
str r2, [r13, #REG_R2]
str r3, [r13, #REG_R3]
str r4, [r13, #REG_R4]
str r5, [r13, #REG_R5]
str r6, [r13, #REG_R6]
str r7, [r13, #REG_R7]
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str fp, [r13, #REG_FP]
str ip, [r13, #REG_IP]
str sp, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
and r0, r0,#0x1f /* we keep the mode as exception number */
str r0, [r13, #REG_PC] /* we store it in a free place */
mov r0, r13 /* put frame address in r0 (C arg 1) */
ldr r1, =_currentExcHandler
ldr lr, =_go_back_1
ldr pc,[r1] /* call handler */
_go_back_1:
ldr r0, [r13, #REG_R0]
ldr r1, [r13, #REG_R1]
ldr r2, [r13, #REG_R2]
ldr r3, [r13, #REG_R3]
ldr r4, [r13, #REG_R4]
ldr r5, [r13, #REG_R5]
ldr r6, [r13, #REG_R6]
ldr r7, [r13, #REG_R7]
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr fp, [r13, #REG_FP]
ldr ip, [r13, #REG_IP]
ldr sp, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
movs pc,r14 /* return */
.globl _Exception_Handler_Abort
_Exception_Handler_Abort:
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
str r2, [r13, #REG_R2]
str r3, [r13, #REG_R3]
str r4, [r13, #REG_R4]
str r5, [r13, #REG_R5]
str r6, [r13, #REG_R6]
str r7, [r13, #REG_R7]
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str sp, [r13, #REG_FP]
str lr, [r13, #REG_IP]
str lr, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
and r0, r0,#0x1f /* we keep the mode as exception number */
str r0, [r13, #REG_PC] /* we store it in a free place */
mov r0, r13 /* put frame address in ro (C arg 1) */
ldr r1, =_currentExcHandler
ldr lr, =_go_back_2
ldr pc,[r1] /* call handler */
_go_back_2:
ldr r0, [r13, #REG_R0]
ldr r1, [r13, #REG_R1]
ldr r2, [r13, #REG_R2]
ldr r3, [r13, #REG_R3]
ldr r4, [r13, #REG_R4]
ldr r5, [r13, #REG_R5]
ldr r6, [r13, #REG_R6]
ldr r7, [r13, #REG_R7]
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr sp, [r13, #REG_FP]
ldr lr, [r13, #REG_IP]
ldr lr, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
subs pc,r14,#4 /* return */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,10 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = score
include $(top_srcdir)/../../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,26 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = cpu.h arm.h armtypes.h
noinst_HEADERS = $(H_FILES)
#
# (OPTIONAL) Add local stuff here using +=
#
PREINSTALL_FILES = \
$(PROJECT_INCLUDE)/rtems/score \
$(H_FILES:%.h=$(PROJECT_INCLUDE)/rtems/score/%.h)
$(PROJECT_INCLUDE)/rtems/score:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/rtems/score/%.h: %.h
$(INSTALL_DATA) $< $@
all: $(PREINSTALL_FILES)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,54 @@
/* no_cpu.h
*
* This file is an example (i.e. "no CPU") of the file which is
* created for each CPU family port of RTEMS.
*
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef _INCLUDE_ARM_h
#define _INCLUDE_ARM_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* This file contains the information required to build
* RTEMS for a particular member of the "arm"
* family when executing in protected mode. It does
* this by setting variables to indicate which implementation
* dependent features are present in a particular member
* of the family.
*/
#if defined(arm)
#define CPU_MODEL_NAME "arm"
#define ARM_HAS_FPU 0
#else
#error "Unsupported CPU Model"
#endif
/*
* Define the name of the CPU family.
*/
#define CPU_NAME "ARM"
#ifdef __cplusplus
}
#endif
#endif /* ! _INCLUDE_ARM_h */
/* end of include file */

View File

@@ -0,0 +1,55 @@
/* armtypes.h
*
* This include file contains type definitions pertaining to the
* arm processor family.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __ARM_TYPES_h
#define __ARM_TYPES_h
#ifndef ASM
#ifdef __cplusplus
extern "C" {
#endif
/*
* This section defines the basic types for this processor.
*/
typedef unsigned char unsigned8; /* unsigned 8-bit integer */
typedef unsigned short unsigned16; /* unsigned 16-bit integer */
typedef unsigned int unsigned32; /* unsigned 32-bit integer */
typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
typedef unsigned16 Priority_Bit_map_control;
typedef signed char signed8; /* 8-bit signed integer */
typedef signed short signed16; /* 16-bit signed integer */
typedef signed int signed32; /* 32-bit signed integer */
typedef signed long long signed64; /* 64 bit signed integer */
typedef unsigned32 boolean; /* Boolean value */
typedef float single_precision; /* single precision float */
typedef double double_precision; /* double precision float */
typedef void no_cpu_isr;
typedef void ( *no_cpu_isr_entry )( void );
#ifdef __cplusplus
}
#endif
#endif /* !ASM */
#endif
/* end of include file */

View File

@@ -0,0 +1,916 @@
/* cpu.h
*
* This include file contains information pertaining to the arm
* processor.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __CPU_h
#define __CPU_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/arm.h> /* pick up machine definitions */
#ifndef ASM
#include <rtems/score/armtypes.h>
#endif
/* conditional compilation parameters */
/*
* Should the calls to _Thread_Enable_dispatch be inlined?
*
* If TRUE, then they are inlined.
* If FALSE, then a subroutine call is made.
*
* Basically this is an example of the classic trade-off of size
* versus speed. Inlining the call (TRUE) typically increases the
* size of RTEMS while speeding up the enabling of dispatching.
* [NOTE: In general, the _Thread_Dispatch_disable_level will
* only be 0 or 1 unless you are in an interrupt handler and that
* interrupt handler invokes the executive.] When not inlined
* something calls _Thread_Enable_dispatch which in turns calls
* _Thread_Dispatch. If the enable dispatch is inlined, then
* one subroutine call is avoided entirely.]
*/
#define CPU_INLINE_ENABLE_DISPATCH FALSE
/*
* Should the body of the search loops in _Thread_queue_Enqueue_priority
* be unrolled one time? In unrolled each iteration of the loop examines
* two "nodes" on the chain being searched. Otherwise, only one node
* is examined per iteration.
*
* If TRUE, then the loops are unrolled.
* If FALSE, then the loops are not unrolled.
*
* The primary factor in making this decision is the cost of disabling
* and enabling interrupts (_ISR_Flash) versus the cost of rest of the
* body of the loop. On some CPUs, the flash is more expensive than
* one iteration of the loop body. In this case, it might be desirable
* to unroll the loop. It is important to note that on some CPUs, this
* code is the longest interrupt disable period in RTEMS. So it is
* necessary to strike a balance when setting this parameter.
*/
#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
/*
* Does RTEMS manage a dedicated interrupt stack in software?
*
* If TRUE, then a stack is allocated in _Interrupt_Manager_initialization.
* If FALSE, nothing is done.
*
* If the CPU supports a dedicated interrupt stack in hardware,
* then it is generally the responsibility of the BSP to allocate it
* and set it up.
*
* If the CPU does not support a dedicated interrupt stack, then
* the porter has two options: (1) execute interrupts on the
* stack of the interrupted task, and (2) have RTEMS manage a dedicated
* interrupt stack.
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
* Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
* possible that both are FALSE for a particular CPU. Although it
* is unclear what that would imply about the interrupt processing
* procedure on that CPU.
*/
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
/*
* Does this CPU have hardware support for a dedicated interrupt stack?
*
* If TRUE, then it must be installed during initialization.
* If FALSE, then no installation is performed.
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
* Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
* possible that both are FALSE for a particular CPU. Although it
* is unclear what that would imply about the interrupt processing
* procedure on that CPU.
*/
#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
/*
* Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
*
* If TRUE, then the memory is allocated during initialization.
* If FALSE, then the memory is allocated during initialization.
*
* This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE
* or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
*/
#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
/*
* Does the RTEMS invoke the user's ISR with the vector number and
* a pointer to the saved interrupt frame (1) or just the vector
* number (0)?
*/
#define CPU_ISR_PASSES_FRAME_POINTER 0
/*
* Does the CPU have hardware floating point?
*
* If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
* If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
*
* If there is a FP coprocessor such as the i387 or mc68881, then
* the answer is TRUE.
*
* The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
* It indicates whether or not this CPU model has FP support. For
* example, it would be possible to have an i386_nofp CPU model
* which set this to false to indicate that you have an i386 without
* an i387 and wish to leave floating point support out of RTEMS.
*/
#if ( ARM_HAS_FPU == 1 )
#define CPU_HARDWARE_FP TRUE
#else
#define CPU_HARDWARE_FP FALSE
#endif
#define CPU_SOFTWARE_FP FALSE
/*
* Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
*
* If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
* If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
*
* So far, the only CPU in which this option has been used is the
* HP PA-RISC. The HP C compiler and gcc both implicitly use the
* floating point registers to perform integer multiplies. If
* a function which you would not think utilize the FP unit DOES,
* then one can not easily predict which tasks will use the FP hardware.
* In this case, this option should be TRUE.
*
* If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
*/
#define CPU_ALL_TASKS_ARE_FP FALSE
/*
* Should the IDLE task have a floating point context?
*
* If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
* and it has a floating point context which is switched in and out.
* If FALSE, then the IDLE task does not have a floating point context.
*
* Setting this to TRUE negatively impacts the time required to preempt
* the IDLE task from an interrupt because the floating point context
* must be saved as part of the preemption.
*/
#define CPU_IDLE_TASK_IS_FP FALSE
/*
* Should the saving of the floating point registers be deferred
* until a context switch is made to another different floating point
* task?
*
* If TRUE, then the floating point context will not be stored until
* necessary. It will remain in the floating point registers and not
* disturned until another floating point task is switched to.
*
* If FALSE, then the floating point context is saved when a floating
* point task is switched out and restored when the next floating point
* task is restored. The state of the floating point registers between
* those two operations is not specified.
*
* If the floating point context does NOT have to be saved as part of
* interrupt dispatching, then it should be safe to set this to TRUE.
*
* Setting this flag to TRUE results in using a different algorithm
* for deciding when to save and restore the floating point context.
* The deferred FP switch algorithm minimizes the number of times
* the FP context is saved and restored. The FP context is not saved
* until a context switch is made to another, different FP task.
* Thus in a system with only one FP task, the FP context will never
* be saved or restored.
*/
#define CPU_USE_DEFERRED_FP_SWITCH FALSE
/*
* Does this port provide a CPU dependent IDLE task implementation?
*
* If TRUE, then the routine _CPU_Thread_Idle_body
* must be provided and is the default IDLE thread body instead of
* _CPU_Thread_Idle_body.
*
* If FALSE, then use the generic IDLE thread body if the BSP does
* not provide one.
*
* This is intended to allow for supporting processors which have
* a low power or idle mode. When the IDLE thread is executed, then
* the CPU can be powered down.
*
* The order of precedence for selecting the IDLE thread body is:
*
* 1. BSP provided
* 2. CPU dependent (if provided)
* 3. generic (if no BSP and no CPU dependent)
*/
#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
/*
* Does the stack grow up (toward higher addresses) or down
* (toward lower addresses)?
*
* If TRUE, then the grows upward.
* If FALSE, then the grows toward smaller addresses.
*/
#define CPU_STACK_GROWS_UP FALSE
/*
* The following is the variable attribute used to force alignment
* of critical RTEMS structures. On some processors it may make
* sense to have these aligned on tighter boundaries than
* the minimum requirements of the compiler in order to have as
* much of the critical data area as possible in a cache line.
*
* The placement of this macro in the declaration of the variables
* is based on the syntactically requirements of the GNU C
* "__attribute__" extension. For example with GNU C, use
* the following to force a structures to a 32 byte boundary.
*
* __attribute__ ((aligned (32)))
*
* NOTE: Currently only the Priority Bit Map table uses this feature.
* To benefit from using this, the data must be heavily
* used so it will stay in the cache and used frequently enough
* in the executive to justify turning this on.
*/
#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32)))
/*
* Define what is required to specify how the network to host conversion
* routines are handled.
*/
#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
#define CPU_BIG_ENDIAN TRUE
#define CPU_LITTLE_ENDIAN FALSE
/*
* The following defines the number of bits actually used in the
* interrupt field of the task mode. How those bits map to the
* CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
*/
#define CPU_MODES_INTERRUPT_MASK 0x00000001
/*
* Processor defined structures
*
* Examples structures include the descriptor tables from the i386
* and the processor control structure on the i960ca.
*/
/* may need to put some structures here. */
/*
* Contexts
*
* Generally there are 2 types of context to save.
* 1. Interrupt registers to save
* 2. Task level registers to save
*
* This means we have the following 3 context items:
* 1. task level context stuff:: Context_Control
* 2. floating point task stuff:: Context_Control_fp
* 3. special interrupt level context :: Context_Control_interrupt
*
* On some processors, it is cost-effective to save only the callee
* preserved registers during a task context switch. This means
* that the ISR code needs to save those registers which do not
* persist across function calls. It is not mandatory to make this
* distinctions between the caller/callee saves registers for the
* purpose of minimizing context saved during task switch and on interrupts.
* If the cost of saving extra registers is minimal, simplicity is the
* choice. Save the same context on interrupt entry as for tasks in
* this case.
*
* Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
* care should be used in designing the context area.
*
* On some CPUs with hardware floating point support, the Context_Control_fp
* structure will not be used or it simply consist of an array of a
* fixed number of bytes. This is done when the floating point context
* is dumped by a "FP save context" type instruction and the format
* is not really defined by the CPU. In this case, there is no need
* to figure out the exact format -- only the size. Of course, although
* this is enough information for RTEMS, it is probably not enough for
* a debugger such as gdb. But that is another problem.
*/
typedef struct {
unsigned32 register_r0;
unsigned32 register_r1;
unsigned32 register_r2;
unsigned32 register_r3;
unsigned32 register_r4;
unsigned32 register_r5;
unsigned32 register_r6;
unsigned32 register_r7;
unsigned32 register_r8;
unsigned32 register_r9;
unsigned32 register_r10;
unsigned32 register_fp;
unsigned32 register_ip;
unsigned32 register_sp;
unsigned32 register_lr;
unsigned32 register_pc;
} Context_Control;
typedef struct {
double some_float_register;
} Context_Control_fp;
typedef Context_Control CPU_Exception_frame;
typedef void (*cpuExcHandlerType) (CPU_Exception_frame*);
extern cpuExcHandlerType _currentExcHandler;
extern void rtems_exception_init_mngt();
/*
* The following structure defines the set of information saved
* on the current stack by RTEMS upon receipt of each interrupt
* that will lead to re-enter the kernel to signal the thread.
*/
typedef CPU_Exception_frame CPU_Interrupt_frame;
/*
* The following table contains the information required to configure
* the XXX processor specific parameters.
*/
typedef struct {
void (*pretasking_hook)( void );
void (*predriver_hook)( void );
void (*postdriver_hook)( void );
void (*idle_task)( void );
boolean do_zero_of_workspace;
unsigned32 idle_task_stack_size;
unsigned32 interrupt_stack_size;
unsigned32 extra_mpci_receive_server_stack;
void * (*stack_allocate_hook)( unsigned32 );
void (*stack_free_hook)( void* );
/* end of fields required on all CPUs */
} rtems_cpu_table;
/*
* Macros to access required entires in the CPU Table are in
* the file rtems/system.h.
*/
/*
* Macros to access NO_CPU specific additions to the CPU Table
*/
/* There are no CPU specific additions to the CPU Table for this port. */
/*
* This variable is optional. It is used on CPUs on which it is difficult
* to generate an "uninitialized" FP context. It is filled in by
* _CPU_Initialize and copied into the task's FP context area during
* _CPU_Context_Initialize.
*/
SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
/*
* On some CPUs, RTEMS supports a software managed interrupt stack.
* This stack is allocated by the Interrupt Manager and the switch
* is performed in _ISR_Handler. These variables contain pointers
* to the lowest and highest addresses in the chunk of memory allocated
* for the interrupt stack. Since it is unknown whether the stack
* grows up or down (in general), this give the CPU dependent
* code the option of picking the version it wants to use.
*
* NOTE: These two variables are required if the macro
* CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
*/
SCORE_EXTERN void *_CPU_Interrupt_stack_low;
SCORE_EXTERN void *_CPU_Interrupt_stack_high;
/*
* With some compilation systems, it is difficult if not impossible to
* call a high-level language routine from assembly language. This
* is especially true of commercial Ada compilers and name mangling
* C++ ones. This variable can be optionally defined by the CPU porter
* and contains the address of the routine _Thread_Dispatch. This
* can make it easier to invoke that routine at the end of the interrupt
* sequence (if a dispatch is necessary).
*/
SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
/*
* Nothing prevents the porter from declaring more CPU specific variables.
*/
/* XXX: if needed, put more variables here */
/*
* The size of the floating point context area. On some CPUs this
* will not be a "sizeof" because the format of the floating point
* area is not defined -- only the size is. This is usually on
* CPUs with a "floating point save context" instruction.
*/
#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
/*
* Amount of extra stack (above minimum stack size) required by
* MPCI receive server thread. Remember that in a multiprocessor
* system this thread must exist and be able to process all directives.
*/
#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
/*
* This defines the number of entries in the ISR_Vector_table managed
* by RTEMS.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 8
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Should be large enough to run all RTEMS tests. This insures
* that a "reasonable" small application should not have any problems.
*/
#define CPU_STACK_MINIMUM_SIZE (1024*4)
/*
* CPU's worst alignment requirement for data types on a byte boundary. This
* alignment does not take into account the requirements for the stack.
*/
#define CPU_ALIGNMENT 8
/*
* This number corresponds to the byte alignment requirement for the
* heap handler. This alignment requirement may be stricter than that
* for the data types alignment specified by CPU_ALIGNMENT. It is
* common for the heap to follow the same alignment requirement as
* CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
* then this should be set to CPU_ALIGNMENT.
*
* NOTE: This does not have to be a power of 2. It does have to
* be greater or equal to than CPU_ALIGNMENT.
*/
#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
/*
* This number corresponds to the byte alignment requirement for memory
* buffers allocated by the partition manager. This alignment requirement
* may be stricter than that for the data types alignment specified by
* CPU_ALIGNMENT. It is common for the partition to follow the same
* alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
* enough for the partition, then this should be set to CPU_ALIGNMENT.
*
* NOTE: This does not have to be a power of 2. It does have to
* be greater or equal to than CPU_ALIGNMENT.
*/
#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
/*
* This number corresponds to the byte alignment requirement for the
* stack. This alignment requirement may be stricter than that for the
* data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
* is strict enough for the stack, then this should be set to 0.
*
* NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
*/
#define CPU_STACK_ALIGNMENT 32
/* ISR handler macros */
/*
* Disable all interrupts for an RTEMS critical section. The previous
* level is returned in _level.
*/
#define _CPU_ISR_Disable( _level ) \
{ \
asm volatile ("MRS r0, cpsr \n" ); \
asm volatile ("ORR r0, r0, #0xc0 \n" ); \
asm volatile ("MSR cpsr, r0 \n" ); \
}
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
* _level is not modified.
*/
#define _CPU_ISR_Enable( _level ) \
{ \
asm volatile ("MRS r0, cpsr \n" ); \
asm volatile ("AND r0, r0, #0xFFFFFF3F \n" ); \
asm volatile ("MSR cpsr, r0 \n" ); \
}
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long RTEMS critical
* sections into two or more parts. The parameter _level is not
* modified.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
{ \
}
/*
* Map interrupt level in task mode onto the hardware that the CPU
* actually provides. Currently, interrupt levels which do not
* map onto the CPU in a generic fashion are undefined. Someday,
* it would be nice if these were "mapped" by the application
* via a callout. For example, m68k has 8 levels 0 - 7, levels
* 8 - 255 would be available for bsp/application specific meaning.
* This could be used to manage a programmable interrupt controller
* via the rtems_task_mode directive.
*
* The get routine usually must be implemented as a subroutine.
*/
#define _CPU_ISR_Set_level( new_level ) \
{ \
}
unsigned32 _CPU_ISR_Get_level( void );
/* end of ISR handler macros */
/* Context handler macros */
/*
* Initialize the context to a state suitable for starting a
* task after a context restore operation. Generally, this
* involves:
*
* - setting a starting address
* - preparing the stack
* - preparing the stack and frame pointers
* - setting the proper interrupt level in the context
* - initializing the floating point context
*
* This routine generally does not set any unnecessary register
* in the context. The state of the "general data" registers is
* undefined at task start time.
*
* NOTE: This is_fp parameter is TRUE if the thread is to be a floating
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point, _is_fp ) \
{ \
(_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \
(_the_context)->register_pc = (_entry_point); \
}
/*
* This routine is responsible for somehow restarting the currently
* executing task. If you are lucky, then all that is necessary
* is restoring the context. Otherwise, there will need to be
* a special assembly routine which does something special in this
* case. Context_Restore should work most of the time. It will
* not work if restarting self conflicts with the stack frame
* assumptions of restoring a context.
*/
#define _CPU_Context_Restart_self( _the_context ) \
_CPU_Context_restore( (_the_context) );
/*
* The purpose of this macro is to allow the initial pointer into
* a floating point context area (used to save the floating point
* context) to be at an arbitrary place in the floating point
* context area.
*
* This is necessary because some FP units are designed to have
* their context saved as a stack which grows into lower addresses.
* Other FP units can be saved by simply moving registers into offsets
* from the base of the context area. Finally some FP units provide
* a "dump context" instruction which could fill in from high to low
* or low to high based on the whim of the CPU designers.
*/
#define _CPU_Context_Fp_start( _base, _offset ) \
( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
/*
* This routine initializes the FP context area passed to it to.
* There are a few standard ways in which to initialize the
* floating point context. The code included for this macro assumes
* that this is a CPU in which a "initial" FP context was saved into
* _CPU_Null_fp_context and it simply copies it to the destination
* context passed to it.
*
* Other models include (1) not doing anything, and (2) putting
* a "null FP status word" in the correct place in the FP context.
*/
#define _CPU_Context_Initialize_fp( _destination ) \
{ \
*((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
}
/* end of Context handler macros */
/* Fatal Error manager macros */
/*
* This routine copies _error into a known place -- typically a stack
* location or a register, optionally disables interrupts, and
* halts/stops the CPU.
*/
#define _CPU_Fatal_halt( _error ) \
{ \
}
/* end of Fatal Error manager macros */
/* Bitfield handler macros */
/*
* This routine sets _output to the bit number of the first bit
* set in _value. _value is of CPU dependent type Priority_Bit_map_control.
* This type may be either 16 or 32 bits wide although only the 16
* least significant bits will be used.
*
* There are a number of variables in using a "find first bit" type
* instruction.
*
* (1) What happens when run on a value of zero?
* (2) Bits may be numbered from MSB to LSB or vice-versa.
* (3) The numbering may be zero or one based.
* (4) The "find first bit" instruction may search from MSB or LSB.
*
* RTEMS guarantees that (1) will never happen so it is not a concern.
* (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
* _CPU_Priority_bits_index(). These three form a set of routines
* which must logically operate together. Bits in the _value are
* set and cleared based on masks built by _CPU_Priority_mask().
* The basic major and minor values calculated by _Priority_Major()
* and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
* to properly range between the values returned by the "find first bit"
* instruction. This makes it possible for _Priority_Get_highest() to
* calculate the major and directly index into the minor table.
* This mapping is necessary to ensure that 0 (a high priority major/minor)
* is the first bit found.
*
* This entire "find first bit" and mapping process depends heavily
* on the manner in which a priority is broken into a major and minor
* components with the major being the 4 MSB of a priority and minor
* the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
* priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
* to the lowest priority.
*
* If your CPU does not have a "find first bit" instruction, then
* there are ways to make do without it. Here are a handful of ways
* to implement this in software:
*
* - a series of 16 bit test instructions
* - a "binary search using if's"
* - _number = 0
* if _value > 0x00ff
* _value >>=8
* _number = 8;
*
* if _value > 0x0000f
* _value >=8
* _number += 4
*
* _number += bit_set_table[ _value ]
*
* where bit_set_table[ 16 ] has values which indicate the first
* bit set
*/
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
{ \
(_output) = 0; /* do something to prevent warnings */ \
}
#endif
/* end of Bitfield handler macros */
/*
* This routine builds the mask which corresponds to the bit fields
* as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
* for that routine.
*/
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Priority_Mask( _bit_number ) \
( 1 << (_bit_number) )
#endif
/*
* This routine translates the bit numbers returned by
* _CPU_Bitfield_Find_first_bit() into something suitable for use as
* a major or minor component of a priority. See the discussion
* for that routine.
*/
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
#endif
/* end of Priority handler macros */
/* functions */
/*
* _CPU_Initialize
*
* This routine performs CPU dependent initialization.
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch)
);
typedef enum {
ARM_EXCEPTION_RESET = 0,
ARM_EXCEPTION_UNDEF = 1,
ARM_EXCEPTION_SWI = 2,
ARM_EXCEPTION_PREF_ABORT = 3,
ARM_EXCEPTION_DATA_ABORT = 4,
ARM_EXCEPTION_RESERVED = 5,
ARM_EXCEPTION_IRQ = 6,
ARM_EXCEPTION_FIQ = 7,
MAX_EXCEPTIONS = 8
} Arm_symbolic_exception_name;
/*
* _CPU_ISR_install_vector
*
* This routine installs an interrupt vector.
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
);
/*
* _CPU_Install_interrupt_stack
*
* This routine installs the hardware interrupt stack pointer.
*
* NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
* is TRUE.
*/
void _CPU_Install_interrupt_stack( void );
/*
* _CPU_Thread_Idle_body
*
* This routine is the CPU dependent IDLE thread body.
*
* NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
* is TRUE.
*/
void _CPU_Thread_Idle_body( void );
/*
* _CPU_Context_switch
*
* This routine switches from the run context to the heir context.
*/
void _CPU_Context_switch(
Context_Control *run,
Context_Control *heir
);
/*
* _CPU_Context_restore
*
* This routine is generally used only to restart self in an
* efficient manner. It may simply be a label in _CPU_Context_switch.
*
* NOTE: May be unnecessary to reload some registers.
*/
void _CPU_Context_restore(
Context_Control *new_context
);
/*
* _CPU_Context_save_fp
*
* This routine saves the floating point context passed to it.
*/
void _CPU_Context_save_fp(
void **fp_context_ptr
);
/*
* _CPU_Context_restore_fp
*
* This routine restores the floating point context passed to it.
*/
void _CPU_Context_restore_fp(
void **fp_context_ptr
);
/* The following routine swaps the endian format of an unsigned int.
* It must be static because it is referenced indirectly.
*
* This version will work on any processor, but if there is a better
* way for your CPU PLEASE use it. The most common way to do this is to:
*
* swap least significant two bytes with 16-bit rotate
* swap upper and lower 16-bits
* swap most significant two bytes with 16-bit rotate
*
* Some CPUs have special instructions which swap a 32-bit quantity in
* a single instruction (e.g. i486). It is probably best to avoid
* an "endian swapping control bit" in the CPU. One good reason is
* that interrupts would probably have to be disabled to insure that
* an interrupt does not try to access the same "chunk" with the wrong
* endian. Another good reason is that on some CPUs, the endian bit
* endianness for ALL fetches -- both code and data -- so the code
* will be fetched incorrectly.
*/
static inline unsigned int CPU_swap_u32(
unsigned int value
)
{
unsigned32 byte1, byte2, byte3, byte4, swapped;
byte4 = (value >> 24) & 0xff;
byte3 = (value >> 16) & 0xff;
byte2 = (value >> 8) & 0xff;
byte1 = value & 0xff;
swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
return( swapped );
}
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
* cpu_asm.h
*
* Very loose template for an include file for the cpu_asm.? file
* if it is implemented as a ".S" file (preprocessed by cpp) instead
* of a ".s" file (preprocessed by gm4 or gasp).
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*
*/
#ifndef __CPU_ASM_h
#define __CPU_ASM_h
/* pull in the generated offsets */
#include <rtems/score/offsets.h>
/*
* Hardware General Registers
*/
/* put something here */
/*
* Hardware Floating Point Registers
*/
/* put something here */
/*
* Hardware Control Registers
*/
/* put something here */
/*
* Calling Convention
*/
/* put something here */
/*
* Temporary registers
*/
/* put something here */
/*
* Floating Point Registers - SW Conventions
*/
/* put something here */
/*
* Temporary floating point registers
*/
/* put something here */
#endif
/* end of file */

View File

@@ -0,0 +1,55 @@
/* armtypes.h
*
* This include file contains type definitions pertaining to the
* arm processor family.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __ARM_TYPES_h
#define __ARM_TYPES_h
#ifndef ASM
#ifdef __cplusplus
extern "C" {
#endif
/*
* This section defines the basic types for this processor.
*/
typedef unsigned char unsigned8; /* unsigned 8-bit integer */
typedef unsigned short unsigned16; /* unsigned 16-bit integer */
typedef unsigned int unsigned32; /* unsigned 32-bit integer */
typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
typedef unsigned16 Priority_Bit_map_control;
typedef signed char signed8; /* 8-bit signed integer */
typedef signed short signed16; /* 16-bit signed integer */
typedef signed int signed32; /* 32-bit signed integer */
typedef signed long long signed64; /* 64 bit signed integer */
typedef unsigned32 boolean; /* Boolean value */
typedef float single_precision; /* single precision float */
typedef double double_precision; /* double precision float */
typedef void no_cpu_isr;
typedef void ( *no_cpu_isr_entry )( void );
#ifdef __cplusplus
}
#endif
#endif /* !ASM */
#endif
/* end of include file */

View File

@@ -0,0 +1,13 @@
Makefile
Makefile.in
aclocal.m4
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
mkinstalldirs

View File

@@ -0,0 +1,14 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
## Descend into the $(RTEMS_BSP_FAMILY) directory
## Currently, the shared directory is not explicitly
## added but it is present in the source tree.
SUBDIRS = shared $(RTEMS_BSP_FAMILY)
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,13 @@
Makefile
Makefile.in
aclocal.m4
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
mkinstalldirs

View File

@@ -0,0 +1,15 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
SUBDIRS = . include console startup start irq wrapup
EXTRA_DIST = bsp_specs
include $(top_srcdir)/../../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,23 @@
%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__ -DUSE_ENHANCED_INTR_API} -Asystem(embedded)
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group \
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
-lc -lgcc --end-group \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:
%{!qrtems: %(old_startfile)} %{qrtems: \
%{!qrtems_debug: start.o%s crtbegin.o%s} \
%{qrtems_debug: start_g.o%s crtbegin.o%s}}
*link:
%{!qrtems: %(old_link)} %{qrtems: -Qy -dp -Bstatic -T linkcmds%s -e _start}

View File

@@ -0,0 +1,43 @@
dnl Process this file with autoconf to produce a configure script.
dnl
dnl $Id$
AC_PREREQ(2.13)
AC_INIT(bsp_specs)
RTEMS_TOP(../../../../../..)
AC_CONFIG_AUX_DIR(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE(rtems-c-src-lib-libbsp-arm-arm_bare_bsp,$RTEMS_VERSION,no)
AM_MAINTAINER_MODE
RTEMS_PROG_CC_FOR_TARGET
RTEMS_CANONICALIZE_TOOLS
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
RTEMS_CHECK_NETWORKING
RTEMS_CANONICAL_HOST
dnl if this is an i386, does gas have good code16 support?
RTEMS_I386_GAS_CODE16
AM_CONDITIONAL(RTEMS_GAS_CODE16,test "$RTEMS_GAS_CODE16" = "yes");
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
AC_CONFIG_SUBDIRS(tools)
AC_SUBST(RTEMS_BSP)
RTEMS_PROJECT_ROOT
# Explicitly list all Makefiles here
AC_OUTPUT(
Makefile
console/Makefile
include/Makefile
irq/Makefile
start/Makefile
startup/Makefile
wrapup/Makefile)

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,32 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@/../../shared/comm:@srcdir@/../../shared/io
PGM = $(ARCH)/console.rel
C_FILES = uart.c console.c printk.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
H_FILES = uart.h bspio.h
console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(console_rel_OBJECTS)
$(make-rel)
all: $(ARCH) $(console_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,24 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = bsp.h registers.h
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/coverhd.h: $(top_srcdir)/../../shared/include/coverhd.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h)
all: $(PREINSTALL_FILES)
EXTRA_DIST = bspio.h bsp.h uart.h registers.h
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,33 @@
/*-------------------------------------------------------------------------+
| bsp.h - ARM BSP
+--------------------------------------------------------------------------+
| This include file contains definitions related to the ARM BSP.
+--------------------------------------------------------------------------+
|
| Copyright (c) Canon Research France SA.]
| Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
| The license and distribution terms for this file may be
| found in found in the file LICENSE in this distribution or at
| http://www.OARcorp.com/rtems/license.html.
|
| $Id$
+--------------------------------------------------------------------------*/
#ifndef __BSP_H_
#define __BSP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <iosupp.h>
#include <console.h>
#include <clockdrv.h>
#endif /* __BSP_H_ */
/* end of include file */

View File

@@ -0,0 +1,53 @@
/*
* BSP registers declaration
*
* Copyright (c) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __REGS_H__
#define __REGS_H__
/*
* VARIABLE DECLARATION
*/
#ifndef __asm__
extern volatile unsigned long *Regs; /* Chip registers */
#endif
/*
* Here must be "defined" each register, to use with Regs as
* LM_Regs[REGISTER1] = value
*/
#define REGISTER1 1
#define REGISTER2 2
/*
* define for UART registers to be able
* to compile and link arm_bare_bsp
*/
#define RSRBR 0
#define RSTHR 1
#define RSIER 2
#define RSIIR 3
#define RSFCR 4
#define RSLCR 5
#define RSLSR 6
#define RSDLL 7
#define RSDLH 8
#define RSCNT 9
#endif /*__REGS_H__*/

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,44 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../shared/irq
PGM = $(ARCH)/irq.rel
C_FILES = irq.c irq_init.c bsp_irq_init.c
S_FILES = irq_asm.S bsp_irq_asm.S
H_FILES = irq.h
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
irq_rel_OBJECTS = $(C_O_FILES) $(S_O_FILES)
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(startup_rel_OBJECTS)
$(make-rel)
all: $(PREINSTALL_FILES) $(ARCH) $(irq_rel_OBJECTS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = irq.c bsp_irq_init.c bsp_irq_asm.S
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,44 @@
/* bsp_irq_asm.S
*
* This file contains the implementation of the IRQ handler
* for a specific BSP
*
* CopyRight (C) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#define __asm__
#include <registers.h>
/*
* Function to obtain, execute an IT handler and acknowledge the IT
*/
.globl ExecuteITHandler
ExecuteITHandler :
/*
* Here is the code to execute the appropriate INT handler
*/
b ReturnFromHandler /* return to ISR handler */
/*
* Function to acknowledge the IT controller
*/
.globl AckControler
AckControler:
/*
* Here is the code to acknowledge the PIC
*/
b ReturnFromAck /* return to ISR handler */

View File

@@ -0,0 +1,27 @@
/* irq_init.c
*
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*
* CopyRight (C) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <irq.h>
#include <bsp.h>
#include <registers.h>
void BSP_rtems_irq_mngt_init() {
/*
* Here is the code to initialize the INT for
* the specified BSP
*/
}

View File

@@ -0,0 +1,119 @@
/* irq.c
*
* This file contains the implementation of the function described in irq.h
*
* CopyRight (C) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
#include <irq.h>
#include <registers.h>
#include <rtems/score/thread.h>
#include <rtems/score/apiext.h>
/*
* This function check that the value given for the irq line
* is valid.
*/
static int isValidInterrupt(int irq)
{
if ( (irq < 0) || (irq > BSP_MAX_INT))
return 0;
return 1;
}
/*
* ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
*/
int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_irq_hdl *HdlTable;
if (!isValidInterrupt(irq->name)) {
return 0;
}
/*
* Check if default handler is actually connected. If not issue an error.
*/
HdlTable = VECTOR_TABLE;
if (*(HdlTable + irq->name) != default_int_handler) {
return 0;
}
_CPU_ISR_Disable(level);
/*
* store the new handler
*/
*(HdlTable + irq->name) = irq->hdl;
/*
* Here is the code to install an interrupt vector
* for the BSP : unmask INT, ....
* ........................
*/
_CPU_ISR_Enable(level);
return 1;
}
int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
{
rtems_irq_hdl *HdlTable;
if (!isValidInterrupt(irq->name)) {
return 0;
}
/*
* Check if the handler is actually connected. If not issue an error.
*/
HdlTable = VECTOR_TABLE;
if (*(HdlTable + irq->name) != irq->hdl) {
return 0;
}
_CPU_ISR_Disable(level);
/*
* Here is the code to uninstall an interrupt vector
* for the BSP : mask INT, ....
* ........................
*/
/*
* restore the default irq value
*/
*(HdlTable + irq->name) = default_int_handler;
_CPU_ISR_Enable(level);
return 1;
}
void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx)
{
/*
* Process pending signals that have not already been
* processed by _Thread_Displatch. 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();
}
}

View File

@@ -0,0 +1,168 @@
/* irq.h
*
* This include file describe the data structure and the functions implemented
* by rtems to write interrupt handlers.
*
* Copyright (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef _IRQ_H_
#define _IRQ_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Include some preprocessor value also used by assember code
*/
#include <rtems.h>
extern void default_int_handler();
/*-------------------------------------------------------------------------+
| Constants
+--------------------------------------------------------------------------*/
/* enum of the possible interrupt sources */
typedef enum {
BSP_INT_1 = 0,
BSP_INT_2 = 1,
BSP_UART = 2,
BSP_MAX_INT = 3
} rtems_irq_symbolic_name;
/* define that can be useful (the values are just examples) */
#define INTMASK 0x01
#define VECTOR_TABLE 0x00
/*
* Type definition for RTEMS managed interrupts
*/
typedef unsigned char rtems_irq_level;
typedef unsigned char rtems_irq_trigger;
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__*);
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 i8259s 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 i8259s 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 i8259s interrupt mask without care...
*/
rtems_irq_is_enabled isOn;
/*
* priority level at the vplus 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 ----------------
*/
/*
* function to initialize the interrupt for a specific BSP
*/
void BSP_rtems_irq_mngt_init();
/*
* 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);
/*
* 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_ */
/* end of include file */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,33 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGMS = $(ARCH)/start.o
S_FILES = start.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
OBJS = $(S_O_FILES)
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
LINKCMDS = $(top_srcdir)/startup/linkcmds
$(PROJECT_RELEASE)/lib/start$(LIB_VARIANT).o: $(ARCH)/start.o
$(INSTALL_DATA) $< $@
all: $(ARCH) $(OBJS) $(TMPINSTALL_FILES)
EXTRA_DIST = start.S
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,157 @@
/*
* start.S : RTEMS entry point
*
* Copyright (C) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
.equ ABORT_Stack, 0
.equ IRQ_Stack, 0x100
.equ FIQ_Stack, 0x200
.equ SVC_Stack, 0x300
/* Some standard definitions...*/
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_ABORT, 0x17
.equ Mode_UNDEF, 0x1B
.equ Mode_SYS, 0x1F /*only available on ARM Arch. v4*/
.equ I_Bit, 0x80
.equ F_Bit, 0x40
.text
.globl _start
_start:
/*
* Here is the code to initialize the low-level BSP environment
* (Chip Select, PLL, ....?)
/* Copy data from FLASH to RAM */
LDR r0, =_initdata /* load address of region */
LDR r1, =0x400000 /* execution address of region */
LDR r2, =_edata /* copy execution address into r2 */
copy:
CMP r1, r2 /* loop whilst r1 < r2 */
LDRLO r3, [r0], #4
STRLO r3, [r1], #4
BLO copy
/* zero the bss */
LDR r1, =__bss_end__ /* get end of ZI region */
LDR r0, =__bss_start__ /* load base address of ZI region */
zi_init:
MOV r2, #0
CMP r0, r1 /* loop whilst r0 < r1 */
STRLOT r2, [r0], #4
BLO zi_init
/* Load basic ARM7 interrupt table */
VectorInit:
MOV R8, #0
ADR R9, Vector_Init_Block
LDMIA R9!, {R0-R7} /* Copy the Vectors (8 words) */
STMIA R8!, {R0-R7}
LDMIA R9!, {R0-R7} /* Copy the .long'ed addresses (8 words) */
STMIA R8!, {R0-R7}
B init2
/*******************************************************
standard exception vectors table
*** Must be located at address 0
********************************************************/
Vector_Init_Block:
LDR PC, Reset_Addr
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
NOP
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
.globl Reset_Addr
Reset_Addr: .long _start
Undefined_Addr: .long Undefined_Handler
SWI_Addr: .long SWI_Handler
Prefetch_Addr: .long Prefetch_Handler
Abort_Addr: .long Abort_Handler
.long 0
IRQ_Addr: .long IRQ_Handler
FIQ_Addr: .long FIQ_Handler
/* The following handlers do not do anything useful */
.globl Undefined_Handler
Undefined_Handler:
B Undefined_Handler
.globl SWI_Handler
SWI_Handler:
B SWI_Handler
.globl Prefetch_Handler
Prefetch_Handler:
B Prefetch_Handler
.globl Abort_Handler
Abort_Handler:
B Abort_Handler
.globl IRQ_Handler
IRQ_Handler:
B IRQ_Handler
.globl FIQ_Handler
FIQ_Handler:
B FIQ_Handler
init2 :
/* --- Initialise stack pointer registers
Set up the ABORT stack pointer last and stay in SVC mode */
MOV r0, #(Mode_ABORT | I_Bit | F_Bit) /* No interrupts */
MSR cpsr, r0
LDR sp, =ABORT_Stack
/* Enter IRQ mode and set up the IRQ stack pointer */
MOV r0, #Mode_IRQ | I_Bit | F_Bit /* No interrupts */
MSR cpsr, r0
LDR sp, =IRQ_Stack
/* Enter FIQ mode and set up the FIQ stack pointer */
MOV r0, #Mode_FIQ | I_Bit | F_Bit /* No interrupts */
MSR cpsr, r0
LDR sp, =FIQ_Stack
/* Set up the SVC stack pointer last and stay in SVC mode */
MOV r0, #Mode_SVC | I_Bit | F_Bit /* No interrupts */
MSR cpsr, r0
LDR sp, =SVC_Stack
/* --- Now we enter the C code */
B boot_card

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,41 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../../shared
C_FILES = bsplibc.c bsppost.c bspstart.c exit.c bootcard.c main.c sbrk.c gnatinstallhandler.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_FILES =
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
startup_rel_OBJECTS = $(C_O_FILES) $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
# USE_INIT_FINI tells main.c what C++ help we need.
$(PGM): $(startup_rel_OBJECTS)
$(make-rel)
$(PROJECT_RELEASE)/lib/linkcmds: linkcmds
$(INSTALL_DATA) $< $@
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/linkcmds
all: $(ARCH) $(startup_rel_OBJECTS) $(PGM) $(TMPINSTALL_FILES)
.PRECIOUS: $(PGM)
EXTRA_DIST = linkcmds
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,164 @@
/*-------------------------------------------------------------------------+
| This file contains the ARM 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.
+--------------------------------------------------------------------------+
|
| Copyright (c) 2000 Canon Research Centre France SA.
| Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
| The license and distribution terms for this file may be
| found in found in the file LICENSE in this distribution or at
| http://www.OARcorp.com/rtems/license.html.
|
+--------------------------------------------------------------------------*/
#include <bsp.h>
#include <uart.h>
#include <libcsupport.h>
#include <rtems/libio.h>
/*-------------------------------------------------------------------------+
| Global Variables
+--------------------------------------------------------------------------*/
/*
* must be initialized with the right address
*/
volatile unsigned long *Regs = (unsigned long*)0xdeadbeef; /* Chip registers */
extern rtems_unsigned32 _end; /* End of BSS. Defined in 'linkcmds'. */
/*
* 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;
/* Size of stack used during initialization. Defined in 'start.s'. */
extern rtems_unsigned32 _stack_size;
rtems_unsigned32 rtemsFreeMemStart;
/* Address of start of free memory - should be updated
after creating new partitions or regions. */
/* The original BSP configuration table from the application and our copy of it
with some changes. */
extern rtems_configuration_table Configuration;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table; /* CPU configuration table. */
char *rtems_progname; /* Program name - from main(). */
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern void rtems_irq_mngt_init(void);
void bsp_libc_init( void *, unsigned32, int );
void bsp_postdriver_hook(void);
/*-------------------------------------------------------------------------+
| Function: bsp_pretasking_hook
| Description: 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.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void bsp_pretasking_hook(void)
{
if(_heap_size == 0)
{
_heap_size = 0x420000 - rtemsFreeMemStart;
}
bsp_libc_init((void *)rtemsFreeMemStart, _heap_size, 0);
rtemsFreeMemStart += _heap_size; /* HEAP_SIZE in KBytes */
#ifdef RTEMS_DEBUG
rtems_debug_enable(RTEMS_DEBUG_ALL_MASK);
#endif /* RTEMS_DEBUG */
} /* bsp_pretasking_hook */
/*-------------------------------------------------------------------------+
| Function: bsp_start
| Description: Called before main is invoked.
| Global Variables: None.
| Arguments: None.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void bsp_start_default( void )
{
rtemsFreeMemStart = (rtems_unsigned32)(&_end); /* &_end+_stack_size;*/
/* set the value of start of free memory. */
/* 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;
/* do not override system IDLE task */
Cpu_table.do_zero_of_workspace = TRUE;
Cpu_table.interrupt_stack_size = 4096;
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;
console_reserve_resources(&BSP_Configuration);
/*
* Init rtems exceptions management
*/
rtems_exception_init_mngt();
/*
* Init rtems interrupt management
*/
rtems_irq_mngt_init();
/*
* The following information is very useful when debugging.
*/
#if 0
printk( "work_space_size = 0x%x\n", 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 );
printk( "_heap_size = 0x%x\n", _heap_size );
/* printk( "_stack_size = 0x%x\n", _stack_size );*/
printk( "rtemsFreeMemStart = 0x%x\n", rtemsFreeMemStart );
printk( "work_space_start = 0x%x\n", BSP_Configuration.work_space_start );
printk( "work_space_size = 0x%x\n", BSP_Configuration.work_space_size );
#endif
} /* bsp_start */
/*
* 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")));

View File

@@ -0,0 +1,48 @@
/*-------------------------------------------------------------------------+
| exit.c - ARM BSP
+--------------------------------------------------------------------------+
| Routines to shutdown and reboot the BSP.
+--------------------------------------------------------------------------+
|
| Copyright (c) 2000 Canon Research Centre France SA.
| Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
| The license and distribution terms for this file may be
| found in found in the file LICENSE in this distribution or at
| http://www.OARcorp.com/rtems/license.html.
|
+--------------------------------------------------------------------------*/
#include <stdio.h>
#include <bsp.h>
#include <bspio.h>
#include <rtems/libio.h>
void rtemsReboot (void)
{
asm volatile ("b _start");
}
void bsp_cleanup(void)
{
unsigned char ch;
static char line[]="\nEXECUTIVE SHUTDOWN! Any key to reboot...";
/*
* AT this point, the console driver is disconnected => we must
* use polled output/input. This is exactly what printk
* does.
*/
printk("\n");
printk(line);
ch = BSP_poll_char();
rtemsReboot();
}

View File

@@ -0,0 +1,240 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SEARCH_DIR(/usr/local/rtems-arm-dev-tools/arm-rtems/lib);
MEMORY {
FLASH (rx) : ORIGIN = 0x200000, LENGTH = 512K
RAM (!rx) : ORIGIN = 0x400000, LENGTH = 128K
}
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
/* . = 0 + SIZEOF_HEADERS;*/
.hash : { *(.hash) } > FLASH
.dynsym : { *(.dynsym) } > FLASH
.dynstr : { *(.dynstr) } > FLASH
.gnu.version : { *(.gnu.version) } > FLASH
.gnu.version_d : { *(.gnu.version_d) } > FLASH
.gnu.version_r : { *(.gnu.version_r) } > FLASH
.rel.init : { *(.rel.init) } > FLASH
.rela.init : { *(.rela.init) } > FLASH
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
} > FLASH
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
} > FLASH
.rel.fini : { *(.rel.fini) } > FLASH
.rela.fini : { *(.rela.fini) } > FLASH
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
} > FLASH
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
} > FLASH
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
} > FLASH
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
} > FLASH
.rel.ctors : { *(.rel.ctors) } > FLASH
.rela.ctors : { *(.rela.ctors) } > FLASH
.rel.dtors : { *(.rel.dtors) } > FLASH
.rela.dtors : { *(.rela.dtors) } > FLASH
.rel.got : { *(.rel.got) } > FLASH
.rela.got : { *(.rela.got) } > FLASH
.rel.sdata :
{
*(.rel.sdata)
*(.rel.sdata.*)
*(.rel.gnu.linkonce.s*)
} > FLASH
.rela.sdata :
{
*(.rela.sdata)
*(.rela.sdata.*)
*(.rela.gnu.linkonce.s*)
} > FLASH
.rel.sbss : { *(.rel.sbss) } > FLASH
.rela.sbss : { *(.rela.sbss) } > FLASH
.rel.bss : { *(.rel.bss) } > FLASH
.rela.bss : { *(.rela.bss) } > FLASH
.rel.plt : { *(.rel.plt) } > FLASH
.rela.plt : { *(.rela.plt) } > FLASH
.init :
{
KEEP (*(.init))
} > FLASH /*=0*/
.plt : { *(.plt) } > FLASH
.text :
{
*(.text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7t) *(.glue_7)
} > FLASH /*=0*/
_etext = .;
PROVIDE (etext = .);
.fini :
{
KEEP (*(.fini))
} > FLASH /*=0*/
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) } > FLASH
.rodata1 : { *(.rodata1) } > FLASH
_erodata = ABSOLUTE(.);
PROVIDE (erodata = ABSOLUTE(.));
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN(256);
_begdata = ALIGN(256);
.arm_end_text :
{
. = ALIGN(256);
_initdata = ALIGN(256);
} > FLASH
.data : AT (_begdata)
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
SORT(CONSTRUCTORS)
} > RAM
.data1 : { *(.data1) } > RAM
.eh_frame : { *(.eh_frame) } > RAM
.gcc_except_table : { *(.gcc_except_table) } > RAM
.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
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))
} > RAM
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} > RAM
.got : { *(.got.plt) *(.got) } > RAM
.dynamic : { *(.dynamic) } > RAM
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
} > RAM
.arm_data :
{
_edata = .;
__bss_start = .;
__bss_start__ = .;
} > RAM
.sbss :
{
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
} > RAM
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
} > RAM
. = ALIGN(32 / 8);
.arm_end :
{
_end = .;
_bss_end__ = . ;
__bss_end__ = . ;
__end__ = . ;
} > RAM
/* 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) }
.comment 0 : { *(.comment) }
/* 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) }
/* 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) }
/*.stack 0x80000 : { _stack = .; *(.stack) }*/
/* These must appear regardless of . */
}

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,32 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
BSP_PIECES = console startup irq
# bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS = $(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/*.o)
LIB = $(ARCH)/libbsp.a
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
$(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a: $(LIB)
$(INSTALL_DATA) $< $@
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/libbsp$(LIB_VARIANT).a
all: $(ARCH) $(OBJS) $(LIB) $(TMPINSTALL_FILES)
.PRECIOUS: $(LIB)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,28 @@
dnl Process this file with autoconf to produce a configure script.
dnl
dnl $Id$
AC_PREREQ(2.13)
AC_INIT(arm_bare_bsp)
RTEMS_TOP(../../../../..)
AC_CONFIG_AUX_DIR(../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE(rtems-c-src-lib-libbsp-arm,$RTEMS_VERSION,no)
AM_MAINTAINER_MODE
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
RTEMS_PROJECT_ROOT
RTEMS_BSP_ALIAS(${RTEMS_BSP},bspdir)
AC_CONFIG_SUBDIRS($bspdir)
# Explicitly list all Makefiles here
AC_OUTPUT(
Makefile
shared/Makefile
shared/comm/Makefile
shared/io/Makefile
shared/irq/Makefile)

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,10 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = comm io irq
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,22 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = uart.h
C_FILES = console.c uart.c
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h)
all: $(PREINSTALL_FILES)
EXTRA_DIST = console.c uart.c uart.h
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,367 @@
/*-------------------------------------------------------------------------+
| console.c - ARM BSP
+--------------------------------------------------------------------------+
| This file contains the ARM console I/O package.
+--------------------------------------------------------------------------+
| COPYRIGHT (c) 2000 Canon Research France SA.
| Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
| The license and distribution terms for this file may be
| found in found in the file LICENSE in this distribution or at
| http://www.OARcorp.com/rtems/license.html.
|
| $Id$
+--------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#undef __assert
void __assert (const char *file, int line, const char *msg);
#include <bsp.h>
#include <bspio.h>
#include <irq.h>
#include <rtems/libio.h>
#include <termios.h>
#include <registers.h>
#include <uart.h>
/*
* Possible value for console input/output :
* BSP_CONSOLE_PORT_CONSOLE
* BSP_UART_COM1
* BSP_UART_COM2
*
* Note:
* 1. Currently BSPPrintkPort, cannot be assigned to COM2,
* it will be fixed soon.
*
* 2. If both BSPConsolePort and BSPPrintkport are assigned
* to same serial device it does not work that great
*/
int BSPConsolePort = BSP_UART_COM1;
int BSPPrintkPort = BSP_UART_COM1;
int BSPBaseBaud = 115200;
/*-------------------------------------------------------------------------+
| External Prototypes
+--------------------------------------------------------------------------*/
extern char BSP_wait_polled_input(void);
extern BSP_polling_getchar_function_type BSP_poll_char;
extern void rtemsReboot(void);
static int conSetAttr(int minor, const struct termios *);
static void isr_on(const rtems_irq_connect_data *);
static void isr_off(const rtems_irq_connect_data *);
static int isr_is_on(const rtems_irq_connect_data *);
/*
* BSP initialization
*/
BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
BSP_polling_getchar_function_type BSP_poll_char = BSP_poll_char_via_serial;
static rtems_irq_connect_data console_isr_data = {BSP_UART,
BSP_uart_termios_isr_com1,
isr_on,
isr_off,
isr_is_on};
static void
isr_on(const rtems_irq_connect_data *unused)
{
return;
}
static void
isr_off(const rtems_irq_connect_data *unused)
{
return;
}
static int
isr_is_on(const rtems_irq_connect_data *irq)
{
if (Regs[INTMASK] & 0x4)
return 0;
else
return 1;
}
void console_reserve_resources(rtems_configuration_table *conf)
{
rtems_termios_reserve_resources(conf, 1);
return;
}
void __assert (const char *file, int line, const char *msg)
{
static char exit_msg[] = "EXECUTIVE SHUTDOWN! Any key to reboot...";
unsigned char ch;
/*
* Note we cannot call exit or printf from here,
* assert can fail inside ISR too
*/
/*
* Close console
*/
close(2);
close(1);
close(0);
printk("\nassert failed: %s: ", file);
printk("%d: ", line);
printk("%s\n\n", msg);
printk(exit_msg);
ch = BSP_poll_char();
printk("\n\n");
rtemsReboot();
}
/*-------------------------------------------------------------------------+
| Console device driver INITIALIZE entry point.
+--------------------------------------------------------------------------+
| Initilizes the I/O console (keyboard + VGA display) driver.
+--------------------------------------------------------------------------*/
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
*/
/* 38400-8-N-1 */
BSP_uart_init(BSPConsolePort, 38400, 0);
/* Set interrupt handler */
console_isr_data.name = BSP_UART;
console_isr_data.hdl = BSP_uart_termios_isr_com1;
console_isr_data.irqLevel = 3;
console_isr_data.irqTrigger = 0;
status = BSP_install_rtems_irq_handler(&console_isr_data);
if (!status){
printk("Error installing serial console interrupt handler!\n");
rtems_fatal_error_occurred(status);
}
/*
* 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 console on port COM1 38400-8-N-1\n\n");
return RTEMS_SUCCESSFUL;
} /* console_initialize */
static int console_open_count = 0;
static int console_last_close(int major, int minor, void *arg)
{
BSP_remove_rtems_irq_handler (&console_isr_data);
return 0;
}
/*-------------------------------------------------------------------------+
| Console device driver OPEN entry point
+--------------------------------------------------------------------------*/
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 =
{
NULL, /* firstOpen */
console_last_close, /* lastClose */
NULL, /* pollRead */
BSP_uart_termios_write_com1, /* write */
conSetAttr, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
status = rtems_termios_open (major, minor, arg, &cb);
if(status != RTEMS_SUCCESSFUL)
{
printk("Error openning console device\n");
return status;
}
/*
* Pass data area info down to driver
*/
BSP_uart_termios_set(BSPConsolePort,
((rtems_libio_open_close_args_t *)arg)->iop->data1);
/* Enable interrupts on channel */
BSP_uart_intr_ctrl(BSPConsolePort, BSP_UART_INTR_CTRL_TERMIOS);
return RTEMS_SUCCESSFUL;
}
/*-------------------------------------------------------------------------+
| Console device driver CLOSE entry point
+--------------------------------------------------------------------------*/
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;
} /* console_close */
/*-------------------------------------------------------------------------+
| Console device driver READ entry point.
+--------------------------------------------------------------------------+
| Read characters from the I/O console. We only have stdin.
+--------------------------------------------------------------------------*/
rtems_device_driver
console_read(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
return rtems_termios_read (arg);
} /* console_read */
/*-------------------------------------------------------------------------+
| Console device driver WRITE entry point.
+--------------------------------------------------------------------------+
| Write characters to the I/O console. Stderr and stdout are the same.
+--------------------------------------------------------------------------*/
rtems_device_driver
console_write(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg)
{
return rtems_termios_write (arg);
} /* console_write */
/*
* Handle ioctl request.
*/
rtems_device_driver
console_control(rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
return rtems_termios_ioctl (arg);
}
static int
conSetAttr(int minor, const struct termios *t)
{
int baud;
switch (t->c_cflag & CBAUD)
{
case B50:
baud = 50;
break;
case B75:
baud = 75;
break;
case B110:
baud = 110;
break;
case B134:
baud = 134;
break;
case B150:
baud = 150;
break;
case B200:
baud = 200;
break;
case B300:
baud = 300;
break;
case B600:
baud = 600;
break;
case B1200:
baud = 1200;
break;
case B1800:
baud = 1800;
break;
case B2400:
baud = 2400;
break;
case B4800:
baud = 4800;
break;
case B9600:
baud = 9600;
break;
case B19200:
baud = 19200;
break;
case B38400:
baud = 38400;
break;
case B57600:
baud = 57600;
break;
case B115200:
baud = 115200;
break;
default:
baud = 0;
rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
return 0;
}
BSP_uart_set_baud(BSPConsolePort, baud);
return 0;
}

View File

@@ -0,0 +1,577 @@
/*
* This software is Copyright (C) 1998 by T.sqware - all rights limited
* It is provided in to the public domain "as is", can be freely modified
* as far as this copyight notice is kept unchanged, but does not imply
* an endorsement by T.sqware of the product in which it is included.
*
* COPYRIGHT (c) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <bsp.h>
#include <irq.h>
#include <registers.h>
#include <uart.h>
#include <rtems/libio.h>
#include <assert.h>
/*
* Basic 16552 driver
*/
struct uart_data
{
int hwFlow;
int baud;
};
static struct uart_data uart_data[2];
/*
* Macros to read/wirte register of uart, if configuration is
* different just rewrite these macros
*/
static inline unsigned char
uread(int uart, unsigned int reg)
{
register unsigned char val;
val = Regs[reg];
return val;
}
static inline void
uwrite(int uart, int reg, unsigned int val)
{
Regs[reg] = val;
}
#ifdef UARTDEBUG
static void
uartError(int uart)
{
unsigned char uartStatus, dummy;
uartStatus = uread(uart, LSR);
dummy = uread(uart, RBR);
if (uartStatus & OE)
printk("********* Over run Error **********\n");
if (uartStatus & PE)
printk("********* Parity Error **********\n");
if (uartStatus & FE)
printk("********* Framing Error **********\n");
if (uartStatus & BI)
printk("********* Parity Error **********\n");
if (uartStatus & ERFIFO)
printk("********* Error receive Fifo **********\n");
}
#else
inline void uartError(int uart)
{
unsigned char uartStatus;
uartStatus = uread(uart, LSR);
uartStatus = uread(uart, RBR);
}
#endif
/*
* Uart initialization, it is hardcoded to 8 bit, no parity,
* one stop bit, FIFO, things to be changed
* are baud rate and nad hw flow control,
* and longest rx fifo setting
*/
void
BSP_uart_init(int uart, int baud, int hwFlow)
{
unsigned char tmp;
/* Sanity check */
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
switch(baud)
{
case 50:
case 75:
case 110:
case 134:
case 300:
case 600:
case 1200:
case 2400:
case 9600:
case 19200:
case 38400:
case 57600:
case 115200:
break;
default:
assert(0);
return;
}
/* Enable UART block */
uwrite(uart, CNT, UART_ENABLE | PAD_ENABLE);
/* Set DLAB bit to 1 */
uwrite(uart, LCR, DLAB);
/* Set baud rate */
uwrite(uart, DLL, (BSPBaseBaud/baud) & 0xff);
uwrite(uart, DLM, ((BSPBaseBaud/baud) >> 8) & 0xff);
/* 8-bit, no parity , 1 stop */
uwrite(uart, LCR, CHR_8_BITS);
/* Enable FIFO */
uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
/* Disable Interrupts */
uwrite(uart, IER, 0);
/* Read status to clear them */
tmp = uread(uart, LSR);
tmp = uread(uart, RBR);
/* Remember state */
uart_data[uart].hwFlow = hwFlow;
uart_data[uart].baud = baud;
return;
}
/*
* Set baud
*/
void
BSP_uart_set_baud(int uart, int baud)
{
unsigned char ier;
/* Sanity check */
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
/*
* This function may be called whenever TERMIOS parameters
* are changed, so we have to make sure that baud change is
* indeed required
*/
if(baud == uart_data[uart].baud)
{
return;
}
ier = uread(uart, IER);
BSP_uart_init(uart, baud, uart_data[uart].hwFlow);
uwrite(uart, IER, ier);
return;
}
/*
* Enable/disable interrupts
*/
void
BSP_uart_intr_ctrl(int uart, int cmd)
{
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
switch(cmd)
{
case BSP_UART_INTR_CTRL_DISABLE:
uwrite(uart, IER, INTERRUPT_DISABLE);
break;
case BSP_UART_INTR_CTRL_ENABLE:
uwrite(uart, IER,
(RECEIVE_ENABLE |
TRANSMIT_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
break;
case BSP_UART_INTR_CTRL_TERMIOS:
uwrite(uart, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
break;
case BSP_UART_INTR_CTRL_GDB:
uwrite(uart, IER, RECEIVE_ENABLE);
break;
default:
assert(0);
break;
}
return;
}
/*
* Status function, -1 if error
* detected, 0 if no received chars available,
* 1 if received char available, 2 if break
* is detected, it will eat break and error
* chars. It ignores overruns - we cannot do
* anything about - it execpt count statistics
* and we are not counting it.
*/
int
BSP_uart_polled_status(int uart)
{
unsigned char val;
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
val = uread(uart, LSR);
if(val & BI)
{
/* BREAK found, eat character */
uread(uart, RBR);
return BSP_UART_STATUS_BREAK;
}
if((val & (DR | OE | FE)) == 1)
{
/* No error, character present */
return BSP_UART_STATUS_CHAR;
}
if((val & (DR | OE | FE)) == 0)
{
/* Nothing */
return BSP_UART_STATUS_NOCHAR;
}
/*
* Framing or parity error
* eat character
*/
uread(uart, RBR);
return BSP_UART_STATUS_ERROR;
}
/*
* Polled mode write function
*/
void
BSP_uart_polled_write(int uart, int val)
{
unsigned char val1;
/* Sanity check */
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
for(;;)
{
if((val1=uread(uart, LSR)) & THRE)
{
break;
}
}
uwrite(uart, THR, val & 0xff);
return;
}
void
BSP_output_char_via_serial(int val)
{
BSP_uart_polled_write(BSPConsolePort, val);
if (val == '\n') BSP_uart_polled_write(BSPConsolePort,'\r');
}
/*
* Polled mode read function
*/
int
BSP_uart_polled_read(int uart)
{
unsigned char val;
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
for(;;)
{
if(uread(uart, LSR) & DR)
{
break;
}
}
val = uread(uart, RBR);
return (int)(val & 0xff);
}
unsigned
BSP_poll_char_via_serial()
{
return BSP_uart_polled_read(BSPConsolePort);
}
/* ================ Termios support =================*/
static volatile int termios_stopped_com1 = 0;
static volatile int termios_tx_active_com1 = 0;
static void* termios_ttyp_com1 = NULL;
static char termios_tx_hold_com1 = 0;
static volatile char termios_tx_hold_valid_com1 = 0;
static volatile int termios_stopped_com2 = 0;
static volatile int termios_tx_active_com2 = 0;
static void* termios_ttyp_com2 = NULL;
static char termios_tx_hold_com2 = 0;
static volatile char termios_tx_hold_valid_com2 = 0;
/*
* Set channel parameters
*/
void
BSP_uart_termios_set(int uart, void *ttyp)
{
assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);
if(uart == BSP_UART_COM1)
{
termios_stopped_com1 = 0;
termios_tx_active_com1 = 0;
termios_ttyp_com1 = ttyp;
termios_tx_hold_com1 = 0;
termios_tx_hold_valid_com1 = 0;
}
else
{
termios_stopped_com2 = 0;
termios_tx_active_com2 = 0;
termios_ttyp_com2 = ttyp;
termios_tx_hold_com2 = 0;
termios_tx_hold_valid_com2 = 0;
}
return;
}
int
BSP_uart_termios_write_com1(int minor, const char *buf, int len)
{
assert(buf != NULL);
if(len <= 0)
{
return 0;
}
/* If there TX buffer is busy - something is royally screwed up */
assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);
if(termios_stopped_com1)
{
/* CTS low */
termios_tx_hold_com1 = *buf;
termios_tx_hold_valid_com1 = 1;
return 0;
}
/* Write character */
uwrite(BSP_UART_COM1, THR, *buf & 0xff);
/* Enable interrupts if necessary */
if(!termios_tx_active_com1)
{
termios_tx_active_com1 = 1;
uwrite(BSP_UART_COM1, IER,
(RECEIVE_ENABLE |
TRANSMIT_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
}
return 0;
}
int
BSP_uart_termios_write_com2(int minor, const char *buf, int len)
{
assert(buf != NULL);
if(len <= 0)
{
return 0;
}
/* If there TX buffer is busy - something is royally screwed up */
assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);
if(termios_stopped_com2)
{
/* CTS low */
termios_tx_hold_com2 = *buf;
termios_tx_hold_valid_com2 = 1;
return 0;
}
/* Write character */
uwrite(BSP_UART_COM2, THR, *buf & 0xff);
/* Enable interrupts if necessary */
if(!termios_tx_active_com2)
{
termios_tx_active_com2 = 1;
uwrite(BSP_UART_COM2, IER,
(RECEIVE_ENABLE |
TRANSMIT_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
}
return 0;
}
void
BSP_uart_termios_isr_com1(void)
{
unsigned char buf[40];
int off, ret, vect;
off = 0;
for(;;)
{
vect = uread(BSP_UART_COM1, IIR) & 0xf;
switch(vect)
{
case NO_MORE_INTR :
/* No more interrupts */
if(off != 0)
{
/* Update rx buffer */
rtems_termios_enqueue_raw_characters(termios_ttyp_com1,
(char *)buf,
off);
}
return;
case TRANSMITTER_HODING_REGISTER_EMPTY :
/*
* TX holding empty: we have to disable these interrupts
* if there is nothing more to send.
*/
ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1);
/* If nothing else to send disable interrupts */
if(ret == 0)
{
uwrite(BSP_UART_COM1, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
termios_tx_active_com1 = 0;
}
break;
case RECEIVER_DATA_AVAIL :
case CHARACTER_TIMEOUT_INDICATION:
/* RX data ready */
assert(off < sizeof(buf));
buf[off++] = uread(BSP_UART_COM1, RBR);
break;
case RECEIVER_ERROR:
/* RX error: eat character */
uartError(BSP_UART_COM1);
break;
default:
/* Should not happen */
assert(0);
return;
}
}
}
void
BSP_uart_termios_isr_com2()
{
unsigned char buf[40];
int off, ret, vect;
off = 0;
for(;;)
{
vect = uread(BSP_UART_COM2, IIR) & 0xf;
switch(vect)
{
case NO_MORE_INTR :
/* No more interrupts */
if(off != 0)
{
/* Update rx buffer */
rtems_termios_enqueue_raw_characters(termios_ttyp_com2,
(char *)buf,
off);
}
return;
case TRANSMITTER_HODING_REGISTER_EMPTY :
/*
* TX holding empty: we have to disable these interrupts
* if there is nothing more to send.
*/
ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
/* If nothing else to send disable interrupts */
if(ret == 0)
{
uwrite(BSP_UART_COM2, IER,
(RECEIVE_ENABLE |
RECEIVER_LINE_ST_ENABLE
)
);
termios_tx_active_com2 = 0;
}
break;
case RECEIVER_DATA_AVAIL :
case CHARACTER_TIMEOUT_INDICATION:
/* RX data ready */
assert(off < sizeof(buf));
buf[off++] = uread(BSP_UART_COM2, RBR);
break;
case RECEIVER_ERROR:
/* RX error: eat character */
uartError(BSP_UART_COM2);
break;
default:
/* Should not happen */
assert(0);
return;
}
}
}

View File

@@ -0,0 +1,158 @@
/*
* This software is Copyright (C) 1998 by T.sqware - all rights limited
* It is provided in to the public domain "as is", can be freely modified
* as far as this copyight notice is kept unchanged, but does not imply
* an endorsement by T.sqware of the product in which it is included.
*
* Copyright (c) Canon Research France SA.]
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*/
#ifndef _BSPUART_H
#define _BSPUART_H
void BSP_uart_init(int uart, int baud, int hwFlow);
void BSP_uart_set_baud(int aurt, int baud);
void BSP_uart_intr_ctrl(int uart, int cmd);
void BSP_uart_throttle(int uart);
void BSP_uart_unthrottle(int uart);
int BSP_uart_polled_status(int uart);
void BSP_uart_polled_write(int uart, int val);
int BSP_uart_polled_read(int uart);
void BSP_uart_termios_set(int uart, void *ttyp);
int BSP_uart_termios_write_com1(int minor, const char *buf, int len);
int BSP_uart_termios_write_com2(int minor, const char *buf, int len);
void BSP_uart_termios_isr_com1();
void BSP_uart_termios_isr_com2();
void BSP_uart_dbgisr_com1(void);
void BSP_uart_dbgisr_com2(void);
extern unsigned BSP_poll_char_via_serial(void);
extern void BSP_output_char_via_serial(int val);
extern int BSPConsolePort;
extern int BSPBaseBaud;
/*
* Command values for BSP_uart_intr_ctrl(),
* values are strange in order to catch errors
* with assert
*/
#define BSP_UART_INTR_CTRL_DISABLE (0)
#define BSP_UART_INTR_CTRL_GDB (0xaa) /* RX only */
#define BSP_UART_INTR_CTRL_ENABLE (0xbb) /* Normal operations */
#define BSP_UART_INTR_CTRL_TERMIOS (0xcc) /* RX & line status */
/* Return values for uart_polled_status() */
#define BSP_UART_STATUS_ERROR (-1) /* No character */
#define BSP_UART_STATUS_NOCHAR (0) /* No character */
#define BSP_UART_STATUS_CHAR (1) /* Character present */
#define BSP_UART_STATUS_BREAK (2) /* Break point is detected */
/* PC UART definitions */
#define BSP_UART_COM1 (0)
#define BSP_UART_COM2 (1)
/*
* Base IO for UART
*/
#define COM1_BASE_IO 0x3F8
#define COM2_BASE_IO 0x2F8
/*
* Offsets from base
*/
/* DLAB 0 */
#define RBR RSRBR /* Rx Buffer Register (read) */
#define THR RSTHR /* Tx Buffer Register (write) */
#define IER RSIER /* Interrupt Enable Register */
/* DLAB X */
#define IIR RSIIR /* Interrupt Ident Register (read) */
#define FCR RSFCR /* FIFO Control Register (write) */
#define LCR RSLCR /* Line Control Register */
#define LSR RSLSR /* Line Status Register */
/* DLAB 1 */
#define DLL RSDLL /* Divisor Latch, LSB */
#define DLM RSDLH /* Divisor Latch, MSB */
/* Uart control */
#define CNT RSCNT /* General Control register */
/*
* define bit for CNT
*/
#define UART_ENABLE 1
#define PAD_ENABLE 2
/*
* Interrupt source definition via IIR
*/
#define NO_MORE_INTR 1
#define TRANSMITTER_HODING_REGISTER_EMPTY 2
#define RECEIVER_DATA_AVAIL 4
#define RECEIVER_ERROR 6
#define CHARACTER_TIMEOUT_INDICATION 12
/*
* Bits definition of IER
*/
#define RECEIVE_ENABLE 0x1
#define TRANSMIT_ENABLE 0x2
#define RECEIVER_LINE_ST_ENABLE 0x4
#define INTERRUPT_DISABLE 0x0
/*
* Bits definition of the Line Status Register (LSR)
*/
#define DR 0x01 /* Data Ready */
#define OE 0x02 /* Overrun Error */
#define PE 0x04 /* Parity Error */
#define FE 0x08 /* Framing Error */
#define BI 0x10 /* Break Interrupt */
#define THRE 0x20 /* Transmitter Holding Register Empty */
#define TEMT 0x40 /* Transmitter Empty */
#define ERFIFO 0x80 /* Error receive Fifo */
/*
* Bits definition of the Line Control Register (LCR)
*/
#define CHR_5_BITS 0
#define CHR_6_BITS 1
#define CHR_7_BITS 2
#define CHR_8_BITS 3
#define WL 0x03 /* Word length mask */
#define STB 0x04 /* 1 Stop Bit, otherwise 2 Stop Bits */
#define PEN 0x08 /* Parity Enabled */
#define EPS 0x10 /* Even Parity Select, otherwise Odd */
#define SP 0x20 /* Stick Parity */
#define BCB 0x40 /* Break Control Bit */
#define DLAB 0x80 /* Enable Divisor Latch Access */
/*
* Bits definition of the FIFO Control Register : WD16C552 or NS16550
*/
#define FIFO_CTRL 0x01 /* Set to 1 permit access to other bits */
#define FIFO_EN 0x01 /* Enable the FIFO */
#define XMIT_RESET 0x04 /* Transmit FIFO Reset */
#define RCV_RESET 0x02 /* Receive FIFO Reset */
#define FCR3 0x08 /* do not understand manual! */
#define RECEIVE_FIFO_TRIGGER1 0x0 /* trigger recieve interrupt after 1 byte */
#define RECEIVE_FIFO_TRIGGER4 0x40 /* trigger recieve interrupt after 4 byte */
#define RECEIVE_FIFO_TRIGGER8 0x80 /* trigger recieve interrupt after 8 byte */
#define RECEIVE_FIFO_TRIGGER12 0xc0 /* trigger recieve interrupt after 14 byte */
#define TRIG_LEVEL 0xc0 /* Mask for the trigger level */
#endif /* _BSPUART_H */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,22 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = bspio.h
C_FILES = printk.c
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h)
all: $(PREINSTALL_FILES)
EXTRA_DIST = bspio.h printk.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,38 @@
/* bspIo.h
*
* This include file contains declaration of interface that
* will be provided by the file contained in this directory.
*
*
* COPYRIGHT (c) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef _LIBBSP_ARM_SHARED_IO_BSP_IO_H
#define _LIBBSP_ARM_SHARED_IO_BSP_IO_H
/*
* All the functions declared as extern after this comment
* MUST be implemented in each BSP. Using this function,
* this directory contains shared code that export higher level
* functionnality described after the next command.
*/
typedef void (*BSP_output_char_function_type) (char c);
typedef char (*BSP_polling_getchar_function_type) (void);
extern BSP_output_char_function_type BSP_output_char;
extern BSP_polling_getchar_function_type BSP_poll_char;
/*
* All the function declared as extern after this comment
* are available for each ix86 BSP by compiling and linking
* the files contained in this directory PROVIDED definition
* and initialisation of the previous variable are done.
*/
void printk(char *fmt, ...);
#endif

View File

@@ -0,0 +1,113 @@
/*-------------------------------------------------------------------------+
| printk.c - ARM BSP
+--------------------------------------------------------------------------+
|
| COPYRIGHT (c) 2000 Canon Research France SA.
| Emmanuel Raguet, mailto:raguet@crf.canon.fr
|
| The license and distribution terms for this file may be
| found in found in the file LICENSE in this distribution or at
| http://www.OARcorp.com/rtems/license.html.
|
| $Id$
+--------------------------------------------------------------------------*/
#include <stdarg.h>
#include <stdio.h>
#include <bspio.h>
/*-------------------------------------------------------------------------+
| Function: printNum
| Description: print number in a given base.
| Global Variables: None.
| Arguments: num - number to print, base - base used to print the number.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
static void
printNum(long unsigned int num, int base, int sign)
{
long unsigned int n;
int count;
char toPrint[20];
if ( (sign == 1) && ((long)num < 0) ) {
BSP_output_char('-');
num = -num;
}
count = 0;
while ((n = num / base) > 0) {
toPrint[count++] = (num - (n*base));
num = n ;
}
toPrint[count++] = num;
for (n = 0; n < count; n++){
BSP_output_char("0123456789ABCDEF"[(int)(toPrint[count-(n+1)])]);
}
} /* printNum */
/*-------------------------------------------------------------------------+
| Function: printk
| Description: a simplified version of printf intended for use when the
console is not yet initialized or in ISR's.
| Global Variables: None.
| Arguments: as in printf: fmt - format string, ... - unnamed arguments.
| Returns: Nothing.
+--------------------------------------------------------------------------*/
void
printk(char *fmt, ...)
{
va_list ap; /* points to each unnamed argument in turn */
char c, *str;
int lflag, base, sign;
_CPU_ISR_Disable(level);
va_start(ap, fmt); /* make ap point to 1st unnamed arg */
for (; *fmt != '\0'; fmt++)
{
lflag = 0;
base = 0;
sign = 0;
if (*fmt == '%')
{
if ((c = *++fmt) == 'l')
{
lflag = 1;
c = *++fmt;
}
switch (c)
{
case 'o': case 'O': base = 8; sign = 0; break;
case 'd': case 'D': base = 10; sign = 1; break;
case 'u': case 'U': base = 10; sign = 0; break;
case 'x': case 'X': base = 16; sign = 0; break;
case 's':
for (str = va_arg(ap, char *); *str; str++)
BSP_output_char(*str);
break;
case 'c':
BSP_output_char(va_arg(ap, char));
break;
default:
BSP_output_char(c);
break;
} /* switch*/
if (base)
printNum(lflag ? va_arg(ap, long int) : (long int)va_arg(ap, int),
base, sign);
}
else
{
BSP_output_char(*fmt);
}
}
va_end(ap); /* clean up when done */
_CPU_ISR_Enable(level);
} /* printk */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,14 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
C_FILES = irq_init.c
S_FILES = irq_asm.S
all:
EXTRA_DIST = irq_asm.S irq_init.c
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,109 @@
/* irq_asm.S
*
* This file contains the implementation of the IRQ handler
*
* CopyRight (C) 2000 Canon Research France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include "asm.h"
#define __asm__
#include <registers.h>
/*
* WARNING : register r5 is important. If you need to use it,
* to forget to save it !!!!!!!!!!
*/
.globl _ISR_Handler
_ISR_Handler:
stmdb sp!, {r4,r5,lr} /* save regs on INT stack */
mrs r4, cpsr /* save current CSPR */
mov r5, r4 /* copy CSPR */
orr r4, r4, #3
msr cpsr, r4 /* switch to SVC mode */
stmdb sp!, {r0-r3,r12,r14} /* save scratch regs on SVC stack */
msr cpsr, r5 /* switch back to INT mode */
ldr r0, =_ISR_Nest_level /* one nest level deeper */
ldr r1, [r0]
add r1, r1,#1
str r1, [r0]
ldr r0, =_Thread_Dispatch_disable_level /* disable multitasking */
ldr r1, [r0]
add r1, r1,#1
str r1, [r0]
b ExecuteITHandler /* BSP specific function to INT handler */
.globl ReturnFromHandler
ReturnFromHandler :
ldr r0, =_ISR_Nest_level /* one less nest level */
ldr r1, [r0]
sub r1, r1,#1
str r1, [r0]
ldr r0, =_Thread_Dispatch_disable_level /* unnest multitasking */
ldr r1, [r0]
sub r1, r1,#1
str r1, [r0]
cmp r1, #0 /* is dispatch enabled */
bne exitit /* Yes, then exit */
ldr r0, =_Context_Switch_necessary /* task switch necessary ? */
ldr r1, [r0]
cmp r1, #0
bne schedule /* yes, call scheduler */
ldr r0, =_ISR_Signals_to_thread_executing
ldr r1, [r0] /* signals sent to Run_thread */
cmp r1, #0 /* while in interrupt handler ? */
beq exitit /* No, exit */
bframe:
mov r1, #0 /* _ISR_Signals_to_thread_executing = FALSE */
str r1, [r0]
/*
* At this point, we need a complete exception context for the
* current thread. We need to complete the interrupt exception
* with the "not-yet-saved" registers
*/
/*
* currently exception context = interrupt handler
* it needs to be optimized
*/
bl _ThreadProcessSignalsFromIrq
b exitit
schedule:
/*
* the scratch registers have already been saved and we are already
* back on the thread system stack. So we can call _Thread_Displatch
* directly
*/
bl _Thread_Dispatch
/*
* fall through exit to restore complete contex (scratch registers
* eip, CS, Flags).
*/
exitit:
b AckControler /* BSP specific function to ack PIC */
.globl ReturnFromAck
ReturnFromAck :
ldmia sp!, {r0-r3,r12,r14} /* restore regs from SVC stack */
msr cpsr, r5 /* switch back to INT mode */
ldmia sp!, {r4,r5,lr} /* restore regs from INT stack */
subs pc,r14,#4 /* return */

View File

@@ -0,0 +1,51 @@
/* irq_init.c
*
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*
* CopyRight (C) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <irq.h>
#include <bsp.h>
#include <bspio.h>
#include <registers.h>
/*
* default int vector
*/
extern void _ISR_Handler();
void default_int_handler()
{
printk("raw_idt_notify has been called \n");
}
void rtems_irq_mngt_init()
{
int i;
long *vectorTable;
vectorTable = VECTOR_TABLE;
_CPU_ISR_Disable(level);
/* 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<BSP_MAX_INT; i++)
*(vectorTable + i) = (long)(default_int_handler);
/* Initialize the INT at the BSP level */
BSP_rtems_irq_mngt_init();
}

View File

@@ -0,0 +1,13 @@
Makefile
Makefile.in
aclocal.m4
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
mkinstalldirs

View File

@@ -0,0 +1,48 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
SUBDIRS = rtems
C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_FILES = cpu_asm.S
S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
H_FILES = asm.h
REL = $(ARCH)/rtems-cpu.rel
rtems_cpu_rel_OBJECTS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_RELEASE)/lib/rtems$(LIB_VARIANT).o: $(ARCH)/rtems.o
$(INSTALL_DATA) $< $@
$(REL): $(rtems_cpu_rel_OBJECTS)
$(make-rel)
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(H_FILES:%=$(PROJECT_INCLUDE)/%)
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/rtems$(LIB_VARIANT).o
all: $(ARCH) $(PREINSTALL_FILES) $(rtems_cpu_rel_OBJECTS) $(REL) $(TMPINSTALL_FILES)
.PRECIOUS: $(REL)
EXTRA_DIST = asm.h cpu.c cpu_asm.S
include $(top_srcdir)/../../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../../automake/local.am

125
cpukit/score/cpu/arm/asm.h Normal file
View File

@@ -0,0 +1,125 @@
/* asm.h
*
* This include file attempts to address the problems
* caused by incompatible flavors of assemblers and
* toolsets. It primarily addresses variations in the
* use of leading underscores on symbols and the requirement
* that register names be preceded by a %.
*
*
* NOTE: The spacing in the use of these macros
* is critical to them working as advertised.
*
* COPYRIGHT:
*
* This file is based on similar code found in newlib available
* from ftp.cygnus.com. The file which was used had no copyright
* notice. This file is freely distributable as long as the source
* of the file is noted. This file is:
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __ARM_ASM_h
#define __ARM_ASM_h
/*
* Indicate we are in an assembly file and get the basic CPU definitions.
*/
#ifndef ASM
#define ASM
#endif
#include <rtems/score/targopts.h>
#include <rtems/score/arm.h>
/*
* Recent versions of GNU cpp define variables which indicate the
* need for underscores and percents. If not using GNU cpp or
* the version does not support this, then you will obviously
* have to define these as appropriate.
*/
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
#ifndef __REGISTER_PREFIX__
#define __REGISTER_PREFIX__
#endif
/* ANSI concatenation macros. */
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
/* Use the right prefix for global labels. */
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
/* Use the right prefix for registers. */
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
/*
* define macros for all of the registers on this CPU
*
* EXAMPLE: #define d0 REG (d0)
*/
#define r0 REG(r0)
#define r1 REG(r1)
#define r2 REG(r2)
#define r3 REG(r3)
#define r4 REG(r4)
#define r5 REG(r5)
#define r6 REG(r6)
#define r7 REG(r7)
#define r8 REG(r8)
#define r9 REG(r9)
#define r10 REG(r10)
#define r11 REG(r11)
#define r12 REG(r12)
#define r13 REG(r13)
#define r14 REG(r14)
#define r15 REG(r15)
#define CPSR REG(CPSR)
#define SPSR REG(SPSR)
/*
* Define macros to handle section beginning and ends.
*/
#define BEGIN_CODE_DCL .text
#define END_CODE_DCL
#define BEGIN_DATA_DCL .data
#define END_DATA_DCL
#define BEGIN_CODE .text
#define END_CODE
#define BEGIN_DATA
#define END_DATA
#define BEGIN_BSS
#define END_BSS
#define END
/*
* Following must be tailor for a particular flavor of the C compiler.
* They may need to put underscores in front of the symbols.
*/
#define PUBLIC(sym) .globl SYM (sym)
#define EXTERN(sym) .globl SYM (sym)
#endif
/* end of include file */

169
cpukit/score/cpu/arm/cpu.c Normal file
View File

@@ -0,0 +1,169 @@
/*
* ARM CPU Dependent Source
*
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#include <rtems/system.h>
#include <rtems.h>
#include <bspio.h>
#include <rtems/score/isr.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/thread.h>
#include <rtems/score/cpu.h>
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
_CPU_Table = *cpu_table;
}
/*PAGE
*
* _CPU_ISR_Get_level
*/
unsigned32 _CPU_ISR_Get_level( void )
{
/*
* This routine returns the current interrupt level.
*/
return 0;
}
/*
* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
*
* Output parameters: NONE
*
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/* pointer on the redirection table in RAM */
long *VectorTable = (long *)(MAX_EXCEPTIONS * 4);
if (old_handler != NULL)
old_handler = *(proc_ptr *)(VectorTable + vector);
*(VectorTable + vector) = (long)new_handler ;
}
/*PAGE
*
* _CPU_Install_interrupt_stack
*/
void _CPU_Install_interrupt_stack( void )
{
}
/*PAGE
*
* _CPU_Thread_Idle_body
*
* NOTES:
*
* 1. This is the same as the regular CPU independent algorithm.
*
* 2. If you implement this using a "halt", "idle", or "shutdown"
* instruction, then don't forget to put it in an infinite loop.
*
* 3. Be warned. Some processors with onboard DMA have been known
* to stop the DMA if the CPU were put in IDLE mode. This might
* also be a problem with other on-chip peripherals. So use this
* hook with caution.
*/
void _CPU_Thread_Idle_body( void )
{
while(1);
/* insert your "halt" instruction here */ ;
}
void _defaultExcHandler (CPU_Exception_frame *ctx)
{
printk("----------------------------------------------------------\n");
printk("Exception %d caught at PC %x by thread %d\n",
ctx->register_pc, ctx->register_lr - 4,
_Thread_Executing->Object.id);
printk("----------------------------------------------------------\n");
printk("Processor execution context at time of the fault was :\n");
printk("----------------------------------------------------------\n");
printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n",
ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3);
printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n",
ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7);
printk(" r8 = %x r9 = %x r10 = %x\n",
ctx->register_r8, ctx->register_r9, ctx->register_r10);
printk(" fp = %x ip = %x sp = %x pc = %x\n",
ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4);
printk("----------------------------------------------------------\n");
if (_ISR_Nest_level > 0) {
/*
* In this case we shall not delete the task interrupted as
* it has nothing to do with the fault. We cannot return either
* because the eip points to the faulty instruction so...
*/
printk("Exception while executing ISR!!!. System locked\n");
while(1);
}
else {
printk(" ************ FAULTY THREAD WILL BE DELETED **************\n");
rtems_task_delete(_Thread_Executing->Object.id);
}
}
cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
extern void _Exception_Handler_Undef_Swi();
extern void _Exception_Handler_Abort();
void rtems_exception_init_mngt()
{
_CPU_ISR_Disable(level);
_CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL);
_CPU_ISR_Enable(level);
}

View File

@@ -0,0 +1,193 @@
/* cpu_asm.s
*
* This file contains all assembly code for the ARM implementation
* of RTEMS.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#include <asm.h>
/*
* Format of ARM Register structure
*/
.set REG_R0, 0
.set REG_R1, 4
.set REG_R2, 8
.set REG_R3, 12
.set REG_R4, 16
.set REG_R5, 20
.set REG_R6, 24
.set REG_R7, 28
.set REG_R8, 32
.set REG_R9, 36
.set REG_R10, 40
.set REG_FP, 44
.set REG_IP, 48
.set REG_SP, 52
.set REG_LR, 56
.set REG_PC, 60
.set SIZE_REGS, REG_PC + 4
/*
* void _CPU_Context_switch( run_context, heir_context )
*
* This routine performs a normal non-FP context.
*
* R0 = run_context R1 = heir_context
*
*/
.globl _CPU_Context_switch
_CPU_Context_switch:
str r2, [r0, #REG_R2]
str r3, [r0, #REG_R3]
str r4, [r0, #REG_R4]
str r5, [r0, #REG_R5]
str r6, [r0, #REG_R6]
str r7, [r0, #REG_R7]
str r8, [r0, #REG_R8]
str r9, [r0, #REG_R9]
str r10, [r0, #REG_R10]
str sp, [r0, #REG_SP]
str lr, [r0, #REG_PC]
ldr r2, [r1, #REG_R2]
ldr r3, [r1, #REG_R3]
ldr r4, [r1, #REG_R4]
ldr r5, [r1, #REG_R5]
ldr r6, [r1, #REG_R6]
ldr r7, [r1, #REG_R7]
ldr r8, [r1, #REG_R8]
ldr r9, [r1, #REG_R9]
ldr r10, [r1, #REG_R10]
ldr sp, [r1, #REG_SP]
ldr lr, [r1, #REG_PC]
mov pc, lr
/*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* void _CPU_Context_restore( new_context )
*
* This routine performs a normal non-FP context.
*/
.globl _CPU_Context_restore
_CPU_Context_restore:
ldr r2, [r0, #REG_R2]
ldr r3, [r0, #REG_R3]
ldr r4, [r0, #REG_R4]
ldr r5, [r0, #REG_R5]
ldr r6, [r0, #REG_R6]
ldr r7, [r0, #REG_R7]
ldr r8, [r0, #REG_R8]
ldr r9, [r0, #REG_R9]
ldr r10, [r0, #REG_R10]
ldr sp, [r0, #REG_SP]
ldr lr, [r0, #REG_PC]
mov pc, lr
.globl _Exception_Handler_Undef_Swi
_Exception_Handler_Undef_Swi:
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
str r2, [r13, #REG_R2]
str r3, [r13, #REG_R3]
str r4, [r13, #REG_R4]
str r5, [r13, #REG_R5]
str r6, [r13, #REG_R6]
str r7, [r13, #REG_R7]
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str fp, [r13, #REG_FP]
str ip, [r13, #REG_IP]
str sp, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
and r0, r0,#0x1f /* we keep the mode as exception number */
str r0, [r13, #REG_PC] /* we store it in a free place */
mov r0, r13 /* put frame address in r0 (C arg 1) */
ldr r1, =_currentExcHandler
ldr lr, =_go_back_1
ldr pc,[r1] /* call handler */
_go_back_1:
ldr r0, [r13, #REG_R0]
ldr r1, [r13, #REG_R1]
ldr r2, [r13, #REG_R2]
ldr r3, [r13, #REG_R3]
ldr r4, [r13, #REG_R4]
ldr r5, [r13, #REG_R5]
ldr r6, [r13, #REG_R6]
ldr r7, [r13, #REG_R7]
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr fp, [r13, #REG_FP]
ldr ip, [r13, #REG_IP]
ldr sp, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
movs pc,r14 /* return */
.globl _Exception_Handler_Abort
_Exception_Handler_Abort:
sub r13,r13,#SIZE_REGS
str r0, [r13, #REG_R0]
str r1, [r13, #REG_R1]
str r2, [r13, #REG_R2]
str r3, [r13, #REG_R3]
str r4, [r13, #REG_R4]
str r5, [r13, #REG_R5]
str r6, [r13, #REG_R6]
str r7, [r13, #REG_R7]
str r8, [r13, #REG_R8]
str r9, [r13, #REG_R9]
str r10, [r13, #REG_R10]
str sp, [r13, #REG_FP]
str lr, [r13, #REG_IP]
str lr, [r13, #REG_SP]
str lr, [r13, #REG_LR]
mrs r0, cpsr /* read the status */
and r0, r0,#0x1f /* we keep the mode as exception number */
str r0, [r13, #REG_PC] /* we store it in a free place */
mov r0, r13 /* put frame address in ro (C arg 1) */
ldr r1, =_currentExcHandler
ldr lr, =_go_back_2
ldr pc,[r1] /* call handler */
_go_back_2:
ldr r0, [r13, #REG_R0]
ldr r1, [r13, #REG_R1]
ldr r2, [r13, #REG_R2]
ldr r3, [r13, #REG_R3]
ldr r4, [r13, #REG_R4]
ldr r5, [r13, #REG_R5]
ldr r6, [r13, #REG_R6]
ldr r7, [r13, #REG_R7]
ldr r8, [r13, #REG_R8]
ldr r9, [r13, #REG_R9]
ldr r10, [r13, #REG_R10]
ldr sp, [r13, #REG_FP]
ldr lr, [r13, #REG_IP]
ldr lr, [r13, #REG_SP]
ldr lr, [r13, #REG_LR]
add r13,r13,#SIZE_REGS
subs pc,r14,#4 /* return */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,125 @@
/* asm.h
*
* This include file attempts to address the problems
* caused by incompatible flavors of assemblers and
* toolsets. It primarily addresses variations in the
* use of leading underscores on symbols and the requirement
* that register names be preceded by a %.
*
*
* NOTE: The spacing in the use of these macros
* is critical to them working as advertised.
*
* COPYRIGHT:
*
* This file is based on similar code found in newlib available
* from ftp.cygnus.com. The file which was used had no copyright
* notice. This file is freely distributable as long as the source
* of the file is noted. This file is:
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __ARM_ASM_h
#define __ARM_ASM_h
/*
* Indicate we are in an assembly file and get the basic CPU definitions.
*/
#ifndef ASM
#define ASM
#endif
#include <rtems/score/targopts.h>
#include <rtems/score/arm.h>
/*
* Recent versions of GNU cpp define variables which indicate the
* need for underscores and percents. If not using GNU cpp or
* the version does not support this, then you will obviously
* have to define these as appropriate.
*/
#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif
#ifndef __REGISTER_PREFIX__
#define __REGISTER_PREFIX__
#endif
/* ANSI concatenation macros. */
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
/* Use the right prefix for global labels. */
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
/* Use the right prefix for registers. */
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
/*
* define macros for all of the registers on this CPU
*
* EXAMPLE: #define d0 REG (d0)
*/
#define r0 REG(r0)
#define r1 REG(r1)
#define r2 REG(r2)
#define r3 REG(r3)
#define r4 REG(r4)
#define r5 REG(r5)
#define r6 REG(r6)
#define r7 REG(r7)
#define r8 REG(r8)
#define r9 REG(r9)
#define r10 REG(r10)
#define r11 REG(r11)
#define r12 REG(r12)
#define r13 REG(r13)
#define r14 REG(r14)
#define r15 REG(r15)
#define CPSR REG(CPSR)
#define SPSR REG(SPSR)
/*
* Define macros to handle section beginning and ends.
*/
#define BEGIN_CODE_DCL .text
#define END_CODE_DCL
#define BEGIN_DATA_DCL .data
#define END_DATA_DCL
#define BEGIN_CODE .text
#define END_CODE
#define BEGIN_DATA
#define END_DATA
#define BEGIN_BSS
#define END_BSS
#define END
/*
* Following must be tailor for a particular flavor of the C compiler.
* They may need to put underscores in front of the symbols.
*/
#define PUBLIC(sym) .globl SYM (sym)
#define EXTERN(sym) .globl SYM (sym)
#endif
/* end of include file */

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,54 @@
/* no_cpu.h
*
* This file is an example (i.e. "no CPU") of the file which is
* created for each CPU family port of RTEMS.
*
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef _INCLUDE_ARM_h
#define _INCLUDE_ARM_h
#ifdef __cplusplus
extern "C" {
#endif
/*
* This file contains the information required to build
* RTEMS for a particular member of the "arm"
* family when executing in protected mode. It does
* this by setting variables to indicate which implementation
* dependent features are present in a particular member
* of the family.
*/
#if defined(arm)
#define CPU_MODEL_NAME "arm"
#define ARM_HAS_FPU 0
#else
#error "Unsupported CPU Model"
#endif
/*
* Define the name of the CPU family.
*/
#define CPU_NAME "ARM"
#ifdef __cplusplus
}
#endif
#endif /* ! _INCLUDE_ARM_h */
/* end of include file */

View File

@@ -0,0 +1,916 @@
/* cpu.h
*
* This include file contains information pertaining to the arm
* processor.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __CPU_h
#define __CPU_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/arm.h> /* pick up machine definitions */
#ifndef ASM
#include <rtems/score/armtypes.h>
#endif
/* conditional compilation parameters */
/*
* Should the calls to _Thread_Enable_dispatch be inlined?
*
* If TRUE, then they are inlined.
* If FALSE, then a subroutine call is made.
*
* Basically this is an example of the classic trade-off of size
* versus speed. Inlining the call (TRUE) typically increases the
* size of RTEMS while speeding up the enabling of dispatching.
* [NOTE: In general, the _Thread_Dispatch_disable_level will
* only be 0 or 1 unless you are in an interrupt handler and that
* interrupt handler invokes the executive.] When not inlined
* something calls _Thread_Enable_dispatch which in turns calls
* _Thread_Dispatch. If the enable dispatch is inlined, then
* one subroutine call is avoided entirely.]
*/
#define CPU_INLINE_ENABLE_DISPATCH FALSE
/*
* Should the body of the search loops in _Thread_queue_Enqueue_priority
* be unrolled one time? In unrolled each iteration of the loop examines
* two "nodes" on the chain being searched. Otherwise, only one node
* is examined per iteration.
*
* If TRUE, then the loops are unrolled.
* If FALSE, then the loops are not unrolled.
*
* The primary factor in making this decision is the cost of disabling
* and enabling interrupts (_ISR_Flash) versus the cost of rest of the
* body of the loop. On some CPUs, the flash is more expensive than
* one iteration of the loop body. In this case, it might be desirable
* to unroll the loop. It is important to note that on some CPUs, this
* code is the longest interrupt disable period in RTEMS. So it is
* necessary to strike a balance when setting this parameter.
*/
#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE
/*
* Does RTEMS manage a dedicated interrupt stack in software?
*
* If TRUE, then a stack is allocated in _Interrupt_Manager_initialization.
* If FALSE, nothing is done.
*
* If the CPU supports a dedicated interrupt stack in hardware,
* then it is generally the responsibility of the BSP to allocate it
* and set it up.
*
* If the CPU does not support a dedicated interrupt stack, then
* the porter has two options: (1) execute interrupts on the
* stack of the interrupted task, and (2) have RTEMS manage a dedicated
* interrupt stack.
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
* Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
* possible that both are FALSE for a particular CPU. Although it
* is unclear what that would imply about the interrupt processing
* procedure on that CPU.
*/
#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE
/*
* Does this CPU have hardware support for a dedicated interrupt stack?
*
* If TRUE, then it must be installed during initialization.
* If FALSE, then no installation is performed.
*
* If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE.
*
* Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and
* CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is
* possible that both are FALSE for a particular CPU. Although it
* is unclear what that would imply about the interrupt processing
* procedure on that CPU.
*/
#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE
/*
* Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager?
*
* If TRUE, then the memory is allocated during initialization.
* If FALSE, then the memory is allocated during initialization.
*
* This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE
* or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE.
*/
#define CPU_ALLOCATE_INTERRUPT_STACK FALSE
/*
* Does the RTEMS invoke the user's ISR with the vector number and
* a pointer to the saved interrupt frame (1) or just the vector
* number (0)?
*/
#define CPU_ISR_PASSES_FRAME_POINTER 0
/*
* Does the CPU have hardware floating point?
*
* If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported.
* If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored.
*
* If there is a FP coprocessor such as the i387 or mc68881, then
* the answer is TRUE.
*
* The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
* It indicates whether or not this CPU model has FP support. For
* example, it would be possible to have an i386_nofp CPU model
* which set this to false to indicate that you have an i386 without
* an i387 and wish to leave floating point support out of RTEMS.
*/
#if ( ARM_HAS_FPU == 1 )
#define CPU_HARDWARE_FP TRUE
#else
#define CPU_HARDWARE_FP FALSE
#endif
#define CPU_SOFTWARE_FP FALSE
/*
* Are all tasks RTEMS_FLOATING_POINT tasks implicitly?
*
* If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed.
* If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed.
*
* So far, the only CPU in which this option has been used is the
* HP PA-RISC. The HP C compiler and gcc both implicitly use the
* floating point registers to perform integer multiplies. If
* a function which you would not think utilize the FP unit DOES,
* then one can not easily predict which tasks will use the FP hardware.
* In this case, this option should be TRUE.
*
* If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well.
*/
#define CPU_ALL_TASKS_ARE_FP FALSE
/*
* Should the IDLE task have a floating point context?
*
* If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task
* and it has a floating point context which is switched in and out.
* If FALSE, then the IDLE task does not have a floating point context.
*
* Setting this to TRUE negatively impacts the time required to preempt
* the IDLE task from an interrupt because the floating point context
* must be saved as part of the preemption.
*/
#define CPU_IDLE_TASK_IS_FP FALSE
/*
* Should the saving of the floating point registers be deferred
* until a context switch is made to another different floating point
* task?
*
* If TRUE, then the floating point context will not be stored until
* necessary. It will remain in the floating point registers and not
* disturned until another floating point task is switched to.
*
* If FALSE, then the floating point context is saved when a floating
* point task is switched out and restored when the next floating point
* task is restored. The state of the floating point registers between
* those two operations is not specified.
*
* If the floating point context does NOT have to be saved as part of
* interrupt dispatching, then it should be safe to set this to TRUE.
*
* Setting this flag to TRUE results in using a different algorithm
* for deciding when to save and restore the floating point context.
* The deferred FP switch algorithm minimizes the number of times
* the FP context is saved and restored. The FP context is not saved
* until a context switch is made to another, different FP task.
* Thus in a system with only one FP task, the FP context will never
* be saved or restored.
*/
#define CPU_USE_DEFERRED_FP_SWITCH FALSE
/*
* Does this port provide a CPU dependent IDLE task implementation?
*
* If TRUE, then the routine _CPU_Thread_Idle_body
* must be provided and is the default IDLE thread body instead of
* _CPU_Thread_Idle_body.
*
* If FALSE, then use the generic IDLE thread body if the BSP does
* not provide one.
*
* This is intended to allow for supporting processors which have
* a low power or idle mode. When the IDLE thread is executed, then
* the CPU can be powered down.
*
* The order of precedence for selecting the IDLE thread body is:
*
* 1. BSP provided
* 2. CPU dependent (if provided)
* 3. generic (if no BSP and no CPU dependent)
*/
#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
/*
* Does the stack grow up (toward higher addresses) or down
* (toward lower addresses)?
*
* If TRUE, then the grows upward.
* If FALSE, then the grows toward smaller addresses.
*/
#define CPU_STACK_GROWS_UP FALSE
/*
* The following is the variable attribute used to force alignment
* of critical RTEMS structures. On some processors it may make
* sense to have these aligned on tighter boundaries than
* the minimum requirements of the compiler in order to have as
* much of the critical data area as possible in a cache line.
*
* The placement of this macro in the declaration of the variables
* is based on the syntactically requirements of the GNU C
* "__attribute__" extension. For example with GNU C, use
* the following to force a structures to a 32 byte boundary.
*
* __attribute__ ((aligned (32)))
*
* NOTE: Currently only the Priority Bit Map table uses this feature.
* To benefit from using this, the data must be heavily
* used so it will stay in the cache and used frequently enough
* in the executive to justify turning this on.
*/
#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32)))
/*
* Define what is required to specify how the network to host conversion
* routines are handled.
*/
#define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE
#define CPU_BIG_ENDIAN TRUE
#define CPU_LITTLE_ENDIAN FALSE
/*
* The following defines the number of bits actually used in the
* interrupt field of the task mode. How those bits map to the
* CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
*/
#define CPU_MODES_INTERRUPT_MASK 0x00000001
/*
* Processor defined structures
*
* Examples structures include the descriptor tables from the i386
* and the processor control structure on the i960ca.
*/
/* may need to put some structures here. */
/*
* Contexts
*
* Generally there are 2 types of context to save.
* 1. Interrupt registers to save
* 2. Task level registers to save
*
* This means we have the following 3 context items:
* 1. task level context stuff:: Context_Control
* 2. floating point task stuff:: Context_Control_fp
* 3. special interrupt level context :: Context_Control_interrupt
*
* On some processors, it is cost-effective to save only the callee
* preserved registers during a task context switch. This means
* that the ISR code needs to save those registers which do not
* persist across function calls. It is not mandatory to make this
* distinctions between the caller/callee saves registers for the
* purpose of minimizing context saved during task switch and on interrupts.
* If the cost of saving extra registers is minimal, simplicity is the
* choice. Save the same context on interrupt entry as for tasks in
* this case.
*
* Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then
* care should be used in designing the context area.
*
* On some CPUs with hardware floating point support, the Context_Control_fp
* structure will not be used or it simply consist of an array of a
* fixed number of bytes. This is done when the floating point context
* is dumped by a "FP save context" type instruction and the format
* is not really defined by the CPU. In this case, there is no need
* to figure out the exact format -- only the size. Of course, although
* this is enough information for RTEMS, it is probably not enough for
* a debugger such as gdb. But that is another problem.
*/
typedef struct {
unsigned32 register_r0;
unsigned32 register_r1;
unsigned32 register_r2;
unsigned32 register_r3;
unsigned32 register_r4;
unsigned32 register_r5;
unsigned32 register_r6;
unsigned32 register_r7;
unsigned32 register_r8;
unsigned32 register_r9;
unsigned32 register_r10;
unsigned32 register_fp;
unsigned32 register_ip;
unsigned32 register_sp;
unsigned32 register_lr;
unsigned32 register_pc;
} Context_Control;
typedef struct {
double some_float_register;
} Context_Control_fp;
typedef Context_Control CPU_Exception_frame;
typedef void (*cpuExcHandlerType) (CPU_Exception_frame*);
extern cpuExcHandlerType _currentExcHandler;
extern void rtems_exception_init_mngt();
/*
* The following structure defines the set of information saved
* on the current stack by RTEMS upon receipt of each interrupt
* that will lead to re-enter the kernel to signal the thread.
*/
typedef CPU_Exception_frame CPU_Interrupt_frame;
/*
* The following table contains the information required to configure
* the XXX processor specific parameters.
*/
typedef struct {
void (*pretasking_hook)( void );
void (*predriver_hook)( void );
void (*postdriver_hook)( void );
void (*idle_task)( void );
boolean do_zero_of_workspace;
unsigned32 idle_task_stack_size;
unsigned32 interrupt_stack_size;
unsigned32 extra_mpci_receive_server_stack;
void * (*stack_allocate_hook)( unsigned32 );
void (*stack_free_hook)( void* );
/* end of fields required on all CPUs */
} rtems_cpu_table;
/*
* Macros to access required entires in the CPU Table are in
* the file rtems/system.h.
*/
/*
* Macros to access NO_CPU specific additions to the CPU Table
*/
/* There are no CPU specific additions to the CPU Table for this port. */
/*
* This variable is optional. It is used on CPUs on which it is difficult
* to generate an "uninitialized" FP context. It is filled in by
* _CPU_Initialize and copied into the task's FP context area during
* _CPU_Context_Initialize.
*/
SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context;
/*
* On some CPUs, RTEMS supports a software managed interrupt stack.
* This stack is allocated by the Interrupt Manager and the switch
* is performed in _ISR_Handler. These variables contain pointers
* to the lowest and highest addresses in the chunk of memory allocated
* for the interrupt stack. Since it is unknown whether the stack
* grows up or down (in general), this give the CPU dependent
* code the option of picking the version it wants to use.
*
* NOTE: These two variables are required if the macro
* CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE.
*/
SCORE_EXTERN void *_CPU_Interrupt_stack_low;
SCORE_EXTERN void *_CPU_Interrupt_stack_high;
/*
* With some compilation systems, it is difficult if not impossible to
* call a high-level language routine from assembly language. This
* is especially true of commercial Ada compilers and name mangling
* C++ ones. This variable can be optionally defined by the CPU porter
* and contains the address of the routine _Thread_Dispatch. This
* can make it easier to invoke that routine at the end of the interrupt
* sequence (if a dispatch is necessary).
*/
SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)();
/*
* Nothing prevents the porter from declaring more CPU specific variables.
*/
/* XXX: if needed, put more variables here */
/*
* The size of the floating point context area. On some CPUs this
* will not be a "sizeof" because the format of the floating point
* area is not defined -- only the size is. This is usually on
* CPUs with a "floating point save context" instruction.
*/
#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp )
/*
* Amount of extra stack (above minimum stack size) required by
* MPCI receive server thread. Remember that in a multiprocessor
* system this thread must exist and be able to process all directives.
*/
#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
/*
* This defines the number of entries in the ISR_Vector_table managed
* by RTEMS.
*/
#define CPU_INTERRUPT_NUMBER_OF_VECTORS 8
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
/*
* Should be large enough to run all RTEMS tests. This insures
* that a "reasonable" small application should not have any problems.
*/
#define CPU_STACK_MINIMUM_SIZE (1024*4)
/*
* CPU's worst alignment requirement for data types on a byte boundary. This
* alignment does not take into account the requirements for the stack.
*/
#define CPU_ALIGNMENT 8
/*
* This number corresponds to the byte alignment requirement for the
* heap handler. This alignment requirement may be stricter than that
* for the data types alignment specified by CPU_ALIGNMENT. It is
* common for the heap to follow the same alignment requirement as
* CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap,
* then this should be set to CPU_ALIGNMENT.
*
* NOTE: This does not have to be a power of 2. It does have to
* be greater or equal to than CPU_ALIGNMENT.
*/
#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
/*
* This number corresponds to the byte alignment requirement for memory
* buffers allocated by the partition manager. This alignment requirement
* may be stricter than that for the data types alignment specified by
* CPU_ALIGNMENT. It is common for the partition to follow the same
* alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict
* enough for the partition, then this should be set to CPU_ALIGNMENT.
*
* NOTE: This does not have to be a power of 2. It does have to
* be greater or equal to than CPU_ALIGNMENT.
*/
#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT
/*
* This number corresponds to the byte alignment requirement for the
* stack. This alignment requirement may be stricter than that for the
* data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT
* is strict enough for the stack, then this should be set to 0.
*
* NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT.
*/
#define CPU_STACK_ALIGNMENT 32
/* ISR handler macros */
/*
* Disable all interrupts for an RTEMS critical section. The previous
* level is returned in _level.
*/
#define _CPU_ISR_Disable( _level ) \
{ \
asm volatile ("MRS r0, cpsr \n" ); \
asm volatile ("ORR r0, r0, #0xc0 \n" ); \
asm volatile ("MSR cpsr, r0 \n" ); \
}
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
* _level is not modified.
*/
#define _CPU_ISR_Enable( _level ) \
{ \
asm volatile ("MRS r0, cpsr \n" ); \
asm volatile ("AND r0, r0, #0xFFFFFF3F \n" ); \
asm volatile ("MSR cpsr, r0 \n" ); \
}
/*
* This temporarily restores the interrupt to _level before immediately
* disabling them again. This is used to divide long RTEMS critical
* sections into two or more parts. The parameter _level is not
* modified.
*/
#define _CPU_ISR_Flash( _isr_cookie ) \
{ \
}
/*
* Map interrupt level in task mode onto the hardware that the CPU
* actually provides. Currently, interrupt levels which do not
* map onto the CPU in a generic fashion are undefined. Someday,
* it would be nice if these were "mapped" by the application
* via a callout. For example, m68k has 8 levels 0 - 7, levels
* 8 - 255 would be available for bsp/application specific meaning.
* This could be used to manage a programmable interrupt controller
* via the rtems_task_mode directive.
*
* The get routine usually must be implemented as a subroutine.
*/
#define _CPU_ISR_Set_level( new_level ) \
{ \
}
unsigned32 _CPU_ISR_Get_level( void );
/* end of ISR handler macros */
/* Context handler macros */
/*
* Initialize the context to a state suitable for starting a
* task after a context restore operation. Generally, this
* involves:
*
* - setting a starting address
* - preparing the stack
* - preparing the stack and frame pointers
* - setting the proper interrupt level in the context
* - initializing the floating point context
*
* This routine generally does not set any unnecessary register
* in the context. The state of the "general data" registers is
* undefined at task start time.
*
* NOTE: This is_fp parameter is TRUE if the thread is to be a floating
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point, _is_fp ) \
{ \
(_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \
(_the_context)->register_pc = (_entry_point); \
}
/*
* This routine is responsible for somehow restarting the currently
* executing task. If you are lucky, then all that is necessary
* is restoring the context. Otherwise, there will need to be
* a special assembly routine which does something special in this
* case. Context_Restore should work most of the time. It will
* not work if restarting self conflicts with the stack frame
* assumptions of restoring a context.
*/
#define _CPU_Context_Restart_self( _the_context ) \
_CPU_Context_restore( (_the_context) );
/*
* The purpose of this macro is to allow the initial pointer into
* a floating point context area (used to save the floating point
* context) to be at an arbitrary place in the floating point
* context area.
*
* This is necessary because some FP units are designed to have
* their context saved as a stack which grows into lower addresses.
* Other FP units can be saved by simply moving registers into offsets
* from the base of the context area. Finally some FP units provide
* a "dump context" instruction which could fill in from high to low
* or low to high based on the whim of the CPU designers.
*/
#define _CPU_Context_Fp_start( _base, _offset ) \
( (void *) _Addresses_Add_offset( (_base), (_offset) ) )
/*
* This routine initializes the FP context area passed to it to.
* There are a few standard ways in which to initialize the
* floating point context. The code included for this macro assumes
* that this is a CPU in which a "initial" FP context was saved into
* _CPU_Null_fp_context and it simply copies it to the destination
* context passed to it.
*
* Other models include (1) not doing anything, and (2) putting
* a "null FP status word" in the correct place in the FP context.
*/
#define _CPU_Context_Initialize_fp( _destination ) \
{ \
*((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \
}
/* end of Context handler macros */
/* Fatal Error manager macros */
/*
* This routine copies _error into a known place -- typically a stack
* location or a register, optionally disables interrupts, and
* halts/stops the CPU.
*/
#define _CPU_Fatal_halt( _error ) \
{ \
}
/* end of Fatal Error manager macros */
/* Bitfield handler macros */
/*
* This routine sets _output to the bit number of the first bit
* set in _value. _value is of CPU dependent type Priority_Bit_map_control.
* This type may be either 16 or 32 bits wide although only the 16
* least significant bits will be used.
*
* There are a number of variables in using a "find first bit" type
* instruction.
*
* (1) What happens when run on a value of zero?
* (2) Bits may be numbered from MSB to LSB or vice-versa.
* (3) The numbering may be zero or one based.
* (4) The "find first bit" instruction may search from MSB or LSB.
*
* RTEMS guarantees that (1) will never happen so it is not a concern.
* (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
* _CPU_Priority_bits_index(). These three form a set of routines
* which must logically operate together. Bits in the _value are
* set and cleared based on masks built by _CPU_Priority_mask().
* The basic major and minor values calculated by _Priority_Major()
* and _Priority_Minor() are "massaged" by _CPU_Priority_bits_index()
* to properly range between the values returned by the "find first bit"
* instruction. This makes it possible for _Priority_Get_highest() to
* calculate the major and directly index into the minor table.
* This mapping is necessary to ensure that 0 (a high priority major/minor)
* is the first bit found.
*
* This entire "find first bit" and mapping process depends heavily
* on the manner in which a priority is broken into a major and minor
* components with the major being the 4 MSB of a priority and minor
* the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest
* priority. And (15 << 4) + 14 corresponds to priority 254 -- the next
* to the lowest priority.
*
* If your CPU does not have a "find first bit" instruction, then
* there are ways to make do without it. Here are a handful of ways
* to implement this in software:
*
* - a series of 16 bit test instructions
* - a "binary search using if's"
* - _number = 0
* if _value > 0x00ff
* _value >>=8
* _number = 8;
*
* if _value > 0x0000f
* _value >=8
* _number += 4
*
* _number += bit_set_table[ _value ]
*
* where bit_set_table[ 16 ] has values which indicate the first
* bit set
*/
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
#define CPU_USE_GENERIC_BITFIELD_DATA TRUE
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
{ \
(_output) = 0; /* do something to prevent warnings */ \
}
#endif
/* end of Bitfield handler macros */
/*
* This routine builds the mask which corresponds to the bit fields
* as searched by _CPU_Bitfield_Find_first_bit(). See the discussion
* for that routine.
*/
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Priority_Mask( _bit_number ) \
( 1 << (_bit_number) )
#endif
/*
* This routine translates the bit numbers returned by
* _CPU_Bitfield_Find_first_bit() into something suitable for use as
* a major or minor component of a priority. See the discussion
* for that routine.
*/
#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
#define _CPU_Priority_bits_index( _priority ) \
(_priority)
#endif
/* end of Priority handler macros */
/* functions */
/*
* _CPU_Initialize
*
* This routine performs CPU dependent initialization.
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch)
);
typedef enum {
ARM_EXCEPTION_RESET = 0,
ARM_EXCEPTION_UNDEF = 1,
ARM_EXCEPTION_SWI = 2,
ARM_EXCEPTION_PREF_ABORT = 3,
ARM_EXCEPTION_DATA_ABORT = 4,
ARM_EXCEPTION_RESERVED = 5,
ARM_EXCEPTION_IRQ = 6,
ARM_EXCEPTION_FIQ = 7,
MAX_EXCEPTIONS = 8
} Arm_symbolic_exception_name;
/*
* _CPU_ISR_install_vector
*
* This routine installs an interrupt vector.
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
);
/*
* _CPU_Install_interrupt_stack
*
* This routine installs the hardware interrupt stack pointer.
*
* NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK
* is TRUE.
*/
void _CPU_Install_interrupt_stack( void );
/*
* _CPU_Thread_Idle_body
*
* This routine is the CPU dependent IDLE thread body.
*
* NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY
* is TRUE.
*/
void _CPU_Thread_Idle_body( void );
/*
* _CPU_Context_switch
*
* This routine switches from the run context to the heir context.
*/
void _CPU_Context_switch(
Context_Control *run,
Context_Control *heir
);
/*
* _CPU_Context_restore
*
* This routine is generally used only to restart self in an
* efficient manner. It may simply be a label in _CPU_Context_switch.
*
* NOTE: May be unnecessary to reload some registers.
*/
void _CPU_Context_restore(
Context_Control *new_context
);
/*
* _CPU_Context_save_fp
*
* This routine saves the floating point context passed to it.
*/
void _CPU_Context_save_fp(
void **fp_context_ptr
);
/*
* _CPU_Context_restore_fp
*
* This routine restores the floating point context passed to it.
*/
void _CPU_Context_restore_fp(
void **fp_context_ptr
);
/* The following routine swaps the endian format of an unsigned int.
* It must be static because it is referenced indirectly.
*
* This version will work on any processor, but if there is a better
* way for your CPU PLEASE use it. The most common way to do this is to:
*
* swap least significant two bytes with 16-bit rotate
* swap upper and lower 16-bits
* swap most significant two bytes with 16-bit rotate
*
* Some CPUs have special instructions which swap a 32-bit quantity in
* a single instruction (e.g. i486). It is probably best to avoid
* an "endian swapping control bit" in the CPU. One good reason is
* that interrupts would probably have to be disabled to insure that
* an interrupt does not try to access the same "chunk" with the wrong
* endian. Another good reason is that on some CPUs, the endian bit
* endianness for ALL fetches -- both code and data -- so the code
* will be fetched incorrectly.
*/
static inline unsigned int CPU_swap_u32(
unsigned int value
)
{
unsigned32 byte1, byte2, byte3, byte4, swapped;
byte4 = (value >> 24) & 0xff;
byte3 = (value >> 16) & 0xff;
byte2 = (value >> 8) & 0xff;
byte1 = value & 0xff;
swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
return( swapped );
}
#define CPU_swap_u16( value ) \
(((value&0xff) << 8) | ((value >> 8)&0xff))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
* cpu_asm.h
*
* Very loose template for an include file for the cpu_asm.? file
* if it is implemented as a ".S" file (preprocessed by cpp) instead
* of a ".s" file (preprocessed by gm4 or gasp).
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*
*/
#ifndef __CPU_ASM_h
#define __CPU_ASM_h
/* pull in the generated offsets */
#include <rtems/score/offsets.h>
/*
* Hardware General Registers
*/
/* put something here */
/*
* Hardware Floating Point Registers
*/
/* put something here */
/*
* Hardware Control Registers
*/
/* put something here */
/*
* Calling Convention
*/
/* put something here */
/*
* Temporary registers
*/
/* put something here */
/*
* Floating Point Registers - SW Conventions
*/
/* put something here */
/*
* Temporary floating point registers
*/
/* put something here */
#endif
/* end of file */

View File

@@ -0,0 +1,55 @@
/* armtypes.h
*
* This include file contains type definitions pertaining to the
* arm processor family.
*
* COPYRIGHT (c) 2000 Canon Research Centre France SA.
* Emmanuel Raguet, mailto:raguet@crf.canon.fr
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*/
#ifndef __ARM_TYPES_h
#define __ARM_TYPES_h
#ifndef ASM
#ifdef __cplusplus
extern "C" {
#endif
/*
* This section defines the basic types for this processor.
*/
typedef unsigned char unsigned8; /* unsigned 8-bit integer */
typedef unsigned short unsigned16; /* unsigned 16-bit integer */
typedef unsigned int unsigned32; /* unsigned 32-bit integer */
typedef unsigned long long unsigned64; /* unsigned 64-bit integer */
typedef unsigned16 Priority_Bit_map_control;
typedef signed char signed8; /* 8-bit signed integer */
typedef signed short signed16; /* 16-bit signed integer */
typedef signed int signed32; /* 32-bit signed integer */
typedef signed long long signed64; /* 64 bit signed integer */
typedef unsigned32 boolean; /* Boolean value */
typedef float single_precision; /* single precision float */
typedef double double_precision; /* double precision float */
typedef void no_cpu_isr;
typedef void ( *no_cpu_isr_entry )( void );
#ifdef __cplusplus
}
#endif
#endif /* !ASM */
#endif
/* end of include file */

View File

@@ -0,0 +1,95 @@
#
# Config file for ARM BOARD --
#
# $Id$
#
include $(RTEMS_ROOT)/make/custom/default.cfg
RTEMS_CPU=arm
RTEMS_CPU_MODEL=arm7tdmi
#RTEMS_PPC_EXCEPTION_PROCESSING_MODEL=new
# This is the actual bsp directory used during the build process.
RTEMS_BSP_FAMILY=arm_bare_bsp
# This section makes the target dependent options file.
# NDEBUG (C library)
# if defined asserts do not generate code. This is commonly used
# as a command line option.
#
# RTEMS_TEST_NO_PAUSE (RTEMS tests)
# do not pause between screens of output in the rtems tests
#
# RTEMS_DEBUG (RTEMS)
# If defined, debug checks in RTEMS and support library code are enabled.
#
define make-target-options
@echo "/* #define NDEBUG 1 */ " >>$@
@echo "#define RTEMS_TEST_NO_PAUSE 1" >>$@
@echo "/* #define RTEMS_DEBUG 1 */" >>$@
endef
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
#
# NOTE : cheking egcc 1.1.1 source code shows that the last know processor
# is the 604 model and that this is the default generation option.
#
#CPU_CFLAGS = -mcpu=arm7tdmi
CPU_CFLAGS =
# optimize flag: typically -0, could use -O4 or -fast
# -O4 is ok for RTEMS
# NOTE2: some level of -O may be actually required by inline assembler (at least
# -O2 so far.
# NOTE2 Apparently nobody really knows the status or r2 and r13.
# As far as I know, small data are pointer impose a very specific compliation
# model => not used.
# Currently the sdata2 and sbss2 sections are empty => r2 is not used...
CFLAGS_OPTIMIZE_V=
#CFLAGS_OPTIMIZE_V=-O4 -mmultiple -mstring -mstrict-align
#CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions -fvolatile-global -fvolatile -mstrict-align -mcpu=750
# debug flags: typically none, but at least -O1 is required due to this
# BSP using inlined code
CFLAGS_DEBUG_V = -O1
#CFLAGS_DEBUG_V = -O1 -mmultiple -mstring -mstrict-align
# The following is a ld command file which works without using the
# -specs system in gcc 2.8. IT HAS NEVER BEEN TESTED WITH THIS BSP!!!
# $(LD) $(XLDFLAGS) -T $(LINKCMDS) \
# -o $@ -u atexit -u __vectors -u download_entry $(LINK_FILES)
# $(LD) $(XLDFLAGS) -Ttext 0x20000 \
# -o $@ -u atexit -u __vectors -u download_entry $(LINK_FILES)
# $(CC) -mmvme -mrtems -nostartfiles -mcpu=603 \
# -o $(basename $@).exe -L $(PROJECT_RELEASE)/lib \
# $(START_FILE) $(LINK_OBJS) \
# $(LD_LIBS) \
# -Wl,-\( -Wl,-lc -Wl,-lrtemsall -Wl,-lgcc -Wl,-\)
define make-exe
$(CC) -v -static -Wl,-Map -Wl,Mapfile -Wl,-T -Wl,linkcmds -Wl,-N -o $(basename $@).obj $(LINK_OBJS) $(LINK_LIBS)
# $(LINK.c) $(LDLIBS) -o $@ $(LINK_OBJS) $(LINK_LIBS)
$(OBJCOPY) -O binary \
--only-section=.text \
--only-section=.data \
--only-section=.rodata \
--strip-unneeded $(basename $@).obj $(basename $@).bin
$(NM) -g -n $(basename $@).obj > $(basename $@).num
$(SIZE) $(basename $@).obj
test -d ${PROJECT_RELEASE}/bin || mkdir ${PROJECT_RELEASE}/bin
f=`basename $@ .exe`; \
cp $(basename $@).bin $(basename $@).exe
cp $(basename $@).bin ${PROJECT_RELEASE}/bin/$${f}$(LIB_VARIANT).exe
endef
# Miscellaneous additions go here
# Let the HWAPI know which set of drivers to build
#DRIVER_ARCHITECTURE=compactpci

View File

@@ -6,6 +6,7 @@
RPM Version binutils-2.10-1
===========================
+ Add initial support for the ARM.
+ Adds support for the h8300.
binutils-2.10-rtems-20000628.diff

View File

@@ -16,6 +16,12 @@ CLEANFILES += binutils.spec.in
MKBINUTILSSPEC_DEPS = $(top_builddir)/mkbinutilspec binutils.spec.in \
$(top_builddir)/setup.cache
arm-rtems-$(BINUTILSVERS).spec: $(MKBINUTILSSPEC_DEPS)
$(MKBINUTILSSPEC) -cfg $(top_builddir)/setup.cache -o . arm-rtems
c4x-rtems-$(BINUTILSVERS).spec: $(MKBINUTILSSPEC_DEPS)
$(MKBINUTILSSPEC) -cfg $(top_builddir)/setup.cache -o . c4x-rtems
h8300-rtems-$(BINUTILSVERS).spec: $(MKBINUTILSSPEC_DEPS)
$(MKBINUTILSSPEC) -cfg $(top_builddir)/setup.cache -o . h8300-rtems
@@ -49,7 +55,10 @@ sh-rtemself-$(BINUTILSVERS).spec: $(MKBINUTILSSPEC_DEPS)
sparc-rtems-$(BINUTILSVERS).spec: $(MKBINUTILSSPEC_DEPS)
$(MKBINUTILSSPEC) -cfg $(top_builddir)/setup.cache -o . sparc-rtems
RPM_SPECS_DATA = h8300-rtems-$(BINUTILSVERS).spec \
RPM_SPECS_DATA = \
arm-rtems-$(BINUTILSVERS).spec \
c4x-rtems-$(BINUTILSVERS).spec \
h8300-rtems-$(BINUTILSVERS).spec \
hppa1.1-rtems-$(BINUTILSVERS).spec \
i386-rtems-$(BINUTILSVERS).spec i960-rtems-$(BINUTILSVERS).spec \
m68k-rtems-$(BINUTILSVERS).spec m68k-rtemself-$(BINUTILSVERS).spec \

View File

@@ -69,7 +69,9 @@ fi
# This is the full buildable set.
if [ "X${TARGETS}" = "X" ] ; then
TARGETS="i386-rtems i960-rtems m68k-rtems \
# do not include c4x or hppa primary targets
# do not include sh-elf or i960-elf secondary targets
TARGETS="arm-rtems h8300-rtems i386-rtems i960-rtems m68k-rtems \
mips64orion-rtems powerpc-rtems sh-rtems sparc-rtems"
fi

View File

@@ -6,8 +6,13 @@
RPM Version gcc2.95.2newlib1.8.2-8
==================================
+ arm
- Add initial support.
+ c4x
- Add initial support.
+ h8300
- Add initial support.
- define CPU type in libfunc
+ i386
- Build soft and HW floating point multilibs for i386 embedded targets.
+ i960
@@ -15,7 +20,7 @@ RPM Version gcc2.95.2newlib1.8.2-8
+ powerpc
- Fixes possible bug in gcc target where incorrect startup files specified.
gcc-2.95.2-rtems-20000710.diff
gcc-2.95.2-rtems-20000724.diff
- Add i386 embedded soft float multlibs (Joel)
- Define _SOFT_FLOAT on i960 when -msoft-float specified (Joel)
- fixes h8300-rtems specific configuration problems (Joel)

View File

@@ -30,6 +30,12 @@ MKGCCNEWLIBSPEC_DEPS = $(top_builddir)/mkgccnewlibspec gccnewlib.spec.in \
MKGCCNEWLIB_C_ONLY_SPEC_DEPS = $(top_builddir)/mkgccnewlibspec \
gccnewlib_c_only.spec.in $(top_builddir)/setup.cache
arm-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIBSPEC_DEPS)
$(MKGCCNEWLIBSPEC) -cfg $(top_builddir)/setup.cache -o . arm-rtems
c4x-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIB_C_ONLY_SPEC_DEPS)
$(MKGCCNEWLIBSPEC) $(C_ONLY_ARG) -cfg $(top_builddir)/setup.cache -o . c4x-rtems
h8300-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIB_C_ONLY_SPEC_DEPS)
$(MKGCCNEWLIBSPEC) $(C_ONLY_ARG) -cfg $(top_builddir)/setup.cache -o . h8300-rtems
@@ -45,9 +51,6 @@ i960-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIB_C_ONLY_SPEC_DEPS)
m68k-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIBSPEC_DEPS)
$(MKGCCNEWLIBSPEC) -cfg $(top_builddir)/setup.cache -o . m68k-rtems
m68k-rtemself-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIBSPEC_DEPS)
$(MKGCCNEWLIBSPEC) -cfg $(top_builddir)/setup.cache -o . m68k-rtemself
mips64orion-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIBSPEC_DEPS)
$(MKGCCNEWLIBSPEC) -cfg $(top_builddir)/setup.cache -o . mips64orion-rtems
@@ -63,10 +66,13 @@ sh-rtemself-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIBSPEC_DEPS)
sparc-rtems-$(GCCNEWLIBVERS).spec: $(MKGCCNEWLIBSPEC_DEPS)
$(MKGCCNEWLIBSPEC) -cfg $(top_builddir)/setup.cache -o . sparc-rtems
RPM_SPECS_DATA = h8300-rtems-$(GCCNEWLIBVERS).spec \
RPM_SPECS_DATA = \
arm-rtems-$(GCCNEWLIBVERS).spec \
c4x-rtems-$(GCCNEWLIBVERS).spec \
h8300-rtems-$(GCCNEWLIBVERS).spec \
hppa1.1-rtems-$(GCCNEWLIBVERS).spec \
i386-rtems-$(GCCNEWLIBVERS).spec i960-rtems-$(GCCNEWLIBVERS).spec \
m68k-rtems-$(GCCNEWLIBVERS).spec m68k-rtemself-$(GCCNEWLIBVERS).spec \
m68k-rtems-$(GCCNEWLIBVERS).spec \
mips64orion-rtems-$(GCCNEWLIBVERS).spec \
powerpc-rtems-$(GCCNEWLIBVERS).spec sh-rtems-$(GCCNEWLIBVERS).spec \
sh-rtemself-$(GCCNEWLIBVERS).spec sparc-rtems-$(GCCNEWLIBVERS).spec

View File

@@ -15,6 +15,12 @@ CLEANFILES += gdb.spec.in
MKGDBSPEC_DEPS = $(top_builddir)/mkgdbspec gdb.spec.in \
$(top_builddir)/setup.cache
arm-rtems-$(GDBVERS).spec: $(MKGDBSPEC_DEPS)
$(MKGDBSPEC) -cfg $(top_builddir)/setup.cache -o . arm-rtems
c4x-rtems-$(GDBVERS).spec: $(MKGDBSPEC_DEPS)
$(MKGDBSPEC) -cfg $(top_builddir)/setup.cache -o . c4x-rtems
h8300-rtems-$(GDBVERS).spec: $(MKGDBSPEC_DEPS)
$(MKGDBSPEC) -cfg $(top_builddir)/setup.cache -o . h8300-rtems
@@ -48,12 +54,14 @@ sh-rtemself-$(GDBVERS).spec: $(MKGDBSPEC_DEPS)
sparc-rtems-$(GDBVERS).spec: $(MKGDBSPEC_DEPS)
$(MKGDBSPEC) -cfg $(top_builddir)/setup.cache -o . sparc-rtems
RPM_SPECS_DATA = h8300-rtems-$(GDBVERS).spec i386-rtems-$(GDBVERS).spec \
hppa1.1-rtems-$(GDBVERS).spec i386-rtems-$(GDBVERS).spec \
i960-rtems-$(GDBVERS).spec m68k-rtems-$(GDBVERS).spec \
m68k-rtemself-$(GDBVERS).spec mips64orion-rtems-$(GDBVERS).spec \
RPM_SPECS_DATA = \
arm-rtems-$(GDBVERS).spec c4x-rtems-$(GDBVERS).spec \
h8300-rtems-$(GDBVERS).spec hppa1.1-rtems-$(GDBVERS).spec \
i386-rtems-$(GDBVERS).spec i960-rtems-$(GDBVERS).spec \
m68k-rtems-$(GDBVERS).spec mips64orion-rtems-$(GDBVERS).spec \
powerpc-rtems-$(GDBVERS).spec sh-rtems-$(GDBVERS).spec \
sh-rtemself-$(GDBVERS).spec sparc-rtems-$(GDBVERS).spec
CLEANFILES += $(RPM_SPECS_DATA)
EXTRA_DIST = $(SUBPACKAGES)

View File

@@ -4,16 +4,16 @@
# $Id$
#
binutils_version=2.10
binutils_patch_version=20000628
binutils_rpm_release=1
binutils_patch_version=20000726
binutils_rpm_release=2
newlib_version=1.8.2
newlib_patch_version=20000606
gcc_version=2.95.2
gcc_patch_version=20000710
gcc_patch_version=20000724
gccnewlib_rpm_release=8
gdb_version=5.0
gdb_patch_version=20000627
gdb_rpm_release=1
rtems_version=rtems-4.5.0-beta3a
rtems_version=ss-20000726
rtems_rpm_release=1
rpm_build_root=/tmp