Index: c/src/lib/libcpu/arm/ChangeLog
===================================================================
--- c/src/lib/libcpu/arm/ChangeLog	(revision 55b891e2face500910f8a3be59fd1664447f2487)
+++ c/src/lib/libcpu/arm/ChangeLog	(revision 142a9df16ac2ac8cd5254dd651a411716ef3ff08)
@@ -1,2 +1,7 @@
+2009-07-10	Xi Yang <hiyangxi@gmail.com>
+
+	* Makefile.am, pxa255/ffuart/ffuart.c, pxa255/include/pxa255.h,
+	pxa255/pmc/pmc.c: Add PMC support.
+
 2009-06-29	Xi Yang <hiyangxi@gmail.com>
 
Index: c/src/lib/libcpu/arm/Makefile.am
===================================================================
--- c/src/lib/libcpu/arm/Makefile.am	(revision 55b891e2face500910f8a3be59fd1664447f2487)
+++ c/src/lib/libcpu/arm/Makefile.am	(revision 142a9df16ac2ac8cd5254dd651a411716ef3ff08)
@@ -44,4 +44,11 @@
 pxa255_ffuart_rel_CPPFLAGS = $(AM_CPPFLAGS)
 pxa255_ffuart_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+## pxa255/pmc
+noinst_PROGRAMS += pxa255/pmc.rel
+pxa255_pmc_rel_SOURCES = pxa255/pmc/pmc.c
+pxa255_pmc_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pxa255_pmc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
 ## pxa255/interrupt
 include_HEADERS += pxa255/irq/irq.h
Index: c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c
===================================================================
--- c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c	(revision 55b891e2face500910f8a3be59fd1664447f2487)
+++ c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c	(revision 142a9df16ac2ac8cd5254dd651a411716ef3ff08)
@@ -21,5 +21,4 @@
 
 volatile int dbg_dly;
-void _start(void);
 
 /* static function prototypes */
Index: c/src/lib/libcpu/arm/pxa255/include/pxa255.h
===================================================================
--- c/src/lib/libcpu/arm/pxa255/include/pxa255.h	(revision 55b891e2face500910f8a3be59fd1664447f2487)
+++ c/src/lib/libcpu/arm/pxa255/include/pxa255.h	(revision 142a9df16ac2ac8cd5254dd651a411716ef3ff08)
@@ -82,10 +82,8 @@
 #define XSCALE_CLOCKS_CCCR      (*(volatile word_t *)(XSCALE_CLOCKS + 0x00))
 
-
 /*Use ffuart port as the console*/
 #define FFUART_BASE   0x40100000
 
-
-/*Write to KSYEYE_MAGIC_ADDRESS makes SKYEYE to exits*/
+/*Write to SKYEYE_MAGIC_ADDRESS to make SKYEYE  exit*/
 
 #define SKYEYE_MAGIC_ADDRESS (*(volatile word_t *)(0xb0000000))
@@ -93,9 +91,19 @@
 
 /*PMC*/
-/*Clock counter overflow flag*/
-#define CCOF (0x01<<10)
-#define ENABLE_CC_INT (0x01<<6)
-#define ENABLE_PMC_CC (0x01)
-#define RESET_CC (0x01<<2)
+#define PMC_PMNC 0
+#define PMC_CCNT 1
+#define PMC_INTEN 2
+#define PMC_FLAG 3
+#define PMC_EVTSEL 4
+#define PMC_PMN0 5
+#define PMC_PMN1 6
+#define PMC_PMN2 7
+#define PMC_PMN3 8
+
+#define PMC_PMNC_E (0x01)
+#define PMC_PMNC_PCR (0x01 << 1)
+#define PMC_PMNC_CCR (0x01 << 2)
+#define PMC_PMNC_CCD (0x01 << 3)
+#define PMC_PMNC_PCD (0x01 << 4)
 
 #endif
Index: c/src/lib/libcpu/arm/pxa255/pmc/pmc.c
===================================================================
--- c/src/lib/libcpu/arm/pxa255/pmc/pmc.c	(revision 55b891e2face500910f8a3be59fd1664447f2487)
+++ c/src/lib/libcpu/arm/pxa255/pmc/pmc.c	(revision 142a9df16ac2ac8cd5254dd651a411716ef3ff08)
@@ -13,33 +13,116 @@
 #include <pxa255.h>
 
-unsigned int int_latency;
-
-static void pmc_isr_on(const rtems_irq_connect_data *unused)
+unsigned int xscale_read_pmc(int reg)
 {
-  unsigned int operand;
-  /*clean CC*/
-  operand = 0x0;
-  asm volatile("mcr p14,0,%0,c1,c0,0 \n"::"r"(operand));
-   /*clean the Clock counter flag and enable the interrupt of CC*/
-  operand = 0x0|RESET_CCOF|ENABLE_CC_INT|RESET_CC|ENABLE_PMC_CC;
-  asm volatile("mcr p14,0,%0,c0,c0,0 \n"::"r"(operand));
-  /*Set to the 4kHZ*/
-  operand = (unsigned int)0xffffffff-(unsigned int)100000;
-  asm volatile("mcr p14,0,%0,c1,c0,0 \n"::"r"(operand));
+  unsigned int val = 0;
+  switch(reg){
+  case PMC_PMNC:
+    asm volatile("mrc p14,0,%0,c0,c1,0\n":"=r"(val):);
+    break;
+  case PMC_CCNT:
+    asm volatile("mrc p14,0,%0,c1,c1,0\n":"=r"(val):);
+    break;
+  case PMC_INTEN:
+    asm volatile("mrc p14,0,%0,c4,c1,0\n":"=r"(val):);
+    break;
+  case PMC_FLAG:
+    asm volatile("mrc p14,0,%0,c5,c1,0\n":"=r"(val):);
+    break;
+  case PMC_EVTSEL:
+    asm volatile("mrc p14,0,%0,c8,c1,0\n":"=r"(val):);
+    break;
+  case PMC_PMN0:
+    asm volatile("mrc p14,0,%0,c0,c2,0\n":"=r"(val):);
+    break;
+  case PMC_PMN1:
+    asm volatile("mrc p14,0,%0,c1,c2,0\n":"=r"(val):);
+    break;
+  case PMC_PMN2:
+    asm volatile("mrc p14,0,%0,c2,c2,0\n":"=r"(val):);
+    break;
+  case PMC_PMN3:
+    asm volatile("mrc p14,0,%0,c3,c2,0\n":"=r"(val):);
+    break;
+  default:
+    val = 0;
+    break;
+  }
+  return val;
 }
 
-static void pmc_isr_off(const rtems_irq_connect_data *unused)
+void xscale_write_pmc(int reg, unsigned int val)
 {
-  unsigned int operand;
-  operand = 0x0|RESET_CCOF;
-  asm volatile("mcr p14,0,%0,c0,c0,0 \n"::"r"(operand));
+  switch(reg){
+  case PMC_PMNC:
+    asm volatile("mcr p14,0,%0,c0,c1,0\n"::"r"(val));
+    break;
+  case PMC_CCNT:
+    asm volatile("mcr p14,0,%0,c1,c1,0\n"::"r"(val));
+    break;
+  case PMC_INTEN:
+    asm volatile("mcr p14,0,%0,c4,c1,0\n"::"r"(val));
+    break;
+  case PMC_FLAG:
+    asm volatile("mcr p14,0,%0,c5,c1,0\n"::"r"(val));
+    break;
+  case PMC_EVTSEL:
+    asm volatile("mcr p14,0,%0,c8,c1,0\n"::"r"(val));
+    break;
+  case PMC_PMN0:
+    asm volatile("mcr p14,0,%0,c0,c2,0\n"::"r"(val));
+    break;
+  case PMC_PMN1:
+    asm volatile("mcr p14,0,%0,c1,c2,0\n"::"r"(val));
+    break;
+  case PMC_PMN2:
+    asm volatile("mcr p14,0,%0,c2,c2,0\n"::"r"(val));
+    break;
+  case PMC_PMN3:
+    asm volatile("mcr p14,0,%0,c3,c2,0\n"::"r"(val));
+    break;
+  default:
+    break;
+  }
 }
 
-static int pmc_isr_is_on(const rtems_irq_connect_data *unused)
+void xscale_pmc_enable_pmc(void)
 {
-  unsigned int operand;
-  asm volatile("mrc p14,0,%0,c0,c0,0 \n":"=r"(operand):);
-  if((operand & ENABLE_PMC_CC ) && (operand & ENABLE_CC_INT))
-    return 1;
-  return 0;
+  unsigned int val;
+  val = xscale_read_pmc(PMC_PMNC);
+  val = (val | PMC_PMNC_E)&(~PMC_PMNC_PCD);
+  xscale_write_pmc(PMC_PMNC,val);
 }
+void xscale_pmc_disable_pmc(void)
+{
+  unsigned int val;
+  val = xscale_read_pmc(PMC_PMNC);
+  val = val & (~PMC_PMNC_E);
+  xscale_write_pmc(PMC_PMNC,val);
+}
+
+void xscale_pmc_reset_pmc(void)
+{
+  unsigned int val;
+  val = xscale_read_pmc(PMC_PMNC);
+  val = val | PMC_PMNC_PCR;
+  xscale_write_pmc(PMC_PMNC,val);
+}
+
+void xscale_pmc_reset_ccnt(void)
+{
+  unsigned int val;
+  val = xscale_read_pmc(PMC_PMNC);
+  val = val | PMC_PMNC_CCR;
+  xscale_write_pmc(PMC_PMNC,val);
+}
+
+void xscale_pmc_setevent(int reg, unsigned char evt)
+{
+  unsigned int val;
+  val = xscale_read_pmc(PMC_EVTSEL);
+  if((reg >= PMC_PMN0) && (reg <= PMC_PMN3)){
+    val &= ~(0xff<<(reg-PMC_PMN0)*8);
+    val |= evt << (reg-PMC_PMN0)*8;
+    xscale_write_pmc(PMC_EVTSEL,val);
+  }
+}
