Patch from John Cotton <john.cotton@nrc.ca>, Charles-Antoine Gauthier

<charles.gauthier@iit.nrc.ca>, and Darlene A. Stewart
<Darlene.Stewart@nrc.ca> to add support for a number of very
significant things:

  + BSPs for many variations on the Motorola MBX8xx board series
  + Cache Manager including initial support for m68040
    and PowerPC
  + Rework of mpc8xx libcpu code so all mpc8xx CPUs now use
    same code base.
  + Rework of eth_comm BSP to utiltize above.

John reports this works on the 821 and 860
This commit is contained in:
Joel Sherrill
2000-06-12 19:57:02 +00:00
parent f481c39c01
commit 8ef38186fa
125 changed files with 13345 additions and 503 deletions

View File

@@ -14,6 +14,7 @@ AC_DEFUN(RTEMS_BSP_ALIAS,
gen68360_040) $2=gen68360 ;; # m68k - 68360 in companion mode
p4600) $2=p4000 ;; # mips64orion - p4000 board w/IDT 4600
p4650) $2=p4000 ;; # mips64orion - p4000 board w/IDT 4650
mbx8*) $2=mbx8xx ;; # MBX821/MBX860 board
pc486) $2=pc386 ;; # i386 - PC with i486DX
pc586) $2=pc386 ;; # i386 - PC with Pentium
pc686) $2=pc386 ;; # i386 - PC with PentiumPro

View File

@@ -23,6 +23,7 @@ AC_MSG_CHECKING([for bsps])
gen68360) rtems_bsp="$rtems_bsp gen68360 gen68360_040";;
p4000) rtems_bsp="$rtems_bsp p4600 p4650";;
mvme162) rtems_bsp="$rtems_bsp mvme162 mvme162lx";;
mbx8xx) rtems_bsp="$rtems_bsp mbx821_001 mbx860_002";;
motorola_powerpc) rtems_bsp="$rtems_bsp mvme2307 mcp750";;
pc386) rtems_bsp="$rtems_bsp pc386 pc486 pc586 pc686";;
*) $1="[$]$1 $file";;

View File

@@ -181,6 +181,7 @@ int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios *);
int tcsetattr(int, int, struct termios *);
int tcdrain(int);
pid_t tcgetprgrp(int);
int tcsetprgrp(int, pid_t);
int tcsendbreak(int, int);

View File

@@ -418,5 +418,27 @@ void _free_r(
{
free( ptr );
}
/*
* rtems_cache_aligned_malloc
*
* DESCRIPTION:
*
* This function is used to allocate storage that spans an
* integral number of cache blocks.
*/
RTEMS_INLINE_ROUTINE void * rtems_cache_aligned_malloc (
size_t nbytes
)
{
/*
* Arrange to have the user storage start on the first cache
* block beyond the header.
*/
return (void *) ((((unsigned long) malloc( nbytes + _CPU_DATA_CACHE_ALIGNMENT - 1 ))
+ _CPU_DATA_CACHE_ALIGNMENT - 1 ) &(~(_CPU_DATA_CACHE_ALIGNMENT - 1)) );
}
#endif

View File

@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/filio.h>
/*
* FreeBSD does not support a full POSIX termios so we have to help it out
@@ -243,7 +244,7 @@ rtems_termios_open (
/*
* Set default parameters
*/
tty->termios.c_iflag = BRKINT | ICRNL | IMAXBEL;
tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
tty->termios.c_oflag = OPOST | ONLCR | XTABS;
tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
@@ -474,6 +475,11 @@ rtems_termios_ioctl (void *arg)
case RTEMS_IO_TCDRAIN:
drainOutput (tty);
break;
case FIONREAD:
/* Half guess that this is the right operation */
*(int *)args->buffer = tty->ccount - tty->cindex;
break;
}
rtems_semaphore_release (tty->osem);
args->ioctl_return = sc;

View File

@@ -1,5 +1,5 @@
/*
* wait() - POSIX 1003.1b 3.2.1
* waitpid() - POSIX 1003.1 3.2.1
*
* $Id$
*/

View File

@@ -8,9 +8,9 @@ AUTOMAKE_OPTIONS = foreign 1.4
MP_H_FILES = eventmp.h mp.h msgmp.h partmp.h regionmp.h semmp.h signalmp.h \
taskmp.h
STD_H_FILES = asr.h attr.h clock.h config.h dpmem.h event.h eventset.h \
intr.h message.h modes.h options.h part.h ratemon.h region.h rtemsapi.h \
sem.h signal.h status.h support.h tasks.h timer.h types.h
STD_H_FILES = asr.h attr.h cache.h clock.h config.h dpmem.h event.h eventset.h \
intr.h message.h modes.h options.h part.h ratemon.h region.h rtemsapi.h sem.h \
signal.h status.h support.h tasks.h timer.h types.h
if HAS_MP
H_FILES = $(STD_H_FILES) $(MP_H_FILES)

View File

@@ -0,0 +1,140 @@
/* cache.h
*
* Cache Manager
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
*
* The functions in this file define the API to the RTEMS Cache Manager and
* are divided into data cache and instruction cache functions. Data cache
* functions are only declared if a data cache is supported. Instruction
* cache functions are only declared if an instruction cache is supported.
* Support for a particular cache exists only if _CPU_x_CACHE_ALIGNMENT is
* defined, where x E {DATA, INST}. These definitions are found in the CPU
* dependent source files in the supercore, often
*
* rtems/c/src/exec/score/cpu/CPU/rtems/score/CPU.h
*
* The functions below are implemented with CPU dependent inline routines
* also found in the above file. In the event that a CPU does not support a
* specific function, the CPU dependent routine does nothing (but does exist).
*
* At this point, the Cache Manager makes no considerations, and provides no
* support for BSP specific issues such as a secondary cache. In such a system,
* the CPU dependent routines would have to be modified, or a BSP layer added
* to this Manager.
*/
#ifndef __CACHE_h
#define __CACHE_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/system.h>
#include <sys/types.h>
/* THESE FUNCTIONS ONLY EXIST IF WE HAVE A DATA CACHE */
#if defined(_CPU_DATA_CACHE_ALIGNMENT)
/*
* This function is called to flush the data cache by performing cache
* copybacks. It must determine how many cache lines need to be copied
* back and then perform the copybacks.
*/
void rtems_flush_multiple_data_cache_lines( const void *, size_t );
/*
* This function is responsible for performing a data cache invalidate.
* It must determine how many cache lines need to be invalidated and then
* perform the invalidations.
*/
void rtems_invalidate_multiple_data_cache_lines( const void *, size_t );
/*
* This function is responsible for performing a data cache flush.
* It flushes the entire cache.
*/
void rtems_flush_entire_data_cache( void );
/*
* This function is responsible for performing a data cache
* invalidate. It invalidates the entire cache.
*/
void rtems_invalidate_entire_data_cache( void );
/*
* This function returns the data cache granularity.
*/
int rtems_get_data_cache_line_size( void );
/*
* This function freezes the data cache.
*/
void rtems_freeze_data_cache( void );
/*
* This function unfreezes the data cache.
*/
void rtems_unfreeze_data_cache( void );
/*
* These functions enable/disable the data cache.
*/
void rtems_enable_data_cache( void );
void rtems_disable_data_cache( void );
#endif
/* THESE FUNCTIONS ONLY EXIST IF WE HAVE AN INSTRUCTION CACHE */
#if defined(_CPU_INST_CACHE_ALIGNMENT)
/*
* This function is responsible for performing an instruction cache
* invalidate. It must determine how many cache lines need to be invalidated
* and then perform the invalidations.
*/
void rtems_invalidate_multiple_inst_cache_lines( const void *, size_t );
/*
* This function is responsible for performing an instruction cache
* invalidate. It invalidates the entire cache.
*/
void rtems_invalidate_entire_inst_cache( void );
/*
* This function returns the instruction cache granularity.
*/
int rtems_get_inst_cache_line_size( void );
/*
* This function freezes the instruction cache.
*/
void rtems_freeze_inst_cache( void );
/*
* This function unfreezes the instruction cache.
*/
void rtems_unfreeze_inst_cache( void );
/*
* These functions enable/disable the instruction cache.
*/
void rtems_enable_inst_cache( void );
void rtems_disable_inst_cache( void );
#endif
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -50,7 +50,7 @@ PARTITION_C_FILES = part.c partcreate.c partdelete.c partgetbuffer.c \
DPMEM_C_FILES = dpmem.c dpmemcreate.c dpmemdelete.c dpmemexternal2internal.c \
dpmemident.c dpmeminternal2external.c
STD_C_FILES = attr.c $(TASK_C_FILES) $(RATEMON_C_FILES) $(INTR_C_FILES) \
STD_C_FILES = attr.c cache.c $(TASK_C_FILES) $(RATEMON_C_FILES) $(INTR_C_FILES) \
$(CLOCK_C_FILES) $(TIMER_C_FILES) $(SEMAPHORE_C_FILES) \
$(MESSAGE_QUEUE_C_FILES) $(EVENT_C_FILES) $(SIGNAL_C_FILES) \
$(PARTITION_C_FILES) $(REGION_C_FILES) $(DPMEM_C_FILES)

View File

@@ -0,0 +1,252 @@
/* cache.c
*
* Cache Manager
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*
*
* The functions in this file define the API to the RTEMS Cache Manager and
* are divided into data cache and instruction cache functions. Data cache
* functions are only declared if a data cache is supported. Instruction
* cache functions are only declared if an instruction cache is supported.
* Support for a particular cache exists only if _CPU_x_CACHE_ALIGNMENT is
* defined, where x E {DATA, INST}. These definitions are found in the CPU
* dependent source files in the supercore, often
*
* rtems/c/src/exec/score/cpu/CPU/rtems/score/CPU.h
*
* The functions below are implemented with CPU dependent inline routines
* also found in the above file. In the event that a CPU does not support a
* specific function, the CPU dependent routine does nothing (but does exist).
*
* At this point, the Cache Manager makes no considerations, and provides no
* support for BSP specific issues such as a secondary cache. In such a system,
* the CPU dependent routines would have to be modified, or a BSP layer added
* to this Manager.
*/
#include <rtems/system.h>
#include <sys/types.h>
#include <rtems/rtems/cache.h>
/*
* THESE FUNCTIONS ONLY EXIST IF WE HAVE A DATA CACHE
*/
#if defined(_CPU_DATA_CACHE_ALIGNMENT)
/*
* This function is called to flush the data cache by performing cache
* copybacks. It must determine how many cache lines need to be copied
* back and then perform the copybacks.
*/
void
rtems_flush_multiple_data_cache_lines( const void * d_addr, size_t n_bytes )
{
const void * final_address;
/*
* Set d_addr to the beginning of the cache line; final_address indicates
* the last address_t which needs to be pushed. Increment d_addr and push
* the resulting line until final_address is passed.
*/
final_address = (void *)((size_t)d_addr + n_bytes - 1);
d_addr = (void *)((size_t)d_addr & ~(_CPU_DATA_CACHE_ALIGNMENT - 1));
while( d_addr <= final_address ) {
_CPU_flush_1_data_cache_line( d_addr );
d_addr = (void *)((size_t)d_addr + _CPU_DATA_CACHE_ALIGNMENT);
}
}
/*
* This function is responsible for performing a data cache invalidate.
* It must determine how many cache lines need to be invalidated and then
* perform the invalidations.
*/
void
rtems_invalidate_multiple_data_cache_lines( const void * d_addr, size_t n_bytes )
{
const void * final_address;
/*
* Set d_addr to the beginning of the cache line; final_address indicates
* the last address_t which needs to be invalidated. Increment d_addr and
* invalidate the resulting line until final_address is passed.
*/
final_address = (void *)((size_t)d_addr + n_bytes - 1);
d_addr = (void *)((size_t)d_addr & ~(_CPU_DATA_CACHE_ALIGNMENT - 1));
while( final_address > d_addr ) {
_CPU_invalidate_1_data_cache_line( d_addr );
d_addr = (void *)((size_t)d_addr + _CPU_DATA_CACHE_ALIGNMENT);
}
}
/*
* This function is responsible for performing a data cache flush.
* It flushes the entire cache.
*/
void
rtems_flush_entire_data_cache( void )
{
/*
* Call the CPU-specific routine
*/
_CPU_flush_entire_data_cache();
}
/*
* This function is responsible for performing a data cache
* invalidate. It invalidates the entire cache.
*/
void
rtems_invalidate_entire_data_cache( void )
{
/*
* Call the CPU-specific routine
*/
_CPU_invalidate_entire_data_cache();
}
/*
* This function returns the data cache granularity.
*/
int
rtems_get_data_cache_line_size( void )
{
return _CPU_DATA_CACHE_ALIGNMENT;
}
/*
* This function freezes the data cache; cache lines
* are not replaced.
*/
void
rtems_freeze_data_cache( void )
{
_CPU_freeze_data_cache();
}
/*
* This function unfreezes the instruction cache.
*/
void rtems_unfreeze_data_cache( void )
{
_CPU_unfreeze_data_cache();
}
/* Turn on the data cache. */
void
rtems_enable_data_cache( void )
{
_CPU_enable_data_cache();
}
/* Turn off the data cache. */
void
rtems_disable_data_cache( void )
{
_CPU_disable_data_cache();
}
#endif
/*
* THESE FUNCTIONS ONLY EXIST IF WE HAVE AN INSTRUCTION CACHE
*/
#if defined(_CPU_INST_CACHE_ALIGNMENT)
/*
* This function is responsible for performing an instruction cache
* invalidate. It must determine how many cache lines need to be invalidated
* and then perform the invalidations.
*/
void
rtems_invalidate_multiple_inst_cache_lines( const void * i_addr, size_t n_bytes )
{
const void * final_address;
/*
* Set i_addr to the beginning of the cache line; final_address indicates
* the last address_t which needs to be invalidated. Increment i_addr and
* invalidate the resulting line until final_address is passed.
*/
final_address = (void *)((size_t)i_addr + n_bytes - 1);
i_addr = (void *)((size_t)i_addr & ~(_CPU_INST_CACHE_ALIGNMENT - 1));
while( final_address > i_addr ) {
_CPU_invalidate_1_inst_cache_line( i_addr );
i_addr = (void *)((size_t)i_addr + _CPU_INST_CACHE_ALIGNMENT);
}
}
/*
* This function is responsible for performing an instruction cache
* invalidate. It invalidates the entire cache.
*/
void
rtems_invalidate_entire_inst_cache( void )
{
/*
* Call the CPU-specific routine
*/
_CPU_invalidate_entire_inst_cache();
}
/*
* This function returns the instruction cache granularity.
*/
int
rtems_get_inst_cache_line_size( void )
{
return _CPU_INST_CACHE_ALIGNMENT;
}
/*
* This function freezes the instruction cache; cache lines
* are not replaced.
*/
void
rtems_freeze_inst_cache( void )
{
_CPU_freeze_inst_cache();
}
/*
* This function unfreezes the instruction cache.
*/
void rtems_unfreeze_inst_cache( void )
{
_CPU_unfreeze_inst_cache();
}
/* Turn on the instruction cache. */
void
rtems_enable_inst_cache( void )
{
_CPU_enable_inst_cache();
}
/* Turn off the instruction cache. */
void
rtems_disable_inst_cache( void )
{
_CPU_disable_inst_cache();
}
#endif

View File

@@ -144,6 +144,142 @@ static inline unsigned int i386_swap_U16(
}
/*
* Added for pagination management
*/
static inline unsigned int i386_get_cr0()
{
register unsigned int segment = 0;
asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
return segment;
}
static inline void i386_set_cr0(unsigned int segment)
{
asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
}
static inline unsigned int i386_get_cr2()
{
register unsigned int segment = 0;
asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
return segment;
}
static inline unsigned int i386_get_cr3()
{
register unsigned int segment = 0;
asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
return segment;
}
static inline void i386_set_cr3(unsigned int segment)
{
asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
}
/*
* Disable the entire cache
*/
void _CPU_disable_cache() {
cr0 regCr0;
regCr0.i = i386_get_cr0();
regCr0.cr0.page_level_cache_disable = 1;
regCr0.cr0.no_write_through = 1;
i386_set_cr0( regCr0.i );
rtems_flush_entire_data_cache();
}
/*
* Enable the entire cache
*/
static inline void _CPU_enable_cache() {
cr0 regCr0;
regCr0.i = i386_get_cr0();
regCr0.cr0.page_level_cache_disable = 0;
regCr0.cr0.no_write_through = 0;
i386_set_cr0( regCr0.i );
/*rtems_flush_entire_data_cache();*/
}
/*
* CACHE MANAGER: The following functions are CPU-specific.
* They provide the basic implementation for the rtems_* cache
* management routines. If a given function has no meaning for the CPU,
* it does nothing by default.
*
* FIXME: Definitions for I386_CACHE_ALIGNMENT are missing above for
* each CPU. The routines below should be implemented per CPU,
* to accomodate the capabilities of each.
*/
/* FIXME: I don't belong here. */
#define I386_CACHE_ALIGNMENT 16
#if defined(I386_CACHE_ALIGNMENT)
#define _CPU_DATA_CACHE_ALIGNMENT I386_CACHE_ALIGNMENT
#define _CPU_INST_CACHE_ALIGNEMNT I386_CACHE_ALIGNMENT
static inline void _CPU_flush_1_data_cache_line (const void * d_addr) {}
static inline void _CPU_invalidate_1_data_cache_line (const void * d_addr) {}
static inline void _CPU_freeze_data_cache (void) {}
static inline void _CPU_unfreeze_data_cache (void) {}
static inline void _CPU_invalidate_1_inst_cache_line const void * d_addr() {}
static inline void _CPU_freeze_inst_cache (void) {}
static inline void _CPU_unfreeze_inst_cache (void) {}
static inline void _CPU_flush_entire_data_cache (
const void * d_addr )
{
asm ("wbinvd");
}
static inline void _CPU_invalidate_entire_data_cache (
const void * d_addr )
{
asm ("invd");
}
static inline void _CPU_enable_data_cache (
void )
{
_CPU_enable_cache();
}
static inline void _CPU_disable_data_cache (
void )
{
_CPU_disable_cache();
}
static inline void _CPU_invalidate_entire_inst_cache (
const void * i_addr )
{
asm ("invd");
}
static inline void _CPU_enable_inst_cache (
void )
{
_CPU_enable_cache();
}
static inline void _CPU_disable_inst_cache (
void )
{
_CPU_disable_cache();
}
#endif
/* routines */
/*

View File

@@ -157,6 +157,7 @@ extern "C" {
# endif
#elif defined(__mc68302__)
#define CPU_MODEL_NAME "m68302"
#define M68K_HAS_VBR 0
#define M68K_HAS_SEPARATE_STACKS 0
@@ -350,22 +351,244 @@ static inline unsigned int m68k_swap_u16(
return( swapped );
}
/* XXX this is only valid for some m68k family members and should be fixed */
#define m68k_enable_caching() \
{ register unsigned32 _ctl=0x01; \
asm volatile ( "movec %0,%%cacr" \
: "=d" (_ctl) : "0" (_ctl) ); \
}
#define CPU_swap_u32( value ) m68k_swap_u32( value )
#define CPU_swap_u16( value ) m68k_swap_u16( value )
/*
* _CPU_virtual_to_physical
*
* DESCRIPTION:
*
* This function is used to map virtual addresses to physical
* addresses.
*
* FIXME: ASSUMES THAT VIRTUAL ADDRESSES ARE THE SAME AS THE
* PHYSICAL ADDRESSES
*/
static inline void * _CPU_virtual_to_physical (
const void * d_addr )
{
return (void *) d_addr;
}
/*
* Since the cacr is common to all mc680x0, provide macros
* for masking values in that register.
*/
/*
* Used to clear bits in the cacr.
*/
#define _CPU_CACR_AND(mask) \
{ \
register unsigned long _value = mask; \
register unsigned long _ctl = 0; \
asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
andl %2, %0; /* and with _val */ \
movec %1, %%cacr" /* write the cacr */ \
: "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
}
/*
* Used to set bits in the cacr.
*/
#define _CPU_CACR_OR(mask) \
{ \
register unsigned long _value = mask; \
register unsigned long _ctl = 0; \
asm volatile ( "movec %%cacr, %0; /* read the cacr */ \
orl %2, %0; /* or with _val */ \
movec %1, %%cacr" /* write the cacr */ \
: "=d" (_ctl) : "0" (_ctl), "d" (_value) : "%%cc" ); \
}
/*
* CACHE MANAGER: The following functions are CPU-specific.
* They provide the basic implementation for the rtems_* cache
* management routines. If a given function has no meaning for the CPU,
* it does nothing by default.
*/
#if ( defined(__mc68020__) || defined(__mc68030__) )
#define M68K_INST_CACHE_ALIGNMENT 16
#if defined(__mc68030__)
#define M68K_DATA_CACHE_ALIGNMENT 16
/* Only the mc68030 has a data cache; it is writethrough only. */
static inline void _CPU_flush_1_data_cache_line ( const void * d_addr ) {}
static inline void _CPU_flush_entire_data_cache ( const void * d_addr ) {}
static inline void _CPU_invalidate_1_data_cache_line (
const void * d_addr )
{
void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
_CPU_CACR_OR(0x00000400);
}
static inline void _CPU_invalidate_entire_data_cache (
void )
{
_CPU_CACR_OR( 0x00000800 );
}
static inline void _CPU_freeze_data_cache (
void )
{
_CPU_CACR_OR( 0x00000200 );
}
static inline void _CPU_unfreeze_data_cache (
void )
{
_CPU_CACR_AND( 0xFFFFFDFF );
}
static inline void _CPU_enable_data_cache ( void )
{
_CPU_CACR_OR( 0x00000100 );
}
static inline void _CPU_disable_data_cache ( void )
{
_CPU_CACR_AND( 0xFFFFFEFF );
}
#endif
/* Both the 68020 and 68030 have instruction caches */
static inline void _CPU_invalidate_1_inst_cache_line (
const void * d_addr )
{
void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
asm volatile ( "movec %0, %%caar" :: "a" (p_address) ); /* write caar */
_CPU_CACR_OR( 0x00000004 );
}
static inline void _CPU_invalidate_entire_inst_cache (
void )
{
_CPU_CACR_OR( 0x00000008 );
}
static inline void _CPU_freeze_inst_cache (
void )
{
_CPU_CACR_OR( 0x00000002);
}
static inline void _CPU_unfreeze_inst_cache (
void )
{
_CPU_CACR_AND( 0xFFFFFFFD );
}
static inline void _CPU_enable_inst_cache ( void )
{
_CPU_CACR_OR( 0x00000001 );
}
static inline void _CPU_disable_inst_cache ( void )
{
_CPU_CACR_AND( 0xFFFFFFFE );
}
#elif ( defined(__mc68040__) || defined (__mc68060__) )
#define M68K_INST_CACHE_ALIGNMENT 16
#define M68K_DATA_CACHE_ALIGNMENT 16
/* Cannot be frozen */
static inline void _CPU_freeze_data_cache ( void ) {}
static inline void _CPU_unfreeze_data_cache ( void ) {}
static inline void _CPU_freeze_inst_cache ( void ) {}
static inline void _CPU_unfreeze_inst_cache ( void ) {}
static inline void _CPU_flush_1_data_cache_line (
const void * d_addr )
{
void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
asm volatile ( "cpushl %%dc,(%0)" :: "a" (p_address) );
}
static inline void _CPU_invalidate_1_data_cache_line (
const void * d_addr )
{
void * p_address = (void *) _CPU_virtual_to_physical( d_addr );
asm volatile ( "cinvl %%dc,(%0)" :: "a" (p_address) );
}
static inline void _CPU_flush_entire_data_cache (
void )
{
asm volatile ( "cpusha %%dc" :: );
}
static inline void _CPU_invalidate_entire_data_cache (
void )
{
asm volatile ( "cinva %%dc" :: );
}
static inline void _CPU_enable_data_cache (
void )
{
_CPU_CACR_OR( 0x80000000 );
}
static inline void _CPU_disable_data_cache (
void )
{
_CPU_CACR_AND( 0x7FFFFFFF );
}
static inline void _CPU_invalidate_1_inst_cache_line (
const void * i_addr )
{
void * p_address = (void *) _CPU_virtual_to_physical( i_addr );
asm volatile ( "cinvl %%ic,(%0)" :: "a" (p_address) );
}
static inline void _CPU_invalidate_entire_inst_cache (
void )
{
asm volatile ( "cinva %%ic" :: );
}
static inline void _CPU_enable_inst_cache (
void )
{
_CPU_CACR_OR( 0x00008000 );
}
static inline void _CPU_disable_inst_cache (
void )
{
_CPU_CACR_AND( 0xFFFF7FFF );
}
#endif
#if defined(M68K_DATA_CACHE_ALIGNMENT)
#define _CPU_DATA_CACHE_ALIGNMENT M68K_DATA_CACHE_ALIGNMENT
#endif
#if defined(M68K_INST_CACHE_ALIGNMENT)
#define _CPU_INST_CACHE_ALIGNMENT M68K_INST_CACHE_ALIGNMENT
#endif
#endif /* !ASM */
#ifdef __cplusplus
}
#endif
#endif
#endif /* __M68K_h */
/* end of include file */

View File

@@ -164,14 +164,20 @@
*/
#define srr0 0x01a
#define srr1 0x01b
#ifdef ppc403
#define srr2 0x3de /* IBM 400 series only */
#define srr3 0x3df /* IBM 400 series only */
#endif /* ppc403 */
#define sprg0 0x110
#define sprg1 0x111
#define sprg2 0x112
#define sprg3 0x113
#define dar 0x013 /* Data Address Register */
#define dec 0x016 /* Decrementer Register */
#if defined(ppc403)
/* the following SPR/DCR registers exist only in IBM 400 series */
#define dear 0x3d5
#define evpr 0x3d6 /* SPR: exception vector prefix register */
@@ -190,9 +196,13 @@
#define br7 0x087 /* DCR: memory bank register 7 */
/* end of IBM400 series register definitions */
#elif defined(mpc860) || defined(mpc821)
/* The following registers are for the MPC8x0 */
#define der 0x095 /* Debug Enable Register */
#define ictrl 0x09E /* Instruction Support Control Register */
#define immr 0x27E /* Internal Memory Map Register */
/* end of MPC8x0 registers */
#endif
/*
* Following must be tailor for a particular flavor of the C compiler.

View File

@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
# C source names
C_FILES = cpu.c ppccache.c
C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
ROOT_H_FILES =

View File

@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
int _CPU_spurious_count = 0;
int _CPU_last_spurious = 0;
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
++_CPU_spurious_count;
_CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
case PPC_IRQ_CPM_RESERVED_0:
case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:

View File

@@ -766,6 +766,15 @@ SCORE_EXTERN struct {
); \
} while (0)
#define _CPU_Data_Cache_Block_Invalidate( _address ) \
do { register void *__address = (_address); \
register unsigned32 _zero = 0; \
asm volatile ( "dcbi %0,%1" : \
"=r" (_zero), "=r" (__address) : \
"0" (_zero), "1" (__address) \
); \
} while (0)
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).

View File

@@ -44,6 +44,8 @@
extern "C" {
#endif
#include <rtems/score/ppctypes.h>
/*
* Define the name of the CPU family.
*/
@@ -220,6 +222,7 @@ extern "C" {
#elif defined(mpc860)
/*
* Added by Jay Monkman (jmonkman@frasca.com) 6/28/98
* with some changes by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
*/
#define CPU_MODEL_NAME "PowerPC MPC860"
@@ -231,7 +234,6 @@ extern "C" {
#define PPC_HAS_FPU 0
#define PPC_HAS_DOUBLE 0
#define PPC_USE_MULTIPLE 1
#define PPC_USE_SPRG 1
#define PPC_MSR_0 0x00009000
#define PPC_MSR_1 0x00001000
@@ -382,6 +384,157 @@ extern "C" {
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
#endif
#ifndef ASM
/*
* CACHE MANAGER: The following functions are CPU-specific.
* They provide the basic implementation for the rtems_* cache
* management routines. If a given function has no meaning for the CPU,
* it does nothing by default.
*
* FIXME: Some functions simply have not been implemented.
*/
#if defined(ppc603) /* And possibly others */
#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
/* Helpful macros */
#define PPC_Get_HID0( _value ) \
do { \
_value = 0; /* to avoid warnings */ \
asm volatile( \
"mfspr %0, 0x3f0;" /* get HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
#define PPC_Set_HID0( _value ) \
do { \
asm volatile( \
"isync;" \
"mtspr 0x3f0, %0;" /* load HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
static inline void _CPU_enable_data_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value |= 0x00004000; /* set DCE bit */
PPC_Set_HID0( value );
}
static inline void _CPU_disable_data_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value &= 0xFFFFBFFF; /* clear DCE bit */
PPC_Set_HID0( value );
}
static inline void _CPU_enable_inst_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value |= 0x00008000; /* Set ICE bit */
PPC_Set_HID0( value );
}
static inline void _CPU_disable_inst_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value &= 0xFFFF7FFF; /* Clear ICE bit */
PPC_Set_HID0( value );
}
#elif ( defined(mpc860) || defined(mpc821) )
#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define mtspr(_spr,_reg) __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
#define isync __asm__ volatile ("isync\n"::)
static inline void _CPU_flush_1_data_cache_line(
const void * _address )
{
register const void *__address = _address;
asm volatile ( "dcbf 0,%0" :: "r" (__address) );
}
static inline void _CPU_invalidate_1_data_cache_line(
const void * _address )
{
register const void *__address = _address;
asm volatile ( "dcbi 0,%0" :: "r" (__address) );
}
static inline void _CPU_flush_entire_data_cache ( void ) {}
static inline void _CPU_invalidate_entire_data_cache ( void ) {}
static inline void _CPU_freeze_data_cache ( void ) {}
static inline void _CPU_unfreeze_data_cache ( void ) {}
static inline void _CPU_enable_data_cache (
void )
{
unsigned32 r1;
r1 = (0x2<<24);
mtspr( 568, r1 );
isync;
}
static inline void _CPU_disable_data_cache (
void )
{
unsigned32 r1;
r1 = (0x4<<24);
mtspr( 568, r1 );
isync;
}
static inline void _CPU_invalidate_1_inst_cache_line(
const void * _address )
{
register const void *__address = _address;
asm volatile ( "icbi 0,%0" :: "r" (__address) );
}
static inline void _CPU_invalidate_entire_inst_cache ( void ) {}
static inline void _CPU_freeze_inst_cache ( void ) {}
static inline void _CPU_unfreeze_inst_cache ( void ) {}
static inline void _CPU_enable_inst_cache (
void )
{
unsigned32 r1;
r1 = (0x2<<24);
mtspr( 560, r1 );
isync;
}
static inline void _CPU_disable_inst_cache (
void )
{
unsigned32 r1;
r1 = (0x4<<24);
mtspr( 560, r1 );
isync;
}
#endif
#endif /* !ASM */
/*
* Unless otherwise specified, assume the model has an IP/EP bit to
* set the exception address prefix.
@@ -550,7 +703,7 @@ extern "C" {
#define PPC_IRQ_LVL6 (PPC_STD_IRQ_LAST + 23)
#define PPC_IRQ_IRQ7 (PPC_STD_IRQ_LAST + 24)
#define PPC_IRQ_LVL7 (PPC_STD_IRQ_LAST + 25)
#define PPC_IRQ_CPM_RESERVED_0 (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_ERROR (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 27)
#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 28)
#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 29)

View File

@@ -164,14 +164,20 @@
*/
#define srr0 0x01a
#define srr1 0x01b
#ifdef ppc403
#define srr2 0x3de /* IBM 400 series only */
#define srr3 0x3df /* IBM 400 series only */
#endif /* ppc403 */
#define sprg0 0x110
#define sprg1 0x111
#define sprg2 0x112
#define sprg3 0x113
#define dar 0x013 /* Data Address Register */
#define dec 0x016 /* Decrementer Register */
#if defined(ppc403)
/* the following SPR/DCR registers exist only in IBM 400 series */
#define dear 0x3d5
#define evpr 0x3d6 /* SPR: exception vector prefix register */
@@ -190,9 +196,13 @@
#define br7 0x087 /* DCR: memory bank register 7 */
/* end of IBM400 series register definitions */
#elif defined(mpc860) || defined(mpc821)
/* The following registers are for the MPC8x0 */
#define der 0x095 /* Debug Enable Register */
#define ictrl 0x09E /* Instruction Support Control Register */
#define immr 0x27E /* Internal Memory Map Register */
/* end of MPC8x0 registers */
#endif
/*
* Following must be tailor for a particular flavor of the C compiler.

View File

@@ -44,6 +44,8 @@
extern "C" {
#endif
#include <rtems/score/ppctypes.h>
/*
* Define the name of the CPU family.
*/
@@ -220,6 +222,7 @@ extern "C" {
#elif defined(mpc860)
/*
* Added by Jay Monkman (jmonkman@frasca.com) 6/28/98
* with some changes by Darlene Stewart (Darlene.Stewart@iit.nrc.ca)
*/
#define CPU_MODEL_NAME "PowerPC MPC860"
@@ -231,7 +234,6 @@ extern "C" {
#define PPC_HAS_FPU 0
#define PPC_HAS_DOUBLE 0
#define PPC_USE_MULTIPLE 1
#define PPC_USE_SPRG 1
#define PPC_MSR_0 0x00009000
#define PPC_MSR_1 0x00001000
@@ -382,6 +384,157 @@ extern "C" {
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
#endif
#ifndef ASM
/*
* CACHE MANAGER: The following functions are CPU-specific.
* They provide the basic implementation for the rtems_* cache
* management routines. If a given function has no meaning for the CPU,
* it does nothing by default.
*
* FIXME: Some functions simply have not been implemented.
*/
#if defined(ppc603) /* And possibly others */
#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
/* Helpful macros */
#define PPC_Get_HID0( _value ) \
do { \
_value = 0; /* to avoid warnings */ \
asm volatile( \
"mfspr %0, 0x3f0;" /* get HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
#define PPC_Set_HID0( _value ) \
do { \
asm volatile( \
"isync;" \
"mtspr 0x3f0, %0;" /* load HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
static inline void _CPU_enable_data_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value |= 0x00004000; /* set DCE bit */
PPC_Set_HID0( value );
}
static inline void _CPU_disable_data_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value &= 0xFFFFBFFF; /* clear DCE bit */
PPC_Set_HID0( value );
}
static inline void _CPU_enable_inst_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value |= 0x00008000; /* Set ICE bit */
PPC_Set_HID0( value );
}
static inline void _CPU_disable_inst_cache (
void )
{
unsigned32 value;
PPC_Get_HID0( value );
value &= 0xFFFF7FFF; /* Clear ICE bit */
PPC_Set_HID0( value );
}
#elif ( defined(mpc860) || defined(mpc821) )
#define _CPU_DATA_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define _CPU_INST_CACHE_ALIGNMENT PPC_CACHE_ALIGNMENT
#define mtspr(_spr,_reg) __asm__ volatile ( "mtspr %0, %1\n" : : "i" ((_spr)), "r" ((_reg)) )
#define isync __asm__ volatile ("isync\n"::)
static inline void _CPU_flush_1_data_cache_line(
const void * _address )
{
register const void *__address = _address;
asm volatile ( "dcbf 0,%0" :: "r" (__address) );
}
static inline void _CPU_invalidate_1_data_cache_line(
const void * _address )
{
register const void *__address = _address;
asm volatile ( "dcbi 0,%0" :: "r" (__address) );
}
static inline void _CPU_flush_entire_data_cache ( void ) {}
static inline void _CPU_invalidate_entire_data_cache ( void ) {}
static inline void _CPU_freeze_data_cache ( void ) {}
static inline void _CPU_unfreeze_data_cache ( void ) {}
static inline void _CPU_enable_data_cache (
void )
{
unsigned32 r1;
r1 = (0x2<<24);
mtspr( 568, r1 );
isync;
}
static inline void _CPU_disable_data_cache (
void )
{
unsigned32 r1;
r1 = (0x4<<24);
mtspr( 568, r1 );
isync;
}
static inline void _CPU_invalidate_1_inst_cache_line(
const void * _address )
{
register const void *__address = _address;
asm volatile ( "icbi 0,%0" :: "r" (__address) );
}
static inline void _CPU_invalidate_entire_inst_cache ( void ) {}
static inline void _CPU_freeze_inst_cache ( void ) {}
static inline void _CPU_unfreeze_inst_cache ( void ) {}
static inline void _CPU_enable_inst_cache (
void )
{
unsigned32 r1;
r1 = (0x2<<24);
mtspr( 560, r1 );
isync;
}
static inline void _CPU_disable_inst_cache (
void )
{
unsigned32 r1;
r1 = (0x4<<24);
mtspr( 560, r1 );
isync;
}
#endif
#endif /* !ASM */
/*
* Unless otherwise specified, assume the model has an IP/EP bit to
* set the exception address prefix.
@@ -550,7 +703,7 @@ extern "C" {
#define PPC_IRQ_LVL6 (PPC_STD_IRQ_LAST + 23)
#define PPC_IRQ_IRQ7 (PPC_STD_IRQ_LAST + 24)
#define PPC_IRQ_LVL7 (PPC_STD_IRQ_LAST + 25)
#define PPC_IRQ_CPM_RESERVED_0 (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_ERROR (PPC_STD_IRQ_LAST + 26)
#define PPC_IRQ_CPM_PC4 (PPC_STD_IRQ_LAST + 27)
#define PPC_IRQ_CPM_PC5 (PPC_STD_IRQ_LAST + 28)
#define PPC_IRQ_CPM_SMC2 (PPC_STD_IRQ_LAST + 29)

View File

@@ -443,6 +443,21 @@ Objects_Control *_Objects_Get (
Objects_Locations *location
);
/*
* _Objects_Get_by_index
*
* DESCRIPTION:
*
* This routine sets the object pointer for the given
* object id based on the given object information structure.
*/
Objects_Control *_Objects_Get_by_index(
Objects_Information *information,
unsigned32 index,
Objects_Locations *location
);
/*
* _Objects_Get_next
*
@@ -459,6 +474,25 @@ Objects_Control *_Objects_Get_next(
Objects_Id *next_id_p
);
/*
* _Objects_Local_iterate
*
* DESCRIPTION:
*
* This function invokes the callback function for each existing object
* of the type specified by the information block pointer. Iteration
* continues until either all objects have been processed, or, if
* break_on_error is TRUE, until an invocation of the callback returns
* something other than 0.
*/
unsigned32 _Objects_Local_iterate(
Objects_Information *information,
unsigned32 (*callback)(Objects_Control *object, void * arg),
void * arg,
boolean break_on_error
);
/*
* Pieces of object.inl are promoted out to the user
*/

View File

@@ -733,6 +733,23 @@ Thread_Control *_Thread_Get (
);
#endif
/*
* _Thread_Local_iterate
*
* DESCRIPTION:
*
* This function invokes the callback function for each existing thread.
* Iteration continues until either all threads have been processed, or,
* if break_on_error is TRUE, until an invocation of the callback returns
* an integer value other than 0.
*/
unsigned32 _Thread_Local_iterate(
unsigned32 (*callback)(Thread_Control *the_thread, void * arg),
void * arg,
boolean break_on_error
);
/*
* _Thread_Idle_body
*

View File

@@ -27,17 +27,18 @@ OBJECT_C_FILES = object.c objectallocate.c objectallocatebyindex.c \
objectclearname.c objectcomparenameraw.c objectcomparenamestring.c \
objectcopynameraw.c objectcopynamestring.c objectextendinformation.c \
objectfree.c objectget.c objectgetbyindex.c objectgetnext.c \
objectinitializeinformation.c objectnametoid.c objectshrinkinformation.c
objectinitializeinformation.c objectlocaliterate.c objectnametoid.c \
objectshrinkinformation.c
THREAD_C_FILES = thread.c threadchangepriority.c threadclearstate.c \
threadclose.c threadcreateidle.c threaddelayended.c threaddispatch.c \
threadevaluatemode.c threadget.c threadhandler.c threadidlebody.c \
threadinitialize.c threadloadenv.c threadready.c threadresettimeslice.c \
threadreset.c threadrestart.c threadresume.c threadrotatequeue.c \
threadsetpriority.c threadsetstate.c threadsettransient.c \
threadstackallocate.c threadstackfree.c threadstart.c \
threadstartmultitasking.c threadsuspend.c threadtickletimeslice.c \
threadyieldprocessor.c
threadinitialize.c threadloadenv.c threadlocaliterate.c threadready.c \
threadresettimeslice.c threadreset.c threadrestart.c threadresume.c \
threadrotatequeue.c threadsetpriority.c threadsetstate.c \
threadsettransient.c threadstackallocate.c threadstackfree.c \
threadstart.c threadstartmultitasking.c threadsuspend.c \
threadtickletimeslice.c threadyieldprocessor.c
THREADQ_C_FILES = threadq.c threadqdequeue.c threadqdequeuefifo.c \
threadqdequeuepriority.c threadqenqueue.c threadqenqueuefifo.c \
@@ -53,8 +54,8 @@ WATCHDOG_C_FILES = watchdog.c watchdogadjust.c watchdoginsert.c \
watchdogremove.c watchdogtickle.c
STD_C_FILES = apiext.c chain.c $(CORE_MESSAGE_QUEUE_C_FILES) \
$(CORE_MUTEX_C_FILES) $(CORE_SEMAPHORE_C_FILES) $(HEAP_C_FILES) interr.c \
isr.c $(OBJECT_C_FILES) $(THREAD_C_FILES) $(THREADQ_C_FILES) \
$(CORE_MUTEX_C_FILES) $(CORE_SEMAPHORE_C_FILES) $(HEAP_C_FILES) \
interr.c isr.c $(OBJECT_C_FILES) $(THREAD_C_FILES) $(THREADQ_C_FILES) \
$(TOD_C_FILES) userext.c $(WATCHDOG_C_FILES) wkspace.c
if HAS_MP

View File

@@ -0,0 +1,77 @@
/*
* object iterator
*
*
* COPYRIGHT (c) 2000.
* On-Line Applications Research Corporation (OAR).
*
* 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 <rtems/system.h>
#include <rtems/score/object.h>
/*PAGE
*
* _Objects_Local_iterate
*
* DESCRIPTION:
*
* This function invokes the callback function for each existing object
* of the type specified by the information block pointer. Iteration
* continues until either all objects have been processed, or, if
* break_on_error is TRUE, until an invocation of the callback returns
* something other than 0.
*
* Input parameters:
* information:
* A pointer to an Objects_Information block. Determines the type of
* object over which to iterate.
* callback:
* A pointer to a function with the indicated signature.
* arg:
* A pointer to some arbitrary entity. Passed on to the callback.
* break_on_error
* If TRUE, stop iterating on error.
*
* Output parameters: NONE
* But callback may write into space pointed to by arg.
*
* Return value:
* 0 if successful
* Value returned by the callback otherwise.
*/
unsigned32 _Objects_Local_iterate(
Objects_Information *information,
unsigned32 (*callback)(Objects_Control *object, void * arg),
void *arg,
boolean break_on_error
)
{
unsigned32 result;
unsigned32 i;
Objects_Control *the_object;
if ( !information )
return 0;
if ( !callback )
return 0;
for( i = 1; i <= information->maximum; i++ ) {
the_object = (Objects_Control *)information->local_table[i];
if( the_object ) {
result = (*callback)( the_object, arg );
if ( result && break_on_error )
return result;
}
}
return 0;
}

View File

@@ -0,0 +1,77 @@
/*
* Thread Iterator
*
*
* COPYRIGHT (c) 2000.
* On-Line Applications Research Corporation (OAR).
*
* 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 <rtems/system.h>
#include <rtems/score/object.h>
#include <rtems/score/thread.h>
/*PAGE
*
* _Thread_Local_iterate
*
* DESCRIPTION:
*
* This function invokes the callback function for each existing thread.
* Iteration continues until either all threads have been processed, or,
* if break_on_error is TRUE, until an invocation of the callback returns
* an integer value other than 0.
*
* Input parameters:
* callback:
* A pointer to a function with the indicated signature.
* arg:
* A pointer to some arbitrary entity. Passed on to the callback.
* break_on_error
* If TRUE, stop iterating on error.
*
*
* Output parameters: NONE
* But callback may write into space pointed to by arg.
*
* Return value:
* 0 if successful
* Value returned by the callback otherwise.
*/
unsigned32 _Thread_Local_iterate(
unsigned32 (*callback)(Thread_Control *the_thread, void * arg),
void *arg,
boolean break_on_error
)
{
unsigned32 class_index;
unsigned32 result;
Objects_Information *information;
if( callback == NULL )
return 0;
for ( class_index = OBJECTS_CLASSES_FIRST ;
class_index <= OBJECTS_CLASSES_LAST ;
class_index++ ) {
information = _Objects_Information_table[ class_index ];
if ( information && information->is_thread ) {
result = _Objects_Local_iterate(
information,
(unsigned32 (*)(Objects_Control *, void *))callback,
arg,
break_on_error );
if( result && break_on_error )
return result;
}
}
return 0;
}

View File

@@ -181,6 +181,7 @@ int tcflow(int, int);
int tcflush(int, int);
int tcgetattr(int, struct termios *);
int tcsetattr(int, int, struct termios *);
int tcdrain(int);
pid_t tcgetprgrp(int);
int tcsetprgrp(int, pid_t);
int tcsendbreak(int, int);

View File

@@ -32,6 +32,9 @@ rtems_cpu_table Cpu_table;
char *rtems_progname;
/* Amount of RAM on this board. Dynamically set in start.S */
unsigned long _M68K_RamSize;
/*
* Use the shared implementations of the following routines
*/

View File

@@ -8,11 +8,12 @@ Please send any comments, improvements, or bug reports to:
Charles-Antoine Gauthier
charles.gauthier@nrc.ca
or
Darlene Stewart
Darlene.Stewart@nrc.ca
Software Engineering Group
Institute for Information Technology
National Research Council of Canada
@@ -20,19 +21,6 @@ Ottawa, ON, K1A 0R6
Canada
WARNING:
--------
The network driver is currently being worked on. It is somewhat functional,
but it does run out of buffers under certain conditions. The code is
also undergoing a substantial reorganization. Before making any changes,
you should check with us for the availability of updates.
Note from Joel: The ttcp performance reported is very nice even if the
driver is still early in its life. :)
Disclaimer
----------
@@ -67,7 +55,6 @@ this file if you want S-records.
Port Description
Console driver
---------------
This BSP includes an termios-capable console driver that supports all
@@ -147,8 +134,62 @@ mvme167.cfg that redefine which variants of libc, libm and libgcc to link
against.
Configuration Parameters
If Jumper J1-4 is installed, certain configuration parameters may be read from
the first 31 bytes of User Area NVRAM starting at 0xFFFC0000. In this case, the
user is responsible for writing the appropriate values to this memory location
(via 167Bug) in order to alter the default behaviour. A zero value results in
the default behaviour. The paramaters that are configurable and their default
settings are described below.
Data Cache Enable (0xFFFC0000 - 1 byte)
write a non-zero value to this location to enable the data cache
default: disabled
Instruction Cache Activation (0xFFFC0001 - 1 byte)
write a non-zero value to this location to enable the instruction cache
default: disabled
Cache Mode (0xFFFC0002 - 2 bytes)
0xFFF0 = cachable, write-through
0xFFF1 = cachable, copyback
0xFFF2 = noncachable, serialized
0xFFF3 = noncachable,
default: cachable, copyback
IP Address (0xFFFC0004 - 4 bytes)
write the hexidecimal representation of the board's IP address in this
location for example, 192.168.1.2 = 0xC0A80102
default: obtain the IP address from an rtems_bsdnet_ifconfig structure
Netmask (0xFFFC0008 - 4 bytes)
write the hexidecimal representation of the netmask in this location
for example, 255.255.255.0 = 0xFFFFFF00
default: obtain the netmask from an rtems_bsdnet_ifconfig structure
Ethernet Address (0xFFFC000C - 6 bytes)
write the board's hardware address in this location
default: obtain the hardware address from an rtems_bsdnet_ifconfig structure
Processor ID (0xFFFC0012 - 2 bytes)
reserved for future use
RMA start (0xFFFC0014 - 4 bytes)
reserved for future use
VMA start (0xFFFC0018 - 4 bytes)
reserved for future use
RamSize (0xFFFC001C - 4 bytes)
reserved for future use
Cache Control and Memory Mapping
If configuration is not obtained from non-volatile RAM (ie. J1-4 is off),
cache control is done through the remaining J1 jumpers as follows:
If Jumper J1-7 is installed, the data cache will be turned on. If Jumper
J1-6 is installed, the instruction cache will be turned on. Removing the
jumper causes the corresponding cache to be left disabled.
@@ -500,4 +541,3 @@ Timing tests:
rtems_rate_monotonic_period: conclude periods -- caller blocks 25
rtems_rate_monotonic_period: obtain status 13

View File

@@ -10,7 +10,7 @@
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group \
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
%{qjava: -lffi -lzgcj -lgcj} %{qc++: -lstdc++} -lc -lgcc --end-group \
%{qjava: -lffi -lgcjgc -lzgcj -lgcj} %{qc++: -lstdc++} -lc -lgcc --end-group \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:

View File

@@ -422,9 +422,9 @@ void BSP_output_string( char * buf );
* Representation of 82596CA LAN controller: Memory Map
*/
typedef volatile struct i82596_regs_ {
unsigned short port_lower; /* 0xFFF46000 */
unsigned short port_upper; /* 0xFFF46002 */
unsigned long chan_attn; /* 0xFFF46004 */
unsigned short port_lower; /* 0xFFF46000 */
unsigned short port_upper; /* 0xFFF46002 */
unsigned long chan_attn; /* 0xFFF46004 */
} i82596_regs;
/*
@@ -432,6 +432,26 @@ typedef volatile struct i82596_regs_ {
*/
#define i82596 ((i82596_regs * const) 0xFFF46000)
/*
* Representation of initialization data in NVRAM
*/
typedef volatile struct nvram_config_ {
unsigned char dcache_enable; /* 0xFFFC0000 */
unsigned char icache_enable; /* 0xFFFC0001 */
unsigned short cache_mode; /* 0xFFFC0002 */
unsigned long ipaddr; /* 0xFFFC0004 */
unsigned long netmask; /* 0xFFFC0008 */
unsigned char enaddr[6]; /* 0xFFFC000C */
unsigned short processor_id; /* 0xFFFC0012 */
unsigned long rma_start; /* 0xFFFC0014 */
unsigned long vma_start; /* 0xFFFC0018 */
unsigned long ramsize; /* 0xFFFC001C */
} nvram_config;
/*
* Pointer to the base of User Area NVRAM
*/
#define nvram ((nvram_config * const) 0xFFFC0000)
/* BSP-wide functions */

View File

@@ -40,6 +40,8 @@
#define UTI_596_ETH_MIN_SIZE 60
#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
/*
* RTEMS events
*/
@@ -57,9 +59,11 @@
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include "uti596.h"
@@ -79,10 +83,10 @@
#define UTI596_DUMP_PORT_FUNCTION 3
/* Types of waiting for commands */
#define UTI596_NO_WAIT 0
#define UTI596_WAIT_FOR_CU_ACCEPT 1
#define UTI596_WAIT_FOR_INITIALIZATION 2
#define UTI596_WAIT_FOR_STAT_C 3
#define UTI596_NO_WAIT 0
#define UTI596_WAIT_FOR_CU_ACCEPT 1
#define UTI596_WAIT_FOR_INITIALIZATION 2
#define UTI596_WAIT_FOR_STAT_C 3
/* Device dependent data structure */
static uti596_softc_ uti596_softc;
@@ -417,6 +421,7 @@ static int uti596_portDump(
* Input parameters:
* sc - pointer to the uti596_softc struct
* wait_type - UTI596_NO_WAIT
* UTI596_WAIT
* UTI596_WAIT_FOR_CU_ACCEPT
* UTI596_WAIT_FOR_INITIALIZATION
* UTI596_WAIT_FOR_STAT_C
@@ -432,16 +437,18 @@ static int uti596_wait(
)
{
rtems_interval ticks_per_second, start_ticks, end_ticks;
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
end_ticks = start_ticks + ticks_per_second;
switch( waitType ) {
case UTI596_NO_WAIT:
return 0;
case UTI596_WAIT_FOR_CU_ACCEPT:
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
end_ticks = start_ticks + ticks_per_second;
case UTI596_WAIT_FOR_CU_ACCEPT:
do {
if (sc->scb.command == 0)
break;
@@ -459,10 +466,6 @@ static int uti596_wait(
return 0;
case UTI596_WAIT_FOR_INITIALIZATION:
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
end_ticks = start_ticks + ticks_per_second;
do {
if( !sc->iscp.busy )
break;
@@ -484,10 +487,6 @@ static int uti596_wait(
}
case UTI596_WAIT_FOR_STAT_C:
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
end_ticks = start_ticks + ticks_per_second;
do {
if( *sc->pCurrent_command_status & STAT_C )
break;
@@ -1550,12 +1549,6 @@ void send_packet(
}
} while( m != NULL && ++bd_count < 16 );
/* This should never happen */
if ( bd_count == 16 ) {
printk(("TX ERROR:Too many mbufs in the packet!!!\n"))
printk(("Must coalesce!\n"))
}
if ( length < UTI_596_ETH_MIN_SIZE ) {
pTbd->data = (char *) word_swap ((unsigned long) sc->zeroes); /* add padding to pTbd */
pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */
@@ -1661,9 +1654,10 @@ int uti596_attach(
{
uti596_softc_ *sc = &uti596_softc; /* device dependent data structure */
struct ifnet * ifp = &sc->arpcom.ac_if; /* ifnet structure */
int unitNumber;
char *unitName;
int unitNumber;
char *unitName;
char *pAddr;
int addr;
#ifdef DBG_ATTACH
printk(("uti596_attach: begins\n"))
@@ -1689,17 +1683,46 @@ int uti596_attach(
else
ifp->if_mtu = ETHERMTU;
/* Ethernet address can be specified in the ifconfig structure or
* it can be read in from BBRAM at $FFFC1F2C (6 bytes)
* mvme167 manual p. 1-47
/*
* If an IP address and netmask are provided in NVRAM, cheat,
* and stuff them into the ifconfig structure, overriding any
* existing or NULL values.
*
* Warning: If values are provided in NVRAM, the ifconfig entries
* should be NULL because buffer memory allocated to hold the
* structure values is unrecoverable and would be lost here.
*/
if ( pConfig->hardware_address) {
if ( addr = nvram->ipaddr ) {
if ( pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT ) )
pConfig->ip_address = inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );
else
rtems_panic("Can't allocate ip_address buffer!\n");
}
if ( addr = nvram->netmask ) {
if ( pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT ) )
pConfig->ip_netmask = inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );
else
rtems_panic("Can't allocate ip_netmask buffer!\n");
}
/* Ethernet address can be specified in NVRAM, or in the ifconfig
* structure. It will be read by default from BBRAM at $FFFC1F2C
* (6 bytes) mvme167 manual p. 1-47
*/
if ( nvram->enaddr ) {
memcpy (sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);
}
else if ( pConfig->hardware_address) {
memcpy (sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
}
else {
memcpy (sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);
}
/* Possibly override default acceptance of broadcast packets */
if (pConfig->ignore_broadcast)
uti596initSetup[8] |= 0x02;
/* Assign requested receive buffer descriptor count */
if (pConfig->rbuf_count)
sc->rxBdCount = pConfig->rbuf_count;
@@ -1715,7 +1738,7 @@ int uti596_attach(
/* Set up fields in the ifnet structure*/
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
ifp->if_init = uti596_init;
ifp->if_init = uti596_init;
ifp->if_ioctl = uti596_ioctl;
ifp->if_start = uti596_start;
ifp->if_output = ether_output;

View File

@@ -17,12 +17,12 @@
*/
/* These are not really needed here */
/* OUTPUT_FORMAT("elf32-m68k") */
OUTPUT_FORMAT("elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
/*
* Declare some sizes. Heap is sized at whatever ram space is left.
* Declare some sizes. Heap is sized at whatever ram space is left.
*/
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x00800000;
_RamSize = DEFINED(_RamSize) ? _RamSize : 4M;

View File

@@ -32,11 +32,13 @@
* physical range 0x0 to 0x7FFFFFFF. We rely on the hardware to signal bus
* errors if we address non-existent memory within this range. Our two
* MVME167s are configured to exist at physical addresses 0x00800000 to
* 0x00BFFFFF and 0x00C00000 to 0x00FFFFFF respectively. We map the space
* from 0x0 to 0x7FFFFFFF as copyback, unless jumper J1-5 is removed, in
* which case we map as writethrough. If jumper J1-7 is removed, the data
* cache is NOT enabled. If jumper J1-6 is removed, the instruction cache
* is not enabled.
* 0x00BFFFFF and 0x00C00000 to 0x00FFFFFF respectively. If jumper J1-4 is
* installed, memeory and cache control can be done by providing parameters
* in NVRAM. See the README for details. If J1-4 is removed, behaviour
* defaults to the following. We map the space from 0x0 to 0x7FFFFFFF as
* copyback, unless jumper J1-5 is removed, in which case we map as writethrough.
* If jumper J1-7 is removed, the data cache is NOT enabled. If jumper J1-6
* is removed, the instruction cache is not enabled.
*
* Copyright (c) 1998, National Research Council of Canada
*
@@ -84,23 +86,39 @@ void page_table_init(
*/
dtt0 = 0x007FC020;
cacr = 0x80008000; /* Data and instruction cache on */
cacr = 0x00000000; /* Data and instruction cache off */
/* Read the J1 header */
j1 = (unsigned char)(lcsr->vector_base & 0xFF);
if ( !(j1 & 0x10) ) {
/* Jumper J1-4 is on, configure from NVRAM */
if ( nvram->dcache_enable )
cacr |= 0x80000000;
if ( nvram->icache_enable )
cacr |= 0x00008000;
if ( nvram->cache_mode )
dtt0 = ((nvram->cache_mode & 0x0003) << 5) | (dtt0 & 0xFFFFFF9F);
}
else {
/* Configure according to other jumper settings */
if ( j1 & 0x80 )
/* Jumper J1-7 if off, disable data caching */
cacr &= 0x7FFFFFFF;
if ( j1 & 0x80 )
/* Jumper J1-7 if off, disable data caching */
cacr &= 0x7FFFFFFF;
if ( j1 & 0x40 )
/* Jumper J1-6 if off, disable instruction caching */
cacr &= 0xFFFF7FFF;
if ( j1 & 0x40 )
/* Jumper J1-6 if off, disable instruction caching */
cacr &= 0xFFFF7FFF;
if ( j1 & 0x20 )
/* Jumper J1-5 is off, enable writethrough caching */
dtt0 &= 0xFFFFFF9F;
if ( j1 & 0x20 )
/* Jumper J1-5 is off, enable writethrough caching */
dtt0 &= 0xFFFFFF9F;
}
/* do it ! */
asm volatile("movec %0, %%tc /* turn off paged address translation */
movec %0, %%cacr /* disable both caches */

View File

@@ -16,7 +16,6 @@
*/
#include <stdio.h>
#include <bsp.h>
#include <mpc860.h>
#include <rtems/error.h>
#include <canbus.h>
/* How many CAN interfaces are there? */
@@ -309,9 +308,9 @@ rtems_device_driver canbus_open(
candev[minor]->ctrl |= I82527_CTRL_IE;
candev[minor]->ctrl &= ~(I82527_CTRL_CCE | I82527_CTRL_INIT);
switch (minor) {
case 0: m860.simask |= M860_SIMASK_IRM3; break;
case 1: m860.simask |= M860_SIMASK_IRM4; break;
case 2: m860.simask |= M860_SIMASK_IRM2; break;
case 0: m8xx.simask |= M8xx_SIMASK_IRM3; break;
case 1: m8xx.simask |= M8xx_SIMASK_IRM4; break;
case 2: m8xx.simask |= M8xx_SIMASK_IRM2; break;
default: return;
}

View File

@@ -27,9 +27,8 @@
* $Id$
*/
#include <bsp.h> /* Must be before libio.h */
#include <rtems/libio.h>
#include <mpc860.h>
#include <mpc860/console.h>
#include <termios.h>
rtems_device_driver console_initialize(rtems_device_major_number major,
@@ -37,8 +36,6 @@ rtems_device_driver console_initialize(rtems_device_major_number major,
void *arg)
{
rtems_status_code status;
rtems_isr_entry old_handler;
rtems_status_code sc;
#ifdef I_WANT_TERMIOS
/*
@@ -48,34 +45,23 @@ rtems_device_driver console_initialize(rtems_device_major_number major,
#endif
/*
* Set up Buffer Descriptors
* Do common initialization.
*/
m860_console_initialize();
m8xx_uart_initialize();
/*
* Do device-specific initialization
*/
m860_scc_initialize(2); /* /dev/console */
m860_scc_initialize(3); /* /dev/tty3 */
m860_scc_initialize(4); /* /dev/tty4 */
m860_smc_initialize(1); /* /dev/tty0 */
m860_smc_initialize(2); /* /dev/tty1 */
m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */
m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */
m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2 */
m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3 */
m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */
sc = rtems_interrupt_catch (m860_scc2_console_interrupt_handler,
PPC_IRQ_CPM_SCC2,
&old_handler);
sc = rtems_interrupt_catch (m860_scc3_console_interrupt_handler,
PPC_IRQ_CPM_SCC3,
&old_handler);
sc = rtems_interrupt_catch (m860_scc4_console_interrupt_handler,
PPC_IRQ_CPM_SCC4,
&old_handler);
sc = rtems_interrupt_catch (m860_smc1_console_interrupt_handler,
PPC_IRQ_CPM_SMC1,
&old_handler);
sc = rtems_interrupt_catch (m860_smc2_console_interrupt_handler,
PPC_IRQ_CPM_SMC2,
&old_handler);
/*
* Set up interrupts
*/
m8xx_uart_interrupts_initialize();
/*
* Register the devices
@@ -102,15 +88,15 @@ rtems_device_driver console_open(rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg)
{
volatile m860SCCRegisters_t *sccregs;
volatile m8xxSCCRegisters_t *sccregs;
#ifdef I_WANT_TERMIOS
static const rtems_termios_callbacks sccPollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
m860_char_poll_read, /* pollRead */
m860_char_poll_write, /* write */
m860_scc_set_attributes, /* setAttributes */
m8xx_uart_pollRead, /* pollRead */
m8xx_uart_pollWrite, /* write */
m8xx_uart_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
@@ -121,30 +107,30 @@ rtems_device_driver console_open(rtems_device_major_number major,
switch (minor) {
case 0:
m860.smc1.smcm = 1; /* Enable SMC1 RX interrupts */
m860.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
m8xx.smc1.smcm = 1; /* Enable SMC1 RX interrupts */
m8xx.cimr |= 1UL << 4; /* Enable SMC1 interrupts */
break;
case 1:
m860.smc2.smcm = 1; /* Enable SMC2 RX interrupts */
m860.cimr |= 1UL << 3; /* Enable SMC2 interrupts */
m8xx.smc2.smcm = 1; /* Enable SMC2 RX interrupts */
m8xx.cimr |= 1UL << 3; /* Enable SMC2 interrupts */
break;
case 2:
m860.cimr |= 1UL << 30; /* Enable SCC1 interrupts */
sccregs = &m860.scc1;
m8xx.cimr |= 1UL << 30; /* Enable SCC1 interrupts */
sccregs = &m8xx.scc1;
break;
case 3:
#ifndef I_WANT_TERMIOS
m860.cimr |= 1UL << 29; /* Enable SCC2 interrupts */
m8xx.cimr |= 1UL << 29; /* Enable SCC2 interrupts */
#endif /* I_WANT_TERMIOS */
sccregs = &m860.scc2;
sccregs = &m8xx.scc2;
break;
case 4:
m860.cimr |= 1UL << 28; /* Enable SCC3 interrupts */
sccregs = &m860.scc3;
m8xx.cimr |= 1UL << 28; /* Enable SCC3 interrupts */
sccregs = &m8xx.scc3;
break;
case 5:
m860.cimr |= 1UL << 27; /* Enable SCC4 interrupts */
sccregs = &m860.scc4;
m8xx.cimr |= 1UL << 27; /* Enable SCC4 interrupts */
sccregs = &m8xx.scc4;
break;
default:
rtems_panic ("CONSOLE: bad minor number");
@@ -186,14 +172,18 @@ rtems_device_driver console_read(rtems_device_major_number major,
void *arg)
{
#ifdef I_WANT_TERMIOS
/*
if (minor == SCC2_MINOR) {
*/
return rtems_termios_read(arg);
/*
}
else {
return m860_console_read(major, minor, arg);
return m8xx_console_read(major, minor, arg);
}
*/
#else
return m860_console_read(major, minor, arg);
return m8xx_console_read(major, minor, arg);
#endif
}
@@ -202,14 +192,18 @@ rtems_device_driver console_write(rtems_device_major_number major,
void *arg)
{
#ifdef I_WANT_TERMIOS
/*
if (minor == SCC2_MINOR) {
*/
return rtems_termios_write(arg);
/*
}
else {
return m860_console_write(major, minor, arg);
return m8xx_console_write(major, minor, arg);
}
*/
#else
return m860_console_write(major, minor, arg);
return m8xx_console_write(major, minor, arg);
#endif
}

View File

@@ -24,6 +24,10 @@ extern "C" {
#include <rtems.h>
#include <console.h>
#include <clockdrv.h>
#include <mpc8xx.h>
#include <mpc8xx/cpm.h>
#include <mpc8xx/mmu.h>
#include <mpc8xx/console.h>
/*
* confdefs.h overrides for this BSP:

View File

@@ -17,7 +17,6 @@
* $Id$
*/
#include <bsp.h>
#include <mpc860.h>
#include <stdio.h>
#include <rtems/error.h>
#include <rtems/rtems_bsdnet.h>
@@ -80,8 +79,8 @@ struct m860_enet_struct {
int txBdHead;
int txBdTail;
int txBdActiveCount;
m860BufferDescriptor_t *rxBdBase;
m860BufferDescriptor_t *txBdBase;
m8xxBufferDescriptor_t *rxBdBase;
m8xxBufferDescriptor_t *txBdBase;
rtems_id rxDaemonTid;
rtems_id txDaemonTid;
@@ -118,11 +117,11 @@ m860_scc1_interrupt_handler (rtems_vector_number v)
/*
* Frame received?
*/
if ((m860.scc1.sccm & 0x8) && (m860.scc1.scce & 0x8)) {
m860.scc1.scce = 0x8;
if ((m8xx.scc1.sccm & 0x8) && (m8xx.scc1.scce & 0x8)) {
m8xx.scc1.scce = 0x8;
/* I don't think the next line is needed. It was in
* the 68360 stuff, though.
* m860.scc1.sccm &= ~0x8;
* m8xx.scc1.sccm &= ~0x8;
*/
enet_driver[0].rxInterrupts++;
rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
@@ -131,16 +130,16 @@ m860_scc1_interrupt_handler (rtems_vector_number v)
/*
* Buffer transmitted or transmitter error?
*/
if ((m860.scc1.sccm & 0x12) && (m860.scc1.scce & 0x12)) {
m860.scc1.scce = 0x12;
if ((m8xx.scc1.sccm & 0x12) && (m8xx.scc1.scce & 0x12)) {
m8xx.scc1.scce = 0x12;
/* I don't think the next line is needed. It was in
* the 68360 stuff, though.
* m860.scc1.sccm &= ~0x12;
* m8xx.scc1.sccm &= ~0x12;
*/
enet_driver[0].txInterrupts++;
rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
}
m860.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
m8xx.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
}
/*
@@ -152,8 +151,8 @@ m860_fec_interrupt_handler (rtems_vector_number v)
/*
* Frame received?
*/
if (m860.fec.ievent & M860_FEC_IEVENT_RFINT) {
m860.fec.ievent = M860_FEC_IEVENT_RFINT;
if (m8xx.fec.ievent & M8xx_FEC_IEVENT_RFINT) {
m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
enet_driver[0].rxInterrupts++;
rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
}
@@ -161,8 +160,8 @@ m860_fec_interrupt_handler (rtems_vector_number v)
/*
* Buffer transmitted or transmitter error?
*/
if (m860.fec.ievent & M860_FEC_IEVENT_TFINT) {
m860.fec.ievent = M860_FEC_IEVENT_TFINT;
if (m8xx.fec.ievent & M8xx_FEC_IEVENT_TFINT) {
m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
enet_driver[0].txInterrupts++;
rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
}
@@ -182,31 +181,31 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
/*
* Configure port A CLK1, CLK2, TXD1 and RXD1 pins
*/
m860.papar |= 0x303;
m860.padir &= ~0x303;
m860.paodr &= ~0x303;
m8xx.papar |= 0x303;
m8xx.padir &= ~0x303;
m8xx.paodr &= ~0x303;
/*
* Configure port C CTS1* and CD1* pins, and PC4-PC7
*
*/
m860.pcpar &= ~0x30;
m860.pcdir |= 0x0f00;
m860.pcdir &= ~0x30;
m860.pcso |= 0x30;
m860.pcdat &= ~0x0f00; /* Clear LOOP */
m860.pcdat |= 0x0700; /* Set FULDL, TPSQEL, TPAPCE */
m8xx.pcpar &= ~0x30;
m8xx.pcdir |= 0x0f00;
m8xx.pcdir &= ~0x30;
m8xx.pcso |= 0x30;
m8xx.pcdat &= ~0x0f00; /* Clear LOOP */
m8xx.pcdat |= 0x0700; /* Set FULDL, TPSQEL, TPAPCE */
/*
* Connect CLK1 and CLK2 to SCC1
*/
m860.sicr &= ~0xFF;
m860.sicr |= (5 << 3) | 4;
m8xx.sicr &= ~0xFF;
m8xx.sicr |= (5 << 3) | 4;
/*
* Initialize SDMA configuration register
*/
m860.sdcr = 1;
m8xx.sdcr = 1;
/*
* Allocate mbuf pointers
@@ -221,94 +220,94 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
/*
* Set receiver and transmitter buffer descriptor bases
*/
sc->rxBdBase = M860AllocateBufferDescriptors(sc->rxBdCount);
sc->txBdBase = M860AllocateBufferDescriptors(sc->txBdCount);
m860.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m860;
m860.scc1p.tbase = (char *)sc->txBdBase - (char *)&m860;
sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
m8xx.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m8xx;
m8xx.scc1p.tbase = (char *)sc->txBdBase - (char *)&m8xx;
/*
* Send "Init parameters" command
*/
M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC1);
m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC1);
/*
* Set receive and transmit function codes
*/
m860.scc1p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
m860.scc1p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
m8xx.scc1p.rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
m8xx.scc1p.tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
/*
* Set maximum receive buffer length
*/
m860.scc1p.mrblr = RBUF_SIZE;
m8xx.scc1p.mrblr = RBUF_SIZE;
/*
* Set CRC parameters
*/
m860.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
m860.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
m8xx.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
m8xx.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
/*
* Clear diagnostic counters
*/
m860.scc1p.un.ethernet.crcec = 0;
m860.scc1p.un.ethernet.alec = 0;
m860.scc1p.un.ethernet.disfc = 0;
m8xx.scc1p.un.ethernet.crcec = 0;
m8xx.scc1p.un.ethernet.alec = 0;
m8xx.scc1p.un.ethernet.disfc = 0;
/*
* Set pad value
*/
m860.scc1p.un.ethernet.pads = 0x8888;
m8xx.scc1p.un.ethernet.pads = 0x8888;
/*
* Set retry limit
*/
m860.scc1p.un.ethernet.ret_lim = 15;
m8xx.scc1p.un.ethernet.ret_lim = 15;
/*
* Set maximum and minimum frame length
*/
m860.scc1p.un.ethernet.mflr = 1518;
m860.scc1p.un.ethernet.minflr = 64;
m860.scc1p.un.ethernet.maxd1 = RBUF_SIZE;
m860.scc1p.un.ethernet.maxd2 = RBUF_SIZE;
m8xx.scc1p.un.ethernet.mflr = 1518;
m8xx.scc1p.un.ethernet.minflr = 64;
m8xx.scc1p.un.ethernet.maxd1 = RBUF_SIZE;
m8xx.scc1p.un.ethernet.maxd2 = RBUF_SIZE;
/*
* Clear group address hash table
*/
m860.scc1p.un.ethernet.gaddr1 = 0;
m860.scc1p.un.ethernet.gaddr2 = 0;
m860.scc1p.un.ethernet.gaddr3 = 0;
m860.scc1p.un.ethernet.gaddr4 = 0;
m8xx.scc1p.un.ethernet.gaddr1 = 0;
m8xx.scc1p.un.ethernet.gaddr2 = 0;
m8xx.scc1p.un.ethernet.gaddr3 = 0;
m8xx.scc1p.un.ethernet.gaddr4 = 0;
/*
* Set our physical address
*/
hwaddr = sc->arpcom.ac_enaddr;
m860.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
m860.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
m860.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
m8xx.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
m8xx.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
m8xx.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
/*
* Aggressive retry
*/
m860.scc1p.un.ethernet.p_per = 0;
m8xx.scc1p.un.ethernet.p_per = 0;
/*
* Clear individual address hash table
*/
m860.scc1p.un.ethernet.iaddr1 = 0;
m860.scc1p.un.ethernet.iaddr2 = 0;
m860.scc1p.un.ethernet.iaddr3 = 0;
m860.scc1p.un.ethernet.iaddr4 = 0;
m8xx.scc1p.un.ethernet.iaddr1 = 0;
m8xx.scc1p.un.ethernet.iaddr2 = 0;
m8xx.scc1p.un.ethernet.iaddr3 = 0;
m8xx.scc1p.un.ethernet.iaddr4 = 0;
/*
* Clear temp address
*/
m860.scc1p.un.ethernet.taddr_l = 0;
m860.scc1p.un.ethernet.taddr_m = 0;
m860.scc1p.un.ethernet.taddr_h = 0;
m8xx.scc1p.un.ethernet.taddr_l = 0;
m8xx.scc1p.un.ethernet.taddr_m = 0;
m8xx.scc1p.un.ethernet.taddr_h = 0;
/*
* Set up receive buffer descriptors
@@ -330,7 +329,7 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
/*
* Clear any outstanding events
*/
m860.scc1.scce = 0xFFFF;
m8xx.scc1.scce = 0xFFFF;
/*
* Set up interrupts
@@ -342,21 +341,21 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
rtems_panic ("Can't attach M860 SCC1 interrupt handler: %s\n",
rtems_status_text (status));
}
m860.scc1.sccm = 0; /* No interrupts unmasked till necessary */
m860.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
m8xx.scc1.sccm = 0; /* No interrupts unmasked till necessary */
m8xx.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
/*
* Set up General SCC Mode Register
* Ethernet configuration
*/
m860.scc1.gsmr_h = 0x0;
m860.scc1.gsmr_l = 0x1088000c;
m8xx.scc1.gsmr_h = 0x0;
m8xx.scc1.gsmr_l = 0x1088000c;
/*
* Set up data synchronization register
* Ethernet synchronization pattern
*/
m860.scc1.dsr = 0xd555;
m8xx.scc1.dsr = 0xd555;
/*
* Set up protocol-specific mode register
@@ -374,13 +373,13 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
* Wait 22 bits before looking for start of frame delimiter
* Disable full-duplex operation
*/
m860.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
m8xx.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
/*
* Enable the TENA (RTS1*) pin
*/
m860.pcpar |= 0x1;
m860.pcdir &= ~0x1;
m8xx.pcpar |= 0x1;
m8xx.pcdir &= ~0x1;
/*
@@ -394,14 +393,14 @@ m860_scc_initialize_hardware (struct m860_enet_struct *sc)
* that used the other module won't work correctly.
* Put this comment in each module that sets these 2 registers
*/
m860.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
m8xx.cicr = 0x00e43e80; /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3,
SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
m860.simask |= M860_SIMASK_LVM1;
m8xx.simask |= M8xx_SIMASK_LVM1;
/*
* Enable receiver and transmitter
*/
m860.scc1.gsmr_l = 0x1088003c;
m8xx.scc1.gsmr_l = 0x1088003c;
}
static void
@@ -415,37 +414,37 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
/*
* Issue reset to FEC
*/
m860.fec.ecntrl=0x1;
m8xx.fec.ecntrl=0x1;
/*
* Put ethernet transciever in reset
*/
m860.pgcra |= 0x80;
m8xx.pgcra |= 0x80;
/*
* Configure I/O ports
*/
m860.pdpar = 0x1fff;
m860.pddir = 0x1c58;
m8xx.pdpar = 0x1fff;
m8xx.pddir = 0x1c58;
/*
* Take ethernet transciever out of reset
*/
m860.pgcra &= ~0x80;
m8xx.pgcra &= ~0x80;
/*
* Set SIU interrupt level to LVL2
*
*/
m860.fec.ivec = 0x02 << 29;
m8xx.fec.ivec = 0x02 << 29;
/*
* Set the TX and RX fifo sizes. For now, we'll split it evenly
*/
/* If you uncomment these, the FEC will not work right.
m860.fec.r_fstart = ((m860.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
m860.fec.x_fstart = 0;
m8xx.fec.r_fstart = ((m8xx.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
m8xx.fec.x_fstart = 0;
*/
/*
@@ -453,20 +452,20 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
*/
hwaddr = sc->arpcom.ac_enaddr;
m860.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
m8xx.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
(hwaddr[2] << 8) | (hwaddr[3] << 0);
m860.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
m8xx.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
/*
* Clear the hash table
*/
m860.fec.hash_table_high = 0;
m860.fec.hash_table_low = 0;
m8xx.fec.hash_table_high = 0;
m8xx.fec.hash_table_low = 0;
/*
* Set up receive buffer size
*/
m860.fec.r_buf_size = 0x5f0; /* set to 1520 */
m8xx.fec.r_buf_size = 0x5f0; /* set to 1520 */
/*
* Allocate mbuf pointers
@@ -481,10 +480,10 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
/*
* Set receiver and transmitter buffer descriptor bases
*/
sc->rxBdBase = M860AllocateBufferDescriptors(sc->rxBdCount);
sc->txBdBase = M860AllocateBufferDescriptors(sc->txBdCount);
m860.fec.r_des_start = (int)sc->rxBdBase;
m860.fec.x_des_start = (int)sc->txBdBase;
sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
m8xx.fec.r_des_start = (int)sc->rxBdBase;
m8xx.fec.x_des_start = (int)sc->txBdBase;
/*
* Set up Receive Control Register:
@@ -493,21 +492,21 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
* Half duplex
* No loopback
*/
m860.fec.r_cntrl = 0x00000006;
m8xx.fec.r_cntrl = 0x00000006;
/*
* Set up Transmit Control Register:
* Half duplex
* No heartbeat
*/
m860.fec.x_cntrl = 0x00000000;
m8xx.fec.x_cntrl = 0x00000000;
/*
* Set up DMA function code:
* Big-endian
* DMA functino code = 0
*/
m860.fec.fun_code = 0x78000000;
m8xx.fec.fun_code = 0x78000000;
/*
* Initialize SDMA configuration register
@@ -516,13 +515,13 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
* FEC arbitration ID = 0 => U-bus arbitration = 6
* RISC arbitration ID = 1 => U-bus arbitration = 5
*/
m860.sdcr = 1;
m8xx.sdcr = 1;
/*
* Set MII speed to 2.5 MHz for 25 Mhz system clock
*/
m860.fec.mii_speed = 0x0a;
m860.fec.mii_data = 0x58021000;
m8xx.fec.mii_speed = 0x0a;
m8xx.fec.mii_data = 0x58021000;
/*
* Set up receive buffer descriptors
@@ -545,9 +544,9 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
/*
* Mask all FEC interrupts and clear events
*/
m860.fec.imask = M860_FEC_IEVENT_TFINT |
M860_FEC_IEVENT_RFINT;
m860.fec.ievent = ~0;
m8xx.fec.imask = M8xx_FEC_IEVENT_TFINT |
M8xx_FEC_IEVENT_RFINT;
m8xx.fec.ievent = ~0;
/*
* Set up interrupts
@@ -559,7 +558,7 @@ m860_fec_initialize_hardware (struct m860_enet_struct *sc)
rtems_panic ("Can't attach M860 FEC interrupt handler: %s\n",
rtems_status_text (status));
m860.simask |= M860_SIMASK_LVM2;
m8xx.simask |= M8xx_SIMASK_LVM2;
}
@@ -583,44 +582,44 @@ m860Enet_retire_tx_bd (struct m860_enet_struct *sc)
i = sc->txBdTail;
nRetired = 0;
while ((sc->txBdActiveCount != 0)
&& (((status = (sc->txBdBase + i)->status) & M860_BD_READY) == 0)) {
&& (((status = (sc->txBdBase + i)->status) & M8xx_BD_READY) == 0)) {
/*
* See if anything went wrong
*/
if (status & (M860_BD_DEFER |
M860_BD_HEARTBEAT |
M860_BD_LATE_COLLISION |
M860_BD_RETRY_LIMIT |
M860_BD_UNDERRUN |
M860_BD_CARRIER_LOST)) {
if (status & (M8xx_BD_DEFER |
M8xx_BD_HEARTBEAT |
M8xx_BD_LATE_COLLISION |
M8xx_BD_RETRY_LIMIT |
M8xx_BD_UNDERRUN |
M8xx_BD_CARRIER_LOST)) {
/*
* Check for errors which stop the transmitter.
*/
if (status & (M860_BD_LATE_COLLISION |
M860_BD_RETRY_LIMIT |
M860_BD_UNDERRUN)) {
if (status & M860_BD_LATE_COLLISION)
if (status & (M8xx_BD_LATE_COLLISION |
M8xx_BD_RETRY_LIMIT |
M8xx_BD_UNDERRUN)) {
if (status & M8xx_BD_LATE_COLLISION)
enet_driver[0].txLateCollision++;
if (status & M860_BD_RETRY_LIMIT)
if (status & M8xx_BD_RETRY_LIMIT)
enet_driver[0].txRetryLimit++;
if (status & M860_BD_UNDERRUN)
if (status & M8xx_BD_UNDERRUN)
enet_driver[0].txUnderrun++;
/*
* Restart the transmitter
*/
/* FIXME: this should get executed only if using the SCC */
M860ExecuteRISC (M860_CR_OP_RESTART_TX | M860_CR_CHAN_SCC1);
m8xx_cp_execute_cmd (M8xx_CR_OP_RESTART_TX | M8xx_CR_CHAN_SCC1);
}
if (status & M860_BD_DEFER)
if (status & M8xx_BD_DEFER)
enet_driver[0].txDeferred++;
if (status & M860_BD_HEARTBEAT)
if (status & M8xx_BD_HEARTBEAT)
enet_driver[0].txHeartbeat++;
if (status & M860_BD_CARRIER_LOST)
if (status & M8xx_BD_CARRIER_LOST)
enet_driver[0].txLostCarrier++;
}
nRetired++;
if (status & M860_BD_LAST) {
if (status & M8xx_BD_LAST) {
/*
* A full frame has been transmitted.
* Free all the associated buffer descriptors.
@@ -649,7 +648,7 @@ scc_rxDaemon (void *arg)
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
rtems_unsigned16 status;
m860BufferDescriptor_t *rxBd;
m8xxBufferDescriptor_t *rxBd;
int rxBdIndex;
/*
@@ -662,9 +661,9 @@ scc_rxDaemon (void *arg)
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod (m, void *);
rxBd->status = M860_BD_EMPTY | M860_BD_INTERRUPT;
rxBd->status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
if (++rxBdIndex == sc->rxBdCount) {
rxBd->status |= M860_BD_WRAP;
rxBd->status |= M8xx_BD_WRAP;
break;
}
}
@@ -679,11 +678,11 @@ scc_rxDaemon (void *arg)
/*
* Wait for packet if there's not one ready
*/
if ((status = rxBd->status) & M860_BD_EMPTY) {
if ((status = rxBd->status) & M8xx_BD_EMPTY) {
/*
* Clear old events
*/
m860.scc1.scce = 0x8;
m8xx.scc1.scce = 0x8;
/*
* Wait for packet
@@ -692,13 +691,13 @@ scc_rxDaemon (void *arg)
* possibility that a packet arrived between the
* `if' above, and the clearing of the event register.
*/
while ((status = rxBd->status) & M860_BD_EMPTY) {
while ((status = rxBd->status) & M8xx_BD_EMPTY) {
rtems_event_set events;
/*
* Unmask RXF (Full frame received) event
*/
m860.scc1.sccm |= 0x8;
m8xx.scc1.sccm |= 0x8;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
@@ -710,16 +709,16 @@ scc_rxDaemon (void *arg)
/*
* Check that packet is valid
*/
if ((status & (M860_BD_LAST |
M860_BD_FIRST_IN_FRAME |
M860_BD_LONG |
M860_BD_NONALIGNED |
M860_BD_SHORT |
M860_BD_CRC_ERROR |
M860_BD_OVERRUN |
M860_BD_COLLISION)) ==
(M860_BD_LAST |
M860_BD_FIRST_IN_FRAME)) {
if ((status & (M8xx_BD_LAST |
M8xx_BD_FIRST_IN_FRAME |
M8xx_BD_LONG |
M8xx_BD_NONALIGNED |
M8xx_BD_SHORT |
M8xx_BD_CRC_ERROR |
M8xx_BD_OVERRUN |
M8xx_BD_COLLISION)) ==
(M8xx_BD_LAST |
M8xx_BD_FIRST_IN_FRAME)) {
/*
* Pass the packet up the chain.
* FIXME: Packet filtering hook could be done here.
@@ -747,29 +746,29 @@ scc_rxDaemon (void *arg)
/*
* Something went wrong with the reception
*/
if (!(status & M860_BD_LAST))
if (!(status & M8xx_BD_LAST))
sc->rxNotLast++;
if (!(status & M860_BD_FIRST_IN_FRAME))
if (!(status & M8xx_BD_FIRST_IN_FRAME))
sc->rxNotFirst++;
if (status & M860_BD_LONG)
if (status & M8xx_BD_LONG)
sc->rxGiant++;
if (status & M860_BD_NONALIGNED)
if (status & M8xx_BD_NONALIGNED)
sc->rxNonOctet++;
if (status & M860_BD_SHORT)
if (status & M8xx_BD_SHORT)
sc->rxRunt++;
if (status & M860_BD_CRC_ERROR)
if (status & M8xx_BD_CRC_ERROR)
sc->rxBadCRC++;
if (status & M860_BD_OVERRUN)
if (status & M8xx_BD_OVERRUN)
sc->rxOverrun++;
if (status & M860_BD_COLLISION)
if (status & M8xx_BD_COLLISION)
sc->rxCollision++;
}
/*
* Reenable the buffer descriptor
*/
rxBd->status = (status & (M860_BD_WRAP | M860_BD_INTERRUPT)) |
M860_BD_EMPTY;
rxBd->status = (status & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT)) |
M8xx_BD_EMPTY;
/*
* Move to next buffer descriptor
@@ -786,7 +785,7 @@ fec_rxDaemon (void *arg)
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
rtems_unsigned16 status;
m860BufferDescriptor_t *rxBd;
m8xxBufferDescriptor_t *rxBd;
int rxBdIndex;
/*
@@ -799,10 +798,10 @@ fec_rxDaemon (void *arg)
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->buffer = mtod (m, void *);
rxBd->status = M860_BD_EMPTY;
m860.fec.r_des_active = 0x1000000;
rxBd->status = M8xx_BD_EMPTY;
m8xx.fec.r_des_active = 0x1000000;
if (++rxBdIndex == sc->rxBdCount) {
rxBd->status |= M860_BD_WRAP;
rxBd->status |= M8xx_BD_WRAP;
break;
}
}
@@ -817,11 +816,11 @@ fec_rxDaemon (void *arg)
/*
* Wait for packet if there's not one ready
*/
if ((status = rxBd->status) & M860_BD_EMPTY) {
if ((status = rxBd->status) & M8xx_BD_EMPTY) {
/*
* Clear old events
*/
m860.fec.ievent = M860_FEC_IEVENT_RFINT;
m8xx.fec.ievent = M8xx_FEC_IEVENT_RFINT;
/*
* Wait for packet
@@ -830,13 +829,13 @@ fec_rxDaemon (void *arg)
* possibility that a packet arrived between the
* `if' above, and the clearing of the event register.
*/
while ((status = rxBd->status) & M860_BD_EMPTY) {
while ((status = rxBd->status) & M8xx_BD_EMPTY) {
rtems_event_set events;
/*
* Unmask RXF (Full frame received) event
*/
m860.fec.ievent |= M860_FEC_IEVENT_RFINT;
m8xx.fec.ievent |= M8xx_FEC_IEVENT_RFINT;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
@@ -848,7 +847,7 @@ fec_rxDaemon (void *arg)
/*
* Check that packet is valid
*/
if (status & M860_BD_LAST) {
if (status & M8xx_BD_LAST) {
/*
* Pass the packet up the chain.
* FIXME: Packet filtering hook could be done here.
@@ -876,27 +875,27 @@ fec_rxDaemon (void *arg)
/*
* Something went wrong with the reception
*/
if (!(status & M860_BD_LAST))
if (!(status & M8xx_BD_LAST))
sc->rxNotLast++;
if (status & M860_BD_LONG)
if (status & M8xx_BD_LONG)
sc->rxGiant++;
if (status & M860_BD_NONALIGNED)
if (status & M8xx_BD_NONALIGNED)
sc->rxNonOctet++;
if (status & M860_BD_SHORT)
if (status & M8xx_BD_SHORT)
sc->rxRunt++;
if (status & M860_BD_CRC_ERROR)
if (status & M8xx_BD_CRC_ERROR)
sc->rxBadCRC++;
if (status & M860_BD_OVERRUN)
if (status & M8xx_BD_OVERRUN)
sc->rxOverrun++;
if (status & M860_BD_COLLISION)
if (status & M8xx_BD_COLLISION)
sc->rxCollision++;
}
/*
* Reenable the buffer descriptor
*/
rxBd->status = (status & M860_BD_WRAP) |
M860_BD_EMPTY;
m860.fec.r_des_active = 0x1000000;
rxBd->status = (status & M8xx_BD_WRAP) |
M8xx_BD_EMPTY;
m8xx.fec.r_des_active = 0x1000000;
/*
* Move to next buffer descriptor
*/
@@ -909,7 +908,7 @@ static void
scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
{
struct m860_enet_struct *sc = ifp->if_softc;
volatile m860BufferDescriptor_t *firstTxBd, *txBd;
volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
struct mbuf *l = NULL;
rtems_unsigned16 status;
int nAdded;
@@ -936,7 +935,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
/*
* Clear old events
*/
m860.scc1.scce = 0x12;
m8xx.scc1.scce = 0x12;
/*
* Wait for buffer descriptor to become available.
@@ -958,7 +957,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Unmask TXB (buffer transmitted) and
* TXE (transmitter error) events.
*/
m860.scc1.sccm |= 0x12;
m8xx.scc1.sccm |= 0x12;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
@@ -971,7 +970,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Don't set the READY flag till the
* whole packet has been readied.
*/
status = nAdded ? M860_BD_READY : 0;
status = nAdded ? M8xx_BD_READY : 0;
/*
* FIXME: Why not deal with empty mbufs at at higher level?
@@ -990,7 +989,7 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
sc->txMbuf[sc->txBdHead] = m;
nAdded++;
if (++sc->txBdHead == sc->txBdCount) {
status |= M860_BD_WRAP;
status |= M8xx_BD_WRAP;
sc->txBdHead = 0;
}
l = m;
@@ -1013,9 +1012,9 @@ scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
*/
if (m == NULL) {
if (nAdded) {
status |= M860_BD_PAD | M860_BD_LAST | M860_BD_TX_CRC | M860_BD_INTERRUPT;
status |= M8xx_BD_PAD | M8xx_BD_LAST | M8xx_BD_TX_CRC | M8xx_BD_INTERRUPT;
txBd->status = status;
firstTxBd->status |= M860_BD_READY;
firstTxBd->status |= M8xx_BD_READY;
sc->txBdActiveCount += nAdded;
}
break;
@@ -1029,7 +1028,7 @@ static void
fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
{
struct m860_enet_struct *sc = ifp->if_softc;
volatile m860BufferDescriptor_t *firstTxBd, *txBd;
volatile m8xxBufferDescriptor_t *firstTxBd, *txBd;
/* struct mbuf *l = NULL; */
rtems_unsigned16 status;
int nAdded;
@@ -1037,7 +1036,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
/*
* Free up buffer descriptors
*/
m860Enet_retire_tx_bd (sc);
m8xxEnet_retire_tx_bd (sc);
/*
* Set up the transmit buffer descriptors.
@@ -1056,7 +1055,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
/*
* Clear old events
*/
m860.fec.ievent = M860_FEC_IEVENT_TFINT;
m8xx.fec.ievent = M8xx_FEC_IEVENT_TFINT;
/*
* Wait for buffer descriptor to become available.
@@ -1078,7 +1077,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Unmask TXB (buffer transmitted) and
* TXE (transmitter error) events.
*/
m860.fec.ievent |= M860_FEC_IEVENT_TFINT;
m8xx.fec.ievent |= M8xx_FEC_IEVENT_TFINT;
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
@@ -1091,7 +1090,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
* Don't set the READY flag till the
* whole packet has been readied.
*/
status = nAdded ? M860_BD_READY : 0;
status = nAdded ? M8xx_BD_READY : 0;
/*
* FIXME: Why not deal with empty mbufs at at higher level?
@@ -1110,7 +1109,7 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
sc->txMbuf[sc->txBdHead] = m;
nAdded++;
if (++sc->txBdHead == sc->txBdCount) {
status |= M860_BD_WRAP;
status |= M8xx_BD_WRAP;
sc->txBdHead = 0;
}
/* l = m;*/
@@ -1135,10 +1134,10 @@ fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
*/
if (m == NULL) {
if (nAdded) {
status |= M860_BD_LAST | M860_BD_TX_CRC;
status |= M8xx_BD_LAST | M8xx_BD_TX_CRC;
txBd->status = status;
firstTxBd->status |= M860_BD_READY;
m860.fec.x_des_active = 0x1000000;
firstTxBd->status |= M8xx_BD_READY;
m8xx.fec.x_des_active = 0x1000000;
sc->txBdActiveCount += nAdded;
}
break;
@@ -1254,9 +1253,9 @@ scc_init (void *arg)
* Set flags appropriately
*/
if (ifp->if_flags & IFF_PROMISC)
m860.scc1.psmr |= 0x200;
m8xx.scc1.psmr |= 0x200;
else
m860.scc1.psmr &= ~0x200;
m8xx.scc1.psmr &= ~0x200;
/*
* Tell the world that we're running.
@@ -1266,7 +1265,7 @@ scc_init (void *arg)
/*
* Enable receiver and transmitter
*/
m860.scc1.gsmr_l |= 0x30;
m8xx.scc1.gsmr_l |= 0x30;
}
static void
@@ -1294,9 +1293,9 @@ fec_init (void *arg)
* Set flags appropriately
*/
if (ifp->if_flags & IFF_PROMISC)
m860.fec.r_cntrl |= 0x8;
m8xx.fec.r_cntrl |= 0x8;
else
m860.fec.r_cntrl &= ~0x8;
m8xx.fec.r_cntrl &= ~0x8;
/*
@@ -1307,7 +1306,7 @@ fec_init (void *arg)
/*
* Enable receiver and transmitter
*/
m860.fec.ecntrl = 0x2;
m8xx.fec.ecntrl = 0x2;
}
@@ -1324,7 +1323,7 @@ scc_stop (struct m860_enet_struct *sc)
/*
* Shut down receiver and transmitter
*/
m860.scc1.gsmr_l &= ~0x30;
m8xx.scc1.gsmr_l &= ~0x30;
}
static void
@@ -1337,7 +1336,7 @@ fec_stop (struct m860_enet_struct *sc)
/*
* Shut down receiver and transmitter
*/
m860.fec.ecntrl = 0x0;
m8xx.fec.ecntrl = 0x0;
}
/*
@@ -1355,7 +1354,7 @@ enet_stats (struct m860_enet_struct *sc)
printf (" Bad CRC:%-8lu", sc->rxBadCRC);
printf (" Overrun:%-8lu", sc->rxOverrun);
printf (" Collision:%-8lu\n", sc->rxCollision);
printf (" Discarded:%-8lu\n", (unsigned long)m860.scc1p.un.ethernet.disfc);
printf (" Discarded:%-8lu\n", (unsigned long)m8xx.scc1p.un.ethernet.disfc);
printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
printf (" Deferred:%-8lu", sc->txDeferred);
@@ -1610,7 +1609,7 @@ rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config)
{
int i;
if ((m860.fec.mii_data & 0xffff) == 0x2000) {
if ((m8xx.fec.mii_data & 0xffff) == 0x2000) {
/* rtems_scc1_driver_attach(config);*/
return rtems_fec_driver_attach(config);
}

View File

@@ -18,7 +18,6 @@
*/
#include <bsp.h>
#include <mpc860.h>
#include <rtems/libio.h>
#include <libcsupport.h>
@@ -115,6 +114,10 @@ void bsp_start(void)
extern int _end;
rtems_unsigned32 heap_start;
rtems_unsigned32 ws_start;
cpu_init();
mmu_init();
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
@@ -166,16 +169,14 @@ void bsp_start(void)
* transciever that is used for 10/100 Mbps ethernet now, so that
* we can attempt to read it later in rtems_enet_driver_attach()
*/
m860.fec.mii_speed = 0x0a;
m860.fec.mii_data = 0x680a0000;
m8xx.fec.mii_speed = 0x0a;
m8xx.fec.mii_data = 0x680a0000;
m860.scc2.sccm=0;
m860.scc2p.rbase=0;
m860.scc2p.tbase=0;
M860ExecuteRISC(M860_CR_OP_STOP_TX | M860_CR_CHAN_SCC2);
mmu_init();
m8xx.scc2.sccm=0;
m8xx.scc2p.rbase=0;
m8xx.scc2p.tbase=0;
m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
}

View File

@@ -0,0 +1,44 @@
/*
* cpuinit.c - this file contains functions for initializing the CPU
*
* Written by Jay Monkman (jmonkman@frasca.com)
*
* $Id$
*/
#include <bsp.h>
/* Macros for handling all the MMU SPRs */
#define PUT_IC_CST(r) __asm__ volatile ("mtspr 0x230,%0\n" ::"r"(r))
#define GET_IC_CST(r) __asm__ volatile ("mfspr %0,0x230\n" :"=r"(r))
#define PUT_DC_CST(r) __asm__ volatile ("mtspr 0x238,%0\n" ::"r"(r))
#define GET_DC_CST(r) __asm__ volatile ("mfspr %0,0x238\n" :"=r"(r))
void cpu_init(void)
{
register unsigned long t1, t2;
/* Let's clear MSR[IR] and MSR[DR] */
t2 = PPC_MSR_IR | PPC_MSR_DR;
__asm__ volatile (
"mfmsr %0\n"
"andc %0, %0, %1\n"
"mtmsr %0\n" :"=r"(t1), "=r"(t2):
"1"(t2));
t1 = M8xx_CACHE_CMD_UNLOCK;
/* PUT_DC_CST(t1); */
PUT_IC_CST(t1);
t1 = M8xx_CACHE_CMD_INVALIDATE;
/* PUT_DC_CST(t1); */
PUT_IC_CST(t1);
t1 = M8xx_CACHE_CMD_ENABLE;
PUT_IC_CST(t1);
t1 = M8xx_CACHE_CMD_SFWT;
/* PUT_DC_CST(t1); */
t1 = M8xx_CACHE_CMD_ENABLE;
/* PUT_DC_CST(t1);*/
}

View File

@@ -128,8 +128,8 @@ SECTIONS
dpram :
{
m860 = .;
_m860 = .;
m8xx = .;
_m8xx = .;
. += (8 * 1024);
} >dpram

View File

@@ -0,0 +1,45 @@
/*
* mmutlbtab.c
*
* This file defines the MMU_TLB_table for the eth_comm board.
*
* 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 <bsp.h>
#include <mpc8xx/mmu.h>
/*
* This MMU_TLB_table is used to statically initialize the Table Lookaside
* Buffers in the MMU of the MPC860 processor.
*
* We initialize the entries in both the instruction and data TLBs
* with the same values - a few bits relevant to the data TLB are unused
* in the instruction TLB.
*
* An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
* Real Page Number (RPN) value are supplied in the table for each TLB entry.
*
* The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
* not have more than 32 lines in it!
*
* We set up the virtual memory map so that virtual address of a
* location is equal to its real address.
*/
MMU_TLB_table_t MMU_TLB_table[] = {
/*
* DRAM: CS1, Start address 0x00000000, 8M,
* ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
* R/W,X for supervisor, no ASID comparison, not cache-inhibited.
* EPN TWC RPN
*/
{ 0x00000200, 0x0D, 0x000001FD } /* DRAM - PS=PS=8M */
};
/*
* MMU_N_TLB_Table_Entries is defined here because the size of the
* MMU_TLB_table is only known in this file.
*/
int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );

View File

@@ -0,0 +1,17 @@
##
## $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 = console include network startup wrapup
include $(top_srcdir)/../../bsp.am
EXTRA_DIST = README bsp_specs times
include $(top_srcdir)/../../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,372 @@
This is a README file for the MBX860/MBX821 port of RTEMS 4.5.0
Please send any comments, improvements, or bug reports to:
Darlene A. Stewart
Software Engineering Group
Institute for Information Technology
National Research Council of Canada
Ottawa, ON, K1A 0R6
Canada
Darlene.Stewart@nrc.ca
Disclaimer
----------
The National Research Council of Canada is distributing this RTEMS
board support package for the Motorola MBX860 and MBX821 as free
software; you can redistribute it and/or modify it under terms of
the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
This software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details. You should have received a
copy of the GNU General Public License along with RTEMS; see file
COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
Cambridge, MA 02139, USA.
Under no circumstances will the National Research Council of Canada
nor Her Majesty the Queen in right of Canada assume any liablility
for the use this software, nor any responsibility for its quality or
its support.
Summary
-------
BSP NAME: mbx8xx
BOARD: Motorola MBX860 and MBX821 Embedded Controllers
BUS: No backplane. On-board ISA, PCI, PC/104 and PCMCIA.
CPU FAMILY: PowerPC
CPU: PowerPC MPC860 or MPC821
COPROCESSORS: Built-in Motorola QUICC
MODE: 32 bit mode
DEBUG MONITOR: EPPC-Bug
PERIPHERALS
===========
TIMERS: PIT / Timebase
RESOLUTION: 1 microsecond / frequency = clock-speed / 16
SERIAL PORTS: 2 or 4 SCCs (SCC1 is hardwired for Ethernet)
2 SMC
1 SIO
REAL-TIME CLOCK: Many. Look at documentation.
DMA: Each SCC and SMC.
VIDEO: None on-board. MPC821 has a built-in LCD panel driver.
SCSI: None on-board.
NETWORKING: Ethernet (10 Mbps) on SCC1
DRIVER INFORMATION
==================
CLOCK DRIVER: yes
CONSOLE DRIVER: yes
SHMSUPP: N/A
TIMER DRIVER: yes
NETWORK DRIVER: yes
NOTES
=====
On-chip resources:
SCC1 network or console
SCC2 serial port
SMC1 gdb debug console/application console
SMC2 application console
CLK1 network
CLK2 network
CLK3
CLK4
CLK5
CLK6
CLK7
CLK8
BRG1 console
BRG2 console
BRG3 console
BRG4 console
RTC
PIT clock
TB
DEC
SWT
*CS0 FLASH
*CS1 DRAM bank (onboard)
*CS2 DRAM bank 0 (1st half of DIMM)
*CS3 DRAM bank 1 (2nd half of DIMM)
*CS4 Battery-Backed SRAM
*CS5 QSPAN PCI
*CS6 QSPAN
*CS7 Boot ROM
UPMA
UPMB
IRQ0
IRQ1
IRQ2
IRQ3
IRQ4
IRQ5
IRQ6
IRQ7
IRQ_LVL0
IRQ_LVL1
IRQ_LVL2
IRQ_LVL3
IRQ_LVL4
IRQ_LVL5
IRQ_LVL6
IRQ_LVL7
Board description
-----------------
Clock rate: 50MHz Entry level boards, 40 MHz others.
Bus width: 8/32 bit Flash, 32 bit DRAM
FLASH: 2-4MB, 120ns
RAM: 4-16MB EDO, 60ns DRAM DIMM
Installation
------------
All MBX821/MBX860 ports share the same source code base. The MPC821 does
not have SCC3 and SCC4. Instead, it has an LCD panel driver. Otherwise,
the MBX821 and MBX860 boards are essentially identical. Entry level boards
do not have all connectors and peripheral devices present. This has no
impact on the source code base; it merely means that some functionality
is not available on these entry level boards. For the most part, the port
uses the standard build process for powerpc targets. However, you must
specify the EXACT model of MBX board that you are building for as the
argument to the RTEMS_BSP make variable. If you do not, the build process
will build for a MBX860-002. Look at rtems/make/custom/mbx8xx.cfg for the
specific list of boards supported and their corresponding names. An
example build command is:
make RTEMS_BSP=mbx821_001 all debug
This will build the optimized and debug versions of all RTEMS libraries,
samples and tests (if the latter are enabled).
The Software Engineering Group of the Institute for Information Technology
only owns an MBX821-001 and MBX86-002. The only provided config files are
mbx821_001.cfg and mbx860_002.cfg. A SPECIFIC CONFIG FILE IS REQUIRED. Use
one of the provided files as a template to create a specific config file for
another model.
We rely on EPPC-BUG to download to the targets. We use the 'PLH" command.
We enabled a TFTP deamon on our development host.
Port Description
Console driver
---------------
This BSP includes an termios-capable console driver that supports SMC1,
SMC2, SCC2, and SCC3 and SCC4 if present. The RTEMS console is selected
in rtems/make/custom/mbx8xx.cfg with the CONSOLE_MINOR variable. We
normally run with the RTEMS application console on SMC1.
Support is provided for polled and interrupt-driven terminal I/O. Interrupt-
driven I/O is selected by setting the UARTS_USE_INTERRUPTS variable in
rtems/make/custom/mbx8xx.cfg. If the variable is not set, or if it is set
to zero, polled I/O is used. If the EPPCBUG_SMC1 variable is set in
rtems/make/custom/mbx8xx.cfg, SMC1 will be used in polled mode with all
I/O done by EPPC-Bug rather than the supplied device driver. This mode
should be used if the application console is shared with EPPC-Bug.
Polled I/O must be used when running the timing tests. It must also be used
to run some other tests and some samples, such as the cdtest. Applications
would normally use interrupt-driven I/O.
EPPC-Bug and I/O
----------------
Be warned that when EPPC-Bug does I/O through a serial port, all interrupts
get turned off in the SIMASK register! This is a definite bug in release 1.1
of the firmware. It may have been fixed in later releases.
To solve this problem that occurs when GDB communicates with EPPC-Bug,
whenever the BSP manipulates the SIMASK, it makes copy of the written
in a global variable called 'simask_copy'. That value must be restored by
GDB before execution resumes. The following commands placed in the .gdbinit
file takes care of this:
# GDB Initialization file for EPPCBug.
define hook-stepi
set language c
set *(int *)0xFA200014=simask_copy
set language auto
end
define hook-step
set language c
set *(int *)0xFA200014=simask_copy
set language auto
end
define hook-continue
set language c
set *(int *)0xFA200014=simask_copy
set language auto
end
define hook-nexti
set language c
set *(int *)0xFA200014=simask_copy
set language auto
end
define hook-next
set language c
set *(int *)0xFA200014=simask_copy
set language auto
end
define hook-finish
set language c
set *(int *)0xFA200014=simask_copy
set language auto
end
Floating-point
--------------
The MPC860 and MPC821 do not have floating-point units. All code should
get compiled with the appropriate -mcpu flag. The nof variants of the gcc
runtime libraries should be used for linking.
Miscellaneous
-------------
All development was based on the eth_comm port.
Host System
-----------
12345678901234567890123456789012345678901234567890123456789012345678901234567890
The port was developed on Pentiums II and III running RedHat Linux 6.0 and
6.1. The following tools were used:
- GNU gcc snapshot dated 19991208 configured for powerpc-rtems;
- GNU binutils 2.9.1 configured for powerpc-rtems;
Gcc 2.95.2 also worked. Gcc 2.95.1 will not compile the console driver with
-O4 or -O3. Compile it manually with -O2.
Known Problems
--------------
The cdtest will not run with interrupt-driven I/O. The reason is that the
constructors for the static objects are called at boot time when the
interrupts are still disabled. The output buffer fills up, but never empties,
and the application goes into an infinite loop waiting for buffer space. This
should have been documented in the rtems/c/src/tests/PROBLEMS file. The moral
of this story is: do not do I/O from the constructors or destructors of static
objects.
The cpuuse and malloctest tests do not work properly, either with polled I/O
or interrupt-driven I/O. They are known not to work with interrupt-driven I/O,
but should work with polled I/O?
Output stops prematurely in the termios test when the console is operating in
interrupt-driven mode because the serial port is re-initialized before all
characters in the last raw output buffer are sent. Adding calls to tcdrain()
in the test task helps, but it does not solve the problem. What happens is
that the CD2401 raises a transmit interrupt when the last character in the
DMA buffer is written into the transmit FIFO, not when the last character
has been transmitted. When tcdrain() returns, there might be up to 16
characters in the output FIFO. The call to tcsetattr() causes the serial port
to re-initialize, at which point the output FIFO is cleared. We could not find
a way to detect whether characters are still in the FIFO and to wait for them
to be transmitted.
The first raw buffer to be transmitted after the console is re-initialized
with tcsetattr() is garbled. At this time, it does not seem worth while to
track this problem down.
In the stackchk test, an access fault exception is raised after the stack is
blown. This is one case were overwritting the first or last 16 bytes of the
stack does cause problems (but hey, an exception occurred, which is better
than propagating the error).
In the stackchk test, an access fault exception is raised after the stack is
blown. This is one case were overwritting the first or last 16 bytes of the
stack does cause problems (but hey, an exception occurred, which is better
than propagating the error).
When using interrupt-driven I/O, psx08 produces all the expected output, but
it does not return control to 167Bug. Is this test supposed to work with
interrupt-driven console I/O?
What's new
----------
All known problems with use of the caches on the MBX860-002 and MBX821-001
have been resolved.
Thanks
------
- to Jay Monkman (jmonkman@frasca.com) of Frasca International, Inc.
for his eth_comm port.
- to On-Line Applications Research Corporation (OAR) for developing
RTEMS and making it available on a Technology Transfer basis;
- to the FSF and to Cygnus Support for great free software;
Test Configuration
------------------
Board: MBX821-001, MBX860-002
CPU: Motorola MPC821, MPC860
Clock Speed: 50 MHz, 40 MHz
RAM: 4 MBytes of 32-bit DRAM
Cache Configuration: Instruction cache on; data cache on, copyback mode.
Times Reported in: clock ticks: TMBCLK = system clock / 16.
Timer Source: Timebase clock
GCC Flags: -O4 -fno-keep-inline-functions -mcpu=(821/860)
Console: Operates in polled mode on SMC2. No I/O through EPPC-Bug.
Test Results
------------
Single processor tests: All tests passed, except the following ones:
- paranoia required the FPSP and the default variants of libm (and libc and
libgcc) for us. It may work with the msoft-float variants for you, but it
does require the FPSP.
- cpuuse and malloctest did not work.
- The stackchk test got an access fault exception before the RTEMS stack
checker had had a chance to detect the corrupted stack.
Multi-processort tests: not applicable -- No MPCI layer yet.
Timing tests:
See the times-mbx821 and times-860 files for the results of the
timing tests.
Network tests:
Network driver is being implemented.

View File

@@ -0,0 +1,26 @@
%rename cpp old_cpp
%rename lib old_lib
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*cpp:
%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
*lib:
%{!qrtems: %(old_lib)} %{qrtems: --start-group \
%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
%{qjava: -lffi -lgcjgc -lzgcj -lgcj} %{qc++: -lstdc++} -lc -lgcc --end-group \
%{!qnolinkcmds: -T linkcmds%s}}
*startfile:
%{!qrtems: %(old_startfile)} %{qrtems: \
%{!qrtems_debug: } \
%{qrtems_debug: } ecrti%O%s}
*endfile:
%{!qrtems: %(old_endfile)} %{qrtems: ecrtn%O%s}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -N -u start -e start}

View File

@@ -0,0 +1,36 @@
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-powerpc-mbx8xx,$RTEMS_VERSION,no)
AM_MAINTAINER_MODE
RTEMS_ENABLE_LIBCDIR
RTEMS_ENABLE_MULTIPROCESSING
RTEMS_ENABLE_NETWORKING
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
RTEMS_CHECK_MULTIPROCESSING(RTEMS_BSP)
RTEMS_CHECK_NETWORKING
RTEMS_CANONICAL_HOST
RTEMS_PROJECT_ROOT
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
AM_CONDITIONAL(HAS_MP,test "$HAS_MP" = "yes")
# Explicitly list a Makefile here
AC_OUTPUT(
Makefile
console/Makefile
include/Makefile
network/Makefile
startup/Makefile
wrapup/Makefile)

View File

@@ -0,0 +1,32 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/console.rel
C_FILES = console.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
$(PGM): $(OBJS)
$(make-rel)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
all-local: $(ARCH) $(OBJS) $(PGM)
.PRECIOUS: $(PGM)
EXTRA_DIST = console.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,484 @@
/*
* console.c
*
* This file contains the MBX8xx termios serial I/O package.
* Only asynchronous I/O is supported.
*
* The SCCs and SMCs are assigned as follows
*
* Channel Device Minor Note
* SMC1 /dev/tty0 0
* SMC2 /dev/tty1 1
* SCC1 2 N/A. Hardwired as ethernet port
* SCC2 /dev/tty2 3
* SCC3 /dev/tty3 4
* SCC4 /dev/tty4 5
*
* All ports support termios. All I/O is interrupt-driven, unless EPPCBug
* is used to do the I/O. To use EPPCBug, define the EPPCBUG_SMC1
* manifest constant in the configuration file (mbx8xx.cfg). EPPCBug I/O
* is currently limited to the EPPCBug debug console. This is a limitation
* of firmware revision 1.1. Later firmware should be able to do I/O
* through any port.This code assumes that the EPPCBug console is the
* default: SMC1.
*
* TO RUN THE TESTS, USE POLLED I/O THROUGH EPPCBUG. Some tests play with
* the interrupt masks and turn off I/O. Those tests will hang with when
* interrupt-driven I/O is used.
*
* Set CONSOLE_MINOR to the appropriate device minor number in the
* config file. This allows the RTEMS application console to be different
* from the EPPBug debug console or the GDB stup I/O port.
*
* This driver handles all five available serial ports: it distinguishes
* the sub-devices using minor device numbers. It is not possible to have
* other protocols running on the other ports when this driver is used as
* currently written.
*
* Based on code (alloc860.c in eth_comm port) by
* Jay Monkman (jmonkman@frasca.com),
* Copyright (C) 1998 by Frasca International, Inc.
*
* Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
* and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>.
* Copyright (c) 1999, National Research Council of Canada
*
*/
#include <stdarg.h>
#include <stdio.h>
#include <bsp.h> /* Must be before libio.h */
#include <rtems/libio.h>
#include <termios.h>
static int _EPPCBug_pollRead( int minor );
static int _EPPCBug_pollWrite( int minor, const char *buf, int len );
/*
* _EPPCBug_pollRead
*
* Read a character from the EPPCBug console, and return it. Return -1
* if there is no character in the input FIFO.
*
* Input parameters:
* minor - selected channel
*
* Output parameters: NONE
*
* Return value: char returned as positive signed int
* -1 if no character is present in the input FIFO.
*/
int _EPPCBug_pollRead(
int minor
)
{
extern volatile m8xx_t m8xx;
char c;
volatile int simask; /* We must read and write m8xx.simask */
int retval;
ISR_Level level;
struct {
int clun;
int dlun;
char * inbuf;
int nbytes_requested;
int reserved;
} volatile input_params;
struct {
int status;
union {
struct {
int input_char_available;
int output_possible;
int break_detected;
int modem_status;
} stat;
struct {
int nbytes_received;
} read;
} u;
} volatile output_params;
retval = -1;
/* Input through EPPCBug console */
input_params.clun = 0;
input_params.dlun = 0;
input_params.reserved = 0;
_ISR_Disable( level );
simask = m8xx.simask;
/* Check for a char in the input FIFO using .CIO_STAT */
asm volatile( "li 10,0x202
mr 3, %0
mr 4, %1
sc"
:: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
if ( (output_params.status == 0) && output_params.u.stat.input_char_available) {
/* Read the char and return it */
input_params.inbuf = &c;
input_params.nbytes_requested = 1;
asm volatile( "li 10,0x200 /* Code for .CIO_READ */
mr 3, %0 /* Address of input_params */
mr 4, %1 /* Address of output_params */
sc" /* Call EPPCBUG */
:: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
if ( (output_params.status == 0) && output_params.u.read.nbytes_received)
retval = (int)c;
}
m8xx.simask = simask;
_ISR_Enable( level );
return retval;
}
/*
* _EPPCBug_pollWrite
*
* Output buffer through EPPCBug. Returns only once every character has been
* sent (polled output).
*
* Input parameters:
* minor - selected channel
* buf - output buffer
* len - number of chars to output
*
* Output parameters: NONE
*
* Return value: IGNORED
*/
int _EPPCBug_pollWrite(
int minor,
const char *buf,
int len
)
{
extern volatile m8xx_t m8xx;
volatile int simask;
int i, retval;
ISR_Level level;
struct {
int clun;
int dlun;
const char * outbuf;
int nbytes_to_output;
int reserved;
} volatile input_params;
struct {
int status;
union {
struct {
int input_char_available;
int output_possible;
int break_detected;
int modem_status;
} stat;
struct {
int nbytes_sent;
} write;
} u;
} volatile output_params;
retval = -1;
/* Output through EPPCBug console */
input_params.clun = 0;
input_params.dlun = 0;
input_params.reserved = 0;
i = 0;
_ISR_Disable( level );
simask = m8xx.simask;
while (i < len) {
/* Wait for space in the output buffer */
do {
/* Check for space in the output FIFO */
asm volatile( "li 10,0x202 /* Code for .CIO_STAT */
mr 3, %0 /* Address of input_params */
mr 4, %1 /* Address of output_params */
sc" /* Call EPPCBUG */
:: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
if (output_params.status)
goto error;
} while (!output_params.u.stat.output_possible);
/* Output the characters until done */
input_params.outbuf = &buf[i];
input_params.nbytes_to_output = len - i;
asm volatile( "li 10,0x201 /* Code for .CIO_WRITE */
mr 3, %0 /* Address of input_params */
mr 4, %1 /* Address of output_params */
sc" /* Call EPPCBUG */
:: "g" (&input_params), "g" (&output_params) : "3", "4", "10" );
if (output_params.status)
goto error;
i += output_params.u.write.nbytes_sent;
}
/* Return something */
m8xx.simask = simask;
_ISR_Enable( level );
return RTEMS_SUCCESSFUL;
error:
m8xx.simask = simask;
_ISR_Enable( level );
return -1;
}
/*
* Print functions: prototyped in bsp.h
* Debug printing on Channel 1
*/
void printk( char *fmt, ... )
{
va_list ap; /* points to each unnamed argument in turn */
static char buf[256];
unsigned int level;
_CPU_ISR_Disable(level);
va_start(ap, fmt); /* make ap point to 1st unnamed arg */
vsprintf(buf, fmt, ap); /* send output to buffer */
BSP_output_string(buf); /* print buffer -- Channel 1 */
va_end(ap); /* clean up and re-enable interrupts */
_CPU_ISR_Enable(level);
}
void BSP_output_string( char * buf )
{
int len = strlen(buf);
int minor; /* will be ignored */
rtems_status_code sc;
sc = _EPPCBug_pollWrite(minor, buf, len);
if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc);
}
/*
***************
* BOILERPLATE *
***************
*
* All these functions are prototyped in rtems/c/src/lib/include/console.h.
*/
/*
* Initialize and register the device
*/
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 common initialization.
*/
m8xx_uart_initialize();
/*
* Do device-specific initialization
*/
#ifndef EPPCBUG_SMC1
m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty0 */
#endif /* EPPCBUG_SMC1 */
m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty1 */
m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty2 */
#ifdef mpc860
m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty3 */
m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty4 */
#endif /* mpc860 */
/*
* Set up interrupts
*/
m8xx_uart_interrupts_initialize();
status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/tty1", major, SMC2_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/tty2", major, SCC2_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
#ifdef mpc860
status = rtems_io_register_name ("/dev/tty3", major, SCC3_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
status = rtems_io_register_name ("/dev/tty4", major, SCC4_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
#endif /* mpc860 */
/* Now register the RTEMS console */
status = rtems_io_register_name ("/dev/console", major, CONSOLE_MINOR);
if (status != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (status);
return RTEMS_SUCCESSFUL;
}
/*
* Open the device
*/
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
/* Used to track termios private data for callbacks */
extern struct rtems_termios_tty *ttyp[];
volatile m8xxSCCRegisters_t *sccregs;
rtems_status_code sc;
rtems_libio_open_close_args_t *args = arg;
#ifdef EPPCBUG_SMC1
static const rtems_termios_callbacks sccEPPCBugCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
_EPPCBug_pollRead, /* pollRead */
_EPPCBug_pollWrite, /* write */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
#endif
#ifdef UARTS_USE_INTERRUPTS
static const rtems_termios_callbacks intrCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
NULL, /* pollRead */
m8xx_uart_write, /* write */
m8xx_uart_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
1 /* outputUsesInterrupts */
};
#else
static const rtems_termios_callbacks pollCallbacks = {
NULL, /* firstOpen */
NULL, /* lastClose */
m8xx_uart_pollRead, /* pollRead */
m8xx_uart_pollWrite, /* write */
m8xx_uart_setAttributes, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* outputUsesInterrupts */
};
#endif
if ( (minor < SMC1_MINOR) || (minor > NUM_PORTS-1) )
return RTEMS_INVALID_NUMBER;
#ifdef EPPCBUG_SMC1
if (minor == SMC1_MINOR)
return rtems_termios_open (major, minor, arg, &sccEPPCBugCallbacks);
#endif /* EPPCBUG_SMC1 */
#ifdef UARTS_USE_INTERRUPTS
sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */
#else
sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
#endif
return sc;
}
/*
* Close the device
*/
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_close (arg);
}
/*
* Read from the device
*/
rtems_device_driver console_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_read(arg);
}
/*
* Write to the device
*/
rtems_device_driver console_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
)
{
return rtems_termios_write(arg);
}
/*
* 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);
}

View File

@@ -0,0 +1,23 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = bsp.h coverhd.h
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/bsp.h: bsp.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/coverhd.h: coverhd.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES += $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/bsp.h \
$(PROJECT_INCLUDE)/coverhd.h
all-local: $(PREINSTALL_FILES)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,121 @@
/* bsp.h
*
* This include file contains all board IO definitions.
*
* This file includes definitions for the MBX860 and MBX821.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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$
*/
#ifndef __MBX8xx_h
#define __MBX8xx_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems.h>
#include <console.h>
#include <clockdrv.h>
#include <mpc8xx.h>
#include <mpc8xx/cpm.h>
#include <mpc8xx/mmu.h>
#include <mpc8xx/console.h>
/*
* Network driver configuration
*/
struct rtems_bsdnet_ifconfig;
extern int rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config);
#define RTEMS_BSP_NETWORK_DRIVER_NAME "scc1"
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_enet_driver_attach
/*
* We need to decide how much memory will be non-cacheable. This
* will mainly be memory that will be used in DMA (network and serial
* buffers).
*/
#define NOCACHE_MEM_SIZE 512*1024
/*
* Define the time limits for RTEMS Test Suite test durations.
* Long test and short test duration limits are provided. These
* values are in seconds and need to be converted to ticks for the
* application.
*
*/
#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
/*
* Stuff for Time Test 27
*/
#define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) set_vector( (handler), 0, 1 )
#define Cause_tm27_intr()
#define Clear_tm27_intr()
#define Lower_tm27_intr()
/* Constants -- THESE SHOULD BE DEFINED IN THE LINKER SCRIPT */
#define RAM_START 0
#define RAM_END 0x100000
/* miscellaneous stuff assumed to exist */
extern rtems_configuration_table BSP_Configuration;
/*
* Device Driver Table Entries
*/
/*
* NOTE: Use the standard Console driver entry
*/
/*
* NOTE: Use the standard Clock driver entry
*/
/*
* How many libio files we want
*/
#define BSP_LIBIO_MAX_FDS 20
/* functions */
void bsp_cleanup( void );
rtems_isr_entry set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
);
/*
* Debug print functions: implemented in console.c
*/
void printk( char *fmt, ... );
void BSP_output_string( char * buf );
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,366 @@
/* coverhd.h
*
* This include file has defines to represent the overhead associated
* with calling a particular directive from C. These are used in the
* Timing Test Suite to ignore the overhead required to pass arguments
* to directives. On some CPUs and/or target boards, this overhead
* is significant and makes it difficult to distinguish internal
* RTEMS execution time from that used to call the directive.
* This file should be updated after running the C overhead timing
* test. Once this update has been performed, the RTEMS Time Test
* Suite should be rebuilt to account for these overhead times in the
* timing results.
*
* NOTE: If these are all zero, then the times reported include
* all calling overhead including passing of arguments.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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$
*/
#ifndef __COVERHD_h
#define __COVERHD_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/targopts.h>
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
#if defined( INSTRUCTION_CACHE_ENABLE )
/*
* 50 MHz processor, cache enabled.
*/
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0
#define CALLING_OVERHEAD_TASK_CREATE 1
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 1
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 1
#define CALLING_OVERHEAD_CLOCK_SET 1
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 1
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 1
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 1
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 0
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#else
/*
* 50 MHz processor, cache disabled.
*/
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 4
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 4
#define CALLING_OVERHEAD_TASK_CREATE 7
#define CALLING_OVERHEAD_TASK_IDENT 6
#define CALLING_OVERHEAD_TASK_START 5
#define CALLING_OVERHEAD_TASK_RESTART 5
#define CALLING_OVERHEAD_TASK_DELETE 4
#define CALLING_OVERHEAD_TASK_SUSPEND 4
#define CALLING_OVERHEAD_TASK_RESUME 4
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 5
#define CALLING_OVERHEAD_TASK_MODE 5
#define CALLING_OVERHEAD_TASK_GET_NOTE 5
#define CALLING_OVERHEAD_TASK_SET_NOTE 5
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 19
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 4
#define CALLING_OVERHEAD_INTERRUPT_CATCH 5
#define CALLING_OVERHEAD_CLOCK_GET 20
#define CALLING_OVERHEAD_CLOCK_SET 19
#define CALLING_OVERHEAD_CLOCK_TICK 3
#define CALLING_OVERHEAD_TIMER_CREATE 5
#define CALLING_OVERHEAD_TIMER_IDENT 4
#define CALLING_OVERHEAD_TIMER_DELETE 5
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 6
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 21
#define CALLING_OVERHEAD_TIMER_RESET 4
#define CALLING_OVERHEAD_TIMER_CANCEL 4
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 6
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 4
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 6
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 5
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 4
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 6
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 6
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 4
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 6
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 5
#define CALLING_OVERHEAD_EVENT_SEND 5
#define CALLING_OVERHEAD_EVENT_RECEIVE 5
#define CALLING_OVERHEAD_SIGNAL_CATCH 4
#define CALLING_OVERHEAD_SIGNAL_SEND 5
#define CALLING_OVERHEAD_PARTITION_CREATE 7
#define CALLING_OVERHEAD_PARTITION_IDENT 6
#define CALLING_OVERHEAD_PARTITION_DELETE 4
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 5
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 5
#define CALLING_OVERHEAD_REGION_CREATE 7
#define CALLING_OVERHEAD_REGION_IDENT 5
#define CALLING_OVERHEAD_REGION_DELETE 4
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 6
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 5
#define CALLING_OVERHEAD_PORT_CREATE 6
#define CALLING_OVERHEAD_PORT_IDENT 5
#define CALLING_OVERHEAD_PORT_DELETE 4
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 6
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 6
#define CALLING_OVERHEAD_IO_INITIALIZE 6
#define CALLING_OVERHEAD_IO_OPEN 6
#define CALLING_OVERHEAD_IO_CLOSE 6
#define CALLING_OVERHEAD_IO_READ 6
#define CALLING_OVERHEAD_IO_WRITE 6
#define CALLING_OVERHEAD_IO_CONTROL 6
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 4
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 5
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 5
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 4
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 4
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 5
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 3
#endif /* defined( INSTRUCTION_CACHE_ENABLE ) */
#else
#if defined( INSTRUCTION_CACHE_ENABLE )
/*
* 40 MHz processor, cache enabled.
*/
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1
#define CALLING_OVERHEAD_TASK_CREATE 1
#define CALLING_OVERHEAD_TASK_IDENT 0
#define CALLING_OVERHEAD_TASK_START 0
#define CALLING_OVERHEAD_TASK_RESTART 0
#define CALLING_OVERHEAD_TASK_DELETE 0
#define CALLING_OVERHEAD_TASK_SUSPEND 0
#define CALLING_OVERHEAD_TASK_RESUME 0
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0
#define CALLING_OVERHEAD_TASK_MODE 0
#define CALLING_OVERHEAD_TASK_GET_NOTE 0
#define CALLING_OVERHEAD_TASK_SET_NOTE 0
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 1
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0
#define CALLING_OVERHEAD_INTERRUPT_CATCH 0
#define CALLING_OVERHEAD_CLOCK_GET 1
#define CALLING_OVERHEAD_CLOCK_SET 1
#define CALLING_OVERHEAD_CLOCK_TICK 0
#define CALLING_OVERHEAD_TIMER_CREATE 0
#define CALLING_OVERHEAD_TIMER_IDENT 0
#define CALLING_OVERHEAD_TIMER_DELETE 0
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 1
#define CALLING_OVERHEAD_TIMER_RESET 0
#define CALLING_OVERHEAD_TIMER_CANCEL 0
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0
#define CALLING_OVERHEAD_EVENT_SEND 0
#define CALLING_OVERHEAD_EVENT_RECEIVE 0
#define CALLING_OVERHEAD_SIGNAL_CATCH 0
#define CALLING_OVERHEAD_SIGNAL_SEND 0
#define CALLING_OVERHEAD_PARTITION_CREATE 1
#define CALLING_OVERHEAD_PARTITION_IDENT 0
#define CALLING_OVERHEAD_PARTITION_DELETE 0
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0
#define CALLING_OVERHEAD_REGION_CREATE 1
#define CALLING_OVERHEAD_REGION_IDENT 0
#define CALLING_OVERHEAD_REGION_DELETE 0
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0
#define CALLING_OVERHEAD_PORT_CREATE 2
#define CALLING_OVERHEAD_PORT_IDENT 0
#define CALLING_OVERHEAD_PORT_DELETE 0
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
#define CALLING_OVERHEAD_IO_INITIALIZE 0
#define CALLING_OVERHEAD_IO_OPEN 0
#define CALLING_OVERHEAD_IO_CLOSE 0
#define CALLING_OVERHEAD_IO_READ 0
#define CALLING_OVERHEAD_IO_WRITE 0
#define CALLING_OVERHEAD_IO_CONTROL 0
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0
#else
/*
* 40 MHz processor, cache disabled.
*/
#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 4
#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 3
#define CALLING_OVERHEAD_TASK_CREATE 6
#define CALLING_OVERHEAD_TASK_IDENT 5
#define CALLING_OVERHEAD_TASK_START 5
#define CALLING_OVERHEAD_TASK_RESTART 4
#define CALLING_OVERHEAD_TASK_DELETE 4
#define CALLING_OVERHEAD_TASK_SUSPEND 4
#define CALLING_OVERHEAD_TASK_RESUME 4
#define CALLING_OVERHEAD_TASK_SET_PRIORITY 5
#define CALLING_OVERHEAD_TASK_MODE 4
#define CALLING_OVERHEAD_TASK_GET_NOTE 5
#define CALLING_OVERHEAD_TASK_SET_NOTE 5
#define CALLING_OVERHEAD_TASK_WAKE_WHEN 17
#define CALLING_OVERHEAD_TASK_WAKE_AFTER 3
#define CALLING_OVERHEAD_INTERRUPT_CATCH 5
#define CALLING_OVERHEAD_CLOCK_GET 17
#define CALLING_OVERHEAD_CLOCK_SET 17
#define CALLING_OVERHEAD_CLOCK_TICK 3
#define CALLING_OVERHEAD_TIMER_CREATE 4
#define CALLING_OVERHEAD_TIMER_IDENT 4
#define CALLING_OVERHEAD_TIMER_DELETE 5
#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 5
#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 19
#define CALLING_OVERHEAD_TIMER_RESET 4
#define CALLING_OVERHEAD_TIMER_CANCEL 4
#define CALLING_OVERHEAD_SEMAPHORE_CREATE 6
#define CALLING_OVERHEAD_SEMAPHORE_IDENT 4
#define CALLING_OVERHEAD_SEMAPHORE_DELETE 5
#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 5
#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 4
#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 4
#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 4
#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 4
#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 5
#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 4
#define CALLING_OVERHEAD_EVENT_SEND 5
#define CALLING_OVERHEAD_EVENT_RECEIVE 5
#define CALLING_OVERHEAD_SIGNAL_CATCH 4
#define CALLING_OVERHEAD_SIGNAL_SEND 4
#define CALLING_OVERHEAD_PARTITION_CREATE 6
#define CALLING_OVERHEAD_PARTITION_IDENT 5
#define CALLING_OVERHEAD_PARTITION_DELETE 4
#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 5
#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 5
#define CALLING_OVERHEAD_REGION_CREATE 6
#define CALLING_OVERHEAD_REGION_IDENT 5
#define CALLING_OVERHEAD_REGION_DELETE 4
#define CALLING_OVERHEAD_REGION_GET_SEGMENT 6
#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 5
#define CALLING_OVERHEAD_PORT_CREATE 6
#define CALLING_OVERHEAD_PORT_IDENT 5
#define CALLING_OVERHEAD_PORT_DELETE 4
#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 5
#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 5
#define CALLING_OVERHEAD_IO_INITIALIZE 5
#define CALLING_OVERHEAD_IO_OPEN 5
#define CALLING_OVERHEAD_IO_CLOSE 5
#define CALLING_OVERHEAD_IO_READ 5
#define CALLING_OVERHEAD_IO_WRITE 5
#define CALLING_OVERHEAD_IO_CONTROL 5
#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 3
#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 4
#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 5
#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 4
#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 4
#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 4
#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 3
#endif /* defined( INSTRUCTION_CACHE_ENABLE ) */
#endif
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,36 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/network.rel
C_FILES = network.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
AM_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
$(PGM): $(OBJS)
$(make-rel)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
if HAS_NETWORKING
all-local: $(ARCH) $(OBJS) $(PGM)
endif
.PRECIOUS: $(PGM)
EXTRA_DIST = network.c
include $(top_srcdir)/../../../../../../automake/local.am

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
VPATH = @srcdir@:@srcdir@/../../../shared
PGM = $(ARCH)/startup.rel
C_FILES = bspclean.c bsplibc.c bsppost.c bspstart.c bootcard.c imbx8xx.c main.c \
mmutlbtab.c sbrk.c setvec.c gnatinstallhandler.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
S_FILES = start.s
S_O_FILES = $(S_FILES:%.s=$(ARCH)/%.o)
OBJS = $(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 +=
#
$(PGM): $(OBJS)
$(make-rel)
$(PROJECT_RELEASE)/lib/linkcmds: linkcmds
$(INSTALL_DATA) $< $@
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/linkcmds
all-local: $(ARCH) $(OBJS) $(PGM) $(TMPINSTALL_FILES)
.PRECIOUS: $(PGM)
EXTRA_DIST = bspstart.c imbx8xx.c linkcmds mmutlbtab.c setvec.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,193 @@
/* bspstart.c
*
* This set of routines starts the application. 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) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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.
*
* Modifications for MBX860:
* Copyright (c) 1999, National Research Council of Canada
*
* $Id$
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <libcsupport.h>
#include <string.h>
#ifdef STACK_CHECKER_ON
#include <stackchk.h>
#endif
/*
* The original table from the application (in ROM) and our copy of it with
* some changes. Configuration is defined in <confdefs.h>. Make sure that
* our configuration tables are uninitialized so that they get allocated in
* the .bss section (RAM).
*/
extern rtems_configuration_table Configuration;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
char *rtems_progname;
/*
* Use the shared implementations of the following routines.
* Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
* rtems/c/src/lib/libbsp/shared/bsplibc.c.
*/
void bsp_postdriver_hook(void);
void bsp_libc_init( void *, unsigned32, int );
/*
* bsp_pretasking_hook
*
* Called when RTEMS initialization is complete but before interrupts and
* tasking are enabled. Used to setup libc and install any BSP extensions.
*
* Must not use libc (to do io) from here, since drivers are not yet
* initialized.
*
* Installed in the rtems_cpu_table defined in
* rtems/c/src/exec/score/cpu/m68k/cpu.h in main() below. Called from
* rtems_initialize_executive() defined in rtems/c/src/exec/sapi/src/init.c
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values: NONE
*/
void bsp_pretasking_hook(void)
{
/*
* These are assigned addresses in the linkcmds file for the BSP. This
* approach is better than having these defined as manifest constants and
* compiled into the kernel, but it is still not ideal when dealing with
* multiprocessor configuration in which each board as a different memory
* map. A better place for defining these symbols might be the makefiles.
* Consideration should also be given to developing an approach in which
* the kernel and the application can be linked and burned into ROM
* independently of each other.
*/
extern unsigned char _HeapStart;
extern unsigned char _HeapEnd;
bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
#ifdef STACK_CHECKER_ON
/*
* Initialize the stack bounds checker
* We can either turn it on here or from the app.
*/
Stack_check_Initialize();
#endif /* STACK_CHECKER_ON */
#ifdef RTEMS_DEBUG
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
#endif
}
/*
* bsp_start()
*
* Board-specific initialization code. Called from the generic boot_card()
* function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
* does some of the board independent initialization. It is called from the
* MBX8xx entry point _start() defined in
* rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
*
* _start() has set up a stack, has zeroed the .bss section, has turned off
* interrupts, and placed the processor in the supervisor mode. boot_card()
* has left the processor in that state when bsp_start() was called.
*
* RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
* ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
* ADDRESSES. Software-controlled address translation would be required
* otherwise.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values: NONE
*/
void bsp_start(void)
{
extern void *_WorkspaceBase;
mmu_init();
/*
* Enable instruction and data caches. Do not force writethrough mode.
*/
#ifdef INSTRUCTION_CACHE_ENABLE
rtems_enable_inst_cache();
#endif
#ifdef DATA_CACHE_ENABLE
rtems_enable_data_cache();
#endif
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
* RTEMS world (e.g. simulator or primitive memory manager), or (as
* typically done by stock BSPs) by subtracting the required amount
* of work space from the last physical address on the CPU board.
*
* In this case, the memory is not malloc'ed. It is just
* "pulled from the air".
*/
BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
/*
* initialize the CPU table for this BSP
*/
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
if( Cpu_table.interrupt_stack_size < 4 * 1024 )
Cpu_table.interrupt_stack_size = 4 * 1024;
Cpu_table.clicks_per_usec = 1; /* for 4MHz extclk */
Cpu_table.serial_per_sec = 10000000;
Cpu_table.serial_external_clock = 1;
Cpu_table.serial_xon_xoff = 0;
Cpu_table.serial_cts_rts = 1;
Cpu_table.serial_rate = 9600;
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
Cpu_table.clock_speed = 50000000;
Cpu_table.timer_average_overhead = 3;
Cpu_table.timer_least_valid = 3;
#else
Cpu_table.clock_speed = 40000000;
Cpu_table.timer_average_overhead = 3;
Cpu_table.timer_least_valid = 3;
#endif
/*
* Call this in case we use TERMIOS for console I/O
*/
m8xx_uart_reserve_resources( &BSP_Configuration );
m8xx.scc2.sccm=0;
m8xx.scc2p.rbase=0;
m8xx.scc2p.tbase=0;
m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
}

View File

@@ -0,0 +1,202 @@
/* bspstart.c
*
* This set of routines starts the application. 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) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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.
*
* Modifications for MBX860:
* Copyright (c) 1999, National Research Council of Canada
*
* $Id$
*/
#include <bsp.h>
#include <rtems/libio.h>
#include <libcsupport.h>
#include <string.h>
#ifdef STACK_CHECKER_ON
#include <stackchk.h>
#endif
/*
* The original table from the application (in ROM) and our copy of it with
* some changes. Configuration is defined in <confdefs.h>. Make sure that
* our configuration tables are uninitialized so that they get allocated in
* the .bss section (RAM).
*/
extern rtems_configuration_table Configuration;
rtems_configuration_table BSP_Configuration;
rtems_cpu_table Cpu_table;
char *rtems_progname;
/*
* Use the shared implementations of the following routines.
* Look in rtems/c/src/lib/libbsp/shared/bsppost.c and
* rtems/c/src/lib/libbsp/shared/bsplibc.c.
*/
void bsp_postdriver_hook(void);
void bsp_libc_init( void *, unsigned32, int );
/*
* bsp_pretasking_hook
*
* Called when RTEMS initialization is complete but before interrupts and
* tasking are enabled. Used to setup libc and install any BSP extensions.
*
* Must not use libc (to do io) from here, since drivers are not yet
* initialized.
*
* Installed in the rtems_cpu_table defined in
* rtems/c/src/exec/score/cpu/m68k/cpu.h in main() below. Called from
* rtems_initialize_executive() defined in rtems/c/src/exec/sapi/src/init.c
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values: NONE
*/
void bsp_pretasking_hook(void)
{
/*
* These are assigned addresses in the linkcmds file for the BSP. This
* approach is better than having these defined as manifest constants and
* compiled into the kernel, but it is still not ideal when dealing with
* multiprocessor configuration in which each board as a different memory
* map. A better place for defining these symbols might be the makefiles.
* Consideration should also be given to developing an approach in which
* the kernel and the application can be linked and burned into ROM
* independently of each other.
*/
extern unsigned char _HeapStart;
extern unsigned char _HeapEnd;
bsp_libc_init( &_HeapStart, &_HeapEnd - &_HeapStart, 0 );
#ifdef STACK_CHECKER_ON
/*
* Initialize the stack bounds checker
* We can either turn it on here or from the app.
*/
Stack_check_Initialize();
#endif /* STACK_CHECKER_ON */
#ifdef RTEMS_DEBUG
rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
#endif
}
/*
* bsp_start()
*
* Board-specific initialization code. Called from the generic boot_card()
* function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
* does some of the board independent initialization. It is called from the
* MBX8xx entry point _start() defined in
* rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
*
* _start() has set up a stack, has zeroed the .bss section, has turned off
* interrupts, and placed the processor in the supervisor mode. boot_card()
* has left the processor in that state when bsp_start() was called.
*
* RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
* ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
* ADDRESSES. Software-controlled address translation would be required
* otherwise.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values: NONE
*/
void bsp_start(void)
{
extern void *_WorkspaceBase;
unsigned32 r1;
mmu_init();
/*
* Enable instruction and data caches. Do not force writethrough mode.
*/
#ifdef INSTRUCTION_CACHE_ENABLE
r1 = M8xx_CACHE_CMD_ENABLE;
_mtspr( M8xx_IC_CST, r1 );
_isync;
#endif
/*
* Warning: EPPCBug 1.1 chokes to death if the data cache is turned on.
* Set DATA_CACHE_ENABLE to zero in mbx8xx.cfg if EPPCBUG is used.
*/
#ifdef DATA_CACHE_ENABLE
r1 = M8xx_CACHE_CMD_ENABLE;
_mtspr( M8xx_DC_CST, r1 );
_isync;
#endif
/*
* Allocate the memory for the RTEMS Work Space. This can come from
* a variety of places: hard coded address, malloc'ed from outside
* RTEMS world (e.g. simulator or primitive memory manager), or (as
* typically done by stock BSPs) by subtracting the required amount
* of work space from the last physical address on the CPU board.
*
* In this case, the memory is not malloc'ed. It is just
* "pulled from the air".
*/
BSP_Configuration.work_space_start = (void *)&_WorkspaceBase;
/*
* initialize the CPU table for this BSP
*/
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
Cpu_table.postdriver_hook = bsp_postdriver_hook;
if( Cpu_table.interrupt_stack_size < 4 * 1024 )
Cpu_table.interrupt_stack_size = 4 * 1024;
Cpu_table.clicks_per_usec = 1; /* for 4MHz extclk */
Cpu_table.serial_per_sec = 10000000;
Cpu_table.serial_external_clock = 1;
Cpu_table.serial_xon_xoff = 0;
Cpu_table.serial_cts_rts = 1;
Cpu_table.serial_rate = 9600;
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
Cpu_table.clock_speed = 50000000;
Cpu_table.timer_average_overhead = 3;
Cpu_table.timer_least_valid = 3;
#else
Cpu_table.clock_speed = 40000000;
Cpu_table.timer_average_overhead = 3;
Cpu_table.timer_least_valid = 3;
#endif
/*
* Call this in case we use TERMIOS for console I/O
*/
m8xx_uart_reserve_resources( &BSP_Configuration );
m8xx.scc2.sccm=0;
m8xx.scc2p.rbase=0;
m8xx.scc2p.tbase=0;
m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );
}

View File

@@ -0,0 +1,535 @@
/*
* imbx8xx.c
*
* MBX860/MBX821 initialization routines.
*
* Copyright (c) 1999, National Research Council of Canada
*
* 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 <bsp.h>
/*
* EPPCBug rev 1.1 is stupid. It clears the interrupt mask register
* in the SIU when it takes control, but does not restore it before
* returning control to the program. We thus keep a copy of the
* register, and restore it from gdb using the hook facilities.
*
* We arrange for simask_copy to be initialized to zero so that
* it resides in the .data section. This avoids having gdb set
* the mask to crud before we get to initialize explicitly. Of
* course, the code will not be safely restartable, but then again,
* a lot of the library code isn't either, so there!
*/
unsigned32 simask_copy = 0;
/*
* The memory controller's UPMA Ram array values.
* The values in table 2-6 and 2-7 in the "MBX Series Embedded
* Controller Programmer's Reference Guide", part number MBXA/PG2,
* differ from the ones in the older MBX Programmer's Guide, part
* number MBXA/PG1. We are assuming that the values in MBXA/PG1
* are for the older MBX boards whose part number does not have
* the "B" suffix, but we have discovered that the values from
* MBXA/PG2 work better, even for the older boards.
*
* THESE VALUES HAVE ONLY BEEN VERIFIED FOR THE MBX821-001 and
* MBX860-002. USE WITH CARE!
*
* NOTE: The MBXA/PG2 manual lists the clock speed of the MBX821_001B
* as being 50 MHz, while the MBXA/IH2.1 manual lists it as 40 MHz.
* We think the MBX821_001B is an entry level board and thus is 50 MHz,
*/
static unsigned32 upmaTable[64] = {
#if ( defined(mbx860_001b) || \
defined(mbx821_001b) || \
defined(mbx821_001) )
/* 50 MHz MBX */
/*
* Note: For the mbx821_001, the following values (from the
* MBXA/PG2 manual) work better than, but are different
* from those published in the original MBXA/PG1 manual and
* initialized by EPPCBug 1.1. In particular, the original
* burst-write values do not work! Also, the following values
* facilitate higher performance.
*/
/* DRAM 60ns - single read. (offset 0x00 in UPM RAM) */
0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
/* DRAM 60ns - burst read. (offset 0x08 in UPM RAM) */
0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x00AF0C04,
0x07AF0C08, 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08,
0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08, 0x0CAF0C04,
0x10AF0C04, 0xF0AFC000, 0xF3BF4805, 0xFFFFC005,
/* DRAM 60ns - single write. (offset 0x18 in UPM RAM) */
0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* DRAM 60ns - burst write. (offset 0x20 in UPM RAM) */
0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* Refresh 60ns. (offset 0x30 in UPM RAM) */
0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* Exception. (offset 0x3c in UPM RAM) */
0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007
#elif ( defined(mbx860_002b) || \
defined(mbx860_003b) || \
defined(mbx860_004b) || \
defined(mbx860_005b) || \
defined(mbx860_006b) || \
defined(mbx821_002b) || \
defined(mbx821_003b) || \
defined(mbx821_004b) || \
defined(mbx821_005b) || \
defined(mbx821_006b) || \
defined(mbx860_001) || \
defined(mbx860_002) || \
defined(mbx860_003) || \
defined(mbx860_004) || \
defined(mbx860_005) || \
defined(mbx821_002) || \
defined(mbx821_003) || \
defined(mbx821_004) || \
defined(mbx821_005) )
/* 40 MHz MBX */
/*
* Note: For the older MBX models (i.e. without the "b"
* suffix, e.g. mbx860_001), the following values (from the
* MBXA/PG2 manual) work better than, but are different
* from those published in the original MBXA/PG1 manual and
* initialized by EPPCBug 1.1. In particular, the following
* burst-read and burst-write values facilitate higher
* performance.
*/
/* DRAM 60ns - single read. (offset 0x00 in UPM RAM) */
0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* DRAM 60ns - burst read. (offset 0x08 in UPM RAM) */
0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* DRAM 60ns - single write. (offset 0x18 in UPM RAM) */
0xCFFF0004, 0x0FFF4004, 0x0CFF0C00, 0x33FF4804,
0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* DRAM 60ns - burst write. (offset 0x20 in UPM RAM) */
0xCFFF0004, 0x0FFF4004, 0x0CFF0C00, 0x03FF0C0C,
0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* Refresh 60ns. (offset 0x30 in UPM RAM) */
0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
/* Exception. (offset 0x3c in UPM RAM) */
0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007
#else
#error "MBX board model not specified."
#endif
};
/*
* Initialize MBX8xx
*/
void _InitMBX8xx (void)
{
register unsigned32 r1, i;
extern unsigned32 simask_copy;
/*
* Get the SIU interrupt mask.
*/
simask_copy = m8xx.simask;
/*
* Initialize the Debug Enable Register (DER) to an appropriate
* value for EPPCBug debugging.
* (This value should also work for BDM debugging.)
*/
r1 = 0x70C67C07; /* All except EXTIE, ALIE, DECIE */
_mtspr( M8xx_DER, r1 );
/*
* Initialize the Instruction Support Control Register (ICTRL) to a
* an appropriate value for normal operation. A different value,
* such as 0x0, may be more appropriate for debugging.
*/
r1 = 0x00000007;
_mtspr( M8xx_ICTRL, r1 );
/*
* Disable and invalidate the instruction and data caches.
*/
r1 = M8xx_CACHE_CMD_DISABLE;
_mtspr( M8xx_IC_CST, r1 );
_isync;
r1 = M8xx_CACHE_CMD_UNLOCKALL;
_mtspr( M8xx_IC_CST, r1 );
_isync;
r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
_mtspr( M8xx_IC_CST, r1 );
_isync;
r1 = M8xx_CACHE_CMD_DISABLE;
_mtspr( M8xx_DC_CST, r1 );
_isync;
r1 = M8xx_CACHE_CMD_UNLOCKALL;
_mtspr( M8xx_DC_CST, r1 );
_isync;
r1 = M8xx_CACHE_CMD_INVALIDATE; /* invalidate all */
_mtspr( M8xx_DC_CST, r1 );
_isync;
/*
* Initialize the Internal Memory Map Register (IMMR)
*
* Use the value in MBXA/PG2, which is also the value that EPPC-Bug
* programmed into our boards. The alternative is the value in
* MBXA/PG1: 0xFFA00000. This value might well depend on the revision
* of the firmware.
*
* THIS VALUE IS ALSO DECLARED IN THE linkcmds FILE and mmutlbtab.c!
*/
r1 = 0xFA200000;
_mtspr( M8xx_IMMR, r1 );
/*
* Initialize the SIU Module Configuration Register (SIUMCR)
* m8xx.siumcr = 0x00602900, the default MBX and firmware value.
*/
m8xx.siumcr = M8xx_SIUMCR_EARP0 | M8xx_SIUMCR_DBGC3 | M8xx_SIUMCR_DBPC0 |
M8xx_SIUMCR_DPC | M8xx_SIUMCR_MLRC2 | M8xx_SIUMCR_SEME;
/*
* Initialize the System Protection Control Register (SYPCR).
* The SYPCR can only be written once after Reset.
* - Enable bus monitor
* - Disable software watchdog timer
* m8xx.sypcr = 0xFFFFFF88, the default MBX and firmware value.
*/
m8xx.sypcr = M8xx_SYPCR_SWTC(0xFFFF) | M8xx_SYPCR_BMT(0xFF) |
M8xx_SYPCR_BME | M8xx_SYPCR_SWF;
/* Initialize the SIU Interrupt Edge Level Mask Register (SIEL) */
m8xx.siel = 0xAAAA0000; /* Default MBX and firmware value. */
/* Initialize the Transfer Error Status Register (TESR) */
m8xx.tesr = 0xFFFFFFFF; /* Default firmware value. */
/* Initialize the SDMA Configuration Register (SDCR) */
m8xx.sdcr = 0x00000001; /* Default firmware value. */
/*
* Initialize the Timebase Status and Control Register (TBSCR)
* m8xx.tbscr = 0x00C3, default MBX and firmware value.
*/
m8xx.tbscrk = M8xx_UNLOCK_KEY; /* unlock TBSCR */
m8xx.tbscr = M8xx_TBSCR_REFA | M8xx_TBSCR_REFB |
M8xx_TBSCR_TBF | M8xx_TBSCR_TBE;
/* Initialize the Real-Time Clock Status and Control Register (RTCSC) */
m8xx.rtcsk = M8xx_UNLOCK_KEY; /* unlock RTCSC */
m8xx.rtcsc = 0x00C3; /* Default MBX and firmware value. */
/* Unlock other Real-Time Clock registers */
m8xx.rtck = M8xx_UNLOCK_KEY; /* unlock RTC */
m8xx.rtseck = M8xx_UNLOCK_KEY; /* unlock RTSEC */
m8xx.rtcalk = M8xx_UNLOCK_KEY; /* unlock RTCAL */
/* Initialize the Periodic Interrupt Status and Control Register (PISCR) */
m8xx.piscrk = M8xx_UNLOCK_KEY; /* unlock PISCR */
m8xx.piscr = 0x0083; /* Default MBX and firmware value. */
/* Initialize the System Clock and Reset Control Register (SCCR)
* Set the clock sources and division factors:
* Timebase Source is GCLK2 / 16
* Real-Time Clock Select is EXTCLK (4.192MHz)
* Real-Time Clock Divide is /4
*/
m8xx.sccrk = M8xx_UNLOCK_KEY; /* unlock SCCR */
m8xx.sccr = 0x02800000; /* for MBX860/MBX821 */
/* Initialize the PLL, Low-Power, and Reset Control Register (PLPRCR) */
/* - set the clock speed and set normal power mode */
m8xx.plprck = M8xx_UNLOCK_KEY; /* unlock PLPRCR */
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
m8xx.plprcr = 0x5F500000;
#else
m8xx.plprcr = 0x4C400000;
#endif
/* Unlock the timebase and decrementer registers. */
m8xx.tbk = M8xx_UNLOCK_KEY;
/*
* Initialize decrementer register to a large value to
* guarantee that a decrementer interrupt will not be
* generated before the kernel is fully initialized.
*/
r1 = 0x7FFFFFFF;
_mtspr( M8xx_DEC, r1 );
/* Initialize the timebase register (TB is 64 bits) */
r1 = 0x00000000;
_mtspr( M8xx_TBU_WR, r1 );
_mtspr( M8xx_TBL_WR, r1 );
/*
* Memory Controller Initialization
*/
/*
* User Programmable Machine A (UPMA) Initialization
*
* If this initialization code is running from DRAM, it is very
* dangerous to change the value of any UPMA Ram array word from
* what the firmware (EPPCBug) initialized it to. Thus we don't
* initialize UPMA if EPPCBUG_VECTORS is defined; we assume EPPCBug
* has done the appropriate initialization.
*
* An exception to our rule, is that, for the older MBX boards
* (those without the "B" suffix, e.g. MBX821-001 and MBX860-002),
* we do re-initialize the burst-read and burst-write values with
* values that are more efficient. Also, in the MBX821 case,
* the burst-write original values set by EPPCBug do not work!
* This change can be done safely because the caches have not yet
* been activated.
*
* The RAM array of UPMA is initialized by writing to each of
* its 64 32-bit RAM locations.
* Note: UPM register initialization should occur before
* initialization of the corresponding BRx and ORx registers.
*/
#if ( !defined(EPPCBUG_VECTORS) )
for( i = 0; i < 64; ++i ) {
m8xx.mdr = upmaTable[i];
m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
}
#elif ( defined(mbx860_001) || \
defined(mbx860_002) || \
defined(mbx860_003) || \
defined(mbx860_004) || \
defined(mbx860_005) || \
defined(mbx821_001) || \
defined(mbx821_002) || \
defined(mbx821_003) || \
defined(mbx821_004) || \
defined(mbx821_005) )
/* Replace the burst-read and burst-write values with better ones. */
/* burst-read values */
for( i = 8; i < 24; ++i ) {
m8xx.mdr = upmaTable[i];
m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
}
/* burst-write values */
for( i = 32; i < 48; ++i ) {
m8xx.mdr = upmaTable[i];
m8xx.mcr = M8xx_MEMC_MCR_WRITE | M8xx_MEMC_MCR_UPMA | M8xx_MEMC_MCR_MAD(i);
}
#endif
#if ( !defined(EPPCBUG_VECTORS) )
/*
* Initialize the memory periodic timer.
* Memory Periodic Timer Prescaler Register (MPTPR: 16-bit register)
* m8xx.mptpr = 0x0200;
*/
m8xx.mptpr = M8xx_MPTPR_PTP(0x2);
/*
* Initialize the Machine A Mode Register (MAMR)
*
* ASSUMES THAT DIMMs ARE NOT INSTALLED!
*
* Without DIMMs:
* m8xx.mamr = 0x13821000 (40 MHz) or 0x18821000 (50 MHz).
*
* With DIMMs:
* m8xx.mamr = 0x06821000 (40 MHz) or 0x08821000 (50 MHz).
*/
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
m8xx.mamr = M8xx_MEMC_MMR_PTP(0x18) | M8xx_MEMC_MMR_PTE |
M8xx_MEMC_MMR_DSP(0x1) | M8xx_MEMC_MMR_G0CL(0) | M8xx_MEMC_MMR_UPWAIT;
#else
m8xx.mamr = M8xx_MEMC_MMR_PTP(0x13) | M8xx_MEMC_MMR_PTE |
M8xx_MEMC_MMR_DSP(0x1) | M8xx_MEMC_MMR_G0CL(0) | M8xx_MEMC_MMR_UPWAIT;
#endif
#endif /* ! defined(EPPCBUG_VECTORS) */
/*
* Initialize the Base and Option Registers (BR0-BR7 and OR0-OR7)
* Note: For all chip selects, ORx should be programmed before BRx,
* except when programming the boot chip select (CS0) after hardware
* reset, in which case, BR0 should be programmed before OR0.
*
* MPC860/MPX821 Memory Map Summary:
* S-ADDR E-ADDR CS PS PE WP MS BI V DESCRIPTION
* FE000000 FE7FFFFF 0 32 N N GPCM Y Y Soldered FLASH Memory
* 00000000 00zFFFFF 1 32 N N UPMA N Y Local DRAM Memory
* 00X00000 0XXXXXXX 2 0 N N UPMA N N DIMM Memory - Bank #0
* 00X00000 0XXXXXXX 3 0 N N UPMA N N DIMM Memory - Bank #1
* FA000000 FA1FFFFF 4 8 N N GPCM Y Y NVRAM & BCSR
* 80000000 DFFFFFFF 5 32 N N GPCM Y Y PCI/ISA I/O & Memory
* FA210000 FA21FFFF 6 32 N N GPCM Y Y QSpan Registers
* FC000000 FC7FFFFF 7 8 N N GPCM Y Y Socketed FLASH Memory
*
* z = 3 for 4MB installed on the motherboard, z = F for 16M
*
* NOTE: The devices selected by CS0 and CS7 can be selected with jumper J4.
* This table assumes that the 32-bit soldered flash device is the boot ROM.
*/
/*
* CS0 : Soldered (32-bit) Flash Memory at 0xFE000000
*
* CHANGE THIS CODE IF YOU CHANGE JUMPER J4 FROM ITS FACTORY DEFAULT SETTING!
* (or better yet, don't reprogram BR0 and OR0; just program BR7 and OR7 to
* access whatever flash device is not selected during hard reset.)
*
* MBXA/PG2 appears to lie in note 14 for table 2-4. The manual states that
* "EPPCBUG configures the reset flash device at the lower address, and the
* nonreset flash device at the higher address." If we take reset flash device
* to mean the boot flash memory, then the statement must mean that BR0 must
* point to the device at the lower address, i.e. 0xFC000000, while BR7 must
* point to the device at the highest address, i.e. 0xFE000000.
*
* THIS IS NOT THE CASE!
*
* The boot flash is always configured to start at 0xFE000000, and the other
* one to start at 0xFC000000. Changing jumper J4 only changes the width of
* the memory ports into these two region.
*
* BR0 = 0xFE000001
* Base addr [0-16] 0b11111110000000000 = 0xFE000000
* Address type [17-19] 0b000
* Port size [20-21] 0b00 = 32 bits
* Parity enable [22] 0b0 = disabled
* Write protect [23] 0b0 = r/w
* Machine select [24-25] 0b00 = GPCM
* Reserved [26-30] 0b00000
* Valid Bit [31] 0b1 = this bank is valid
* OR0 = 0xFF800930 @ 40 MHz, 0xFF800940 @ 50 MHz
* Address mask [0-16] 0b11111111100000000 = 0xFF800000
* Addr type mask [17-19] 0b000 = no address-type protection
* CS negation time [20] 0b1
* ACS [21-22] 0b00 = CS output at same time as address lines
* Burst inhibit [23] 0b1 = bank does not support burst accesses
* Cycle length [24-27] 0b0011/0b0100 = 3/4 clock cycle wait states
* SETA [28] 0b0 = TA generated internally
* Timing relaxed [29] 0b0 = not relaxed
* Extended hold time [30] 0b0 = not extended
* Reserved [31] 0b0
*
* m8xx.memc[0]._or = 0xFF800930 (40 MHz)
* m8xx.memc[0]._or = 0xFF800940 (50 MHz)
* m8xx.memc[0]._br = 0xFE000001
*/
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
m8xx.memc[0]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(4);
#else
m8xx.memc[0]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
#endif
m8xx.memc[0]._br = M8xx_BR_BA(0xFE000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
/*
* CS1 : Local DRAM Memory at 0x00000000
* m8xx.memc[1]._or = 0xFFC00400;
* m8xx.memc[1]._br = 0x00000081;
*/
m8xx.memc[1]._or = M8xx_MEMC_OR_4M | M8xx_MEMC_OR_ATM(0) |
M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
m8xx.memc[1]._br = M8xx_BR_BA(0x00000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
M8xx_BR_MS_UPMA | M8xx_MEMC_BR_V;
/*
* CS2 : DIMM Memory - Bank #0, not present
* m8xx.memc[2]._or = 0x00000400;
* m8xx.memc[2]._br = 0x00000080;
*/
m8xx.memc[2]._or = M8xx_MEMC_OR_ATM(0) |
M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
m8xx.memc[2]._br = M8xx_BR_AT(0) | M8xx_BR_PS32 |
M8xx_BR_MS_UPMA; /* ! M8xx_MEMC_BR_V */
/*
* CS3 : DIMM Memory - Bank #1, not present
* m8xx.memc[3]._or = 0x00000400;
* m8xx.memc[3]._br = 0x00000080;
*/
m8xx.memc[3]._or = M8xx_MEMC_OR_ATM(0) |
M8xx_MEMC_OR_ACS_QRTR | M8xx_MEMC_OR_SCY(0);
m8xx.memc[3]._br = M8xx_BR_AT(0) | M8xx_BR_PS32 |
M8xx_BR_MS_UPMA; /* ! M8xx_MEMC_BR_V */
/*
* CS4 : Battery-Backed SRAM at 0xFA000000
* m8xx.memc[4]._or = 0xFFE00920@ 40 MHz, 0xFFE00930 @ 50 MHz
* m8xx.memc[4]._br = 0xFA000401;
*/
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
m8xx.memc[4]._or = M8xx_MEMC_OR_2M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
#else
m8xx.memc[4]._or = M8xx_MEMC_OR_2M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(2);
#endif
m8xx.memc[4]._br = M8xx_BR_BA(0xFA000000) | M8xx_BR_AT(0) | M8xx_BR_PS8 |
M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
/*
* CS5 : PCI I/O and Memory at 0x80000000
* m8xx.memc[5]._or = 0xA0000108;
* m8xx.memc[5]._br = 0x80000001;
*/
m8xx.memc[5]._or = 0xA0000000 | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_ACS_NORM |
M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(0) | M8xx_MEMC_OR_SETA;
m8xx.memc[5]._br = M8xx_BR_BA(0x80000000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
/*
* CS6 : QSPAN Registers at 0xFA210000
* m8xx.memc[6]._or = 0xFFFF0108;
* m8xx.memc[6]._br = 0xFA210001;
*/
m8xx.memc[6]._or = M8xx_MEMC_OR_64K | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_ACS_NORM |
M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(0) | M8xx_MEMC_OR_SETA;
m8xx.memc[6]._br = M8xx_BR_BA(0xFA210000) | M8xx_BR_AT(0) | M8xx_BR_PS32 |
M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
/*
* CS7 : Socketed (8-bit) Flash at 0xFC000000
* m8xx.memc[7]._or = 0xFF800930 @ 40 MHz, 0xFF800940 @ 50 MHz
* m8xx.memc[7]._br = 0xFC000401;
*/
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
m8xx.memc[7]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(4);
#else
m8xx.memc[7]._or = M8xx_MEMC_OR_8M | M8xx_MEMC_OR_ATM(0) | M8xx_MEMC_OR_CSNT |
M8xx_MEMC_OR_ACS_NORM | M8xx_MEMC_OR_BI | M8xx_MEMC_OR_SCY(3);
#endif
m8xx.memc[7]._br = M8xx_BR_BA(0xFC000000) | M8xx_BR_AT(0) | M8xx_BR_PS8 |
M8xx_BR_MS_GPCM | M8xx_MEMC_BR_V;
}

View File

@@ -0,0 +1,259 @@
/*
* This file contains directives for the GNU linker that are specific
* to the MBX860-2 board.
*
* $Id$
*/
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
OUTPUT_ARCH(powerpc)
ENTRY(start)
/*
* Declare some sizes.
* XXX: The assignment of ". += XyzSize;" fails in older gld's if the
* number used there is not constant. If this happens to you, edit
* the lines marked XXX below to use a constant value.
*/
HeapSize = DEFINED(HeapSize) ? HeapSize : 0x100000; /* 1M Heap */
StackSize = DEFINED(StackSize) ? StackSize : 0x1000;
MEMORY
{
ram : org = 0x0, l = 4M
nvram : org = 0xfa000000, l = 32K
dpram : org = 0xfa200000, l = 16K
flash : org = 0xfc000000, l = 2M
immr : org = 0xfa200000, l = 16K
}
SECTIONS
{
/*
* If the vectors are specified statically rather than created at run time,
* accumulate them starting at VMA 0x0.
*/
.vectors :
{
*(.vectors)
} >ram
/*
* The stack will live in this area - between the vectors and
* the text section.
*/
.text 0x10000:
{
/* Read-only sections, merged into text segment: */
text.start = .;
/* Entry point is the .entry section */
*(.entry)
*(.entry2)
/* Actual code */
*(.text)
*(.text.*)
/* C++ constructors/destructors */
*(.gnu.linkonce.t*)
/* Initialization and finalization code.
*
* Various files can provide initialization and finalization functions.
* The bodies of these functions are in .init and .fini sections. We
* accumulate the bodies here, and prepend function prologues from
* ecrti.o and function epilogues from ecrtn.o. ecrti.o must be linked
* first; ecrtn.o must be linked last. Because these are wildcards, it
* doesn't matter if the user does not actually link against ecrti.o and
* ecrtn.o; the linker won't look for a file to match a wildcard. The
* wildcard also means that it doesn't matter which directory ecrti.o
* and ecrtn.o are in.
*/
PROVIDE (_init = .);
*ecrti.o(.init)
*(.init)
*ecrtn.o(.init)
PROVIDE (_fini = .);
*ecrti.o(.fini)
*(.fini)
*ecrtn.o(.init)
/*
* C++ constructors and destructors for static objects.
* PowerPC EABI does not use crtstuff yet, so we build "old-style"
* constructor and destructor lists that begin with the list lenght
* end terminate with a NULL entry.
*/
PROVIDE (__CTOR_LIST__ = .);
/* LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) */
*crtbegin.o(.ctors)
*(.ctors)
*crtend.o(.ctors)
LONG(0)
PROVIDE (__CTOR_END__ = .);
PROVIDE (__DTOR_LIST__ = .);
/* LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) */
*crtbegin.o(.dtors)
*(.dtors)
*crtend.o(.dtors)
LONG(0)
PROVIDE (__DTOR_END__ = .);
/* Exception frame info */
*(.eh_frame)
/* Miscellaneous read-only data */
_rodata_start = . ;
*(.gnu.linkonce.r*)
*(.lit)
*(.shdata)
*(.rodata)
*(.rodata1)
*(.descriptors)
*(rom_ver)
_erodata = .;
/* Various possible names for the end of the .text section */
etext = ALIGN(0x10);
_etext = .;
_endtext = .;
text.end = .;
PROVIDE (etext = .);
PROVIDE (__etext = .);
} > ram
/* R/W Data */
.data :
{
data_start = .;
*(.data)
*(.data.*)
*(.data1)
PROVIDE (__SDATA_START__ = .);
*(.sdata)
*(.gnu.linkonce.d*)
PROVIDE (__SDATA_END__ = .);
PROVIDE (__EXCEPT_START__ = .);
*(.gcc_except_table)
PROVIDE (__EXCEPT_END__ = .);
PROVIDE(__GOT_START__ = .);
*(.got.plt)
*(.got)
PROVIDE(__GOT_END__ = .);
*(.got1)
PROVIDE (__GOT2_START__ = .);
PROVIDE (_GOT2_START_ = .);
*(.got2)
PROVIDE (__GOT2_END__ = .);
PROVIDE (_GOT2_END_ = .);
PROVIDE (__FIXUP_START__ = .);
PROVIDE (_FIXUP_START_ = .);
*(.fixup)
PROVIDE (_FIXUP_END_ = .);
PROVIDE (__FIXUP_END__ = .);
/* We want the small data sections together, so single-instruction offsets
* can access them all.
*/
PROVIDE (__SDATA2_START__ = .);
*(.sdata2)
PROVIDE (__SDATA2_END__ = .);
} > ram
.bss :
{
PROVIDE (__SBSS_START__ = .);
PROVIDE (__SBSS2_START__ = .);
*(.sbss2)
PROVIDE (__SBSS2_END__ = .);
bss.start = .;
*(.bss)
*(.sbss)
*(COMMON)
. = ALIGN(4);
bss.end = .;
PROVIDE (__SBSS_END__ = .);
} > ram
bss.size = bss.end - bss.start;
text.size = text.end - text.start;
PROVIDE(_end = bss.end);
_HeapStart = .;
__HeapStart = .;
. += HeapSize; /* XXX -- Old gld can't handle this */
/* . += 0x80000; */ /* HeapSize for old gld */
_HeapEnd = .;
__HeapEnd = .;
clear_end = .;
_WorkspaceBase = .;
__WorkspaceBase = .;
dpram :
{
m8xx = .;
_m8xx = .;
. += (16 * 1024);
} >immr
/* 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) }
/* These must appear regardless of . */
}

View File

@@ -0,0 +1,132 @@
/*
* mmutlbtab.c
*
* This file defines the MMU_TLB_table for the MBX8xx.
*
* Copyright (c) 1999, National Research Council of Canada
*
* 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 <bsp.h>
#include <mpc8xx/mmu.h>
/*
* This MMU_TLB_table is used to statically initialize the Table Lookaside
* Buffers in the MMU of the MBX8xx board.
*
* We initialize the entries in both the instruction and data TLBs
* with the same values - a few bits relevant to the data TLB are unused
* in the instruction TLB.
*
* An Effective Page Number (EPN), Tablewalk Control Register (TWC) and
* Real Page Number (RPN) value are supplied in the table for each TLB entry.
*
* The instruction and data TLBs each can hold 32 entries, so _TLB_Table must
* not have more than 32 lines in it!
*
* We set up the virtual memory map so that virtual address of a
* location is equal to its real address.
*/
MMU_TLB_table_t MMU_TLB_table[] = {
/*
* DRAM: CS1, Start address 0x00000000, 4M,
* ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
* R/W,X for all, no ASID comparison, not cache-inhibited.
* Last 512K block is cache-inhibited, but not guarded for use by EPPCBug.
* EPN TWC RPN
*/
{ 0x00000200, 0x05, 0x000009FD }, /* DRAM - PS=512K */
{ 0x00080200, 0x05, 0x000809FD }, /* DRAM - PS=512K */
{ 0x00100200, 0x05, 0x001009FD }, /* DRAM - PS=512K */
{ 0x00180200, 0x05, 0x001809FD }, /* DRAM - PS=512K */
{ 0x00200200, 0x05, 0x002009FD }, /* DRAM - PS=512K */
{ 0x00280200, 0x05, 0x002809FD }, /* DRAM - PS=512K */
{ 0x00300200, 0x05, 0x003009FD }, /* DRAM - PS=512K */
{ 0x00380200, 0x05, 0x003809FF }, /* DRAM - PS=512K, cache-inhibited */
/*
*
* NVRAM: CS4, Start address 0xFA000000, 32K,
* ASID=0x0, APG=0x0, not guarded memory, copyback data cache policy,
* R/W,X for all, no ASID comparison, cache-inhibited.
*
* EPN TWC RPN
*/
{ 0xFA000200, 0x01, 0xFA0009FF }, /* NVRAM - PS=16K */
{ 0xFA004200, 0x01, 0xFA0049FF }, /* NVRAM - PS=16K */
/*
*
* Board Control/Status Register #1/#2: CS4, Start address 0xFA100000, (4 x 8 bits?)
* ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
* R/W,X for all, no ASID comparison, cache-inhibited.
* EPN TWC RPN
*/
{ 0xFA100200, 0x11, 0xFA1009F7 }, /* BCSR - PS=4K */
/*
*
* (IMMR-SPRs) Dual Port RAM: Start address 0xFA200000, 16K,
* ASID=0x0, APG=0x0, guarded memory, copyback data cache policy,
* R/W,X for all, no ASID comparison, cache-inhibited.
*
* Note: We use the value in MBXA/PG2, which is also the value that
* EPPC-Bug programmed into our boards. The alternative is the value
* in MBXA/PG1: 0xFFA00000. This value might well depend on the revision
* of the firmware.
* EPN TWC RPN
*/
{ 0xFA200200, 0x11, 0xFA2009FF }, /* IMMR - PS=16K */
/*
*
* Flash: CS0, Start address 0xFE000000, 4M, (BootROM-EPPCBug)
* ASID=0x0, APG=0x0, not guarded memory,
* R/O,X for all, no ASID comparison, not cache-inhibited.
* EPN TWC RPN
*/
{ 0xFE000200, 0x05, 0xFE000CFD }, /* Flash - PS=512K */
{ 0xFE080200, 0x05, 0xFE080CFD }, /* Flash - PS=512K */
{ 0xFE100200, 0x05, 0xFE100CFD }, /* Flash - PS=512K */
{ 0xFE180200, 0x05, 0xFE180CFD }, /* Flash - PS=512K */
{ 0xFE200200, 0x05, 0xFE200CFD }, /* Flash - PS=512K */
{ 0xFE280200, 0x05, 0xFE280CFD }, /* Flash - PS=512K */
{ 0xFE300200, 0x05, 0xFE300CFD }, /* Flash - PS=512K */
{ 0xFE380200, 0x05, 0xFE380CFD }, /* Flash - PS=512K */
/*
* BootROM: CS7, Start address 0xFC000000, 4M?, (socketed FLASH)
* ASID=0x0, APG=0x0, not guarded memory,
* R/O,X for all, no ASID comparison, not cache-inhibited.
* EPN TWC RPN
*/
{ 0xFC000200, 0x05, 0xFC000CFD }, /* BootROM - PS=512K */
/*
*
* PCI/ISA I/O Space: CS5, Start address 0x80000000, 512M?
* ASID=0x0, APG=0x0, guarded memory,
* R/W,X for all, no ASID comparison, cache-inhibited.
* EPN TWC RPN
*/
{ 0x80000200, 0x1D, 0x800009FF }, /* PCI I/O - PS=8M */
/*
*
* PCI/ISA Memory Space: CS5, Start address 0xC0000000, 512M?
* ASID=0x0, APG=0x0, guarded memory,
* R/W,X for all, no ASID comparison, cache-inhibited.
* EPN TWC RPN
*/
{ 0xC0000200, 0x1D, 0xC00009FF }, /* PCI Memory - PS=8M */
/*
*
* PCI Bridge/QSPAN Registers: CS6, Start address 0xFA210000, 4K
* ASID=0x0, APG=0x0, guarded memory,
* R/W,X for all, no ASID comparison, cache-inhibited.
* EPN TWC RPN
*/
{ 0xFA210200, 0x11, 0xFA2109F7 } /* QSPAN - PS=4K */
};
/*
* MMU_N_TLB_Table_Entries is defined here because the size of the
* MMU_TLB_table is only known in this file.
*/
int MMU_N_TLB_Table_Entries = ( sizeof(MMU_TLB_table) / sizeof(MMU_TLB_table[0]) );

View File

@@ -0,0 +1,44 @@
/* set_vector
*
* This routine installs an interrupt vector on the target Board/CPU.
* This routine is allowed to be as board dependent as necessary.
*
* INPUT:
* handler - interrupt handler entry point
* vector - vector number
* type - 0 indicates raw hardware connect
* 1 indicates RTEMS interrupt connect
*
* RETURNS:
* address of previous interrupt handler
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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 <rtems.h>
#include <bsp.h>
rtems_isr_entry set_vector( /* returns old vector */
rtems_isr_entry handler, /* isr routine */
rtems_vector_number vector, /* vector number */
int type /* RTEMS or RAW intr */
)
{
rtems_isr_entry previous_isr;
if (type) {
rtems_interrupt_catch(handler, vector, (rtems_isr_entry *) &previous_isr );
} else {
/* XXX: install non-RTEMS ISR as "raw" interupt */
}
return previous_isr;
}

View File

@@ -0,0 +1,383 @@
/* start.S
*
* This file contains the entry veneer for RTEMS programs
* on the MBX8xx board.
* It jumps to the BSP which is responsible for performing
* all remaining initialization.
*
* This file is based on several others:
*
* (1) start360.s from the gen68360 BSP by
* W. Eric Norum (eric@skatter.usask.ca)
* with the following copyright and license:
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* (2) start.s for the eth_comm port by
* Jay Monkman (jmonkman@fracsa.com),
* which itself is based on the
*
* (3) dlentry.s for the Papyrus BSP, written by:
* Andrew Bray <andy@i-cubed.co.uk>
* with the following copyright and license:
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* (4) start860.S for the MBX821/MBX860, written by:
* Darlene A. Stewart <darlene.stewart@iit.nrc.ca>
* Copyright (c) 1999, National Research Council of Canada
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Modifications (for MBX8xx) of respective RTEMS files:
* Copyright (c) 1999, National Research Council of Canada
*/
#include "asm.h"
/*
* The initial stack is set to run BELOW the code base address.
* (between the vectors and text sections)
*
* All the entry veneer has to do is to clear the BSS.
*/
/*
* GDB likes to have debugging information for the entry veneer.
* Play compiler and provide some DWARF information.
*
* CHANGE TO SUIT YOUR SETUP!
*/
.section .entry,"ax",@progbits
.L_text_b:
.L_LC1:
.previous
.section .debug_sfnames
.L_sfnames_b:
.byte "rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/"
.byte 0
.L_F0:
.byte "start.S"
.byte 0
.previous
.section .line
.L_line_b:
.4byte .L_line_e-.L_line_b
.4byte .L_text_b
.L_LE1:
.L_line_last:
.4byte 0x0
.2byte 0xffff
.4byte .L_text_e-.L_text_b
.L_line_e:
.previous
.section .debug_srcinfo
.L_srcinfo_b:
.4byte .L_line_b
.4byte .L_sfnames_b
.4byte .L_text_b
.4byte .L_text_e
.4byte 0xffffffff
.4byte .L_LE1-.L_line_b
.4byte .L_F0-.L_sfnames_b
.4byte .L_line_last-.L_line_b
.4byte 0xffffffff
.previous
.section .debug_pubnames
.4byte .L_debug_b
.4byte .L_P0
.byte "start"
.byte 0
.4byte 0x0
.byte 0
.previous
.section .debug_aranges
.4byte .L_debug_b
.4byte .L_text_b
.4byte .L_text_e-.L_text_b
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0
.4byte 0x0
.4byte 0x0
.previous
.section .debug
.L_debug_b:
.L_D1:
.4byte .L_D1_e-.L_D1
.2byte 0x11 /* TAG_compile_unit */
.2byte 0x12 /* AT_sibling */
.4byte .L_D2
.2byte 0x38 /* AT_name */
.byte "start.S"
.byte 0
.2byte 0x258 /* AT_producer */
.byte "GAS 2.5.2"
.byte 0
.2byte 0x111 /* AT_low_pc */
.4byte .L_text_b
.2byte 0x121 /* AT_high_pc */
.4byte .L_text_e
.2byte 0x106 /* AT_stmt_list */
.4byte .L_line_b
.2byte 0x1b8 /* AT_comp_dir */
.byte "rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/"
.byte 0
.2byte 0x8006 /* AT_sf_names */
.4byte .L_sfnames_b
.2byte 0x8016 /* AT_src_info */
.4byte .L_srcinfo_b
.L_D1_e:
.L_P0:
.L_D3:
.4byte .L_D3_e-.L_D3
.2byte 0x6 /* TAG_global_subroutine */
.2byte 0x12 /* AT_sibling */
.4byte .L_D4
.2byte 0x38 /* AT_name */
.byte "start"
.byte 0
.2byte 0x278 /* AT_prototyped */
.byte 0
.2byte 0x111 /* AT_low_pc */
.4byte .L_text_b
.2byte 0x121 /* AT_high_pc */
.4byte .L_text_e
.2byte 0x8041 /* AT_body_begin */
.4byte .L_text_b
.2byte 0x8051 /* AT_body_end */
.4byte .L_text_e
.L_D3_e:
.L_D4:
.4byte .L_D4_e-.L_D4
.align 2
.L_D4_e:
.L_D2:
.previous
/*
* Tell C's eabi-ctor's that we have an atexit function,
* and that it is to register __do_global_dtors.
*/
EXTERN_PROC(atexit)
PUBLIC_VAR(__atexit)
.section ".sdata","aw"
.align 2
SYM(__atexit):
EXT_PROC_REF(atexit)@fixup
.previous
.section ".fixup","aw"
.align 2
EXT_SYM_REF(__atexit)
.previous
/* That should do it */
/*
* Put the entry point in its own section. That way, we can guarantee
* to put it first in the .text section in the linker script.
*/
.section .entry
PUBLIC_VAR (start)
SYM(start):
bl .startup /* or bl .spin */
base_addr:
/*
* Parameters from linker
*/
toc_pointer:
.long __GOT_START__
bss_length:
.long bss.size
bss_addr:
.long bss.start
PUBLIC_VAR (text_addr)
text_addr:
.long text.start
PUBLIC_VAR (text_length)
text_length:
.long text.size
/*
* Spin, if necessary, to acquire control from debugger (CodeWarrior).
*/
spin:
.long 0x0001
.spin:
lis r3, spin@ha
lwz r3, spin@l(r3)
cmpwi r3, 0x1
beq .spin
/*
* Initialization code
*/
.startup:
/* Get the start address. */
mflr r1
/* Initialize essential registers. */
bl initregs
nop
/*
* C_setup.
*/
/* set toc */
lwz r2, toc_pointer-base_addr(r1)
/* Set up stack pointer = beginning of text section - 56 */
addi r1, r1, -56-4
/* Initialize the memory mapped MPC821 registers (done in C). */
EXTERN_PROC (_InitMBX8xx)
bl PROC (_InitMBX8xx)
nop
/* Clear the bss section. */
bl bssclr
nop
/* clear argc and argv */
xor r3, r3, r3
xor r4, r4, r4
EXTERN_PROC (boot_card)
bl PROC (boot_card) /* call the first C routine */
nop
/* we should never return from boot_card, but in case we do ... */
/* The next instructions are dependent on your runtime environment */
/* Return to EPPCBug */
lis r10, 0x0400 /* Data cache disable */
mtspr 568, r10
isync
mtspr 560, r10 /* Instruction cache disable */
isync
stop_here:
li r10, 0x0F00 /* .RETURN */
sc
b stop_here
nop
/*
* bssclr - zero out bss
*/
bssclr:
lis r3, base_addr@ha
addi r3, r3, base_addr@l
lwz r4, bss_addr-base_addr(r3) /* Start of bss */
lwz r5, bss_length-base_addr(r3) /* Length of bss */
rlwinm. r5,r5,30,0x3FFFFFFF /* form length/4 */
beqlr /* no bss - return */
mtctr r5 /* set ctr reg */
li r5,0x0000 /* r5 = 0 */
clear_bss:
stw r5,0(r4) /* store r6 */
addi r4,r4,0x4 /* update r4 */
bdnz clear_bss /* dec counter and loop */
blr /* return */
/*
* initregs
* Initialize the MSR and basic core PowerPC registers
*
* Register usage:
* r0 - scratch
*/
initregs:
/*
* Disable address translation. We should already be running in real space,
* so this should be a no-op, i.e. no need to switch instruction stream
* addresses from virtual space to real space. Other bits set the processor
* for big-endian mode, exceptions vectored to 0x000n_nnnn (vectors are
* already in low memory!), no execution tracing, machine check exceptions
* enabled, floating-point not available (MPC8xx has none), supervisor
* priviledge level, external interrupts disabled, power management
* disabled (normal operation mode).
*/
li r0, 0x1000 /* MSR_ME */
mtmsr r0 /* Context-synchronizing */
isync
/*
* Clear the exception handling registers.
* Note SPRG3 is reserved for use by EPPCBug on the MBX8xx.
*/
li r0, 0x0000
mtdar r0
mtspr sprg0, r0
mtspr sprg1, r0
mtspr sprg2, r0
mtspr srr0, r0
mtspr srr1, r0
mr r6, r0
mr r7, r0
mr r8, r0
mr r9, r0
mr r10, r0
mr r11, r0
mr r12, r0
mr r13, r0
mr r14, r0
mr r15, r0
mr r16, r0
mr r17, r0
mr r18, r0
mr r19, r0
mr r20, r0
mr r21, r0
mr r22, r0
mr r23, r0
mr r24, r0
mr r25, r0
mr r26, r0
mr r27, r0
mr r28, r0
mr r29, r0
mr r30, r0
mr r31, r0
blr /* return */
.L_text_e:

View File

@@ -0,0 +1,191 @@
#
# Timing Test Suite Results for the MBX821-001
#
# $Id$
#
Board: MBX821
CPU: MPC821
Clock Speed: 50 MHz
Memory Configuration: 4Mb EDO, 60ns DRAM
Wait States:
Times Reported in: clock ticks
Timer Source: Timebase register (TMBCLK = (cpu clock speed / 16) = 3.125MHz)
Column A: Data & instruction caches disabled (2000-05-04)
Column B: Data & instruction caches enabled (UPM/A: new burst r/w values) (2000-05-04)
# DESCRIPTION A B
== ================================================================= ==== ====
1 rtems_semaphore_create 181 79
rtems_semaphore_delete 196 55
rtems_semaphore_obtain: available 128 12
rtems_semaphore_obtain: not available -- NO_WAIT 128 12
rtems_semaphore_release: no waiting tasks 162 16
2 rtems_semaphore_obtain: not available -- caller blocks 405 113
3 rtems_semaphore_release: task readied -- preempts caller 317 72
4 rtems_task_restart: blocked task -- preempts caller 549 156
rtems_task_restart: ready task -- preempts caller 539 150
rtems_semaphore_release: task readied -- returns to caller 201 25
rtems_task_create 585 153
rtems_task_start 257 67
rtems_task_restart: suspended task -- returns to caller 309 83
rtems_task_delete: suspended task 555 118
rtems_task_restart: ready task -- returns to caller 317 85
rtems_task_restart: blocked task -- returns to caller 374 113
rtems_task_delete: blocked task 571 130
5 rtems_task_suspend: calling task 314 63
rtems_task_resume: task readied -- preempts caller 263 49
6 rtems_task_restart: calling task 385 53
rtems_task_suspend: returns to caller 132 18
rtems_task_resume: task readied -- returns to caller 145 20
rtems_task_delete: ready task 574 135
7 rtems_task_restart: suspended task -- preempts caller 505 111
8 rtems_task_set_priority: obtain current priority 111 11
rtems_task_set_priority: returns to caller 207 20
rtems_task_mode: obtain current mode 56 6
rtems_task_mode: no reschedule 70 8
rtems_task_mode: reschedule -- returns to caller 75 32
rtems_task_mode: reschedule -- preempts caller 292 97
rtems_task_set_note 112 11
rtems_task_get_note 113 11
rtems_clock_set 250 25
rtems_clock_get 6 1
9 rtems_message_queue_create 751 320
rtems_message_queue_send: no waiting tasks 241 33
rtems_message_queue_urgent: no waiting tasks 238 39
rtems_message_queue_receive: available 229 29
rtems_message_queue_flush: no messages flushed 104 12
rtems_message_queue_flush: messages flushed 127 12
rtems_message_queue_delete 242 83
10 rtems_message_queue_receive: not available -- NO_WAIT 147 16
rtems_message_queue_receive: not available -- caller blocks 416 94
11 rtems_message_queue_send: task readied -- preempts caller 377 82
12 rtems_message_queue_send: task readied -- returns to caller 262 50
13 rtems_message_queue_urgent: task readied -- preempts caller 377 85
14 rtems_message_queue_urgent: task readied -- returns to caller 262 43
15 rtems_event_receive: obtain current events 10 1
rtems_event_receive: not available -- NO_WAIT 102 9
rtems_event_receive: not available -- caller blocks 346 76
rtems_event_send: no task readied 104 10
rtems_event_receive: available 105 24
rtems_event_send: task readied -- returns to caller 181 26
16 rtems_event_send: task readied -- preempts caller 308 78
17 rtems_task_set_priority: preempts caller 408 76
18 rtems_task_delete: calling task 749 174
19 rtems_signal_catch 75 9
rtems_signal_send: returns to caller 120 35
rtems_signal_send: signal to self 198 74
exit ASR overhead: returns to calling task 158 63
exit ASR overhead: returns to preempting task 249 65
20 rtems_partition_create 247 102
rtems_region_create 196 78
rtems_partition_get_buffer: available 117 26
rtems_partition_get_buffer: not available 110 10
rtems_partition_return_buffer 127 30
rtems_partition_delete 145 31
rtems_region_get_segment: available 156 19
rtems_region_get_segment: not available -- NO_WAIT 143 36
rtems_region_return_segment: no waiting tasks 167 15
rtems_region_get_segment: not available -- caller blocks 429 167
rtems_region_return_segment: task readied -- preempts caller 418 142
rtems_region_return_segment: task readied -- returns to caller 298 71
rtems_region_delete 146 25
rtems_io_initialize 13 2
rtems_io_open 9 1
rtems_io_close 9 1
rtems_io_read 9 1
rtems_io_write 9 1
rtems_io_control 9 1
21 rtems_task_ident 1143 139
rtems_message_queue_ident 1115 141
rtems_semaphore_ident 1285 158
rtems_partition_ident 1115 132
rtems_region_ident 1137 144
rtems_port_ident 1115 133
rtems_timer_ident 1117 140
rtems_rate_monotonic_ident 1116 136
22 rtems_message_queue_broadcast: task readied -- returns to caller 281 84
rtems_message_queue_broadcast: no waiting tasks 177 17
rtems_message_queue_broadcast: task readied -- preempts caller 398 114
23 rtems_timer_create 127 15
rtems_timer_fire_after: inactive 191 23
rtems_timer_fire_after: active 204 24
rtems_timer_cancel: active 118 15
rtems_timer_cancel: inactive 104 13
rtems_timer_reset: inactive 176 21
rtems_timer_reset: active 189 22
rtems_timer_fire_when: inactive 237 28
rtems_timer_fire_when: active 237 28
rtems_timer_delete: active 167 25
rtems_timer_delete: inactive 153 23
rtems_task_wake_when 408 83
24 rtems_task_wake_after: yield -- returns to caller 85 8
rtems_task_wake_after: yields -- preempts caller 287 56
25 rtems_clock_tick 59 25
26 _ISR_Disable 3 1
_ISR_Flash 3 0
_ISR_Enable 1 0
_Thread_Disable_dispatch 4 0
_Thread_Enable_dispatch 59 6
_Thread_Set_state 59 16
_Thread_Disptach (NO FP) 242 52
context switch: no floating point contexts 183 44
context switch: self 62 2
context switch: to another task 64 3
context switch: restore 1st FP task 189 40
fp context switch: save idle, restore idle 186 39
fp context switch: save idle, restore initialized 67 4
fp context switch: save initialized, restore initialized 67 5
_Thread_Resume 51 24
_Thread_Unblock 47 12
_Thread_Ready 54 9
_Thread_Get 33 3
_Semaphore_Get 26 2
_Thread_Get: invalid id 5 0
27 interrupt entry overhead: returns to interrupted task 0 0
interrupt exit overhead: returns to interrupted task 1 1
interrupt entry overhead: returns to nested interrupt 0 0
interrupt exit overhead: returns to nested interrupt 0 0
interrupt entry overhead: returns to preempting task
interrupt exit overhead: returns to preempting task
28 rtems_port_create 145 55
rtems_port_external_to_internal 101 9
rtems_port_internal_to_external 101 9
rtems_port_delete 144 40
29 rtems_rate_monotonic_create 135 57
rtems_rate_monotonic_period: initiate period -- returns to caller 176 77
rtems_rate_monotonic_period: obtain status 110 35
rtems_rate_monotonic_cancel 131 50
rtems_rate_monotonic_delete: inactive 160 61
rtems_rate_monotonic_delete: active 178 41
rtems_rate_monotonic_period: conclude periods -- caller blocks 284 67

View File

@@ -0,0 +1,191 @@
#
# Timing Test Suite Results for the MBX860-002
#
# $Id$
#
Board: MBX860
CPU: MPC860
Clock Speed: 40 MHz
Memory Configuration: 4Mb EDO, 60ns DRAM
Wait States:
Times Reported in: clock ticks
Timer Source: Timebase register (TMBCLK = (cpu clock speed / 16) = 2.5Mhz)
Column A: Data & instruction caches disabled (2000-05-03)
Column B: Data & instruction caches enabled (UPM/A: new burst r/w values) (2000-05-04)
# DESCRIPTION A B
== ================================================================= ==== ====
1 rtems_semaphore_create 159 67
rtems_semaphore_delete 173 52
rtems_semaphore_obtain: available 113 26
rtems_semaphore_obtain: not available -- NO_WAIT 113 28
rtems_semaphore_release: no waiting tasks 144 22
2 rtems_semaphore_obtain: not available -- caller blocks 346 121
3 rtems_semaphore_release: task readied -- preempts caller 268 89
4 rtems_task_restart: blocked task -- preempts caller 475 130
rtems_task_restart: ready task -- preempts caller 465 132
rtems_semaphore_release: task readied -- returns to caller 179 48
rtems_task_create 521 154
rtems_task_start 228 57
rtems_task_restart: suspended task -- returns to caller 275 74
rtems_task_delete: suspended task 494 139
rtems_task_restart: ready task -- returns to caller 283 78
rtems_task_restart: blocked task -- returns to caller 333 98
rtems_task_delete: blocked task 507 144
5 rtems_task_suspend: calling task 266 88
rtems_task_resume: task readied -- preempts caller 220 61
6 rtems_task_restart: calling task 334 75
rtems_task_suspend: returns to caller 117 24
rtems_task_resume: task readied -- returns to caller 129 29
rtems_task_delete: ready task 510 138
7 rtems_task_restart: suspended task -- preempts caller 436 135
8 rtems_task_set_priority: obtain current priority 98 11
rtems_task_set_priority: returns to caller 183 32
rtems_task_mode: obtain current mode 51 8
rtems_task_mode: no reschedule 62 9
rtems_task_mode: reschedule -- returns to caller 66 25
rtems_task_mode: reschedule -- preempts caller 246 69
rtems_task_set_note 99 11
rtems_task_get_note 100 23
rtems_clock_set 222 35
rtems_clock_get 6 1
9 rtems_message_queue_create 667 262
rtems_message_queue_send: no waiting tasks 215 58
rtems_message_queue_urgent: no waiting tasks 212 53
rtems_message_queue_receive: available 204 43
rtems_message_queue_flush: no messages flushed 93 17
rtems_message_queue_flush: messages flushed 113 22
rtems_message_queue_delete 214 76
10 rtems_message_queue_receive: not available -- NO_WAIT 131 20
rtems_message_queue_receive: not available -- caller blocks 357 118
11 rtems_message_queue_send: task readied -- preempts caller 322 109
12 rtems_message_queue_send: task readied -- returns to caller 234 67
13 rtems_message_queue_urgent: task readied -- preempts caller 322 94
14 rtems_message_queue_urgent: task readied -- returns to caller 234 62
15 rtems_event_receive: obtain current events 8 1
rtems_event_receive: not available -- NO_WAIT 90 9
rtems_event_receive: not available -- caller blocks 294 88
rtems_event_send: no task readied 91 10
rtems_event_receive: available 93 22
rtems_event_send: task readied -- returns to caller 161 41
16 rtems_event_send: task readied -- preempts caller 260 84
17 rtems_task_set_priority: preempts caller 349 108
18 rtems_task_delete: calling task 652 203
19 rtems_signal_catch 66 9
rtems_signal_send: returns to caller 107 41
rtems_signal_send: signal to self 176 62
exit ASR overhead: returns to calling task 140 56
exit ASR overhead: returns to preempting task 207 54
20 rtems_partition_create 220 78
rtems_region_create 175 71
rtems_partition_get_buffer: available 103 21
rtems_partition_get_buffer: not available 97 10
rtems_partition_return_buffer 113 24
rtems_partition_delete 128 26
rtems_region_get_segment: available 137 27
rtems_region_get_segment: not available -- NO_WAIT 126 36
rtems_region_return_segment: no waiting tasks 148 31
rtems_region_get_segment: not available -- caller blocks 366 119
rtems_region_return_segment: task readied -- preempts caller 359 114
rtems_region_return_segment: task readied -- returns to caller 265 72
rtems_region_delete 129 33
rtems_io_initialize 12 2
rtems_io_open 9 1
rtems_io_close 9 1
rtems_io_read 9 1
rtems_io_write 9 1
rtems_io_control 9 1
21 rtems_task_ident 1019 137
rtems_message_queue_ident 993 139
rtems_semaphore_ident 1144 162
rtems_partition_ident 993 132
rtems_region_ident 1012 143
rtems_port_ident 993 132
rtems_timer_ident 994 138
rtems_rate_monotonic_ident 993 135
22 rtems_message_queue_broadcast: task readied -- returns to caller 249 80
rtems_message_queue_broadcast: no waiting tasks 157 27
rtems_message_queue_broadcast: task readied -- preempts caller 340 94
23 rtems_timer_create 114 15
rtems_timer_fire_after: inactive 170 36
rtems_timer_fire_after: active 182 36
rtems_timer_cancel: active 104 14
rtems_timer_cancel: inactive 92 12
rtems_timer_reset: inactive 156 29
rtems_timer_reset: active 168 31
rtems_timer_fire_when: inactive 210 43
rtems_timer_fire_when: active 210 42
rtems_timer_delete: active 148 24
rtems_timer_delete: inactive 136 20
rtems_task_wake_when 350 99
24 rtems_task_wake_after: yield -- returns to caller 76 10
rtems_task_wake_after: yields -- preempts caller 242 63
25 rtems_clock_tick 51 19
26 _ISR_Disable 3 0
_ISR_Flash 2 0
_ISR_Enable 0 0
_Thread_Disable_dispatch 3 0
_Thread_Enable_dispatch 52 8
_Thread_Set_state 51 15
_Thread_Disptach (NO FP) 201 53
context switch: no floating point contexts 148 44
context switch: self 41 4
context switch: to another task 44 5
context switch: restore 1st FP task 154 41
fp context switch: save idle, restore idle 152 42
fp context switch: save idle, restore initialized 46 5
fp context switch: save initialized, restore initialized 47 4
_Thread_Resume 45 19
_Thread_Unblock 42 10
_Thread_Ready 47 8
_Thread_Get 29 3
_Semaphore_Get 23 2
_Thread_Get: invalid id 5 0
27 interrupt entry overhead: returns to interrupted task 0 0
interrupt exit overhead: returns to interrupted task 0 0
interrupt entry overhead: returns to nested interrupt 0 0
interrupt exit overhead: returns to nested interrupt 0 0
interrupt entry overhead: returns to preempting task
interrupt exit overhead: returns to preempting task
28 rtems_port_create 128 48
rtems_port_external_to_internal 90 9
rtems_port_internal_to_external 90 13
rtems_port_delete 128 30
29 rtems_rate_monotonic_create 120 48
rtems_rate_monotonic_period: initiate period -- returns to caller 156 55
rtems_rate_monotonic_period: obtain status 98 27
rtems_rate_monotonic_cancel 115 39
rtems_rate_monotonic_delete: inactive 141 51
rtems_rate_monotonic_delete: active 158 46
rtems_rate_monotonic_period: conclude periods -- caller blocks 240 76

View File

@@ -0,0 +1,40 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
# We only build the networking device driver if HAS_NETWORKING was defined
if HAS_NETWORKING
NETWORKING = network
endif
BSP_PIECES = startup console $(NETWORKING)
# pieces to pick up out of libcpu/ppc
# CPU_PIECES = mpc8xx/clock mpc8xx/console-generic mpc8xx/cpm \
mpc8xx/mmu mpc8xx/timer mpc8xx/vectors
# bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(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-local: $(ARCH) $(OBJS) $(LIB) $(TMPINSTALL_FILES)
.PRECIOUS: $(LIB)
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
# C source names
C_FILES = cpu.c ppccache.c
C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
ROOT_H_FILES =

View File

@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
int _CPU_spurious_count = 0;
int _CPU_last_spurious = 0;
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
++_CPU_spurious_count;
_CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
case PPC_IRQ_CPM_RESERVED_0:
case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:

View File

@@ -766,6 +766,15 @@ SCORE_EXTERN struct {
); \
} while (0)
#define _CPU_Data_Cache_Block_Invalidate( _address ) \
do { register void *__address = (_address); \
register unsigned32 _zero = 0; \
asm volatile ( "dcbi %0,%1" : \
"=r" (_zero), "=r" (__address) : \
"0" (_zero), "1" (__address) \
); \
} while (0)
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).

View File

@@ -418,5 +418,27 @@ void _free_r(
{
free( ptr );
}
/*
* rtems_cache_aligned_malloc
*
* DESCRIPTION:
*
* This function is used to allocate storage that spans an
* integral number of cache blocks.
*/
RTEMS_INLINE_ROUTINE void * rtems_cache_aligned_malloc (
size_t nbytes
)
{
/*
* Arrange to have the user storage start on the first cache
* block beyond the header.
*/
return (void *) ((((unsigned long) malloc( nbytes + _CPU_DATA_CACHE_ALIGNMENT - 1 ))
+ _CPU_DATA_CACHE_ALIGNMENT - 1 ) &(~(_CPU_DATA_CACHE_ALIGNMENT - 1)) );
}
#endif

View File

@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/filio.h>
/*
* FreeBSD does not support a full POSIX termios so we have to help it out
@@ -243,7 +244,7 @@ rtems_termios_open (
/*
* Set default parameters
*/
tty->termios.c_iflag = BRKINT | ICRNL | IMAXBEL;
tty->termios.c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
tty->termios.c_oflag = OPOST | ONLCR | XTABS;
tty->termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
tty->termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOK | ECHOE | ECHOCTL;
@@ -474,6 +475,11 @@ rtems_termios_ioctl (void *arg)
case RTEMS_IO_TCDRAIN:
drainOutput (tty);
break;
case FIONREAD:
/* Half guess that this is the right operation */
*(int *)args->buffer = tty->ccount - tty->cindex;
break;
}
rtems_semaphore_release (tty->osem);
args->ioctl_return = sc;

View File

@@ -132,47 +132,6 @@ static inline unsigned short i386_get_gs()
return segment;
}
/*
* Added for pagination management
*/
static inline unsigned int i386_get_cr0()
{
register unsigned int segment = 0;
asm volatile ( "movl %%cr0,%0" : "=r" (segment) : "0" (segment) );
return segment;
}
static inline void i386_set_cr0(unsigned int segment)
{
asm volatile ( "movl %0,%%cr0" : "=r" (segment) : "0" (segment) );
}
static inline unsigned int i386_get_cr2()
{
register unsigned int segment = 0;
asm volatile ( "movl %%cr2,%0" : "=r" (segment) : "0" (segment) );
return segment;
}
static inline unsigned int i386_get_cr3()
{
register unsigned int segment = 0;
asm volatile ( "movl %%cr3,%0" : "=r" (segment) : "0" (segment) );
return segment;
}
static inline void i386_set_cr3(unsigned int segment)
{
asm volatile ( "movl %0,%%cr3" : "=r" (segment) : "0" (segment) );
}
/*
* IO Port Access Routines
*/
@@ -479,12 +438,6 @@ typedef struct {
page_table_entry pageTableEntry[MAX_ENTRY];
} page_table;
static inline void flush_cache()
{
/* Would this be better as a macro? */
asm ("wbinvd"); /* gcc did not like a volatile being on this */
}
/* C declaration for paging management */

View File

@@ -45,7 +45,7 @@ extern rtems_unsigned32 rtemsFreeMemStart;
void _CPU_disable_paging() {
cr0 regCr0;
flush_cache();
rtems_flush_entire_data_cache();
regCr0.i = i386_get_cr0();
regCr0.cr0.paging = 0;
i386_set_cr0( regCr0.i );
@@ -60,7 +60,7 @@ void _CPU_enable_paging() {
regCr0.i = i386_get_cr0();
regCr0.cr0.paging = 1;
i386_set_cr0( regCr0.i );
flush_cache();
rtems_flush_entire_data_cache();
}
@@ -153,32 +153,6 @@ int init_paging() {
return 0;
}
/*
* Disable the entire cache
*/
void _CPU_disable_cache() {
cr0 regCr0;
regCr0.i = i386_get_cr0();
regCr0.cr0.page_level_cache_disable = 1;
regCr0.cr0.no_write_through = 1;
i386_set_cr0( regCr0.i );
flush_cache();
}
/*
* Disable the entire cache
*/
void _CPU_enable_cache() {
cr0 regCr0;
regCr0.i = i386_get_cr0();
regCr0.cr0.page_level_cache_disable = 0;
regCr0.cr0.no_write_through = 0;
i386_set_cr0( regCr0.i );
/*flush_cache();*/
}
/*
* Is cache enable
*/

View File

@@ -16,11 +16,8 @@ endif
if mpc6xx
CPU_SUBDIR = mpc6xx
endif
if mpc821
CPU_SUBDIR = mpc821
endif
if mpc860
CPU_SUBDIR = mpc860
if mpc8xx
CPU_SUBDIR = mpc8xx
endif
if ppc403
CPU_SUBDIR = ppc403

View File

@@ -26,16 +26,20 @@ RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
AM_CONDITIONAL(shared,
test "$RTEMS_CPU_MODEL" = "mpc750" \
|| test "$RTEMS_CPU_MODEL" = "mpc604" )
AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "mpc750" \
|| test "$RTEMS_CPU_MODEL" = "mpc604" \
|| test "$RTEMS_CPU_MODEL" = "mpc6xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc821" \
|| test "$RTEMS_CPU_MODEL" = "mpc860" \
|| test "$RTEMS_CPU_MODEL" = "mpc8xx" )
AM_CONDITIONAL(mpc505, test "$RTEMS_CPU_MODEL" = "mpc505")
AM_CONDITIONAL(mpc6xx, test "$RTEMS_CPU_MODEL" = "mpc6xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc604" \
|| test "$RTEMS_CPU_MODEL" = "mpc750" )
AM_CONDITIONAL(mpc821, test "$RTEMS_CPU_MODEL" = "mpc821")
AM_CONDITIONAL(mpc860, test "$RTEMS_CPU_MODEL" = "mpc860")
AM_CONDITIONAL(mpc8xx, test "$RTEMS_CPU_MODEL" = "mpc8xx" \
|| test "$RTEMS_CPU_MODEL" = "mpc821" \
|| test "$RTEMS_CPU_MODEL" = "mpc860" )
AM_CONDITIONAL(ppc403, test "$RTEMS_CPU_MODEL" = "ppc403")
# Explicitly list all Makefiles here
@@ -44,18 +48,14 @@ Makefile
mpc505/Makefile
mpc505/timer/Makefile
mpc505/vectors/Makefile
mpc821/Makefile
mpc821/clock/Makefile
mpc821/console-generic/Makefile
mpc821/include/Makefile
mpc821/timer/Makefile
mpc821/vectors/Makefile
mpc860/Makefile
mpc860/clock/Makefile
mpc860/console-generic/Makefile
mpc860/include/Makefile
mpc860/timer/Makefile
mpc860/vectors/Makefile
mpc8xx/Makefile
mpc8xx/clock/Makefile
mpc8xx/console-generic/Makefile
mpc8xx/cpm/Makefile
mpc8xx/include/Makefile
mpc8xx/mmu/Makefile
mpc8xx/timer/Makefile
mpc8xx/vectors/Makefile
ppc403/Makefile
ppc403/clock/Makefile
ppc403/console/Makefile

View File

@@ -0,0 +1,10 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = include console-generic clock timer vectors cpm mmu
include $(top_srcdir)/../../../../../automake/subdirs.am
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,19 @@
#
# $Id$
#
Various non BSP dependant support routines.
clock - Uses the MPC860/MPC821 PIT (Programmable interval timer) to
generate RTEMS clock ticks.
console_generic - Uses the MPC860/MPC821 SCCs and SMCs to to serial I/O.
include - console.h: function declarations for console related functions
timer - Uses the MPC860/MPC821 timebase register for timing
tests. It only uses the lower 32 bits
vectors - MPC860/MPC821 specific vector entry points.
Includes CPU dependant, application independant
handlers: alignment.

View File

@@ -0,0 +1,30 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/clock.rel
## C sources
C_FILES = clock.c
clock_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 +=
#
AM_CFLAGS = $(CFLAGS_OS_V)
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,188 @@
/* clock.c
*
* This routine initializes the PIT on the MPC8xx.
* The tick frequency is specified by the bsp.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copyright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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 <bsp.h>
#include <clockdrv.h>
#include <rtems/libio.h>
#include <stdlib.h> /* for atexit() */
#include <mpc8xx.h>
extern rtems_cpu_table Cpu_table; /* owned by BSP */
volatile rtems_unsigned32 Clock_driver_ticks;
extern volatile m8xx_t m8xx;
void Clock_exit( void );
/*
* These are set by clock driver during its init
*/
rtems_device_major_number rtems_clock_major = ~0;
rtems_device_minor_number rtems_clock_minor;
/*
* ISR Handler
*/
rtems_isr Clock_isr(rtems_vector_number vector)
{
m8xx.piscr |= M8xx_PISCR_PS;
Clock_driver_ticks++;
rtems_clock_tick();
}
void Install_clock(rtems_isr_entry clock_isr)
{
#ifdef EPPCBUG_SMC1
extern unsigned32 simask_copy;
#endif /* EPPCBUG_SMC1 */
rtems_isr_entry previous_isr;
rtems_unsigned32 pit_value;
Clock_driver_ticks = 0;
pit_value = (BSP_Configuration.microseconds_per_tick *
Cpu_table.clicks_per_usec) - 1 ;
if (pit_value > 0xffff) { /* pit is only 16 bits long */
rtems_fatal_error_occurred(-1);
}
if (BSP_Configuration.ticks_per_timeslice) {
/*
* initialize the interval here
* First tick is set to right amount of time in the future
* Future ticks will be incremented over last value set
* in order to provide consistent clicks in the face of
* interrupt overhead
*/
rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr);
m8xx.sccr &= ~(1<<24);
m8xx.pitc = pit_value;
/* set PIT irq level, enable PIT, PIT interrupts */
/* and clear int. status */
m8xx.piscr = M8xx_PISCR_PIRQ(0) |
M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE;
#ifdef EPPCBUG_SMC1
simask_copy = m8xx.simask | M8xx_SIMASK_LVM0;
#endif /* EPPCBUG_SMC1 */
m8xx.simask |= M8xx_SIMASK_LVM0;
}
atexit(Clock_exit);
}
void
ReInstall_clock(rtems_isr_entry new_clock_isr)
{
rtems_isr_entry previous_isr;
rtems_unsigned32 isrlevel = 0;
rtems_interrupt_disable(isrlevel);
rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr);
rtems_interrupt_enable(isrlevel);
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*/
void
Clock_exit(void)
{
if ( BSP_Configuration.ticks_per_timeslice ) {
/* disable PIT and PIT interrupts */
m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE);
(void) set_vector(0, PPC_IRQ_LVL0, 1);
}
}
rtems_device_driver Clock_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
Install_clock( Clock_isr );
/*
* make major/minor avail to others such as shared memory driver
*/
rtems_clock_major = major;
rtems_clock_minor = minor;
return RTEMS_SUCCESSFUL;
}
rtems_device_driver Clock_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *pargp
)
{
rtems_libio_ioctl_args_t *args = pargp;
if (args == 0)
goto done;
/*
* This is hokey, but until we get a defined interface
* to do this, it will just be this simple...
*/
if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
Clock_isr(PPC_IRQ_LVL0);
}
else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
ReInstall_clock(args->buffer);
}
done:
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,30 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/console-generic.rel
## C sources
C_FILES = console-generic.c
console_generic_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 +=
#
AM_CFLAGS = $(CFLAGS_OS_V)
$(PGM): $(console_generic_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/cp.rel
## C sources
C_FILES = cp.c dpram.c
clock_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 +=
#
AM_CFLAGS = $(CFLAGS_OS_V)
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,34 @@
/*
* cp.c
*
* MPC8xx CPM RISC Communication Processor routines.
*
* Based on code (alloc860.c in eth_comm port) by
* Jay Monkman (jmonkman@frasca.com),
* which, in turn, is based on code by
* W. Eric Norum (eric@skatter.usask.ca).
*
* Modifications by Darlene Stewart (Darlene.Stewart@iit.nrc.ca):
* Copyright (c) 1999, National Research Council of Canada
*/
#include <bsp.h>
#include <rtems/rtems/intr.h>
#include <rtems/error.h>
/*
* Send a command to the CPM RISC processer
*/
void m8xx_cp_execute_cmd( unsigned16 command )
{
rtems_unsigned16 lvl;
rtems_interrupt_disable(lvl);
while (m8xx.cpcr & M8xx_CR_FLG) {
continue;
}
m8xx.cpcr = command | M8xx_CR_FLG;
rtems_interrupt_enable (lvl);
}

View File

@@ -0,0 +1,89 @@
/*
* dpram.c
*
* MPC8xx dual-port RAM allocation routines
*
* Based on code (alloc860.c in eth_comm port) by
* Jay Monkman (jmonkman@frasca.com),
* which, in turn, is based on code by
* W. Eric Norum (eric@skatter.usask.ca).
*
*
* Modifications :
* Copyright (c) 1999, National Research Council of Canada
*/
#include <bsp.h>
#include <rtems/rtems/intr.h>
#include <rtems/error.h>
/*
* Allocation order:
* - Dual-Port RAM section 0
* - Dual-Port RAM section 1
* - Dual-Port RAM section 2
* - Dual-Port RAM section 3
* - Dual-Port RAM section 4
*/
static struct {
unsigned8 *base;
unsigned int size;
unsigned int used;
} dpram_regions[] = {
{ (char *)&m8xx.dpram0[0], sizeof m8xx.dpram0, 0 },
{ (char *)&m8xx.dpram1[0], sizeof m8xx.dpram1, 0 },
{ (char *)&m8xx.dpram2[0], sizeof m8xx.dpram2, 0 },
{ (char *)&m8xx.dpram3[0], sizeof m8xx.dpram3, 0 },
{ (char *)&m8xx.dpram4[0], sizeof m8xx.dpram4, 0 },
};
#define NUM_DPRAM_REGIONS (sizeof(dpram_regions) / sizeof(dpram_regions[0]))
void *
m8xx_dpram_allocate( unsigned int byte_count )
{
unsigned int i;
ISR_Level level;
void *blockp = NULL;
byte_count = (byte_count + 3) & ~0x3;
/*
* Running with interrupts disabled is usually considered bad
* form, but this routine is probably being run as part of an
* initialization sequence so the effect shouldn't be too severe.
*/
_ISR_Disable (level);
for ( i = 0; i < NUM_DPRAM_REGIONS; i++ ) {
/*
* Verify that the region is available for use.
* This test is necessary because if extra microcode modules
* are installed, some regions are locked and unavailable.
* See MPC860 User's Manual Pages 19-9 to 19-11.
*/
if (dpram_regions[i].used == 0) {
volatile unsigned char *cp = dpram_regions[i].base;
*cp = 0xAA;
if (*cp != 0xAA)
dpram_regions[i].used = dpram_regions[i].size;
else {
*cp = 0x55;
if (*cp != 0x55)
dpram_regions[i].used = dpram_regions[i].size;
}
*cp = 0x0;
}
if (dpram_regions[i].size - dpram_regions[i].used >= byte_count) {
blockp = dpram_regions[i].base + dpram_regions[i].used;
dpram_regions[i].used += byte_count;
break;
}
}
_ISR_Enable(level);
if (blockp == NULL)
rtems_panic("Can't allocate %d bytes of dual-port RAM.\n", byte_count);
return blockp;
}

View File

@@ -0,0 +1,28 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = mpc8xx.h
MPC8XX_H_FILES = console.h cpm.h mmu.h
noinst_HEADERS = $(H_FILES) $(MPC8XX_H_FILES)
PREINSTALL_FILES = \
$(PROJECT_INCLUDE)/mpc8xx \
$(H_FILES:%.h=$(PROJECT_INCLUDE)/%.h) \
$(MPC8XX_H_FILES:%.h=$(PROJECT_INCLUDE)/mpc8xx/%.h)
$(PROJECT_INCLUDE)/mpc8xx:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/mpc8xx/%.h: %.h
$(INSTALL_DATA) $< $@
all-local: $(PREINSTALL_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,37 @@
/*
* $Id$
*/
#ifndef _M8xx_CONSOLE_H_
#define _M8xx_CONSOLE_H_
#include <rtems/libio.h>
void m8xx_uart_reserve_resources(rtems_configuration_table *configuration);
void m8xx_uart_initialize(void);
void m8xx_uart_interrupts_initialize(void);
void m8xx_uart_scc_initialize (int minor);
void m8xx_uart_smc_initialize (int minor);
/* Termios callbacks */
int m8xx_uart_pollRead(int minor);
int m8xx_uart_pollWrite(int minor, const char* buf, int len);
int m8xx_uart_write(int minor, const char *buf, int len);
int m8xx_uart_setAttributes(int, const struct termios* t);
#ifdef mpc860
#define NUM_PORTS 6 /* number of serial ports for mpc860 */
#else
#define NUM_PORTS 4 /* number of serial ports for mpc821 */
#endif
#define SMC1_MINOR 0
#define SMC2_MINOR 1
#define SCC1_MINOR 2
#define SCC2_MINOR 3
#define SCC3_MINOR 4
#define SCC4_MINOR 5
#endif

View File

@@ -0,0 +1,38 @@
/*
* cpm.h
*
* This include file contains definitions pertaining
* to the Communications Processor Module (CPM) on the MPC8xx.
*
* Copyright (c) 1999, National Research Council of Canada
*
* 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 __M8xx_CPM_h
#define __M8xx_CPM_h
#ifdef __cplusplus
extern "C" {
#endif
#include <bsp.h>
/* Functions */
void m8xx_cp_execute_cmd( unsigned16 command );
void *m8xx_dpram_allocate( unsigned int byte_count );
#define m8xx_bd_allocate(count) \
m8xx_dpram_allocate( (count) * sizeof(m8xxBufferDescriptor_t) )
#define m8xx_RISC_timer_table_allocate(count) \
m8xx_dpram_allocate( (count) * 4 )
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -0,0 +1,49 @@
/*
* mmu.h
*
* This include file contains definitions pertaining
* to the MMU on the MPC8xx.
*
* Copyright (c) 1999, National Research Council of Canada
*
* 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 __M8xx_MMU_h
#define __M8xx_MMU_h
#ifdef __cplusplus
extern "C" {
#endif
#include <bsp.h>
/*
* The MMU_TLB_table is used to statically initialize the Table Lookaside
* Buffers in the MMU of an MPC8xx.
*/
typedef struct {
unsigned32 mmu_epn; /* Effective Page Number */
unsigned32 mmu_twc; /* Tablewalk Control Register */
unsigned32 mmu_rpn; /* Real Page Number */
} MMU_TLB_table_t;
/*
* The MMU_TLB_table and its size, MMU_N_TLB_Table_Entries, must be
* supplied by the BSP.
*/
extern MMU_TLB_table_t MMU_TLB_table[]; /* MMU TLB table supplied by BSP */
extern int MMU_N_TLB_Table_Entries; /* Number of entries in MMU TLB table */
/* Functions */
void mmu_init( void );
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/mmu.rel
## C sources
C_FILES = mmu.c
clock_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 +=
#
AM_CFLAGS = $(CFLAGS_OS_V)
$(PGM): $(clock_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,120 @@
/*
* mmu.c
*
* This file contains routines for initializing
* and manipulating the MMU on the MPC8xx.
*
* Copyright (c) 1999, National Research Council of Canada
*
* 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 <bsp.h>
#include <mpc8xx/mmu.h>
/*
* mmu_init
*
* This routine sets up the virtual memory maps on an MPC8xx.
* The MPC8xx does not support block address translation (BATs)
* and does not have segment registers. Thus, we must set up page
* translation. However, its MMU supports variable size pages
* (1-, 4-, 16-, 512-Kbyte or 8-Mbyte), which simplifies the task.
*
* The MPC8xx has separate data and instruction 32-entry translation
* lookaside buffers (TLB). By mapping all of DRAM as one huge page,
* we can preload the TLBs and not have to be concerned with taking
* TLB miss exceptions.
*
* We set up the virtual memory map so that virtual address of a
* location is equal to its real address.
*/
void mmu_init( void )
{
register unsigned32 reg1, i;
/*
* Initialize the TLBs
*
* Instruction address translation and data address translation
* must be disabled during initialization (IR=0, DR=0 in MSR).
* We can assume the MSR has already been set this way.
*/
/*
* Initialize IMMU & DMMU Control Registers (MI_CTR & MD_CTR)
* GPM [0] 0b0 = PowerPC mode
* PPM [1] 0b0 = Page resolution of protection
* CIDEF [2] 0b0/0b1 = Default cache-inhibit attribute =
* NO for IMMU, YES for DMMU!
* reserved/WTDEF [3] 0b0 = Default write-through attribute = not
* RSV4x [4] 0b0 = 4 entries not reserved
* reserved/TWAM [5] 0b0/0b1 = 4-Kbyte page hardware assist
* PPCS [6] 0b0 = Ignore user/supervisor state
* reserved [7-18] 0x00
* xTLB_INDX [19-23] 31 = 0x1F
* reserved [24-31] 0x00
*
* Note: It is important that cache-inhibit be set as the default for the
* data cache when the DMMU is disabled in order to prevent internal memory
* mapped registers from being cached accidentally when address translation
* is turned off at the start of exception processing.
*/
reg1 = M8xx_MI_CTR_ITLB_INDX(31);
_mtspr( M8xx_MI_CTR, reg1 );
reg1 = M8xx_MD_CTR_CIDEF | M8xx_MD_CTR_TWAM | M8xx_MD_CTR_DTLB_INDX(31);
_mtspr( M8xx_MD_CTR, reg1 );
_isync;
/*
* Invalidate all TLB entries in both TLBs.
* Note: We rely on the RSV4 bit in MI_CTR and MD_CTR being 0b0, so
* all 32 entries are invalidated.
*/
__asm__ volatile ("tlbia\n"::);
_isync;
/*
* Set Current Address Space ID Register (M_CASID).
* Supervisor: CASID = 0
*/
reg1 = 0;
_mtspr( M8xx_M_CASID, reg1 );
/*
* Initialize the MMU Access Protection Registers (MI_AP, MD_AP)
* We ignore the Access Protection Group (APG) mechanism globally
* by setting all of the Mx_AP fields to 0b01 : client access
* permission is defined by page protection bits.
*/
reg1 = 0x55555555;
_mtspr( M8xx_MI_AP, reg1 );
_mtspr( M8xx_MD_AP, reg1 );
/*
* Load both 32-entry TLBs with values from the MMU_TLB_table
* which is defined in the BSP.
* Note the _TLB_Table must have at most 32 entries. This code
* makes no effort to enforce this restriction.
*/
for( i = 0; i < MMU_N_TLB_Table_Entries; ++i ) {
reg1 = MMU_TLB_table[i].mmu_epn;
_mtspr( M8xx_MI_EPN, reg1 );
_mtspr( M8xx_MD_EPN, reg1 );
reg1 = MMU_TLB_table[i].mmu_twc;
_mtspr( M8xx_MI_TWC, reg1 );
_mtspr( M8xx_MD_TWC, reg1 );
reg1 = MMU_TLB_table[i].mmu_rpn; /* RPN must be written last! */
_mtspr( M8xx_MI_RPN, reg1 );
_mtspr( M8xx_MD_RPN, reg1 );
}
/*
* Turn on address translation by setting MSR[IR] and MSR[DR].
*/
_CPU_MSR_Value( reg1 );
reg1 |= PPC_MSR_IR | PPC_MSR_DR;
_CPU_MSR_SET( reg1 );
}

View File

@@ -0,0 +1,30 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = ${ARCH}/timer.rel
## C sources
C_FILES = timer.c
timer_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 +=
#
AM_CFLAGS = $(CFLAGS_OS_V)
$(PGM): $(timer_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = $(C_FILES)
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,104 @@
/* timer.c
*
* This file manages the interval timer on the PowerPC MPC8xx.
* NOTE: This is not the PIT, but rather the RTEMS interval
* timer
* We shall use the bottom 32 bits of the timebase register,
*
* The following was in the 403 version of this file. I don't
* know what it means. JTM 5/19/98
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
* Author: Jay Monkman (jmonkman@frasca.com)
* Copywright (C) 1998 by Frasca International, Inc.
*
* Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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 <bsp.h>
#include <rtems.h>
#include <mpc8xx.h>
extern rtems_cpu_table Cpu_table; /* owned by BSP */
static volatile rtems_unsigned32 Timer_starting;
static rtems_boolean Timer_driver_Find_average_overhead;
/*
* This is so small that this code will be reproduced where needed.
*/
static inline rtems_unsigned32 get_itimer(void)
{
rtems_unsigned32 ret;
asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
return ret;
}
void Timer_initialize(void)
{
/* set interrupt level and enable timebase. This should never */
/* generate an interrupt however. */
m8xx.tbscr |= M8xx_TBSCR_TBIRQ(4) | M8xx_TBSCR_TBE;
Timer_starting = get_itimer();
}
int Read_timer(void)
{
rtems_unsigned32 clicks;
rtems_unsigned32 total;
clicks = get_itimer();
total = clicks - Timer_starting;
if ( Timer_driver_Find_average_overhead == 1 )
return total; /* in XXX microsecond units */
else {
if ( total < Cpu_table.timer_least_valid ) {
return 0; /* below timer resolution */
}
return (total - Cpu_table.timer_average_overhead);
}
}
rtems_status_code Empty_function(void)
{
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
}

View File

@@ -0,0 +1,33 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
## FIXME
VPATH = @srcdir@:@srcdir@/../../ppc403/vectors
PGM = ${ARCH}/vectors.rel
## Assembly sources
S_FILES = vectors.S align_h.S
vectors_rel_OBJECTS = $(S_FILES:%.S=${ARCH}/%.o)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
AM_CFLAGS = $(CFLAGS_OS_V)
$(PGM): $(vectors_rel_OBJECTS)
$(make-rel)
all-local: ${ARCH} $(PGM)
EXTRA_DIST = vectors.S README
include $(top_srcdir)/../../../../../automake/local.am

View File

@@ -0,0 +1,23 @@
#
# $Id$
#
The location of the vectors file object is critical.
From the comments at the head of vectors.S:
The issue with this file is getting it loaded at the right place.
The first vector MUST be at address 0x????0100.
How this is achieved is dependant on the tool chain.
...
The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
offset from 0x????0000 to the first location in the file. This
will be either 0x0000 or 0xfff0.
The eth_comm BSP defines PPC_VECTOR_FILE_BASE to be 0x00000000.
The MBX8xx BSP also defines PPC_VECTOR_FILE_BASE to be 0x00000000.
Change these values to 0xFFF00000 if your are implementing an actual
boot rom.

View File

@@ -0,0 +1,430 @@
/* align_h.S 1.1 - 95/12/04
*
* This file contains the assembly code for the MPC860
* alignment exception handler for RTEMS.
*
* Based upon IBM provided code for the PowerPC 403 with the following release:
*
* This source code has been made available to you by IBM on an AS-IS
* basis. Anyone receiving this source is licensed under IBM
* copyrights to use it in any way he or she deems fit, including
* copying it, modifying it, compiling it, and redistributing it either
* with or without modifications. No license under IBM patents or
* patent applications is to be implied by the copyright license.
*
* Any user of this software should understand that IBM cannot provide
* technical support for this software and will not be responsible for
* any consequences resulting from the use of this software.
*
* Any person who transfers this source code or any derivative work
* must include the IBM copyright notice, this paragraph, and the
* preceding two paragraphs in the transferred software.
*
* COPYRIGHT I B M CORPORATION 1995
* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
*
* Modifications:
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Additional modifications by Darlene Stewart (Darlene.Stewart@iit.nrc.ca):
* Removed saving and restoring of PPC403-specific SRR2 and SRR3.
* Access DAR instead of PPC403-specific DEAR.
*
* $Id$
*/
#include "asm.h"
#define ALIGN_REGS 0x0140
.set CACHE_SIZE,16 # cache line size of 32 bytes
.set CACHE_SIZE_L2,4 # cache line size, log 2
.set Open_gpr0,0
.set Open_gpr1,4
.set Open_gpr2,8
.set Open_gpr3,12
.set Open_gpr4,16
.set Open_gpr5,20
.set Open_gpr6,24
.set Open_gpr7,28
.set Open_gpr8,32
.set Open_gpr9,36
.set Open_gpr10,40
.set Open_gpr11,44
.set Open_gpr12,48
.set Open_gpr13,52
.set Open_gpr14,56
.set Open_gpr15,60
.set Open_gpr16,64
.set Open_gpr17,68
.set Open_gpr18,72
.set Open_gpr19,76
.set Open_gpr20,80
.set Open_gpr21,84
.set Open_gpr22,88
.set Open_gpr23,92
.set Open_gpr24,96
.set Open_gpr25,100
.set Open_gpr26,104
.set Open_gpr27,108
.set Open_gpr28,112
.set Open_gpr29,116
.set Open_gpr30,120
.set Open_gpr31,124
.set Open_xer,128
.set Open_lr,132
.set Open_ctr,136
.set Open_cr,140
.set Open_srr0,144
.set Open_srr1,148
/*
* This code makes several assumptions for processing efficiency
* * General purpose registers are continuous in the image, beginning with
* Open_gpr0
* * Hash table is highly dependent on opcodes - opcode changes *will*
* require rework of the instruction decode mechanism.
*/
.text
.globl align_h
.align CACHE_SIZE_L2
align_h:
/*-----------------------------------------------------------------------
* Store GPRs in Open Reg save area
* Set up r2 as base reg, r1 pointing to Open Reg save area
*----------------------------------------------------------------------*/
stmw r0,ALIGN_REGS(r0)
li r1,ALIGN_REGS
/*-----------------------------------------------------------------------
* Store special purpose registers in reg save area
*----------------------------------------------------------------------*/
mfxer r7
mflr r8
mfcr r9
mfctr r10
stw r7,Open_xer(r1)
stw r8,Open_lr(r1)
stw r9,Open_cr(r1)
stw r10,Open_ctr(r1)
mfspr r9, srr0 /* SRR 0 */
mfspr r10, srr1 /* SRR 1 */
stw r9,Open_srr0(r1)
stw r10,Open_srr1(r1)
/* Set up common registers */
mfspr r5, dar /* DAR: R5 is data (exception) address */
lwz r9,Open_srr0(r1) /* get faulting instruction */
addi r7,r9,4 /* bump instruction */
stw r7,Open_srr0(r1) /* restore to image */
lwz r9, 0(r9) /* retrieve actual instruction */
rlwinm r6,r9,18,25,29 /* r6 is RA * 4 field from instruction */
rlwinm r7,r9,6,26,31 /* r7 is primary opcode */
bl ref_point /* establish addressibility */
ref_point:
mflr r11 /* r11 is the anchor point for ref_point */
addi r10, r7, -31 /* r10 = r7 - 31 */
rlwinm r10,r10,2,2,31 /* r10 *= 4 */
add r10, r10, r11 /* r10 += anchor point */
lwz r10, primary_jt-ref_point(r10)
mtlr r10
rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */
la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */
blr
primary_jt:
.long xform
.long lwz
.long lwzu
.long 0
.long 0
.long stw
.long stwu
.long 0
.long 0
.long lhz
.long lhzu
.long lha
.long lhau
.long sth
.long sthu
.long lmw
.long stmw
/*
* handlers
*/
/*
* xform instructions require an additional decode. Fortunately, a relatively
* simple hash step breaks the instructions out with no collisions
*/
xform:
rlwinm r7,r9,31,22,31 /* r7 is secondary opcode */
rlwinm r10,r7,27,5,31 /* r10 = r7 >> 5 */
add r10,r7,r10 /* r10 = r7 + r10 */
rlwinm r10,r10,2,25,29 /* r10 = (r10 & 0x1F) * 4 */
add r10,r10,r11 /* r10 += anchor point */
lwz r10, secondary_ht-ref_point(r10)
mtlr r10
la r7,Open_gpr0(r1) /* r7 is address of GPR 0 in list */
rlwinm r8,r9,13,25,29 /* r8 is RD * 4 */
blrl
secondary_ht:
.long lhzux /* b 0 0x137 */
.long lhax /* b 1 0x157 */
.long lhaux /* b 2 0x177 */
.long sthx /* b 3 0x197 */
.long sthux /* b 4 0x1b7 */
.long 0 /* b 5 */
.long lwbrx /* b 6 0x216 */
.long 0 /* b 7 */
.long 0 /* b 8 */
.long 0 /* b 9 */
.long stwbrx /* b A 0x296 */
.long 0 /* b B */
.long 0 /* b C */
.long 0 /* b D */
.long lhbrx /* b E 0x316 */
.long 0 /* b F */
.long 0 /* b 10 */
.long 0 /* b 11 */
.long sthbrx /* b 12 0x396 */
.long 0 /* b 13 */
.long lwarx /* b 14 0x014 */
.long dcbz /* b 15 0x3f6 */
.long 0 /* b 16 */
.long lwzx /* b 17 0x017 */
.long lwzux /* b 18 0x037 */
.long 0 /* b 19 */
.long stwcx /* b 1A 0x096 */
.long stwx /* b 1B 0x097 */
.long stwux /* b 1C 0x0B7 */
.long 0 /* b 1D */
.long 0 /* b 1E */
.long lhzx /* b 1F 0x117 */
/*
* for all handlers
* r4 - Addressability to interrupt context
* r5 - DAR address (faulting data address)
* r6 - RA field * 4
* r7 - Address of GPR 0 in image
* r8 - RD field * 4
* r9 - Failing instruction
*/
/* Load halfword algebraic with update */
lhau:
/* Load halfword algebraic with update indexed */
lhaux:
stwx r5,r7,r6 /* update RA with effective addr */
/* Load halfword algebraic */
lha:
/* Load halfword algebraic indexed */
lhax:
lswi r10,r5,2 /* load two bytes into r10 */
srawi r10,r10,16 /* shift right 2 bytes, extending sign */
stwx r10,r7,r8 /* update reg image */
b align_complete /* return */
/* Load Half Word Byte-Reversed Indexed */
lhbrx:
lswi r10,r5,2 /* load two bytes from DEAR into r10 */
rlwinm r10,r10,0,0,15 /* mask off lower 2 bytes */
stwbrx r10,r7,r8 /* store reversed in reg image */
b align_complete /* return */
/* Load Half Word and Zero with Update */
lhzu:
/* Load Half Word and Zero with Update Indexed */
lhzux:
stwx r5,r7,r6 /* update RA with effective addr */
/* Load Half Word and Zero */
lhz:
/* Load Half Word and Zero Indexed */
lhzx:
lswi r10,r5,2 /* load two bytes from DEAR into r10 */
rlwinm r10,r10,16,16,31 /* shift right 2 bytes, with zero fill */
stwx r10,r7,r8 /* update reg image */
b align_complete /* return */
/*
* Load Multiple Word
*/
lmw:
lwzx r9,r6,r7 /* R9 contains saved value of RA */
addi r10,r7,32*4 /* r10 points to r31 in image + 4 */
rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */
subfic r8,r8,32 /* r8 is reg count to load */
mtctr r8 /* load counter */
addi r8,r8,-1 /* r8-- */
rlwinm r8,r8,2,2,31 /* r8 *= 4 */
add r5,r5,r8 /* update DEAR to point to last reg */
lwmloop:
lswi r11,r5,4 /* load r11 with 4 bytes from DEAR */
stwu r11,-4(r10) /* load image and decrement pointer */
addi r5,r5,-4 /* decrement effective address */
bdnz lwmloop
stwx r9,r6,r7 /* restore RA (in case it was trashed) */
b align_complete /* return */
/*
* Load Word and Reserve Indexed
*/
lwarx:
lswi r10,r5,4 /* load four bytes from DEAR into r10 */
stwx r10,r7,r8 /* update reg image */
rlwinm r5,r5,0,0,29 /* Word align address */
lwarx r10,0,r5 /* Set reservation */
b align_complete /* return */
/*
* Load Word Byte-Reversed Indexed
*/
lwbrx:
lswi r10,r5,4 /* load four bytes from DEAR into r10 */
stwbrx r10,r7,r8 /* store reversed in reg image */
b align_complete /* return */
/* Load Word and Zero with Update */
lwzu:
/* Load Word and Zero with Update Indexed */
lwzux:
stwx r5,r7,r6 /* update RA with effective addr */
/* Load Word and Zero */
lwz:
/* Load Word and Zero Indexed */
lwzx:
lswi r10,r5,4 /* load four bytes from DEAR into r10 */
stwx r10,r7,r8 /* update reg image */
b align_complete /* return */
/* Store instructions */
/* */
/* Store Half Word and Update */
sthu:
/* Store Half Word and Update Indexed */
sthux:
stwx r5,r7,r6 /* Update RA with effective address */
/* Store Half Word */
sth:
/* Store Half Word Indexed */
sthx:
lwzx r10,r8,r7 /* retrieve source register value */
rlwinm r10,r10,16,0,15 /* move two bytes to high end of reg */
stswi r10,r5,2 /* store bytes to DEAR address */
b align_complete /* return */
/* */
/* Store Half Word Byte-Reversed Indexed */
sthbrx:
lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */
stswi r10,r5,2 /* move two bytes to DEAR address */
b align_complete /* return */
/* */
/* Store Multiple Word */
stmw:
addi r10,r7,32*4 /* r10 points to r31 in image + 4 */
rlwinm r8,r8,30,2,31 /* r8 >>= 2 (recovers RT) */
subfic r8,r8,32 /* r8 is reg count to load */
mtctr r8 /* load counter */
addi r8,r8,-1 /* r8-- */
rlwinm r8,r8,2,2,31 /* r8 *= 4 */
add r5,r5,r8 /* update DEAR to point to last reg */
stmloop:
lwzu r11,-4(r10) /* get register value */
stswi r11,r5,4 /* output to DEAR address */
addi r5,r5,-4 /* decrement effective address */
bdnz stmloop
b align_complete /* return */
/* */
/* Store Word and Update */
stwu:
/* Store Word and Update Indexed */
stwux:
stwx r5,r7,r6 /* Update RA with effective address */
/* Store Word */
stw:
/* Store Word Indexed */
stwx:
lwzx r10,r8,r7 /* retrieve source register value */
stswi r10,r5,4 /* store bytes to DEAR address */
b align_complete /* return */
/* */
/* Store Word Byte-Reversed Indexed */
stwbrx:
lwbrx r10,r8,r7 /* retrieve src reg value byte reversed */
stswi r10,r5,4 /* move two bytes to DEAR address */
b align_complete /* return */
/* */
/* Store Word Conditional Indexed */
stwcx:
rlwinm r10,r5,0,0,29 /* r10 = word aligned DEAR */
lwz r11,0(r10) /* save original value of store */
stwcx. r11,r0,r10 /* attempt store to address */
bne stwcx_moveon /* store failed, move on */
stw r11,0(r10) /* repair damage */
lwzx r9,r7,r8 /* get register value */
stswi r10,r5,4 /* store bytes to DEAR address */
stwcx_moveon:
mfcr r11 /* get condition reg */
lwz r9,Open_cr(r1) /* get condition reg image */
rlwimi r9,r11,0,0,2 /* insert 3 CR bits into cr image */
lwz r11,Open_xer(r1) /* get XER reg */
rlwimi r9,r11,29,2,2 /* insert XER SO bit into cr image */
stw r9,Open_cr(r1) /* store cr image */
b align_complete /* return */
/* */
/* Data Cache Block Zero */
dcbz:
rlwinm r5,r5,0,0,31-CACHE_SIZE_L2
/* get address to nearest Cache line */
addi r5,r5,-4 /* adjust by a word */
addi r10,r0,CACHE_SIZE/4 /* set counter value */
mtctr r10
addi r11,r0,0 /* r11 = 0 */
dcbz_loop:
stwu r11,4(r5) /* store a word and update EA */
bdnz dcbz_loop
b align_complete /* return */
align_complete:
/*-----------------------------------------------------------------------
* Restore regs and return from the interrupt
*----------------------------------------------------------------------*/
lmw r26,Open_xer+ALIGN_REGS(r0)
mtxer r26
mtlr r27
mtctr r28
mtcrf 0xFF, r29
mtspr srr0, r30 /* SRR 0 */
mtspr srr1, r31 /* SRR 1 */
lmw r1,Open_gpr1+ALIGN_REGS(r0)
lwz r0,Open_gpr0+ALIGN_REGS(r0)
rfi

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
int _CPU_spurious_count = 0;
int _CPU_last_spurious = 0;
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
++_CPU_spurious_count;
_CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
case PPC_IRQ_CPM_RESERVED_0:
case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:

View File

@@ -5,7 +5,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
# C source names
C_FILES = cpu.c ppccache.c
C_FILES = cpu.c
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o)
ROOT_H_FILES =

View File

@@ -50,6 +50,9 @@
static void ppc_spurious(int, CPU_Interrupt_frame *);
int _CPU_spurious_count = 0;
int _CPU_last_spurious = 0;
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
@@ -369,6 +372,8 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
++_CPU_spurious_count;
_CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
@@ -748,7 +753,7 @@ unsigned32 ppc_exception_vector_addr(
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
case PPC_IRQ_CPM_RESERVED_0:
case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:

View File

@@ -766,6 +766,15 @@ SCORE_EXTERN struct {
); \
} while (0)
#define _CPU_Data_Cache_Block_Invalidate( _address ) \
do { register void *__address = (_address); \
register unsigned32 _zero = 0; \
asm volatile ( "dcbi %0,%1" : \
"=r" (_zero), "=r" (__address) : \
"0" (_zero), "1" (__address) \
); \
} while (0)
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).

View File

@@ -1,7 +1,7 @@
/*
* cpu.h
*
* This file contains some powerpc MSR and registers access definitions.
* This file contains some powerpc MSR and registers access definitions.
*
* It is a stripped down version of linux ppc processor.h file...
*
@@ -15,10 +15,12 @@
* $Id$
*/
#ifndef __ASM_PPC_PROCESSOR_H
#define __ASM_PPC_PROCESSOR_H
#ifndef __PPC_CPU_H
#define __PPC_CPU_H
#include <bsp/residual.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Bit encodings for Machine State Register (MSR) */
#define MSR_POW (1<<18) /* Enable Power Management */
@@ -247,16 +249,6 @@ static inline void PPC_Set_timebase_register (unsigned long long tbr)
}
#define _CPU_Data_Cache_Block_Flush( _address ) \
do { register void *__address = (_address); \
register unsigned32 _zero = 0; \
asm volatile ( "dcbf %0,%1" : \
"=r" (_zero), "=r" (__address) : \
"0" (_zero), "1" (__address) \
); \
} while (0)
/*
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
* This indicates the end of an RTEMS critical section. The parameter
@@ -325,7 +317,12 @@ static inline void PPC_Set_timebase_register (unsigned long long tbr)
asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \
} while (0)
#endif /* __ASM_PPC_PROCESSOR_H */
#ifdef __cplusplus
}
#endif
#endif /* __PPC_CPU_H */

View File

@@ -88,17 +88,26 @@ endif
# debug flag;
CFLAGS_DEBUG_V+=-Wno-unused
CXXFLAGS_DEBUG_V+=
ifeq ($(RTEMS_USE_GCC272),no)
CFLAGS_DEBUG_V+=-qrtems_debug
CXXFLAGS_DEBUG_V+=-qrtems_debug
endif
# when debugging, optimize flag: typically empty
# some compilers do allow optimization with their "-g"
CFLAGS_DEBUG_OPTIMIZE_V=-g
CXXFLAGS_DEBUG_OPTIMIZE_V=-g
# profile flag; use gprof(1)
CFLAGS_PROFILE_V=-pg
CXXFLAGS_PROFILE_V=-pg
ifndef AUTOMAKE
# default is to optimize
CFLAGS_OPTIMIZE=$(CFLAGS_OPTIMIZE_V)
CFLAGS_OPTIMIZE =$(CFLAGS_OPTIMIZE_V)
CXXFLAGS_OPTIMIZE=$(CXXFLAGS_OPTIMIZE_V)
endif
# dynamic libraries
@@ -106,7 +115,8 @@ endif
#ASFLAGS_DYNAMIC_V=
ifndef AUTOMAKE
CFLAGS += $(CFLAGS_OPTIMIZE) $(CFLAGS_DEBUG) $(CFLAGS_PROFILE)
CFLAGS += $(CFLAGS_OPTIMIZE) $(CFLAGS_DEBUG) $(CFLAGS_PROFILE)
CXXFLAGS += $(CXXFLAGS_OPTIMIZE) $(CXXFLAGS_DEBUG) $(CXXFLAGS_PROFILE)
endif
# List of library paths without -L

View File

@@ -67,6 +67,7 @@ AC_SUBST(BARE_CPU_MODEL)
AC_CONFIG_SUBDIRS(tools)
AC_CONFIG_SUBDIRS(support)
AC_CONFIG_SUBDIRS(samples)
AC_CONFIG_SUBDIRS(libffi)
AC_CONFIG_SUBDIRS($cfg_subdirs)
# Explicitly list all Makefiles here

Some files were not shown because too many files have changed in this diff Show More