added haleakala BSP contributed by Michael Hamel

This commit is contained in:
Thomas Doerfler
2008-07-14 08:46:06 +00:00
parent 9ec9123344
commit 3c6fe2e7f9
40 changed files with 2658 additions and 80 deletions

View File

@@ -1,3 +1,13 @@
2008-07-14 Thomas Doerfler <thomas.doerfler@embedded-brains.de>
* Makefile.am, new-exceptions/raw_exception.c,
* new-exceptions/bspsupport/irq.c, ppc403/clock/clock_4xx.c,
* ppc403/include/ppc405ex.h, ppc403/include/ppc405gp.h,
* ppc403/timer/timer.c, rtems/powerpc/powerpc.h,
* shared/include/cpuIdent.c, shared/include/cpuIdent.h,
* shared/include/powerpc-utility.h:
Added support for PPC405EX (contributed by Michael Hamel)
2008-07-11 Sebastian Huber <sebastian.huber@embedded-brains.de>
* Makefile.am: Install powerpc-utility.h.
@@ -15,13 +25,14 @@
ppc_exc_vector_base for CPUs with IVPR register.
* new-exceptions/bspsupport/ppc_exc.S,
new-exceptions/bspsupport/ppc_exc_asm_macros.h,
new-exceptions/bspsupport/ppc_exc_bspsupp.h,
new-exceptions/bspsupport/ppc_exc_hdl.c,
new-exceptions/bspsupport/vectors.h,
new-exceptions/bspsupport/vectors_init.c: Conistent code layout in most
assember code sections and usage of defines for registers. Usage of
standard header files to avoid multiple definitions.
* new-exceptions/bspsupport/ppc_exc_asm_macros.h,
* new-exceptions/bspsupport/ppc_exc_bspsupp.h,
* new-exceptions/bspsupport/ppc_exc_hdl.c,
* new-exceptions/bspsupport/vectors.h,
* new-exceptions/bspsupport/vectors_init.c:
Conistent code layout in most assember code sections and usage of
defines for registers. Usage of standard header files to avoid
multiple definitions.
Optimized exception code: Removed many branches and exploit branch
prediction for asynchronous exceptions, moved common wrap code into

View File

@@ -126,8 +126,19 @@ ppc403_tty_drv_rel_CPPFLAGS = $(AM_CPPFLAGS)
ppc403_tty_drv_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
endif
endif # ppc403
if ppc405
## ppc4xx/include
include_ppc4xxdir = $(includedir)/ppc4xx
include_ppc4xx_HEADERS = ppc403/include/ppc405gp.h \
ppc403/include/ppc405ex.h
endif # ppc405
## mpc5xx
EXTRA_DIST += mpc5xx/README
if mpc5xx
include_mpc5xxdir = $(includedir)/mpc5xx
@@ -341,6 +352,7 @@ mpc8260_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
if mpc83xx
include_mpc83xxdir = $(includedir)/mpc83xx
include_mpc83xx_HEADERS = mpc83xx/include/mpc83xx.h
include_mpc83xx_HEADERS += mpc83xx/network/tsec.h

View File

@@ -38,6 +38,7 @@ static rtems_irq_connect_data* rtems_hdl_tbl;
SPR_RW(BOOKE_TSR)
SPR_RW(PPC405_TSR)
/* legacy mode for bookE DEC exception;
* to avoid the double layer of function calls
@@ -52,8 +53,12 @@ int C_dispatch_dec_handler_bookE (BSP_Exception_frame *frame, unsigned int excNu
/* clear interrupt; we must do this
* before C_dispatch_irq_handler()
* re-enables MSR_EE.
* Note that PPC405 uses a different SPR# for TSR
*/
_write_BOOKE_TSR( BOOKE_TSR_DIS );
if ( ppc_cpu_is_bookE()==PPC_BOOKE_405)
_write_PPC405_TSR( BOOKE_TSR_DIS );
else
_write_BOOKE_TSR( BOOKE_TSR_DIS );
return C_dispatch_irq_handler(frame, ASM_DEC_VECTOR);
}

View File

@@ -162,7 +162,8 @@ static const cat_ini_t mpc_5xx_vector_categories[LAST_VALID_EXC + 1] = {
static const cat_ini_t ppc_405_vector_categories[LAST_VALID_EXC + 1] = {
[ ASM_EXT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_BOOKE_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC,
[ ASM_BOOKE_DEC_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, /* PIT */
[ ASM_BOOKE_FIT_VECTOR ] = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, /* FIT */
[ ASM_PROT_VECTOR ] = PPC_EXC_CLASSIC,
[ ASM_ISI_VECTOR ] = PPC_EXC_CLASSIC,
@@ -371,6 +372,8 @@ ppc_raw_exception_category rval = PPC_EXC_INVALID;
rval = mpc_860_vector_categories[vector];
break;
case PPC_405:
case PPC_405GP:
case PPC_405EX:
rval = ppc_405_vector_categories[vector];
break;
default:

View File

@@ -0,0 +1,251 @@
/* clock.c
*
* This routine initializes the interval timer on the
* PowerPC 405 CPU. The tick frequency is specified by the bsp.
*
* 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:
*
* Modifications for deriving timer clock from cpu system clock by
* Thomas Doerfler <td@imd.m.isar.de>
* for these modifications:
* COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
*
* COPYRIGHT (c) 1989-2007.
* 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.rtems.com/license/LICENSE.
*
* Modifications for PPC405GP by Dennis Ehlin
*
* Further modifications for PPC405GP/EX by Michael Hamel
*
* $Id$
*/
#include <rtems.h>
#include <rtems/clockdrv.h>
#include <rtems/libio.h>
#include <stdlib.h> /* for atexit() */
#include <rtems/bspIo.h>
#include <ppc405common.h>
#include <libcpu/cpuIdent.h>
#include <bsp/irq.h>
/* PPC405GP */
#define CPC0_CR1 0xB2
#define CR1_CETE 0x00800000
/* PPC405EX */
#define SDR0_C405 0x180
#define SDR_CETE 0x02000000
volatile uint32_t Clock_driver_ticks;
static uint32_t pit_value, tick_time;
void Clock_exit( 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 */
);
/* Defined in bspstart.c */
extern uint32_t bsp_clicks_per_usec;
extern boolean bsp_timer_internal_clock;
/*
* 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
*/
void Clock_isr(void* handle)
{
Clock_driver_ticks++;
rtems_clock_tick();
}
int ClockIsOn(const rtems_irq_connect_data* unused)
{
return ((mfspr(TCR) & PIE) != 0);
}
void ClockOff(const rtems_irq_connect_data* unused)
{
register uint32_t r;
r = mfspr(TCR);
mtspr(TCR, r & ~(PIE | ARE) );
}
void ClockOn(const rtems_irq_connect_data* unused)
{
uint32_t iocr, r;
ppc_cpu_id_t cpu;
Clock_driver_ticks = 0;
cpu = get_ppc_cpu_type();
if (cpu==PPC_405GP) {
iocr = mfdcr(CPC0_CR1);
if (bsp_timer_internal_clock) iocr &= ~CR1_CETE ;/* timer clocked from system clock */
else iocr |= CR1_CETE; /* select external timer clock */
mtdcr(CPC0_CR1,iocr);
} else if (cpu==PPC_405EX) {
mfsdr(SDR0_C405,iocr);
if (bsp_timer_internal_clock) iocr &= ~SDR_CETE ;/* timer clocked from system clock */
else iocr |= SDR_CETE; /* select external timer clock */
mtsdr(SDR0_C405,iocr);
} else {
printk("clock.c:unrecognised CPU");
rtems_fatal_error_occurred(1);
}
pit_value = rtems_configuration_get_microseconds_per_tick() * bsp_clicks_per_usec;
mtspr(PIT,pit_value);
tick_time = mfspr(TBL) + pit_value;
r = mfspr(TCR);
mtspr(TCR, r | PIE | ARE);
}
void Install_clock(void (*clock_isr)(void *))
{
/*
* 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_irq_connect_data clockIrqConnData;
Clock_driver_ticks = 0;
clockIrqConnData.on = ClockOn;
clockIrqConnData.off = ClockOff;
clockIrqConnData.isOn = ClockIsOn;
clockIrqConnData.name = BSP_PIT;
clockIrqConnData.hdl = clock_isr;
if ( ! BSP_install_rtems_irq_handler (&clockIrqConnData)) {
printk("Unable to connect Clock Irq handler\n");
rtems_fatal_error_occurred(1);
}
atexit(Clock_exit);
}
void
ReInstall_clock(void (*new_clock_isr)(void *))
{
uint32_t isrlevel = 0;
rtems_irq_connect_data clockIrqConnData;
rtems_interrupt_disable(isrlevel);
clockIrqConnData.name = BSP_PIT;
if ( ! BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
printk("Unable to stop system clock\n");
rtems_fatal_error_occurred(1);
}
BSP_remove_rtems_irq_handler (&clockIrqConnData);
clockIrqConnData.on = ClockOn;
clockIrqConnData.off = ClockOff;
clockIrqConnData.isOn = ClockIsOn;
clockIrqConnData.name = BSP_PIT;
clockIrqConnData.hdl = new_clock_isr;
if (!BSP_install_rtems_irq_handler (&clockIrqConnData)) {
printk("Unable to connect Clock Irq handler\n");
rtems_fatal_error_occurred(1);
}
rtems_interrupt_enable(isrlevel);
}
/*
* Called via atexit()
* Remove the clock interrupt handler by setting handler to NULL
*
* This will not work on the 405GP because
* when bit's are set in TCR they can only be unset by a reset
*/
void Clock_exit(void)
{
rtems_irq_connect_data clockIrqConnData;
clockIrqConnData.name = BSP_PIT;
if (!BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
printk("Unable to stop system clock\n");
rtems_fatal_error_occurred(1);
}
BSP_remove_rtems_irq_handler (&clockIrqConnData);
}
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!=NULL) {
/*
* 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(NULL);
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
ReInstall_clock(args->buffer);
}
return RTEMS_SUCCESSFUL;
}

View File

@@ -0,0 +1,158 @@
/*
Constants for manipulating system registers of PPC 405EX in C
Michael Hamel ADInstruments May 2008
*/
#include <libcpu/powerpc-utility.h>
/* Indirect access to Clocking/Power-On registers */
#define CPR0_DCR_BASE 0x0C
#define cprcfga (CPR0_DCR_BASE+0x0)
#define cprcfgd (CPR0_DCR_BASE+0x1)
#define mtcpr(reg, d) \
do { \
PPC_SET_DEVICE_CONTROL_REGISTER(cprcfga,reg); \
PPC_SET_DEVICE_CONTROL_REGISTER(cprcfgd,d); \
} while (0)
#define mfcpr(reg, d) \
do { \
PPC_SET_DEVICE_CONTROL_REGISTER(cprcfga,reg); \
d = PPC_DEVICE_CONTROL_REGISTER(cprcfgd); \
} while (0)
/* Indirect access to System registers */
#define SDR_DCR_BASE 0x0E
#define sdrcfga (SDR_DCR_BASE+0x0)
#define sdrcfgd (SDR_DCR_BASE+0x1)
#define mtsdr(reg, d) \
do { \
PPC_SET_DEVICE_CONTROL_REGISTER(sdrcfga,reg); \
PPC_SET_DEVICE_CONTROL_REGISTER(sdrcfgd,d); \
} while (0)
#define mfsdr(reg, d) \
do { \
PPC_SET_DEVICE_CONTROL_REGISTER(sdrcfga,reg); \
d = PPC_DEVICE_CONTROL_REGISTER(sdrcfgd); \
} while (0)
/* Indirect access to EBC registers */
#define EBC_DCR_BASE 0x12
#define ebccfga (EBC_DCR_BASE+0x0)
#define ebccfgd (EBC_DCR_BASE+0x1)
#define mtebc(reg, d) \
do { \
PPC_SET_DEVICE_CONTROL_REGISTER(ebccfga,reg); \
PPC_SET_DEVICE_CONTROL_REGISTER(ebccfgd,d); \
} while (0)
#define mfebc(reg, d) \
do { \
PPC_SET_DEVICE_CONTROL_REGISTER(ebccfga,reg); \
d = PPC_DEVICE_CONTROL_REGISTER(ebccfgd); \
} while (0)
/* EBC DCRs */
enum {
/*
EBC0_B0CR = 0,
EBC0_B1CR = 1,
EBC0_B2CR = 2,
EBC0_B3CR = 3,
EBC0_B0AP = 0x10,
EBC0_B1AP = 0x11,
EBC0_B2AP = 0x12,
EBC0_B3AP = 0x13,
EBC0_BEAR = 0x20,
EBC0_BESR = 0x21,
EBC0_CFG = 0x23,
*/
EBC0_CID = 0x24
};
enum {
SDR0_UART0 = 0x120,
SDR0_UART1 = 0x121,
SDR0_C405 = 0x180,
SDR0_MALTBL = 0x280,
SDR0_MALRBL = 0x2A0,
SDR0_MALTBS = 0x2C0,
SDR0_MALRBS = 0x2E0
};
/* Memory-mapped registers */
/*======================= Ethernet =================== */
typedef struct EthernetRegisters_EX {
uint32_t mode0;
uint32_t mode1;
uint32_t xmtMode0;
uint32_t xmtMode1;
uint32_t rcvMode;
uint32_t intStatus;
uint32_t intEnable;
uint32_t addrHi;
uint32_t addrLo;
uint32_t VLANTPID;
uint32_t VLANTCI;
uint32_t pauseTimer;
uint32_t multicastAddr[2];
uint32_t multicastMask[2];
uint32_t unused[4];
uint32_t lastSrcLo;
uint32_t lastSrcHi;
uint32_t IPGap;
uint32_t STAcontrol;
uint32_t xmtReqThreshold;
uint32_t rcvWatermark;
uint32_t bytesXmtd;
uint32_t bytesRcvd;
uint32_t unused2;
uint32_t revID;
uint32_t unused3[2];
uint32_t indivHash[8];
uint32_t groupHash[8];
uint32_t xmtPause;
} EthernetRegisters_EX;
enum {
EMAC0Address = 0xEF600900,
EMAC1Address = 0xEF600A00
};
typedef struct GPIORegisters {
uint32_t OR;
uint32_t GPIO_TCR; /* Note that TCR is defined as a DCR name */
uint32_t OSRL;
uint32_t OSRH;
uint32_t TSRL;
uint32_t TSRH;
uint32_t ODR;
uint32_t IR;
uint32_t RR1;
uint32_t RR2;
uint32_t RR3;
uint32_t unknown;
uint32_t ISR1L;
uint32_t ISR1H;
uint32_t ISR2L;
uint32_t ISR2H;
uint32_t ISR3L;
uint32_t ISR3H;
} GPIORegisters;
enum { GPIOAddress = 0xEF600800 };

View File

@@ -0,0 +1,146 @@
/* SDRAM DCRs */
enum {
SDRAM0_BESR0 = 0,
SDRAM0_BESR1 = 8,
SDRAM0_BEAR = 0x10,
SDRAM0_CFG = 0x20,
SDRAM0_STATUS = 0x24,
SDRAM0_RTR = 0x30,
SDRAM0_PMIT = 0x34,
SDRAM0_TR = 0x80
};
/* EBC DCRs */
enum {
EBC0_B0CR = 0,
EBC0_B1CR = 1,
EBC0_B2CR = 2,
EBC0_B3CR = 3,
EBC0_B4CR = 4,
EBC0_B5CR = 5,
EBC0_B6CR = 6,
EBC0_B7CR = 7,
EBC0_B0AP = 0x10,
EBC0_B1AP = 0x11,
EBC0_B2AP = 0x12,
EBC0_B3AP = 0x13,
EBC0_B4AP = 0x14,
EBC0_B5AP = 0x15,
EBC0_B6AP = 0x16,
EBC0_B7AP = 0x17,
EBC0_BEAR = 0x20,
EBC0_BESR0 = 0x21,
EBC0_BESR1 = 0x22,
EBC0_CFG = 0x23
};
/* Memory-mapped registers */
typedef struct EthernetRegisters_GP {
uint32_t mode0;
uint32_t mode1;
uint32_t xmtMode0;
uint32_t xmtMode1;
uint32_t rcvMode;
uint32_t intStatus;
uint32_t intEnable;
uint32_t addrHi;
uint32_t addrLo;
uint32_t VLANTPID;
uint32_t VLANTCI;
uint32_t pauseTimer;
uint32_t indivHash[4];
uint32_t groupHash[4];
uint32_t lastSrcLo;
uint32_t lastSrcHi;
uint32_t IPGap;
uint32_t STAcontrol;
uint32_t xmtReqThreshold;
uint32_t rcvWatermark;
uint32_t bytesXmtd;
uint32_t bytesRcvd;
} EthernetRegisters_GP;
enum { EMACAddress = 0xEF600800 };
enum {
// Mode 0 bits
kEMACRxIdle = 0x80000000,
kEMACTxIdle = 0x40000000,
kEMACSoftRst = 0x20000000,
kEMACTxEnable = 0x10000000,
kEMACRxEnable = 0x08000000,
// Mode 1 bits
kEMACFullDuplex = 0x80000000,
kEMACIgnoreSQE = 0x01000000,
kEMAC100MBbps = 0x00400000,
kEMAC4KRxFIFO = 0x00300000,
kEMAC2KTxFIFO = 0x00080000,
kEMACTx0Multi = 0x00008000,
kEMACTxDependent= 0x00014000,
// Tx mode bits
kEMACNewPacket0 = 0x80000000,
kEMACNewPacket1 = 0x40000000,
// Receive mode bits
kEMACStripPadding = 0x80000000,
kEMACStripFCS = 0x40000000,
kEMACRcvRunts = 0x20000000,
kEMACRcvFCSErrs = 0x10000000,
kEMACRcvOversize = 0x08000000,
kEMACPromiscRcv = 0x01000000,
kEMACPromMultRcv = 0x00800000,
kEMACIndivRcv = 0x00400000,
kEMACHashRcv = 0x00200000,
kEMACBrcastRcv = 0x00100000,
kEMACMultcastRcv = 0x00080000,
// Buffer descriptor control bits
kMALTxReady = 0x8000,
kMALRxEmpty = 0x8000,
kMALWrap = 0x4000,
kMALContinuous = 0x2000,
kMALLast = 0x1000,
kMALRxFirst = 0x0800,
kMALInterrupt = 0x0400,
// EMAC Tx descriptor bits sent
kEMACGenFCS = 0x200,
kEMACGenPad = 0x100,
kEMACInsSrcAddr = 0x080,
kEMACRepSrcAddr = 0x040,
kEMACInsVLAN = 0x020,
kEMACRepVLAN = 0x010,
// EMAC TX descriptor bits returned
kEMACErrMask = 0x3FF,
kEMACFCSWrong = 0x200,
kEMACBadPrev = 0x100,
kEMACLostCarrier = 0x080,
kEMACDeferred = 0x040,
kEMACCollFail = 0x020,
kEMACLateColl = 0x010,
kEMACMultColl = 0x008,
kEMACOneColl = 0x004,
kEMACUnderrun = 0x002,
kEMACSQEFail = 0x001,
// EMAC Rx descriptor bits returned
kEMACOverrun = 0x200,
kEMACPausePkt = 0x100,
kEMACBadPkt = 0x080,
kEMACRuntPkt = 0x040,
kEMACShortEvt = 0x020,
kEMACAlignErr = 0x010,
kEMACBadFCS = 0x008,
kEMACPktLong = 0x004,
kEMACPktOOR = 0x002,
kEMACPktIRL = 0x001
};

View File

@@ -1,6 +1,6 @@
/* timer.c
*
* This file manages the interval timer on the PowerPC 403*.
* This file manages the interval timer on the PowerPC 405.
* We shall use the bottom 32 bits of the timebase register,
*
* NOTE: It is important that the timer start/stop overhead be
@@ -32,85 +32,47 @@
*
* Modifications for PPC405GP by Dennis Ehlin
*
* Further mods for PPC405EX/EXr by Michael Hamel
*
* $Id$
*
*/
#include <rtems.h>
#include <libcpu/powerpc-utility.h>
static volatile uint32_t Timer_starting;
static rtems_boolean Timer_driver_Find_average_overhead;
extern uint32_t bsp_timer_least_valid;
extern uint32_t bsp_timer_average_overhead;
/*
* This is so small that this code will be reproduced where needed.
*/
static inline uint32_t get_itimer(void)
{
uint32_t ret;
#ifndef ppc405
asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); /* TBLO */
#else /* ppc405 */
/* asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); TBLO */
asm volatile ("mfspr %0, 0x10c" : "=r" ((ret))); /* 405GP TBL */
#endif /* ppc405 */
return ret;
}
static volatile uint32_t startedAt;
static rtems_boolean subtractOverhead;
void Timer_initialize()
{
uint32_t iocr;
#ifndef ppc405
asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */
iocr &= ~4;
iocr |= 4; /* Select external timer clock */
asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */
#else /* ppc405 */
asm volatile ("mfdcr %0, 0x0b2" : "=r" (iocr)); /*405GP CPC0_CR1 */
/* asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); IOCR */
/* iocr |= 0x800000; select external timer clock CETE*/
iocr &= ~0x800000; /* timer clocked from system clock CETE*/
asm volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */
/* asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); IOCR */
#endif /* ppc405 */
Timer_starting = get_itimer();
/* We are going to rely on clock.c to sort out where the clock comes from */
startedAt = ppc_time_base();
}
int Read_timer()
{
uint32_t clicks;
uint32_t total;
extern uint32_t bsp_timer_least_valid;
extern uint32_t bsp_timer_average_overhead;
uint32_t clicks, total;
clicks = get_itimer();
total = clicks - Timer_starting;
if ( Timer_driver_Find_average_overhead == 1 )
return total; /* in XXX microsecond units */
else {
if ( total < bsp_timer_least_valid )
return 0; /* below timer resolution */
return (total - bsp_timer_average_overhead);
}
clicks = ppc_time_base();
total = clicks - startedAt;
if ( ! subtractOverhead )
return total; /* in XXX microsecond units */
else if ( total < bsp_timer_least_valid )
return 0; /* below timer resolution */
else
return (total - bsp_timer_average_overhead);
}
rtems_status_code Empty_function( void )
{
return RTEMS_SUCCESSFUL;
return RTEMS_SUCCESSFUL;
}
void Set_find_average_overhead(
rtems_boolean find_flag
)
void Set_find_average_overhead( rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
subtractOverhead = find_flag;
}

View File

@@ -45,6 +45,10 @@ $(PROJECT_INCLUDE)/libcpu/$(dirstamp):
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(PROJECT_INCLUDE)/libcpu/powerpc-utility.h: shared/include/powerpc-utility.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/powerpc-utility.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/powerpc-utility.h
if !mpc5xx
$(PROJECT_INCLUDE)/libcpu/raw_exception.h: new-exceptions/raw_exception.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/raw_exception.h
@@ -93,7 +97,21 @@ $(PROJECT_INCLUDE)/tty_drv.h: ppc403/tty_drv/tty_drv.h $(PROJECT_INCLUDE)/$(dirs
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/tty_drv.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/tty_drv.h
endif
endif
endif # ppc403
if ppc405
$(PROJECT_INCLUDE)/ppc4xx/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/ppc4xx
@: > $(PROJECT_INCLUDE)/ppc4xx/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/ppc4xx/$(dirstamp)
$(PROJECT_INCLUDE)/ppc4xx/ppc405gp.h: ppc403/include/ppc405gp.h $(PROJECT_INCLUDE)/ppc4xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ppc4xx/ppc405gp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/ppc4xx/ppc405gp.h
$(PROJECT_INCLUDE)/ppc4xx/ppc405ex.h: ppc403/include/ppc405ex.h $(PROJECT_INCLUDE)/ppc4xx/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ppc4xx/ppc405ex.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/ppc4xx/ppc405ex.h
endif # ppc405
if mpc5xx
$(PROJECT_INCLUDE)/mpc5xx/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/mpc5xx

View File

@@ -115,6 +115,17 @@ extern "C" {
#define PPC_HAS_EXCEPTION_PREFIX 0
#define PPC_HAS_EVPR 1
#elif defined (ppc405)
#define PPC_CACHE_ALIGNMENT 32
#define PPC_HAS_RI 0
#define PPC_HAS_RFCI 1
#define PPC_USE_MULTIPLE 1
#define PPC_I_CACHE 16384
#define PPC_D_CACHE 16384 /* except GP/CR */
#define PPC_HAS_EXCEPTION_PREFIX 0
#define PPC_HAS_EVPR 1
#elif defined(mpc555)
/* Copied from mpc505 */

View File

@@ -31,6 +31,8 @@ char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
{
switch (cpu) {
case PPC_405: return "PPC405";
case PPC_405GP: return "PPC405GP";
case PPC_405EX: return "PPC405EX";
case PPC_601: return "MPC601";
case PPC_5XX: return "MPC5XX";
case PPC_603: return "MPC603";
@@ -69,6 +71,8 @@ ppc_cpu_id_t get_ppc_cpu_type()
switch (pvr) {
case PPC_405:
case PPC_405GP:
case PPC_405EX:
case PPC_601:
case PPC_5XX:
case PPC_603:
@@ -128,6 +132,8 @@ ppc_cpu_id_t get_ppc_cpu_type()
switch ( current_ppc_cpu ) {
case PPC_405:
case PPC_405GP:
case PPC_405EX:
current_ppc_features.is_bookE = PPC_BOOKE_405;
break;
case PPC_8540:

View File

@@ -32,6 +32,11 @@ typedef enum
PPC_604r = 0xA,
PPC_7400 = 0xC,
PPC_405 = 0x2001,
PPC_405EX = 0x1291, /* + 405EXr */
PPC_405GP = 0x4011, /* + 405CR */
PPC_405GPr = 0x5091,
PPC_405EZ = 0x4151,
PPC_405EP = 0x5121,
PPC_7455 = 0x8001, /* Kate Feng */
PPC_7457 = 0x8002,
PPC_620 = 0x16,

View File

@@ -14,6 +14,9 @@
* D-82178 Puchheim
* Germany
* rtems@embedded-brains.de
*
* access function for Device Control Registers inspired by "ppc405common.h"
* from Michael Hamel ADInstruments May 2008
*
* The license and distribution terms for this file may be found in the file
* LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
@@ -189,6 +192,7 @@ static inline void ppc_write_word( uint32_t value, volatile void *dest)
);
}
static inline void *ppc_stack_pointer()
{
void *sp;
@@ -301,6 +305,8 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
PPC_Set_decrementer( dec);
}
#define PPC_STRINGOF(x) #x
/* Do not use the following macros. Use the inline functions instead. */
#define PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER( spr) \
@@ -324,6 +330,20 @@ static inline void ppc_set_decrementer_register( uint32_t dec)
#define PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER_EXPAND( spr, val) \
PPC_INTERNAL_MACRO_SET_SPECIAL_PURPOSE_REGISTER( spr, val)
/*
* PPC4xx have Device Control Registers...
*/
#define PPC_DEVICE_CONTROL_REGISTER(dcr) \
({uint32_t val;asm volatile ("mfspr %0," PPC_STRINGOF(dcr) \
: "=r" (val)); val;})
#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr,val) \
do { \
asm volatile ("mtspr " PPC_STRINGOF(dcr)",%0" \
:: "r" (val)); \
} while (0)
static inline uint32_t ppc_special_purpose_register_0()
{
PPC_INTERNAL_MACRO_RETURN_SPECIAL_PURPOSE_REGISTER_EXPAND( SPRG0);