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.
This commit is contained in:
Joel Sherrill
2009-06-04 16:33:31 +00:00
parent 2c9fde8bdb
commit d7a915dade
15 changed files with 1021 additions and 1 deletions

View File

@@ -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.

View File

@@ -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 \

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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;

View File

@@ -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__ */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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__ */

View File

@@ -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;
}

View File

@@ -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;
}