Index: c/src/lib/libbsp/m68k/uC5282/ChangeLog
===================================================================
--- c/src/lib/libbsp/m68k/uC5282/ChangeLog	(revision c0640a2bd883972b2f507214bdd6e5a75a6dacd4)
+++ c/src/lib/libbsp/m68k/uC5282/ChangeLog	(revision 3f60fb4f3aac86eaa327438004e59ee348a3d84d)
@@ -1,2 +1,9 @@
+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>
 
Index: c/src/lib/libbsp/m68k/uC5282/clock/clock.c
===================================================================
--- c/src/lib/libbsp/m68k/uC5282/clock/clock.c	(revision c0640a2bd883972b2f507214bdd6e5a75a6dacd4)
+++ c/src/lib/libbsp/m68k/uC5282/clock/clock.c	(revision 3f60fb4f3aac86eaa327438004e59ee348a3d84d)
@@ -27,9 +27,9 @@
  * Place in static RAM so updates don't hit the SDRAM
  */
-extern int __SRAMBASE[];
-#define IDLE_COUNTER      __SRAMBASE[0]
-#define FILTERED_IDLE     __SRAMBASE[1]
-#define MAX_IDLE_COUNT    __SRAMBASE[2]
-#define USEC_PER_TICK     __SRAMBASE[3]
+#define IDLE_COUNTER    __SRAMBASE.idle_counter
+#define FILTERED_IDLE   __SRAMBASE.filtered_idle
+#define MAX_IDLE_COUNT  __SRAMBASE.max_idle_count
+#define PITC_PER_TICK   __SRAMBASE.pitc_per_tick
+#define NSEC_PER_PITC   __SRAMBASE.nsec_per_pitc
 #define FILTER_SHIFT    6
 
@@ -38,6 +38,6 @@
     int i = MCF5282_PIT3_PCNTR;
     if (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF)
-        i = MCF5282_PIT3_PCNTR - USEC_PER_TICK;
-    return (USEC_PER_TICK - i) * 1000;
+        i = MCF5282_PIT3_PCNTR - PITC_PER_TICK;
+    return (PITC_PER_TICK - i) * NSEC_PER_PITC;
 }
 
@@ -49,5 +49,5 @@
 #define Clock_driver_support_at_tick()                                       \
     do {                                                                     \
-        int idle = IDLE_COUNTER;                                             \
+        unsigned idle = IDLE_COUNTER;                                        \
         IDLE_COUNTER = 0;                                                    \
         if (idle > MAX_IDLE_COUNT)                                           \
@@ -76,18 +76,29 @@
  * Set up the clock hardware
  *
- * Prescale so that it counts in microseconds
- * System clock frequency better be 2**n (1<=n<=16) MHz!
+ * f_pit = f_clk / 2^(preScaleCode+1) / N  = 1/(us_per_tick/us_per_s)
+ *
+ * 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()                       \
     do {                                                                 \
+		unsigned long long N;                                            \
         int level;                                                       \
-        int preScaleCode = -2;                                           \
-        int preScaleDivisor = bsp_get_CPU_clock_speed() / 1000000;       \
-        while (preScaleDivisor) {                                        \
-            preScaleDivisor >>= 1;                                       \
-            preScaleCode++;                                              \
-        }                                                                \
-        IDLE_COUNTER = 0;                                                \
-        FILTERED_IDLE = 0;                                               \
+        int preScaleCode = 0;                                            \
+		N  = bsp_get_CPU_clock_speed();                                  \
+		N *= rtems_configuration_get_microseconds_per_tick();            \
+		N /= 2*1000000; /* min_prescale * us_per_s */                    \
+		while ( N > 0x10000 ) {                                          \
+			preScaleCode++;                                              \
+			N >>= 1;                                                     \
+		}                                                                \
+		PITC_PER_TICK  = N;                                              \
+		N  = 2000000000ULL << preScaleCode;                              \
+		N /= bsp_get_CPU_clock_speed();                                  \
+		NSEC_PER_PITC  = N;                                              \
+        IDLE_COUNTER   = 0;                                              \
+        FILTERED_IDLE  = 0;                                              \
         MAX_IDLE_COUNT = 0;                                              \
         bsp_allocate_interrupt(PIT3_IRQ_LEVEL, PIT3_IRQ_PRIORITY);       \
@@ -102,6 +113,5 @@
                             MCF5282_PIT_PCSR_PIE |                       \
                             MCF5282_PIT_PCSR_RLD;                        \
-        USEC_PER_TICK = rtems_configuration_get_microseconds_per_tick(); \
-        MCF5282_PIT3_PMR = USEC_PER_TICK - 1;                            \
+        MCF5282_PIT3_PMR = PITC_PER_TICK - 1;                            \
         MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) |         \
                             MCF5282_PIT_PCSR_PIE |                       \
@@ -115,6 +125,7 @@
 Thread bsp_idle_thread(uint32_t ignored)
 {
-    for(;;)
-        __asm__ volatile ("addq.l #1,__SRAMBASE"); /* Atomic increment */
+  /* Atomic increment */
+  for(;;)
+    __asm__ volatile ("addq.l #1,%0"::"m"(IDLE_COUNTER));
 }
 
Index: c/src/lib/libbsp/m68k/uC5282/include/bsp.h
===================================================================
--- c/src/lib/libbsp/m68k/uC5282/include/bsp.h	(revision c0640a2bd883972b2f507214bdd6e5a75a6dacd4)
+++ c/src/lib/libbsp/m68k/uC5282/include/bsp.h	(revision 3f60fb4f3aac86eaa327438004e59ee348a3d84d)
@@ -135,4 +135,29 @@
 #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
 }
Index: c/src/lib/libbsp/m68k/uC5282/network/network.c
===================================================================
--- c/src/lib/libbsp/m68k/uC5282/network/network.c	(revision c0640a2bd883972b2f507214bdd6e5a75a6dacd4)
+++ c/src/lib/libbsp/m68k/uC5282/network/network.c	(revision 3f60fb4f3aac86eaa327438004e59ee348a3d84d)
@@ -81,10 +81,4 @@
     #error "Driver must have MCLBYTES > RBUF_SIZE"
 #endif
-
-typedef struct mcf5282BufferDescriptor_ {
-    volatile uint16_t   status;
-    uint16_t			length;
-    volatile void      *buffer;
-} mcf5282BufferDescriptor_t;
 
 /*
@@ -198,9 +192,8 @@
  * Allow some space at the beginning for other diagnostic counters
  */
-extern char __SRAMBASE[];
 static mcf5282BufferDescriptor_t *
 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;
 
