forked from Imagelibrary/rtems
2011-03-04 Till Straumann <strauman@slac.stanford.edu>
PR 1738/bsps * clock/clock.c, include/bsp.h, network/network.c: system clock driver programs the PIT w/o assuming the CPU clock frequency being a power of two.
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
2011-03-04 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
|
PR 1738/bsps
|
||||||
|
* clock/clock.c, include/bsp.h, network/network.c: system clock driver
|
||||||
|
programs the PIT w/o assuming the CPU clock frequency being a power
|
||||||
|
of two.
|
||||||
|
|
||||||
2011-02-17 Till Straumann <strauman@slac.stanford.edu>
|
2011-02-17 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
PR 1738/bsps
|
PR 1738/bsps
|
||||||
|
|||||||
@@ -26,19 +26,19 @@
|
|||||||
* CPU load counters
|
* CPU load counters
|
||||||
* Place in static RAM so updates don't hit the SDRAM
|
* Place in static RAM so updates don't hit the SDRAM
|
||||||
*/
|
*/
|
||||||
extern int __SRAMBASE[];
|
#define IDLE_COUNTER __SRAMBASE.idle_counter
|
||||||
#define IDLE_COUNTER __SRAMBASE[0]
|
#define FILTERED_IDLE __SRAMBASE.filtered_idle
|
||||||
#define FILTERED_IDLE __SRAMBASE[1]
|
#define MAX_IDLE_COUNT __SRAMBASE.max_idle_count
|
||||||
#define MAX_IDLE_COUNT __SRAMBASE[2]
|
#define PITC_PER_TICK __SRAMBASE.pitc_per_tick
|
||||||
#define USEC_PER_TICK __SRAMBASE[3]
|
#define NSEC_PER_PITC __SRAMBASE.nsec_per_pitc
|
||||||
#define FILTER_SHIFT 6
|
#define FILTER_SHIFT 6
|
||||||
|
|
||||||
uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
||||||
{
|
{
|
||||||
int i = MCF5282_PIT3_PCNTR;
|
int i = MCF5282_PIT3_PCNTR;
|
||||||
if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF)
|
if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF)
|
||||||
i = MCF5282_PIT3_PCNTR - USEC_PER_TICK;
|
i = MCF5282_PIT3_PCNTR - PITC_PER_TICK;
|
||||||
return (USEC_PER_TICK - i) * 1000;
|
return (PITC_PER_TICK - i) * NSEC_PER_PITC;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
|
#define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick
|
||||||
@@ -48,7 +48,7 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
|||||||
*/
|
*/
|
||||||
#define Clock_driver_support_at_tick() \
|
#define Clock_driver_support_at_tick() \
|
||||||
do { \
|
do { \
|
||||||
int idle = IDLE_COUNTER; \
|
unsigned idle = IDLE_COUNTER; \
|
||||||
IDLE_COUNTER = 0; \
|
IDLE_COUNTER = 0; \
|
||||||
if (idle > MAX_IDLE_COUNT) \
|
if (idle > MAX_IDLE_COUNT) \
|
||||||
MAX_IDLE_COUNT = idle; \
|
MAX_IDLE_COUNT = idle; \
|
||||||
@@ -75,18 +75,29 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
|||||||
/*
|
/*
|
||||||
* Set up the clock hardware
|
* Set up the clock hardware
|
||||||
*
|
*
|
||||||
* Prescale so that it counts in microseconds
|
* f_pit = f_clk / 2^(preScaleCode+1) / N = 1/(us_per_tick/us_per_s)
|
||||||
* System clock frequency better be 2**n (1<=n<=16) MHz!
|
*
|
||||||
|
* N = f_clk / 2^(preScaleCode+1) * us_per_tick / us_per_s
|
||||||
|
*
|
||||||
|
* ns_per_pit_clk = ns_per_s / (f_clk / 2^(preScaleCode+1))
|
||||||
|
* = ns_per_s * 2^(preScaleCode+1) / f_clk;
|
||||||
*/
|
*/
|
||||||
#define Clock_driver_support_initialize_hardware() \
|
#define Clock_driver_support_initialize_hardware() \
|
||||||
do { \
|
do { \
|
||||||
|
unsigned long long N; \
|
||||||
int level; \
|
int level; \
|
||||||
int preScaleCode = -2; \
|
int preScaleCode = 0; \
|
||||||
int preScaleDivisor = bsp_get_CPU_clock_speed() / 1000000; \
|
N = bsp_get_CPU_clock_speed(); \
|
||||||
while (preScaleDivisor) { \
|
N *= rtems_configuration_get_microseconds_per_tick(); \
|
||||||
preScaleDivisor >>= 1; \
|
N /= 2*1000000; /* min_prescale * us_per_s */ \
|
||||||
|
while ( N > 0x10000 ) { \
|
||||||
preScaleCode++; \
|
preScaleCode++; \
|
||||||
|
N >>= 1; \
|
||||||
} \
|
} \
|
||||||
|
PITC_PER_TICK = N; \
|
||||||
|
N = 2000000000ULL << preScaleCode; \
|
||||||
|
N /= bsp_get_CPU_clock_speed(); \
|
||||||
|
NSEC_PER_PITC = N; \
|
||||||
IDLE_COUNTER = 0; \
|
IDLE_COUNTER = 0; \
|
||||||
FILTERED_IDLE = 0; \
|
FILTERED_IDLE = 0; \
|
||||||
MAX_IDLE_COUNT = 0; \
|
MAX_IDLE_COUNT = 0; \
|
||||||
@@ -101,8 +112,7 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
|||||||
MCF5282_PIT_PCSR_OVW | \
|
MCF5282_PIT_PCSR_OVW | \
|
||||||
MCF5282_PIT_PCSR_PIE | \
|
MCF5282_PIT_PCSR_PIE | \
|
||||||
MCF5282_PIT_PCSR_RLD; \
|
MCF5282_PIT_PCSR_RLD; \
|
||||||
USEC_PER_TICK = rtems_configuration_get_microseconds_per_tick(); \
|
MCF5282_PIT3_PMR = PITC_PER_TICK - 1; \
|
||||||
MCF5282_PIT3_PMR = USEC_PER_TICK - 1; \
|
|
||||||
MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \
|
MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \
|
||||||
MCF5282_PIT_PCSR_PIE | \
|
MCF5282_PIT_PCSR_PIE | \
|
||||||
MCF5282_PIT_PCSR_RLD | \
|
MCF5282_PIT_PCSR_RLD | \
|
||||||
@@ -115,7 +125,7 @@ uint32_t bsp_clock_nanoseconds_since_last_tick(void)
|
|||||||
Thread bsp_idle_thread(uint32_t ignored)
|
Thread bsp_idle_thread(uint32_t ignored)
|
||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
asm volatile ("addq.l #1,__SRAMBASE"); /* Atomic increment */
|
asm volatile ("addq.l #1,%0"::"m"(IDLE_COUNTER)); /* Atomic increment */
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtems_bsp_cpu_load_percentage(void)
|
int rtems_bsp_cpu_load_percentage(void)
|
||||||
|
|||||||
@@ -134,6 +134,31 @@ int BSP_vme2local_adrs(unsigned am, unsigned long vmeaddr, unsigned long *plocal
|
|||||||
void *bsp_idle_thread( uintptr_t ignored );
|
void *bsp_idle_thread( uintptr_t ignored );
|
||||||
#define BSP_IDLE_TASK_BODY bsp_idle_thread
|
#define BSP_IDLE_TASK_BODY bsp_idle_thread
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SRAM. The BSP uses SRAM for maintaining some clock-driver data
|
||||||
|
* and for ethernet descriptors (and the initial stack during
|
||||||
|
* early boot).
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct mcf5282BufferDescriptor_ {
|
||||||
|
volatile uint16_t status;
|
||||||
|
uint16_t length;
|
||||||
|
volatile void *buffer;
|
||||||
|
} mcf5282BufferDescriptor_t;
|
||||||
|
|
||||||
|
extern struct {
|
||||||
|
uint32_t idle_counter;
|
||||||
|
uint32_t filtered_idle;
|
||||||
|
uint32_t max_idle_count;
|
||||||
|
uint32_t pitc_per_tick;
|
||||||
|
uint32_t nsec_per_pitc;
|
||||||
|
uint32_t pad[3]; /* align to 16-bytes for descriptors */
|
||||||
|
mcf5282BufferDescriptor_t fec_descriptors[];
|
||||||
|
/* buffer descriptors are allocated from here */
|
||||||
|
|
||||||
|
/* initial stack is at top of SRAM (start.S) */
|
||||||
|
} __SRAMBASE;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -81,12 +81,6 @@
|
|||||||
#error "Driver must have MCLBYTES > RBUF_SIZE"
|
#error "Driver must have MCLBYTES > RBUF_SIZE"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct mcf5282BufferDescriptor_ {
|
|
||||||
volatile uint16_t status;
|
|
||||||
uint16_t length;
|
|
||||||
volatile void *buffer;
|
|
||||||
} mcf5282BufferDescriptor_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-device data
|
* Per-device data
|
||||||
*/
|
*/
|
||||||
@@ -197,11 +191,10 @@ mcf5282_mii_interrupt_handler( rtems_vector_number v )
|
|||||||
* Ensure 128-bit (16-byte) alignment
|
* Ensure 128-bit (16-byte) alignment
|
||||||
* Allow some space at the beginning for other diagnostic counters
|
* Allow some space at the beginning for other diagnostic counters
|
||||||
*/
|
*/
|
||||||
extern char __SRAMBASE[];
|
|
||||||
static mcf5282BufferDescriptor_t *
|
static mcf5282BufferDescriptor_t *
|
||||||
mcf5282_bd_allocate(unsigned int count)
|
mcf5282_bd_allocate(unsigned int count)
|
||||||
{
|
{
|
||||||
static mcf5282BufferDescriptor_t *bdp = (mcf5282BufferDescriptor_t *)(__SRAMBASE+16);
|
static mcf5282BufferDescriptor_t *bdp = __SRAMBASE.fec_descriptors;
|
||||||
mcf5282BufferDescriptor_t *p = bdp;
|
mcf5282BufferDescriptor_t *p = bdp;
|
||||||
|
|
||||||
bdp += count;
|
bdp += count;
|
||||||
|
|||||||
Reference in New Issue
Block a user