forked from Imagelibrary/rtems
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:
@@ -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.
|
||||
|
||||
13
c/src/exec/score/cpu/arm/.cvsignore
Normal file
13
c/src/exec/score/cpu/arm/.cvsignore
Normal 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
|
||||
48
c/src/exec/score/cpu/arm/Makefile.am
Normal file
48
c/src/exec/score/cpu/arm/Makefile.am
Normal 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
c/src/exec/score/cpu/arm/asm.h
Normal file
125
c/src/exec/score/cpu/arm/asm.h
Normal 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 */
|
||||
|
||||
|
||||
34
c/src/exec/score/cpu/arm/configure.in
Normal file
34
c/src/exec/score/cpu/arm/configure.in
Normal 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)
|
||||
169
c/src/exec/score/cpu/arm/cpu.c
Normal file
169
c/src/exec/score/cpu/arm/cpu.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
193
c/src/exec/score/cpu/arm/cpu_asm.S
Normal file
193
c/src/exec/score/cpu/arm/cpu_asm.S
Normal 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 */
|
||||
|
||||
|
||||
2
c/src/exec/score/cpu/arm/rtems/.cvsignore
Normal file
2
c/src/exec/score/cpu/arm/rtems/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
10
c/src/exec/score/cpu/arm/rtems/Makefile.am
Normal file
10
c/src/exec/score/cpu/arm/rtems/Makefile.am
Normal 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
|
||||
2
c/src/exec/score/cpu/arm/rtems/score/.cvsignore
Normal file
2
c/src/exec/score/cpu/arm/rtems/score/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
26
c/src/exec/score/cpu/arm/rtems/score/Makefile.am
Normal file
26
c/src/exec/score/cpu/arm/rtems/score/Makefile.am
Normal 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
|
||||
54
c/src/exec/score/cpu/arm/rtems/score/arm.h
Normal file
54
c/src/exec/score/cpu/arm/rtems/score/arm.h
Normal 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 */
|
||||
55
c/src/exec/score/cpu/arm/rtems/score/armtypes.h
Normal file
55
c/src/exec/score/cpu/arm/rtems/score/armtypes.h
Normal 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 */
|
||||
916
c/src/exec/score/cpu/arm/rtems/score/cpu.h
Normal file
916
c/src/exec/score/cpu/arm/rtems/score/cpu.h
Normal 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
|
||||
69
c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h
Normal file
69
c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h
Normal 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 */
|
||||
55
c/src/exec/score/cpu/arm/rtems/score/types.h
Normal file
55
c/src/exec/score/cpu/arm/rtems/score/types.h
Normal 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 */
|
||||
13
c/src/lib/libbsp/arm/.cvsignore
Normal file
13
c/src/lib/libbsp/arm/.cvsignore
Normal 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
|
||||
14
c/src/lib/libbsp/arm/Makefile.am
Normal file
14
c/src/lib/libbsp/arm/Makefile.am
Normal 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
|
||||
13
c/src/lib/libbsp/arm/arm_bare_bsp/.cvsignore
Normal file
13
c/src/lib/libbsp/arm/arm_bare_bsp/.cvsignore
Normal 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
|
||||
15
c/src/lib/libbsp/arm/arm_bare_bsp/Makefile.am
Normal file
15
c/src/lib/libbsp/arm/arm_bare_bsp/Makefile.am
Normal 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
|
||||
23
c/src/lib/libbsp/arm/arm_bare_bsp/bsp_specs
Normal file
23
c/src/lib/libbsp/arm/arm_bare_bsp/bsp_specs
Normal 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}
|
||||
|
||||
43
c/src/lib/libbsp/arm/arm_bare_bsp/configure.in
Normal file
43
c/src/lib/libbsp/arm/arm_bare_bsp/configure.in
Normal 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)
|
||||
2
c/src/lib/libbsp/arm/arm_bare_bsp/console/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/arm_bare_bsp/console/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
32
c/src/lib/libbsp/arm/arm_bare_bsp/console/Makefile.am
Normal file
32
c/src/lib/libbsp/arm/arm_bare_bsp/console/Makefile.am
Normal 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
|
||||
2
c/src/lib/libbsp/arm/arm_bare_bsp/include/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/arm_bare_bsp/include/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
24
c/src/lib/libbsp/arm/arm_bare_bsp/include/Makefile.am
Normal file
24
c/src/lib/libbsp/arm/arm_bare_bsp/include/Makefile.am
Normal 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
|
||||
33
c/src/lib/libbsp/arm/arm_bare_bsp/include/bsp.h
Normal file
33
c/src/lib/libbsp/arm/arm_bare_bsp/include/bsp.h
Normal 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 */
|
||||
|
||||
53
c/src/lib/libbsp/arm/arm_bare_bsp/include/registers.h
Normal file
53
c/src/lib/libbsp/arm/arm_bare_bsp/include/registers.h
Normal 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__*/
|
||||
|
||||
2
c/src/lib/libbsp/arm/arm_bare_bsp/irq/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/arm_bare_bsp/irq/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
44
c/src/lib/libbsp/arm/arm_bare_bsp/irq/Makefile.am
Normal file
44
c/src/lib/libbsp/arm/arm_bare_bsp/irq/Makefile.am
Normal 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
|
||||
44
c/src/lib/libbsp/arm/arm_bare_bsp/irq/bsp_irq_asm.S
Normal file
44
c/src/lib/libbsp/arm/arm_bare_bsp/irq/bsp_irq_asm.S
Normal 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 */
|
||||
|
||||
27
c/src/lib/libbsp/arm/arm_bare_bsp/irq/bsp_irq_init.c
Normal file
27
c/src/lib/libbsp/arm/arm_bare_bsp/irq/bsp_irq_init.c
Normal 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
|
||||
*/
|
||||
|
||||
}
|
||||
119
c/src/lib/libbsp/arm/arm_bare_bsp/irq/irq.c
Normal file
119
c/src/lib/libbsp/arm/arm_bare_bsp/irq/irq.c
Normal 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();
|
||||
}
|
||||
}
|
||||
168
c/src/lib/libbsp/arm/arm_bare_bsp/irq/irq.h
Normal file
168
c/src/lib/libbsp/arm/arm_bare_bsp/irq/irq.h
Normal 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 */
|
||||
2
c/src/lib/libbsp/arm/arm_bare_bsp/start/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/arm_bare_bsp/start/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
33
c/src/lib/libbsp/arm/arm_bare_bsp/start/Makefile.am
Normal file
33
c/src/lib/libbsp/arm/arm_bare_bsp/start/Makefile.am
Normal 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
|
||||
157
c/src/lib/libbsp/arm/arm_bare_bsp/start/start.S
Normal file
157
c/src/lib/libbsp/arm/arm_bare_bsp/start/start.S
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2
c/src/lib/libbsp/arm/arm_bare_bsp/startup/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/arm_bare_bsp/startup/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
41
c/src/lib/libbsp/arm/arm_bare_bsp/startup/Makefile.am
Normal file
41
c/src/lib/libbsp/arm/arm_bare_bsp/startup/Makefile.am
Normal 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
|
||||
|
||||
164
c/src/lib/libbsp/arm/arm_bare_bsp/startup/bspstart.c
Normal file
164
c/src/lib/libbsp/arm/arm_bare_bsp/startup/bspstart.c
Normal 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")));
|
||||
48
c/src/lib/libbsp/arm/arm_bare_bsp/startup/exit.c
Normal file
48
c/src/lib/libbsp/arm/arm_bare_bsp/startup/exit.c
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
240
c/src/lib/libbsp/arm/arm_bare_bsp/startup/linkcmds
Normal file
240
c/src/lib/libbsp/arm/arm_bare_bsp/startup/linkcmds
Normal 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 . */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
2
c/src/lib/libbsp/arm/arm_bare_bsp/wrapup/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/arm_bare_bsp/wrapup/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
32
c/src/lib/libbsp/arm/arm_bare_bsp/wrapup/Makefile.am
Normal file
32
c/src/lib/libbsp/arm/arm_bare_bsp/wrapup/Makefile.am
Normal 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
|
||||
28
c/src/lib/libbsp/arm/configure.in
Normal file
28
c/src/lib/libbsp/arm/configure.in
Normal 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)
|
||||
2
c/src/lib/libbsp/arm/shared/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/shared/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
10
c/src/lib/libbsp/arm/shared/Makefile.am
Normal file
10
c/src/lib/libbsp/arm/shared/Makefile.am
Normal 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
|
||||
2
c/src/lib/libbsp/arm/shared/comm/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/shared/comm/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
22
c/src/lib/libbsp/arm/shared/comm/Makefile.am
Normal file
22
c/src/lib/libbsp/arm/shared/comm/Makefile.am
Normal 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
|
||||
367
c/src/lib/libbsp/arm/shared/comm/console.c
Normal file
367
c/src/lib/libbsp/arm/shared/comm/console.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
577
c/src/lib/libbsp/arm/shared/comm/uart.c
Normal file
577
c/src/lib/libbsp/arm/shared/comm/uart.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
158
c/src/lib/libbsp/arm/shared/comm/uart.h
Normal file
158
c/src/lib/libbsp/arm/shared/comm/uart.h
Normal 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 */
|
||||
|
||||
|
||||
|
||||
2
c/src/lib/libbsp/arm/shared/io/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/shared/io/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
22
c/src/lib/libbsp/arm/shared/io/Makefile.am
Normal file
22
c/src/lib/libbsp/arm/shared/io/Makefile.am
Normal 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
|
||||
38
c/src/lib/libbsp/arm/shared/io/bspio.h
Normal file
38
c/src/lib/libbsp/arm/shared/io/bspio.h
Normal 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
|
||||
113
c/src/lib/libbsp/arm/shared/io/printk.c
Normal file
113
c/src/lib/libbsp/arm/shared/io/printk.c
Normal 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 */
|
||||
|
||||
2
c/src/lib/libbsp/arm/shared/irq/.cvsignore
Normal file
2
c/src/lib/libbsp/arm/shared/irq/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
14
c/src/lib/libbsp/arm/shared/irq/Makefile.am
Normal file
14
c/src/lib/libbsp/arm/shared/irq/Makefile.am
Normal 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
|
||||
109
c/src/lib/libbsp/arm/shared/irq/irq_asm.S
Normal file
109
c/src/lib/libbsp/arm/shared/irq/irq_asm.S
Normal 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 */
|
||||
|
||||
51
c/src/lib/libbsp/arm/shared/irq/irq_init.c
Normal file
51
c/src/lib/libbsp/arm/shared/irq/irq_init.c
Normal 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();
|
||||
}
|
||||
|
||||
13
cpukit/score/cpu/arm/.cvsignore
Normal file
13
cpukit/score/cpu/arm/.cvsignore
Normal 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
|
||||
48
cpukit/score/cpu/arm/Makefile.am
Normal file
48
cpukit/score/cpu/arm/Makefile.am
Normal 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
125
cpukit/score/cpu/arm/asm.h
Normal 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
169
cpukit/score/cpu/arm/cpu.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
193
cpukit/score/cpu/arm/cpu_asm.S
Normal file
193
cpukit/score/cpu/arm/cpu_asm.S
Normal 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 */
|
||||
|
||||
|
||||
2
cpukit/score/cpu/arm/rtems/.cvsignore
Normal file
2
cpukit/score/cpu/arm/rtems/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
125
cpukit/score/cpu/arm/rtems/asm.h
Normal file
125
cpukit/score/cpu/arm/rtems/asm.h
Normal 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 */
|
||||
|
||||
|
||||
2
cpukit/score/cpu/arm/rtems/score/.cvsignore
Normal file
2
cpukit/score/cpu/arm/rtems/score/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
54
cpukit/score/cpu/arm/rtems/score/arm.h
Normal file
54
cpukit/score/cpu/arm/rtems/score/arm.h
Normal 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 */
|
||||
916
cpukit/score/cpu/arm/rtems/score/cpu.h
Normal file
916
cpukit/score/cpu/arm/rtems/score/cpu.h
Normal 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
|
||||
69
cpukit/score/cpu/arm/rtems/score/cpu_asm.h
Normal file
69
cpukit/score/cpu/arm/rtems/score/cpu_asm.h
Normal 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 */
|
||||
55
cpukit/score/cpu/arm/rtems/score/types.h
Normal file
55
cpukit/score/cpu/arm/rtems/score/types.h
Normal 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 */
|
||||
95
make/custom/arm_bare_bsp.cfg
Normal file
95
make/custom/arm_bare_bsp.cfg
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user