diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-06-04 16:33:31 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-06-04 16:33:31 +0000 |
commit | d7a915dadec627b1906fcc22f45f573cd73914a3 (patch) | |
tree | 44f7096debd2aeb14a339c1c6aad4f562303b4a5 /c/src/lib/libcpu/arm/pxa255 | |
parent | 2009-06-04 Xi Yang <hiyangxi@gmail.com> (diff) | |
download | rtems-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 '')
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/clock/clock.c | 117 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/ffuart/ffuart.c | 224 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/include/bits.h | 50 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/include/ffuart.h | 50 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/include/pxa255.h | 102 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_asm.S | 33 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/irq/bsp_irq_init.c | 37 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/irq/irq.c | 115 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/irq/irq.h | 94 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/pmc/pmc.c | 45 | ||||
-rwxr-xr-x | c/src/lib/libcpu/arm/pxa255/timer/timer.c | 95 |
11 files changed, 962 insertions, 0 deletions
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; +} + |