summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/arm
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2009-06-04 16:33:31 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2009-06-04 16:33:31 +0000
commitd7a915dadec627b1906fcc22f45f573cd73914a3 (patch)
tree44f7096debd2aeb14a339c1c6aad4f562303b4a5 /c/src/lib/libcpu/arm
parent2009-06-04 Xi Yang <hiyangxi@gmail.com> (diff)
downloadrtems-d7a915dadec627b1906fcc22f45f573cd73914a3.tar.bz2
2009-06-04 Xi Yang <hiyangxi@gmail.com>
* Makefile.am, configure.ac, preinstall.am: New Gumstix BSP and PXA255 support. * pxa255/clock/clock.c, pxa255/ffuart/ffuart.c, pxa255/include/bits.h, pxa255/include/ffuart.h, pxa255/include/pxa255.h, pxa255/irq/bsp_irq_asm.S, pxa255/irq/bsp_irq_init.c, pxa255/irq/irq.c, pxa255/irq/irq.h, pxa255/pmc/pmc.c, pxa255/timer/timer.c: New files.
Diffstat (limited to 'c/src/lib/libcpu/arm')
-rw-r--r--c/src/lib/libcpu/arm/ChangeLog10
-rw-r--r--c/src/lib/libcpu/arm/Makefile.am30
-rw-r--r--c/src/lib/libcpu/arm/configure.ac5
-rw-r--r--c/src/lib/libcpu/arm/preinstall.am15
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/clock/clock.c117
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c224
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/include/bits.h50
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/include/ffuart.h50
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/include/pxa255.h102
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/irq/bsp_irq_asm.S33
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/irq/bsp_irq_init.c37
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/irq/irq.c115
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/irq/irq.h94
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/pmc/pmc.c45
-rwxr-xr-xc/src/lib/libcpu/arm/pxa255/timer/timer.c95
15 files changed, 1021 insertions, 1 deletions
diff --git a/c/src/lib/libcpu/arm/ChangeLog b/c/src/lib/libcpu/arm/ChangeLog
index 51e284b4b2..23bbf963b9 100644
--- a/c/src/lib/libcpu/arm/ChangeLog
+++ b/c/src/lib/libcpu/arm/ChangeLog
@@ -1,3 +1,13 @@
+2009-06-04 Xi Yang <hiyangxi@gmail.com>
+
+ * Makefile.am, configure.ac, preinstall.am: New Gumstix BSP and PXA255
+ support.
+ * pxa255/clock/clock.c, pxa255/ffuart/ffuart.c, pxa255/include/bits.h,
+ pxa255/include/ffuart.h, pxa255/include/pxa255.h,
+ pxa255/irq/bsp_irq_asm.S, pxa255/irq/bsp_irq_init.c,
+ pxa255/irq/irq.c, pxa255/irq/irq.h, pxa255/pmc/pmc.c,
+ pxa255/timer/timer.c: New files.
+
2009-06-02 Joel Sherrill <joel.sherrill@OARcorp.com>
* at91rm9200/dbgu/dbgu.c: Needed carriage return on newline.
diff --git a/c/src/lib/libcpu/arm/Makefile.am b/c/src/lib/libcpu/arm/Makefile.am
index 8c52124ad2..b51f3a3b48 100644
--- a/c/src/lib/libcpu/arm/Makefile.am
+++ b/c/src/lib/libcpu/arm/Makefile.am
@@ -23,6 +23,36 @@ shared_arm920_rel_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/shared/src
shared_arm920_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
+if pxa255
+include_HEADERS = pxa255/include/pxa255.h pxa255/include/ffuart.h
+
+##pxa255/clock
+noinst_PROGRAMS += pxa255/clock.rel
+pxa255_clock_rel_SOURCES = pxa255/clock/clock.c
+pxa255_clock_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pxa255_clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+## pxa255/timer
+noinst_PROGRAMS += pxa255/timer.rel
+pxa255_timer_rel_SOURCES = pxa255/timer/timer.c
+pxa255_timer_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pxa255_timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+## pxa255/ffuart
+noinst_PROGRAMS += pxa255/ffuart.rel
+pxa255_ffuart_rel_SOURCES = pxa255/ffuart/ffuart.c
+pxa255_ffuart_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pxa255_ffuart_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+## pxa255/interrupt
+include_HEADERS += pxa255/irq/irq.h
+noinst_PROGRAMS += pxa255/irq.rel
+pxa255_irq_rel_SOURCES = pxa255/irq/irq.c pxa255/irq/bsp_irq_init.c \
+ ../../libbsp/arm/shared/irq/irq_init.c pxa255/irq/bsp_irq_asm.S \
+ ../../libbsp/arm/shared/irq/irq_asm.S pxa255/irq/irq.h
+pxa255_irq_rel_CPPFLAGS = $(AM_CPPFLAGS)
+pxa255_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+endif
+
if at91rm9200
include_HEADERS = at91rm9200/include/at91rm9200.h at91rm9200/include/at91rm9200_dbgu.h \
at91rm9200/include/at91rm9200_emac.h at91rm9200/include/at91rm9200_gpio.h \
diff --git a/c/src/lib/libcpu/arm/configure.ac b/c/src/lib/libcpu/arm/configure.ac
index 4fa6989842..232c988677 100644
--- a/c/src/lib/libcpu/arm/configure.ac
+++ b/c/src/lib/libcpu/arm/configure.ac
@@ -24,12 +24,15 @@ RTEMS_PROG_CCAS
AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "at91rm9200" || \
test "$RTEMS_CPU_MODEL" = "mc9328mxl" || \
test "$RTEMS_CPU_MODEL" = "s3c2410" || \
- test "$RTEMS_CPU_MODEL" = "s3c2400")
+ test "$RTEMS_CPU_MODEL" = "s3c2400" || \
+ test "$RTEMS_CPU_MODEL" = "pxa255")
+
AM_CONDITIONAL(at91rm9200, test "$RTEMS_CPU_MODEL" = "at91rm9200")
AM_CONDITIONAL(mc9328mxl, test "$RTEMS_CPU_MODEL" = "mc9328mxl")
AM_CONDITIONAL(s3c2400, test "$RTEMS_CPU_MODEL" = "s3c2400")
AM_CONDITIONAL(s3c2410, test "$RTEMS_CPU_MODEL" = "s3c2410")
AM_CONDITIONAL(lpc22xx, test "$RTEMS_CPU_MODEL" = "lpc22xx")
+AM_CONDITIONAL(pxa255, test "$RTEMS_CPU_MODEL" = "pxa255")
RTEMS_AMPOLISH3
diff --git a/c/src/lib/libcpu/arm/preinstall.am b/c/src/lib/libcpu/arm/preinstall.am
index 9771854ad3..3fab40ed38 100644
--- a/c/src/lib/libcpu/arm/preinstall.am
+++ b/c/src/lib/libcpu/arm/preinstall.am
@@ -28,6 +28,21 @@ $(PROJECT_INCLUDE)/libcpu/mmu.h: shared/include/mmu.h $(PROJECT_INCLUDE)/libcpu/
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu.h
endif
+
+if pxa255
+$(PROJECT_INCLUDE)/pxa255.h: pxa255/include/pxa255.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pxa255.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/pxa255.h
+
+$(PROJECT_INCLUDE)/ffuart.h: pxa255/include/ffuart.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ffuart.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ffuart.h
+
+$(PROJECT_INCLUDE)/irq.h: pxa255/irq/irq.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/irq.h
+endif
+
if at91rm9200
$(PROJECT_INCLUDE)/at91rm9200.h: at91rm9200/include/at91rm9200.h $(PROJECT_INCLUDE)/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/at91rm9200.h
diff --git a/c/src/lib/libcpu/arm/pxa255/clock/clock.c b/c/src/lib/libcpu/arm/pxa255/clock/clock.c
new file mode 100755
index 0000000000..e4f6fc9cdf
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/clock/clock.c
@@ -0,0 +1,117 @@
+/*
+ * By Yang Xi <hiyangxi@gmail.com>
+ * PXA255 clock specific using the System Timer
+ *
+ * RTEMS uses IRQ 26 as Clock Source
+ *
+ * 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.
+ *
+ *
+ * $Id$
+ */
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h>
+#include <bsp.h>
+#include <irq.h>
+#include <pxa255.h>
+
+
+
+static unsigned long period_num;
+
+
+
+
+
+/**
+ * Enables clock interrupt.
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_on(const rtems_irq_connect_data *unused)
+{
+
+ /*Clear the interrupt bit */
+ XSCALE_OS_TIMER_TSR = 0x1;
+
+
+ /* enable timer interrupt */
+ XSCALE_OS_TIMER_IER |= 0x1;
+
+ period_num = TIMER_RATE*(Configuration.microseconds_per_tick/10000);
+
+ XSCALE_OS_TIMER_MR0 = XSCALE_OS_TIMER_TCR + period_num;
+
+}
+
+/**
+ * Disables clock interrupts
+ *
+ * If the interrupt is always on, this can be a NOP.
+ */
+static void clock_isr_off(const rtems_irq_connect_data *unused)
+{
+ /*Clear the interrupt bit */
+ XSCALE_OS_TIMER_TSR = 0x1;
+ /* disable timer interrupt*/
+ XSCALE_OS_TIMER_IER &= ~0x1;
+ return;
+}
+
+/**
+ * Tests to see if clock interrupt is enabled, and returns 1 if so.
+ * If interrupt is not enabled, returns 0.
+ *
+ * If the interrupt is always on, this always returns 1.
+ */
+static int clock_isr_is_on(const rtems_irq_connect_data *irq)
+{
+ /* check timer interrupt */
+ return XSCALE_OS_TIMER_IER & 0x1;
+}
+
+rtems_isr Clock_isr(rtems_vector_number vector);
+
+/* Replace the first value with the clock's interrupt name. */
+rtems_irq_connect_data clock_isr_data = {XSCALE_IRQ_OS_TIMER,
+ (rtems_irq_hdl)Clock_isr,
+ clock_isr_on,
+ clock_isr_off,
+ clock_isr_is_on,
+ 3, /* unused for ARM cpus */
+ 0 }; /* unused for ARM cpus */
+
+
+#define Clock_driver_support_install_isr( _new, _old ) \
+ BSP_install_rtems_irq_handler(&clock_isr_data)
+
+void Clock_driver_support_initialize_hardware(void)
+{
+
+
+ period_num = TIMER_RATE*(Configuration.microseconds_per_tick/10000);
+
+}
+
+
+#define CLOCK_VECTOR 0
+
+#define Clock_driver_support_at_tick() \
+ do { \
+ ;\
+ XSCALE_OS_TIMER_TSR = 0x1;/* read the status to clear the int */ \
+ XSCALE_OS_TIMER_MR0 = XSCALE_OS_TIMER_TCR + period_num;/*Add the match register*/ \
+ ;\
+ } while (0)
+
+void Clock_driver_support_shutdown_hardware( void )
+{
+ BSP_remove_rtems_irq_handler(&clock_isr_data);
+}
+
+#include "../../../../libbsp/shared/clockdrv_shell.h"
diff --git a/c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c b/c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c
new file mode 100755
index 0000000000..7bbac0ba96
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c
@@ -0,0 +1,224 @@
+/*
+ * Console driver for pxa255 full function port by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <termios.h>
+
+#include <pxa255.h>
+#include <ffuart.h>
+#include <rtems/bspIo.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+volatile int dbg_dly;
+
+/* static function prototypes */
+static int ffuart_first_open(int major, int minor, void *arg);
+static int ffuart_last_close(int major, int minor, void *arg);
+static int ffuart_read(int minor);
+static int ffuart_write(int minor, const char *buf, int len);
+static void ffuart_init(int minor);
+static void ffuart_write_polled(int minor, char c);
+static int ffuart_set_attributes(int minor, const struct termios *t);
+
+/* Pointers to functions for handling the UART. */
+console_fns ffuart_fns =
+{
+ libchip_serial_default_probe,
+ ffuart_first_open,
+ ffuart_last_close,
+ ffuart_read,
+ ffuart_write,
+ ffuart_init,
+ ffuart_write_polled, /* not used in this driver */
+ ffuart_set_attributes,
+ FALSE /* TRUE if interrupt driven, FALSE if not. */
+};
+
+
+/*
+ * This is called the first time each device is opened. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd enable interrupts here.
+ */
+static int ffuart_first_open(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+
+/*
+ * This is called the last time each device is closed. Since
+ * the driver is polled, we don't have to do anything. If the driver
+ * were interrupt driven, we'd disable interrupts here.
+ */
+static int ffuart_last_close(int major, int minor, void *arg)
+{
+ return 0;
+}
+
+
+/*
+ * Read one character from UART.
+ *
+ * return -1 if there's no data, otherwise return
+ * the character in lowest 8 bits of returned int.
+ */
+static int ffuart_read(int minor)
+{
+ char c;
+ console_tbl *console_entry;
+ ffuart_reg_t *ffuart;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+ if (console_entry == NULL) {
+ return -1;
+ }
+
+ ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
+
+ if (!(ffuart->lsr & FULL_RECEIVE)) {
+ return -1;
+ }
+
+ c = ffuart->rbr & 0xff;
+
+ return c;
+}
+
+
+/*
+ * Write buffer to UART
+ *
+ * return 1 on success, -1 on error
+ */
+static int ffuart_write(int minor, const char *buf, int len)
+{
+ int i, x;
+ char c;
+ console_tbl *console_entry;
+ ffuart_reg_t *ffuart;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+ if (console_entry == NULL) {
+ return -1;
+ }
+
+ ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
+
+ for (i = 0; i < len; i++) {
+
+ while(1) {
+ if (ffuart->lsr & SEND_EMPTY) {
+ break;
+ }
+ }
+
+ c = (char) buf[i];
+ if(c=='\n'){
+ ffuart->rbr = '\r';
+ for (x = 0; x < 100; x++) {
+ dbg_dly++; /* using a global so this doesn't get optimized out */
+ }
+ while(1){
+ if(ffuart->lsr & SEND_EMPTY){
+ break;
+ }
+ }
+ ffuart->rbr = c;
+ }
+ ffuart->rbr = c;
+
+ /* the TXRDY flag does not seem to update right away (is this true?) */
+ /* so we wait a bit before continuing */
+ for (x = 0; x < 100; x++) {
+ dbg_dly++; /* using a global so this doesn't get optimized out */
+ }
+ }
+
+ return 1;
+}
+
+
+static void ffuart_init(int minor)
+{
+
+
+ console_tbl *console_entry;
+ ffuart_reg_t *ffuart;
+ unsigned int divisor;
+
+ console_entry = BSP_get_uart_from_minor(minor);
+
+
+
+ if (console_entry == NULL) {
+ return;
+ }
+
+ ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
+ ffuart->lcr |= DLAB;
+ /*Set the Bound*/
+ ffuart->lcr |= DLAB;
+ divisor = FREQUENCY_UART / (115200*16);
+ ffuart->rbr = divisor & 0xff;
+ ffuart->ier = (divisor >> 8)&0xff;
+ /*Disable FIFO*/
+ ffuart->iir = 0;
+ ffuart->lcr &=~DLAB;
+ /*Enable UART*/
+ ffuart->ier = 0x40;
+ ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT;
+
+}
+
+/* I'm not sure this is needed for the shared console driver. */
+static void ffuart_write_polled(int minor, char c)
+{
+ ffuart_write(minor, &c, 1);
+}
+
+/* This is for setting baud rate, bits, etc. */
+static int ffuart_set_attributes(int minor, const struct termios *t)
+{
+ return 0;
+}
+
+/***********************************************************************/
+/*
+ * The following functions are not used by TERMIOS, but other RTEMS
+ * functions use them instead.
+ */
+/***********************************************************************/
+/*
+ * Read from UART. This is used in the exit code, and can't
+ * rely on interrupts.
+ */
+int ffuart_poll_read(int minor)
+{
+ return ffuart_read(minor);
+}
+
+
+/*
+ * Write a character to the console. This is used by printk() and
+ * maybe other low level functions. It should not use interrupts or any
+ * RTEMS system calls. It needs to be very simple
+ */
+static void _BSP_put_char( char c ) {
+ ffuart_write_polled(0, c);
+}
+
+BSP_output_char_function_type BSP_output_char = _BSP_put_char;
diff --git a/c/src/lib/libcpu/arm/pxa255/include/bits.h b/c/src/lib/libcpu/arm/pxa255/include/bits.h
new file mode 100755
index 0000000000..f16eaec61b
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/include/bits.h
@@ -0,0 +1,50 @@
+/*
+ * Bit position definitions
+ *
+ * Copyright (c) 2002 by Cogent Computer Systems
+ * Written by Mike Kelly <mike@cogcomp.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#ifndef __BITS_H__
+#define __BITS_H__
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#endif /* __BITS_H__ */
+
diff --git a/c/src/lib/libcpu/arm/pxa255/include/ffuart.h b/c/src/lib/libcpu/arm/pxa255/include/ffuart.h
new file mode 100755
index 0000000000..db01efc296
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/include/ffuart.h
@@ -0,0 +1,50 @@
+/*
+ * FFUART for PXA250 CPU by Yang Xi<hiyangxi@gmail.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef __FFUART_H__
+#define __FFUART_H__
+
+typedef struct {
+ /*
+ *Receive buffer(DLAB=0).Transmit buffer(DLAB=0).
+ *Divisor Latch Low(DLAB=1)
+ */
+ volatile unsigned int rbr;
+ /*Interrupt enable(DLAB=0). Divisor Latch High(DLAB=1)*/
+ volatile unsigned int ier;
+ /*Interrupt identification.FIFO control*/
+ volatile unsigned int iir;
+ /*Line Control*/
+ volatile unsigned int lcr;
+ /*Modem control*/
+ volatile unsigned int mcr;
+ /*Line Status*/
+ volatile unsigned int lsr;
+ /*Modem status*/
+ volatile unsigned int msr;
+ /*Scratch Pad*/
+ volatile unsigned int spr;
+ /*Infrared Selection*/
+ volatile unsigned int isr;
+} ffuart_reg_t;
+
+
+#define EIGHT_BITS_NOPARITY_1STOPBIT 0x3
+#define DLAB 0x80
+
+
+/*Divisor = frequency_uart/(16 * BaudRate*)*/
+#define FREQUENCY_UART (14745600)
+
+#define SEND_EMPTY 0x20
+#define FULL_RECEIVE 0x01
+
+#endif
+
diff --git a/c/src/lib/libcpu/arm/pxa255/include/pxa255.h b/c/src/lib/libcpu/arm/pxa255/include/pxa255.h
new file mode 100755
index 0000000000..4d75bba1b2
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/include/pxa255.h
@@ -0,0 +1,102 @@
+/*
+ * By Yang Xi <hiyangxi@gmail.com>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef __PXA_255_H__
+#define __PXA_255_H__
+
+typedef unsigned int word_t;
+
+/*Interrupt*/
+
+#define PRIMARY_IRQS 32
+#define GPIO_IRQS (85 - 2) /* The first two IRQs have level
+ one interrupts */
+#define GPIO_IRQ 10
+
+#define IRQS (PRIMARY_IRQS + GPIO_IRQS)
+
+/* Interrupt Controller */
+#define INTERRUPT_OFFSET 0xd00000
+#define XSCALE_IRQ_OS_TIMER 26
+#define XSCALE_IRQ_PMU 12
+#define XSCALE_IRQ_STUART 20
+
+#define PMU_IRQ 12
+#define CCNT_IRQ_ENABLE 1UL << 6
+#define PMN1_IRQ_ENABLE 1UL << 5
+#define PMN0_IRQ_ENABLE 1UL << 4
+
+#define IODEVICE_VADDR 0x40000000
+#define XSCALE_INT (IODEVICE_VADDR + INTERRUPT_OFFSET)
+
+#define XSCALE_INT_ICMR (*(volatile word_t *)(XSCALE_INT + 0x04)) /* Mask register */
+#define XSCALE_INT_ICLR (*(volatile word_t *)(XSCALE_INT + 0x08)) /* FIQ / IRQ selection */
+#define XSCALE_INT_ICCR (*(volatile word_t *)(XSCALE_INT + 0x14)) /* Control register */
+#define XSCALE_INT_ICIP (*(volatile word_t *)(XSCALE_INT + 0x00)) /* IRQ pending */
+#define XSCALE_INT_ICFP (*(volatile word_t *)(XSCALE_INT + 0x0c)) /* FIQ pending */
+#define XSCALE_INT_ICPR (*(volatile word_t *)(XSCALE_INT + 0x10)) /* Pending (unmasked) */
+
+/* GPIO */
+#define GPIO_OFFSET 0xe00000
+#define PXA_GPIO (IODEVICE_VADDR + GPIO_OFFSET)
+
+#define PXA_GEDR0 (*(volatile word_t *)(PXA_GPIO + 0x48)) /* GPIO edge detect 0 */
+#define PXA_GEDR1 (*(volatile word_t *)(PXA_GPIO + 0x4C)) /* GPIO edge detect 1 */
+#define PXA_GEDR2 (*(volatile word_t *)(PXA_GPIO + 0x50)) /* GPIO edge detect 2 */
+
+
+/* PXA2XX Timer */
+
+#define TIMER_OFFSET 0x0a00000
+#define CLOCKS_OFFSET 0x1300000
+/*I change the TIMER_RATE to 36864,because when I use 3686400, the period will be calculate
+ to 30000*/
+#define TIMER_RATE 36864
+
+#define XSCALE_TIMERS (IODEVICE_VADDR + TIMER_OFFSET)
+
+/* Match registers */
+#define XSCALE_OS_TIMER_MR0 (*(volatile word_t *)(XSCALE_TIMERS + 0x00))
+#define XSCALE_OS_TIMER_MR1 (*(volatile word_t *)(XSCALE_TIMERS + 0x04))
+#define XSCALE_OS_TIMER_MR2 (*(volatile word_t *)(XSCALE_TIMERS + 0x08))
+#define XSCALE_OS_TIMER_MR3 (*(volatile word_t *)(XSCALE_TIMERS + 0x0c))
+
+/* Interrupt enable register */
+#define XSCALE_OS_TIMER_IER (*(volatile word_t *)(XSCALE_TIMERS + 0x1c))
+/* Watchdog match enable register */
+#define XSCALE_OS_TIMER_WMER (*(volatile word_t *)(XSCALE_TIMERS + 0x18))
+/* Timer count register */
+#define XSCALE_OS_TIMER_TCR (*(volatile word_t *)(XSCALE_TIMERS + 0x10))
+/* Timer status register */
+#define XSCALE_OS_TIMER_TSR (*(volatile word_t *)(XSCALE_TIMERS + 0x14))
+
+#define XSCALE_CLOCKS (IODEVICE_VADDR + CLOCKS_VOFFSET)
+
+#define XSCALE_CLOCKS_CCCR (*(volatile word_t *)(XSCALE_CLOCKS + 0x00))
+
+
+/*Use ffuart port as the console*/
+#define FFUART_BASE 0x40100000
+
+
+/*Write the MAGIC_NUMBER to the MAGIC_ADDRESS then the Skyeye will exit,
+ we can use this function to automatic test the RTEMS bsp */
+
+#define SKYEYE_MAGIC_ADDRESS (*(volatile word_t *)(0xb0000000))
+#define SKYEYE_MAGIC_NUMBER (0xf0f0f0f0)
+
+/*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)
+
+#endif
diff --git a/c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_asm.S b/c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_asm.S
new file mode 100755
index 0000000000..cda40aa9de
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_asm.S
@@ -0,0 +1,33 @@
+/*
+ * PXA255 Interrupt handler by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopgindog.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#define __asm__
+
+ .globl ExecuteITHandler
+ExecuteITHandler :
+/*
+ * Look at interrupt status register to determine source.
+ * From source, determine offset into expanded vector table
+ * and load vector into r0 and handler address into r1.
+ */
+ ldr r0,=0x40d00000
+ ldr r1,[r0]
+ clz r0,r1
+ cmp r0,#32
+ moveq pc,lr /*All zeros*/
+ mov r2,#31
+ sub r0,r2,r0
+ ldr r2,=IRQ_table
+ add r2,r2,r0,LSL #2
+ ldr r1,[r2]
+ mov pc,r1
+
+
diff --git a/c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_init.c b/c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_init.c
new file mode 100755
index 0000000000..dcbc095975
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_init.c
@@ -0,0 +1,37 @@
+/*
+ * PXA255 interrupt controller by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopgindog.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <irq.h>
+#include <bsp.h>
+#include <pxa255.h>
+
+extern void default_int_handler();
+
+void (*IRQ_table[PRIMARY_IRQS])(uint32_t vector);
+/*
+ * Interrupt system initialization. Disable interrupts, clear
+ * any that are pending.
+ */
+void BSP_rtems_irq_mngt_init()
+{
+ int i;
+
+ /* Initialize the vector table contents with default handler */
+ for (i=0; i<PRIMARY_IRQS; i++) {
+ IRQ_table[i] = default_int_handler;
+ }
+
+ /* disable all interrupts */
+ XSCALE_INT_ICMR = 0x0;
+ /*Direct the interrupt to IRQ*/
+ XSCALE_INT_ICLR = 0x0;
+}
+
diff --git a/c/src/lib/libcpu/arm/pxa255/irq/irq.c b/c/src/lib/libcpu/arm/pxa255/irq/irq.c
new file mode 100755
index 0000000000..7146d35a44
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/irq/irq.c
@@ -0,0 +1,115 @@
+/*
+ * PXA255 Interrupt handler by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+#include <bsp.h>
+#include <irq.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apiext.h>
+#include <pxa255.h>
+
+/*
+ * This function check that the value given for the irq line
+ * is valid.
+ */
+static int isValidInterrupt(int irq)
+{
+ if ( (irq < 0) || (irq >= PRIMARY_IRQS)) {
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Installs the interrupt handler.
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ rtems_interrupt_level level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+
+ /*
+ * Check if default handler is actually connected. If not, issue
+ * an error. Note: irq->name is a number corresponding to the
+ * interrupt number . We
+ * convert it to a long word offset to get source's vector register
+ */
+ if (IRQ_table[irq->name]!= default_int_handler) {
+ return 0;
+ }
+
+ _CPU_ISR_Disable(level);
+
+ /*
+ * store the new handler
+ */
+ IRQ_table[irq->name] = irq->hdl;
+
+ /*
+ * unmask interrupt
+ */
+ XSCALE_INT_ICMR = XSCALE_INT_ICMR | 1 << irq->name;
+
+
+
+ /*
+ * Enable interrupt on device
+ */
+ if(irq->on) {
+ irq->on(irq);
+ }
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/*
+ * Remove and interrupt handler
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ rtems_interrupt_level level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+
+ /*
+ * Check if the handler is actually connected. If not, issue an error.
+ */
+ if (IRQ_table[irq->name]!= irq->hdl) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+
+ /*
+ * mask interrupt
+ */
+ XSCALE_INT_ICMR = XSCALE_INT_ICMR & (~(1 << irq->name));
+
+ /*
+ * Disable interrupt on device
+ */
+ if(irq->off) {
+ irq->off(irq);
+ }
+
+ /*
+ * restore the default irq value
+ */
+ IRQ_table[irq->name] = default_int_handler;
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
diff --git a/c/src/lib/libcpu/arm/pxa255/irq/irq.h b/c/src/lib/libcpu/arm/pxa255/irq/irq.h
new file mode 100755
index 0000000000..dc7eff0784
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/irq/irq.h
@@ -0,0 +1,94 @@
+/*
+ * Interrupt handler Header file for PXA By Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef __IRQ_H__
+#define __IRQ_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __asm__
+
+/*
+ * Include some preprocessor value also used by assember code
+ */
+
+#include <rtems.h>
+#include <pxa255.h>
+
+extern void default_int_handler();
+extern void (*IRQ_table[PRIMARY_IRQS])(uint32_t vector);
+
+
+
+/* vector table used by shared/irq_init.c */
+
+typedef unsigned char rtems_irq_level;
+typedef unsigned char rtems_irq_trigger;
+struct __rtems_irq_connect_data__; /* forward declaratiuon */
+typedef unsigned int rtems_irq_number;
+typedef void (*rtems_irq_hdl) (uint32_t vector);
+typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
+typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
+typedef int (*rtems_irq_is_enabled)(const struct __rtems_irq_connect_data__*);
+
+typedef struct __rtems_irq_connect_data__ {
+ /* IRQ line */
+ rtems_irq_number name;
+
+ /* Handler */
+ rtems_irq_hdl hdl;
+
+ /* function for enabling interrupts at device level. */
+ rtems_irq_enable on;
+
+ /* function for disabling interrupts at device level. */
+ rtems_irq_disable off;
+
+ /* Function to test if interrupt is enabled */
+ rtems_irq_is_enabled isOn;
+
+ /* priority level of interrupt */
+ rtems_irq_level irqLevel;
+
+ /* Trigger method (rising/falling edge or high/low level) */
+ rtems_irq_trigger irqTrigger;
+} rtems_irq_connect_data;
+
+/*
+ * function to initialize the interrupt for a specific BSP
+ */
+void BSP_rtems_irq_mngt_init();
+
+
+/*
+ * function to connect a particular irq handler.
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
+
+/*
+ * function to get the current RTEMS irq handler for ptr->name.
+ */
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+
+/*
+ * function to disconnect the RTEMS irq handler for ptr->name.
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+
+#endif /* __asm__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IRQ_H__ */
diff --git a/c/src/lib/libcpu/arm/pxa255/pmc/pmc.c b/c/src/lib/libcpu/arm/pxa255/pmc/pmc.c
new file mode 100755
index 0000000000..dc784be5ad
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/pmc/pmc.c
@@ -0,0 +1,45 @@
+/*
+ * By Yang Xi <hiyangxi@gmail.com>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <pxa255.h>
+
+unsigned int int_latency;
+
+static void pmc_isr_on(const rtems_irq_connect_data *unused)
+{
+ 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));
+}
+
+static void pmc_isr_off(const rtems_irq_connect_data *unused)
+{
+ unsigned int operand;
+ operand = 0x0|RESET_CCOF;
+ asm volatile("mcr p14,0,%0,c0,c0,0 \n"::"r"(operand));
+}
+
+static int pmc_isr_is_on(const rtems_irq_connect_data *unused)
+{
+ 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;
+}
diff --git a/c/src/lib/libcpu/arm/pxa255/timer/timer.c b/c/src/lib/libcpu/arm/pxa255/timer/timer.c
new file mode 100755
index 0000000000..2e531715c3
--- /dev/null
+++ b/c/src/lib/libcpu/arm/pxa255/timer/timer.c
@@ -0,0 +1,95 @@
+/*
+ *PXA255 timer by Yang Xi <hiyangxi@gmail.com>
+ * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
+ *
+ * Notes:
+ * This file manages the benchmark timer used by the RTEMS Timing Test
+ * Suite. Each measured time period is demarcated by calls to
+ * Timer_initialize() and Read_timer(). Read_timer() usually returns
+ * the number of microseconds since Timer_initialize() exitted.
+ *
+ * It is important that the timer start/stop overhead be determined
+ * when porting or modifying this code.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <pxa255.h>
+
+uint32_t tstart;
+bool Timer_driver_Find_average_overhead;
+static uint32_t tick_time;
+/*
+ * Use the timer count register to measure.
+ * The frequency of it is 3.4864MHZ
+ *The longest period we are able to capture is 4G/3.4864MHZ
+ *
+ *
+ */
+void Timer_initialize( void )
+{
+
+ tick_time = XSCALE_OS_TIMER_TCR;
+
+}
+
+/*
+ * The following controls the behavior of Read_timer().
+ *
+ * AVG_OVEREHAD is the overhead for starting and stopping the timer. It
+ * is usually deducted from the number returned.
+ *
+ * LEAST_VALID is the lowest number this routine should trust. Numbers
+ * below this are "noise" and zero is returned.
+ */
+
+#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */
+ /* (Y countdowns) to start/stop the timer. */
+ /* This value is in microseconds. */
+#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */
+
+int Read_timer( void )
+{
+
+ uint32_t total;
+ total = XSCALE_OS_TIMER_TCR;
+ if(total>=tick_time)
+ total -= tick_time;
+ else
+ total += 0xffffffff-tick_time; /*Round up but not overflow*/
+
+ if ( Timer_driver_Find_average_overhead == 1 )
+ return total; /*Counter cycles*/
+ else {
+ if ( total < LEAST_VALID )
+ return 0; /* below timer resolution */
+ return total;
+ }
+
+}
+
+/*
+ * Empty function call used in loops to measure basic cost of looping
+ * in Timing Test Suite.
+ */
+
+rtems_status_code Empty_function( void )
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+void Set_find_average_overhead(
+ bool find_flag
+)
+{
+ Timer_driver_Find_average_overhead = find_flag;
+}
+