From 30abd24b7e7bc1f66b22527792931cf4468b06b8 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 15 Aug 2008 20:18:41 +0000 Subject: 2008-08-15 Allan Hessenflow * ChangeLog, Makefile.am, README, configure.ac, preinstall.am, cache/cache.c, cache/cache_.h, clock/clock.c, clock/rtc.c, clock/tod.h, include/bf533.h, include/bf537.h, include/cecRegs.h, include/coreTimerRegs.h, include/dmaRegs.h, include/ebiuRegs.h, include/ethernetRegs.h, include/gpioRegs.h, include/memoryRegs.h, include/mmuRegs.h, include/ppiRegs.h, include/rtcRegs.h, include/sicRegs.h, include/spiRegs.h, include/sportRegs.h, include/timerRegs.h, include/twiRegs.h, include/uartRegs.h, include/wdogRegs.h, interrupt/interrupt.c, interrupt/interrupt.h, mmu/mmu.c, mmu/mmu.h, network/ethernet.c, network/ethernet.h, serial/spi.c, serial/spi.h, serial/sport.c, serial/sport.h, serial/twi.c, serial/twi.h, serial/uart.c, serial/uart.h, timer/timer.c: New files. --- c/src/lib/libcpu/bfin/ChangeLog | 16 + c/src/lib/libcpu/bfin/Makefile.am | 106 +++ c/src/lib/libcpu/bfin/README | 15 + c/src/lib/libcpu/bfin/cache/cache.c | 128 ++++ c/src/lib/libcpu/bfin/cache/cache_.h | 21 + c/src/lib/libcpu/bfin/clock/clock.c | 150 +++++ c/src/lib/libcpu/bfin/clock/rtc.c | 184 ++++++ c/src/lib/libcpu/bfin/clock/tod.h | 63 ++ c/src/lib/libcpu/bfin/configure.ac | 32 + c/src/lib/libcpu/bfin/include/bf533.h | 136 ++++ c/src/lib/libcpu/bfin/include/bf537.h | 226 +++++++ c/src/lib/libcpu/bfin/include/cecRegs.h | 49 ++ c/src/lib/libcpu/bfin/include/coreTimerRegs.h | 32 + c/src/lib/libcpu/bfin/include/dmaRegs.h | 100 +++ c/src/lib/libcpu/bfin/include/ebiuRegs.h | 136 ++++ c/src/lib/libcpu/bfin/include/ethernetRegs.h | 422 ++++++++++++ c/src/lib/libcpu/bfin/include/gpioRegs.h | 39 ++ c/src/lib/libcpu/bfin/include/memoryRegs.h | 61 ++ c/src/lib/libcpu/bfin/include/mmuRegs.h | 57 ++ c/src/lib/libcpu/bfin/include/ppiRegs.h | 61 ++ c/src/lib/libcpu/bfin/include/rtcRegs.h | 68 ++ c/src/lib/libcpu/bfin/include/sicRegs.h | 35 + c/src/lib/libcpu/bfin/include/spiRegs.h | 72 +++ c/src/lib/libcpu/bfin/include/sportRegs.h | 114 ++++ c/src/lib/libcpu/bfin/include/timerRegs.h | 48 ++ c/src/lib/libcpu/bfin/include/twiRegs.h | 121 ++++ c/src/lib/libcpu/bfin/include/uartRegs.h | 73 +++ c/src/lib/libcpu/bfin/include/wdogRegs.h | 36 ++ c/src/lib/libcpu/bfin/interrupt/interrupt.c | 197 ++++++ c/src/lib/libcpu/bfin/interrupt/interrupt.h | 82 +++ c/src/lib/libcpu/bfin/mmu/mmu.c | 44 ++ c/src/lib/libcpu/bfin/mmu/mmu.h | 65 ++ c/src/lib/libcpu/bfin/network/ethernet.c | 884 ++++++++++++++++++++++++++ c/src/lib/libcpu/bfin/network/ethernet.h | 56 ++ c/src/lib/libcpu/bfin/preinstall.am | 129 ++++ c/src/lib/libcpu/bfin/serial/spi.c | 109 ++++ c/src/lib/libcpu/bfin/serial/spi.h | 52 ++ c/src/lib/libcpu/bfin/serial/sport.c | 2 + c/src/lib/libcpu/bfin/serial/sport.h | 2 + c/src/lib/libcpu/bfin/serial/twi.c | 256 ++++++++ c/src/lib/libcpu/bfin/serial/twi.h | 70 ++ c/src/lib/libcpu/bfin/serial/uart.c | 412 ++++++++++++ c/src/lib/libcpu/bfin/serial/uart.h | 59 ++ c/src/lib/libcpu/bfin/timer/timer.c | 106 +++ 44 files changed, 5126 insertions(+) create mode 100644 c/src/lib/libcpu/bfin/ChangeLog create mode 100644 c/src/lib/libcpu/bfin/Makefile.am create mode 100644 c/src/lib/libcpu/bfin/README create mode 100644 c/src/lib/libcpu/bfin/cache/cache.c create mode 100644 c/src/lib/libcpu/bfin/cache/cache_.h create mode 100644 c/src/lib/libcpu/bfin/clock/clock.c create mode 100644 c/src/lib/libcpu/bfin/clock/rtc.c create mode 100644 c/src/lib/libcpu/bfin/clock/tod.h create mode 100644 c/src/lib/libcpu/bfin/configure.ac create mode 100644 c/src/lib/libcpu/bfin/include/bf533.h create mode 100644 c/src/lib/libcpu/bfin/include/bf537.h create mode 100644 c/src/lib/libcpu/bfin/include/cecRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/coreTimerRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/dmaRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/ebiuRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/ethernetRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/gpioRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/memoryRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/mmuRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/ppiRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/rtcRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/sicRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/spiRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/sportRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/timerRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/twiRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/uartRegs.h create mode 100644 c/src/lib/libcpu/bfin/include/wdogRegs.h create mode 100644 c/src/lib/libcpu/bfin/interrupt/interrupt.c create mode 100644 c/src/lib/libcpu/bfin/interrupt/interrupt.h create mode 100644 c/src/lib/libcpu/bfin/mmu/mmu.c create mode 100644 c/src/lib/libcpu/bfin/mmu/mmu.h create mode 100644 c/src/lib/libcpu/bfin/network/ethernet.c create mode 100644 c/src/lib/libcpu/bfin/network/ethernet.h create mode 100644 c/src/lib/libcpu/bfin/preinstall.am create mode 100644 c/src/lib/libcpu/bfin/serial/spi.c create mode 100644 c/src/lib/libcpu/bfin/serial/spi.h create mode 100644 c/src/lib/libcpu/bfin/serial/sport.c create mode 100644 c/src/lib/libcpu/bfin/serial/sport.h create mode 100644 c/src/lib/libcpu/bfin/serial/twi.c create mode 100644 c/src/lib/libcpu/bfin/serial/twi.h create mode 100644 c/src/lib/libcpu/bfin/serial/uart.c create mode 100644 c/src/lib/libcpu/bfin/serial/uart.h create mode 100644 c/src/lib/libcpu/bfin/timer/timer.c (limited to 'c/src/lib/libcpu') diff --git a/c/src/lib/libcpu/bfin/ChangeLog b/c/src/lib/libcpu/bfin/ChangeLog new file mode 100644 index 0000000000..32b7509de7 --- /dev/null +++ b/c/src/lib/libcpu/bfin/ChangeLog @@ -0,0 +1,16 @@ +2008-08-15 Allan Hessenflow + + * ChangeLog, Makefile.am, README, configure.ac, preinstall.am, + cache/cache.c, cache/cache_.h, clock/clock.c, clock/rtc.c, + clock/tod.h, include/bf533.h, include/bf537.h, include/cecRegs.h, + include/coreTimerRegs.h, include/dmaRegs.h, include/ebiuRegs.h, + include/ethernetRegs.h, include/gpioRegs.h, include/memoryRegs.h, + include/mmuRegs.h, include/ppiRegs.h, include/rtcRegs.h, + include/sicRegs.h, include/spiRegs.h, include/sportRegs.h, + include/timerRegs.h, include/twiRegs.h, include/uartRegs.h, + include/wdogRegs.h, interrupt/interrupt.c, interrupt/interrupt.h, + mmu/mmu.c, mmu/mmu.h, network/ethernet.c, network/ethernet.h, + serial/spi.c, serial/spi.h, serial/sport.c, serial/sport.h, + serial/twi.c, serial/twi.h, serial/uart.c, serial/uart.h, + timer/timer.c: New files. + diff --git a/c/src/lib/libcpu/bfin/Makefile.am b/c/src/lib/libcpu/bfin/Makefile.am new file mode 100644 index 0000000000..3eb65cce94 --- /dev/null +++ b/c/src/lib/libcpu/bfin/Makefile.am @@ -0,0 +1,106 @@ +## +## $Id$ +## + +ACLOCAL_AMFLAGS = -I ../../../aclocal + +include $(top_srcdir)/../../../automake/compile.am + +EXTRA_DIST = + +noinst_PROGRAMS = + +include_libcpudir = $(includedir)/libcpu +include_libcpu_HEADERS = + +include_libcpu_HEADERS += include/bf533.h +include_libcpu_HEADERS += include/bf537.h +include_libcpu_HEADERS += include/cecRegs.h +include_libcpu_HEADERS += include/memoryRegs.h +include_libcpu_HEADERS += include/mmuRegs.h +include_libcpu_HEADERS += include/sicRegs.h +include_libcpu_HEADERS += include/ebiuRegs.h +include_libcpu_HEADERS += include/ppiRegs.h +include_libcpu_HEADERS += include/coreTimerRegs.h +include_libcpu_HEADERS += include/wdogRegs.h +include_libcpu_HEADERS += include/timerRegs.h +include_libcpu_HEADERS += include/dmaRegs.h +include_libcpu_HEADERS += include/ethernetRegs.h +include_libcpu_HEADERS += include/uartRegs.h +include_libcpu_HEADERS += include/sportRegs.h +include_libcpu_HEADERS += include/twiRegs.h +include_libcpu_HEADERS += include/spiRegs.h +include_libcpu_HEADERS += include/rtcRegs.h +include_libcpu_HEADERS += include/gpioRegs.h + + +include_libcpu_HEADERS += ../shared/include/cache.h +noinst_PROGRAMS += cache.rel +cache_rel_SOURCES = cache/cache.c ../shared/src/cache_aligned_malloc.c \ + ../shared/src/cache_manager.c cache/cache_.h +cache_rel_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/cache +cache_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_libcpu_HEADERS += mmu/mmu.h +noinst_PROGRAMS += mmu.rel +mmu_rel_SOURCES = mmu/mmu.c +mmu_rel_CPPFLAGS = $(AM_CPPFLAGS) +mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_libcpu_HEADERS += interrupt/interrupt.h +noinst_PROGRAMS += interrupt.rel +interrupt_rel_SOURCES = interrupt/interrupt.c +interrupt_rel_CPPFLAGS = $(AM_CPPFLAGS) +interrupt_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += clock.rel +clock_rel_SOURCES = clock/clock.c +clock_rel_CPPFLAGS = $(AM_CPPFLAGS) +clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += rtc.rel +rtc_rel_SOURCES = clock/rtc.c +rtc_rel_CPPFLAGS = $(AM_CPPFLAGS) +rtc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_libcpu_HEADERS += serial/uart.h +noinst_PROGRAMS += uart.rel +uart_rel_SOURCES = serial/uart.c +uart_rel_CPPFLAGS = $(AM_CPPFLAGS) +uart_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_libcpu_HEADERS += serial/sport.h +noinst_PROGRAMS += sport.rel +sport_rel_SOURCES = serial/sport.c +sport_rel_CPPFLAGS = $(AM_CPPFLAGS) +sport_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_libcpu_HEADERS += serial/spi.h +noinst_PROGRAMS += spi.rel +spi_rel_SOURCES = serial/spi.c +spi_rel_CPPFLAGS = $(AM_CPPFLAGS) +spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +include_libcpu_HEADERS += serial/twi.h +noinst_PROGRAMS += twi.rel +twi_rel_SOURCES = serial/twi.c +twi_rel_CPPFLAGS = $(AM_CPPFLAGS) +twi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +noinst_PROGRAMS += timer.rel +timer_rel_SOURCES = timer/timer.c +timer_rel_CPPFLAGS = $(AM_CPPFLAGS) +timer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) + +if HAS_NETWORKING +## network +include_libcpu_HEADERS += network/ethernet.h +network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ +noinst_PROGRAMS += network.rel +network_rel_SOURCES = network/ethernet.c +network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(network_CPPFLAGS) +network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +endif + +include $(srcdir)/preinstall.am +include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/lib/libcpu/bfin/README b/c/src/lib/libcpu/bfin/README new file mode 100644 index 0000000000..8a7c592857 --- /dev/null +++ b/c/src/lib/libcpu/bfin/README @@ -0,0 +1,15 @@ +# +# $Id$ +# + +This hierarchy contains support routines for the Analog Devices +Blackfin family of processors. + +It is assumed that bsp.h includes , where xxx is +the processor type. This is how the libcpu modules determine which +processor variant they're being built for. + +serial/spi* and serial/sport* are currently just placeholders. +serial/twi* does not contain enough code to do anything useful; +it is however a start at an I2C driver. + diff --git a/c/src/lib/libcpu/bfin/cache/cache.c b/c/src/lib/libcpu/bfin/cache/cache.c new file mode 100644 index 0000000000..992e12ffc9 --- /dev/null +++ b/c/src/lib/libcpu/bfin/cache/cache.c @@ -0,0 +1,128 @@ +/* Blackfin Cache Support + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include +#include +#include +#include "cache_.h" + + +/* There are many syncs in the following code because they should be + harmless except for wasting time, and this is easier than figuring out + exactly where they're needed to protect from the effects of write + buffers and queued reads. Many of them are likely unnecessary. */ + + +void _CPU_cache_flush_1_data_line(const void *d_addr) { + + __asm__ __volatile__ ("ssync; flush [%0]; ssync" :: "a" (d_addr)); +} + +/* Blackfins can't just invalidate cache; they can only do flush + + invalidate. If the line isn't dirty then this is equivalent to + just an invalidate. Even if it is dirty, this should still be + okay since with a pure invalidate method the caller would have no + way to insure the dirty line hadn't been written out anyway prior + to the invalidate. */ +void _CPU_cache_invalidate_1_data_line(const void *d_addr) { + + __asm__ __volatile__ ("ssync; flushinv [%0]; ssync" :: "a" (d_addr)); +} + +void _CPU_cache_freeze_data(void) { +} + +void _CPU_cache_unfreeze_data(void) { +} + +void _CPU_cache_invalidate_1_instruction_line(const void *d_addr) { + + __asm__ __volatile__ ("ssync; iflush [%0]; ssync" :: "a" (d_addr)); +} + +void _CPU_cache_freeze_instruction(void) { +} + +void _CPU_cache_unfreeze_instruction(void) { +} + +/* incredibly inefficient... It would be better to make use of the + DTEST_COMMAND/DTEST_DATAx registers to find the addresses in each + cache line and flush just those. However the documentation I've + seen on those is a bit sketchy, and I sure wouldn't want to get it + wrong. */ +void _CPU_cache_flush_entire_data(void) { + uint32_t i; + + i = 0; + __asm__ __volatile__ ("ssync"); + do { + __asm__ __volatile__ ("flush [%0]" :: "a" (i)); + i += CPU_DATA_CACHE_ALIGNMENT; + } while (i); + __asm__ __volatile__ ("ssync"); +} + +void _CPU_cache_invalidate_entire_data(void) { + uint32_t dmemControl; + + __asm__ __volatile__ ("ssync"); + dmemControl = *(uint32_t volatile *) DMEM_CONTROL; + *(uint32_t volatile *) DMEM_CONTROL = dmemControl & ~DMEM_CONTROL_DMC_MASK; + *(uint32_t volatile *) DMEM_CONTROL = dmemControl; + __asm__ __volatile__ ("ssync"); +} + +/* this does not actually enable data cache unless CPLBs are also enabled. + LIBCPU_DATA_CACHE_CONFIG contains the DMEM_CONTROL_DMC bits to set. */ +void _CPU_cache_enable_data(void) { + + __asm__ __volatile__ ("ssync"); + *(uint32_t volatile *) DMEM_CONTROL |= LIBCPU_DATA_CACHE_CONFIG; + __asm__ __volatile__ ("ssync"); +} + +void _CPU_cache_disable_data(void) { + + __asm__ __volatile__ ("ssync"); + *(uint32_t volatile *) DMEM_CONTROL &= ~DMEM_CONTROL_DMC_MASK; + __asm__ __volatile__ ("ssync"); +} + +void _CPU_cache_invalidate_entire_instruction(void) { + uint32_t imemControl; + + __asm__ __volatile__ ("ssync"); + imemControl = *(uint32_t volatile *) IMEM_CONTROL; + *(uint32_t volatile *) IMEM_CONTROL = imemControl & ~IMEM_CONTROL_IMC; + *(uint32_t volatile *) IMEM_CONTROL = imemControl; + __asm__ __volatile__ ("ssync"); +} + +/* this only actually enables the instruction cache if the CPLBs are also + enabled. */ +void _CPU_cache_enable_instruction(void) { + + __asm__ __volatile__ ("ssync"); + *(uint32_t volatile *) IMEM_CONTROL |= IMEM_CONTROL_IMC; + __asm__ __volatile__ ("ssync"); +} + +void _CPU_cache_disable_instruction(void) { + + __asm__ __volatile__ ("ssync"); + *(uint32_t volatile *) IMEM_CONTROL &= ~IMEM_CONTROL_IMC; + __asm__ __volatile__ ("ssync"); +} + diff --git a/c/src/lib/libcpu/bfin/cache/cache_.h b/c/src/lib/libcpu/bfin/cache/cache_.h new file mode 100644 index 0000000000..728ac0609e --- /dev/null +++ b/c/src/lib/libcpu/bfin/cache/cache_.h @@ -0,0 +1,21 @@ +/* + * Blackfin Cache Manager Support + * + * $Id$ + */ + +#ifndef _cache__h_ +#define _cache__h_ + +#define CPU_DATA_CACHE_ALIGNMENT 32 +#define CPU_INSTRUCTION_CACHE_ALIGNMENT 32 + +#ifdef BSP_DATA_CACHE_CONFIG +#define LIBCPU_DATA_CACHE_CONFIG BSP_DATA_CACHE_CONFIG +#else +/* use 16K of each SRAM bank */ +#define LIBCPU_DATA_CACHE_CONFIG (3 << DMEM_CONTROL_DMC_SHIFT) +#endif + +#endif /* _cache__h_ */ + diff --git a/c/src/lib/libcpu/bfin/clock/clock.c b/c/src/lib/libcpu/bfin/clock/clock.c new file mode 100644 index 0000000000..b45a8a1979 --- /dev/null +++ b/c/src/lib/libcpu/bfin/clock/clock.c @@ -0,0 +1,150 @@ +/* RTEMS Clock Tick Driver for Blackfin. Uses Blackfin Core Timer. + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include +#include +#include + +#include +#include + + +volatile uint32_t Clock_driver_ticks; + +void Clock_exit(void); + +/* + * Major and minor number. + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +static rtems_isr clockISR(rtems_vector_number vector) { + + Clock_driver_ticks += 1; + +#ifdef CLOCK_DRIVER_USE_FAST_IDLE + do { + rtems_clock_tick(); + } while (_Thread_Executing == _Thread_Idle && + _Thread_Heir == _Thread_Executing); +#else + rtems_clock_tick(); +#endif +} + + +/* + * Clock_exit + * + * This routine allows the clock driver to exit by masking the interrupt and + * disabling the clock's counter. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: NONE + * + */ + +void Clock_exit(void) { + + *(uint32_t volatile *) TCNTL = 0; +} + +/* + * Clock_initialize + * + * This routine initializes the clock driver. + * + * Input parameters: + * major - clock device major number + * minor - clock device minor number + * parg - pointer to optional device driver arguments + * + * Output parameters: NONE + * + * Return values: + * rtems_device_driver status code + */ + +rtems_device_driver Clock_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp) { + + Clock_driver_ticks = 0; + + set_vector(clockISR, CEC_CORE_TIMER_VECTOR, 1); + + *(uint32_t volatile *) TCNTL = TCNTL_TMPWR | TCNTL_TAUTORLD; + *(uint32_t volatile *) TSCALE = 0; + *(uint32_t volatile *) TPERIOD = CCLK / 1000000 * + rtems_configuration_get_microseconds_per_tick(); + *(uint32_t volatile *) TCNTL = TCNTL_TMPWR | TCNTL_TAUTORLD | TCNTL_TMREN; + + atexit(Clock_exit); + /* + * make major/minor avail to others such as shared memory driver + */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + +/* + * Clock_control + * + * This routine is the clock device driver control entry point. + * + * Input parameters: + * major - clock device major number + * minor - clock device minor number + * parg - pointer to optional device driver arguments + * + * Output parameters: NONE + * + * Return values: + * rtems_device_driver status code + */ + +rtems_device_driver Clock_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp) { + rtems_interrupt_level isrLevel; + rtems_libio_ioctl_args_t *args = pargp; + + if (args == 0) + goto done; + + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) { + clockISR(CEC_CORE_TIMER_VECTOR); + } else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) { + rtems_interrupt_disable(isrLevel); + set_vector(args->buffer, CEC_CORE_TIMER_VECTOR, 1); + rtems_interrupt_enable(isrLevel); + } + +done: + return RTEMS_SUCCESSFUL; +} + diff --git a/c/src/lib/libcpu/bfin/clock/rtc.c b/c/src/lib/libcpu/bfin/clock/rtc.c new file mode 100644 index 0000000000..dace52eae2 --- /dev/null +++ b/c/src/lib/libcpu/bfin/clock/rtc.c @@ -0,0 +1,184 @@ +/* Real Time Clock Driver for Blackfin + * + * Copyright (c) 2006 by Atos Automacao Industrial Ltda. + * written by Alain Schaefer + * and Antonio Giovanini + * + * 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 +#include "tod.h" +#include +#include +#include +#include +#include + +/* The following are inside RTEMS -- we are violating visibility!!! + * Perhaps an API could be defined to get days since 1 Jan. + */ +extern const uint16_t _TOD_Days_to_date[2][13]; + +/* + * Prototypes and routines used below + */ +int Leap_years_until_now (int year); + +void Init_RTC(void) +{ + *((uint16_t*)RTC_PREN) = RTC_PREN_PREN; /* Enable Prescaler */ +} + +rtems_device_driver rtc_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor_arg, + void *arg +) +{ + rtems_status_code status; + + /* + * Register and initialize the primary RTC's + */ + + status = rtems_io_register_name( "/dev/rtc", major, 0 ); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + + Init_RTC(); + + setRealTimeToRTEMS(); + return RTEMS_SUCCESSFUL; +} + +/* + * Read time from RTEMS' clock manager and set it to RTC + */ + +void setRealTimeFromRTEMS (void) +{ + rtems_time_of_day time_buffer; + rtems_status_code status; + + status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time_buffer ); + if (status == RTEMS_SUCCESSFUL){ + setRealTime(&time_buffer); + } +} + +/* + * Read real time from RTC and set it to RTEMS' clock manager + */ + +void setRealTimeToRTEMS (void) +{ + rtems_time_of_day time_buffer; + + getRealTime(&time_buffer); + rtems_clock_set( &time_buffer ); +} + + /* + * Set the RTC time + */ +int setRealTime( + rtems_time_of_day *tod +) +{ + uint32_t days; + rtems_time_of_day tod_temp; + + tod_temp = *tod; + + days = (tod_temp.year - TOD_BASE_YEAR) * 365 + \ + _TOD_Days_to_date[0][tod_temp.month] + tod_temp.day - 1; + if (tod_temp.month < 3) + days += Leap_years_until_now (tod_temp.year - 1); + else + days += Leap_years_until_now (tod_temp.year); + + *((uint32_t volatile *)RTC_STAT) = (days << RTC_STAT_DAYS_SHIFT)| + (tod_temp.hour << RTC_STAT_HOURS_SHIFT)| + (tod_temp.minute << RTC_STAT_MINUTES_SHIFT)| + tod_temp.second; + + return 0; +} + + /* + * Get the time from the RTC. + */ + +void getRealTime( + rtems_time_of_day *tod +) +{ + uint32_t days, rtc_reg; + rtems_time_of_day tod_temp; + int n, Leap_year; + + rtc_reg = *((uint32_t volatile *)RTC_STAT); + + days = (rtc_reg >> RTC_STAT_DAYS_SHIFT) + 1; + + /* finding year */ + tod_temp.year = days/365 + TOD_BASE_YEAR; + if (days%365 > Leap_years_until_now (tod_temp.year - 1)) { + days = (days%365) - Leap_years_until_now (tod_temp.year - 1); + } else { + tod_temp.year--; + days = (days%365) + 365 - Leap_years_until_now (tod_temp.year - 1); + } + + /* finding month and day */ + Leap_year = (((!(tod_temp.year%4)) && (tod_temp.year%100)) || + (!(tod_temp.year%400)))?1:0; + for (n=1; n<=12; n++) { + if (days <= _TOD_Days_to_date[Leap_year][n+1]) { + tod_temp.month = n; + tod_temp.day = days - _TOD_Days_to_date[Leap_year][n]; + break; + } + } + + tod_temp.hour = (rtc_reg & RTC_STAT_HOURS_MASK) >> RTC_STAT_HOURS_SHIFT; + tod_temp.minute = (rtc_reg & RTC_STAT_MINUTES_MASK) >> RTC_STAT_MINUTES_SHIFT; + tod_temp.second = (rtc_reg & RTC_STAT_SECONDS_MASK); + tod_temp.ticks = 0; + *tod = tod_temp; +} + +/* + * Return the difference between RTC and RTEMS' clock manager time in minutes. + * If the difference is greater than 1 day, this returns 9999. + */ + +int checkRealTime (void) +{ + rtems_time_of_day rtems_tod; + rtems_time_of_day rtc_tod; + uint32_t rtems_time; + uint32_t rtc_time; + + rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod ); + getRealTime ( &rtc_tod ); + + rtems_time = _TOD_To_seconds( &rtems_tod ); + rtc_time = _TOD_To_seconds( &rtc_tod ); + + return rtems_time - rtc_time; +} + +int Leap_years_until_now (int year) +{ + return ((year/4 - year/100 + year/400) - + ((TOD_BASE_YEAR - 1)/4 - (TOD_BASE_YEAR - 1)/100 + + (TOD_BASE_YEAR - 1)/400)); +} diff --git a/c/src/lib/libcpu/bfin/clock/tod.h b/c/src/lib/libcpu/bfin/clock/tod.h new file mode 100644 index 0000000000..244f5f3ae4 --- /dev/null +++ b/c/src/lib/libcpu/bfin/clock/tod.h @@ -0,0 +1,63 @@ +/* tod.h + * + * Real Time Clock definitions for eZKit533. + * + * Copyright (c) 2006 by Atos Automacao Industrial Ltda. + * written by Alain Schaefer + * and Antonio Giovanini + * + * 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 TOD_H +#define TOD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Set the RTC. + */ + +int setRealTime( + rtems_time_of_day *tod +); + +/* + * Get the time from the RTC. + */ + +void getRealTime( + rtems_time_of_day *tod +); + +/* + * Read real time from RTC and set it to RTEMS' clock manager + */ + +void setRealTimeToRTEMS(); + +/* + * Read time from RTEMS' clock manager and set it to RTC + */ + +void setRealTimeFromRTEMS(); + +/* + * Return the difference between RTC and RTEMS' clock manager time in minutes. + * If the difference is greater than 1 day, this returns 9999. + */ + +int checkRealTime(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libcpu/bfin/configure.ac b/c/src/lib/libcpu/bfin/configure.ac new file mode 100644 index 0000000000..561a3885dc --- /dev/null +++ b/c/src/lib/libcpu/bfin/configure.ac @@ -0,0 +1,32 @@ +## Process this file with autoconf to produce a configure script. +## +## $Id$ +## + +AC_PREREQ(2.60) +AC_INIT([rtems-c-src-lib-libcpu-bfin],[_RTEMS_VERSION],[http://www.rtems.org/bugzilla]) +RTEMS_TOP([../../../../..],[../../..]) + +RTEMS_CANONICAL_TARGET_CPU + +AM_INIT_AUTOMAKE([no-define foreign subdir-objects 1.10]) +AM_MAINTAINER_MODE + +RTEMS_ENV_RTEMSBSP + +RTEMS_PROJECT_ROOT + +RTEMS_PROG_CC_FOR_TARGET +AM_PROG_CC_C_O +RTEMS_CANONICALIZE_TOOLS +RTEMS_PROG_CCAS + +RTEMS_CHECK_NETWORKING +AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") + +RTEMS_AMPOLISH3 + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile +]) +AC_OUTPUT diff --git a/c/src/lib/libcpu/bfin/include/bf533.h b/c/src/lib/libcpu/bfin/include/bf533.h new file mode 100644 index 0000000000..44a0b9b982 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/bf533.h @@ -0,0 +1,136 @@ +/* Blackfin BF533 Definitions + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _bf533_h_ +#define _bf533_h_ + +/* register (or register block) addresses */ + +#define SIC_BASE_ADDRESS 0xffc00100 +#define WDOG_BASE_ADDRESS 0xffc00200 +#define RTC_BASE_ADDRESS 0xffc00300 +#define UART0_BASE_ADDRESS 0xffc00400 +#define SPI_BASE_ADDRESS 0xffc00500 +#define TIMER_BASE_ADDRESS 0xffc00600 +#define TIMER_CHANNELS 3 +#define TIMER_PITCH 0x10 +#define TIMER0_BASE_ADDRESS 0xffc00600 +#define TIMER1_BASE_ADDRESS 0xffc00610 +#define TIMER2_BASE_ADDRESS 0xffc00620 +#define TIMER_ENABLE 0xffc00640 +#define TIMER_DISABLE 0xffc00644 +#define TIMER_STATUS 0xffc00648 +#define PORTFIO_BASE_ADDRESS 0xffc00700 +#define SPORT0_BASE_ADDRESS 0xffc00800 +#define SPORT1_BASE_ADDRESS 0xffc00900 +#define EBIU_BASE_ADDRESS 0xffc00a00 +#define DMA_TC_PER 0xffc00b0c +#define DMA_TC_CNT 0xffc00b10 +#define DMA_BASE_ADDRESS 0xffc00c00 +#define DMA_CHANNELS 8 +#define DMA_PITCH 0x40 +#define DMA0_BASE_ADDRESS 0xffc00c00 +#define DMA1_BASE_ADDRESS 0xffc00c40 +#define DMA2_BASE_ADDRESS 0xffc00c80 +#define DMA3_BASE_ADDRESS 0xffc00cc0 +#define DMA4_BASE_ADDRESS 0xffc00d00 +#define DMA5_BASE_ADDRESS 0xffc00d40 +#define DMA6_BASE_ADDRESS 0xffc00d80 +#define DMA7_BASE_ADDRESS 0xffc00dc0 +#define MDMA_BASE_ADDRESS 0xffc00e00 +#define MDMA_CHANNELS 2 +#define MDMA_D_S 0x40 +#define MDMA_PITCH 0x80 +#define MDMA0D_BASE_ADDRESS 0xffc00e00 +#define MDMA0S_BASE_ADDRESS 0xffc00e40 +#define MDMA1D_BASE_ADDRESS 0xffc00e80 +#define MDMA1S_BASE_ADDRESS 0xffc00ec0 +#define PPI_BASE_ADDRESS 0xffc01000 + + +/* register fields */ + +#define DMA_TC_PER_MDMA_ROUND_ROBIN_PERIOD_MASK 0xf800 +#define DMA_TC_PER_MDMA_ROUND_ROBIN_PERIOD_SHIFT 11 +#define DMA_TC_PER_DAB_TRAFFIC_PERIOD_MASK 0x0700 +#define DMA_TC_PER_DAB_TRAFFIC_PERIOD_SHIFT 8 +#define DMA_TC_PER_DEB_TRAFFIC_PERIOD_MASK 0x00f0 +#define DMA_TC_PER_DEB_TRAFFIC_PERIOD_SHIFT 4 +#define DMA_TC_PER_DCB_TRAFFIC_PERIOD_MASK 0x000f +#define DMA_TC_PER_DCB_TRAFFIC_PERIOD_SHIFT 0 + +#define DMA_TC_CNT_MDMA_ROUND_ROBIN_COUNT_MASK 0xf800 +#define DMA_TC_CNT_MDMA_ROUND_ROBIN_COUNT_SHIFT 11 +#define DMA_TC_CNT_DAB_TRAFFIC_COUNT_MASK 0x0700 +#define DMA_TC_CNT_DAB_TRAFFIC_COUNT_SHIFT 8 +#define DMA_TC_CNT_DEB_TRAFFIC_COUNT_MASK 0x00f0 +#define DMA_TC_CNT_DEB_TRAFFIC_COUNT_SHIFT 4 +#define DMA_TC_CNT_DCB_TRAFFIC_COUNT_MASK 0x000f +#define DMA_TC_CNT_DCB_TRAFFIC_COUNT_SHIFT 0 + +#define TIMER_ENABLE_TIMEN2 0x0004 +#define TIMER_ENABLE_TIMEN1 0x0002 +#define TIMER_ENABLE_TIMEN0 0x0001 + +#define TIMER_DISABLE_TIMDIS2 0x0004 +#define TIMER_DISABLE_TIMDIS1 0x0002 +#define TIMER_DISABLE_TIMDIS0 0x0001 + +#define TIMER_STATUS_TRUN2 0x00004000 +#define TIMER_STATUS_TRUN1 0x00002000 +#define TIMER_STATUS_TRUN0 0x00001000 +#define TIMER_STATUS_TOVF_ERR2 0x00000040 +#define TIMER_STATUS_TOVF_ERR1 0x00000020 +#define TIMER_STATUS_TOVF_ERR0 0x00000010 +#define TIMER_STATUS_TIMIL2 0x00000004 +#define TIMER_STATUS_TIMIL1 0x00000002 +#define TIMER_STATUS_TIMIL0 0x00000001 + +/* Core Event Controller vectors */ + +#define CEC_EMULATION_VECTOR 0 +#define CEC_RESET_VECTOR 1 +#define CEC_NMI_VECTOR 2 +#define CEC_EXCEPTIONS_VECTOR 3 +#define CEC_HARDWARE_ERROR_VECTOR 5 +#define CEC_CORE_TIMER_VECTOR 6 +#define CEC_INTERRUPT_BASE_VECTOR 7 +#define CEC_INTERRUPT_COUNT 9 + + +/* System Interrupt Controller vectors */ + +#define SIC_PLL_WAKEUP_VECTOR 0 +#define SIC_DMA_ERROR_VECTOR 1 +#define SIC_PPI_ERROR_VECTOR 2 +#define SIC_SPORT0_ERROR_VECTOR 3 +#define SIC_SPORT1_ERROR_VECTOR 4 +#define SIC_SPI_ERROR_VECTOR 5 +#define SIC_UART0_ERROR_VECTOR 6 +#define SIC_RTC_VECTOR 7 +#define SIC_DMA0_PPI_VECTOR 8 +#define SIC_DMA1_SPORT0_RX_VECTOR 9 +#define SIC_DMA2_SPORT0_TX_VECTOR 10 +#define SIC_DMA3_SPORT1_RX_VECTOR 11 +#define SIC_DMA4_SPORT1_TX_VECTOR 12 +#define SIC_DMA5_SPI_VECTOR 13 +#define SIC_DMA6_UART0_RX_VECTOR 14 +#define SIC_DMA7_UART0_TX_VECTOR 15 +#define SIC_TIMER0_VECTOR 16 +#define SIC_TIMER1_VECTOR 17 +#define SIC_TIMER2_VECTOR 18 +#define SIC_MDMA0_VECTOR 21 +#define SIC_MDMA1_VECTOR 22 +#define SIC_WATCHDOG_VECTOR 23 + +#endif /* _bf533_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/bf537.h b/c/src/lib/libcpu/bfin/include/bf537.h new file mode 100644 index 0000000000..82454410f6 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/bf537.h @@ -0,0 +1,226 @@ +/* Blackfin BF537 Definitions + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _bf537_h_ +#define _bf537_h_ + +/* register (or register block) addresses */ + +#define SIC_BASE_ADDRESS 0xffc00100 +#define WDOG_BASE_ADDRESS 0xffc00200 +#define RTC_BASE_ADDRESS 0xffc00300 +#define UART0_BASE_ADDRESS 0xffc00400 +#define SPI_BASE_ADDRESS 0xffc00500 +#define TIMER_BASE_ADDRESS 0xffc00600 +#define TIMER_CHANNELS 8 +#define TIMER_PITCH 0x10 +#define TIMER0_BASE_ADDRESS 0xffc00600 +#define TIMER1_BASE_ADDRESS 0xffc00610 +#define TIMER2_BASE_ADDRESS 0xffc00620 +#define TIMER3_BASE_ADDRESS 0xffc00630 +#define TIMER4_BASE_ADDRESS 0xffc00640 +#define TIMER5_BASE_ADDRESS 0xffc00650 +#define TIMER6_BASE_ADDRESS 0xffc00660 +#define TIMER7_BASE_ADDRESS 0xffc00670 +#define TIMER_ENABLE 0xffc00680 +#define TIMER_DISABLE 0xffc00684 +#define TIMER_STATUS 0xffc00688 +#define PORTFIO_BASE_ADDRESS 0xffc00700 +#define SPORT0_BASE_ADDRESS 0xffc00800 +#define SPORT1_BASE_ADDRESS 0xffc00900 +#define EBIU_BASE_ADDRESS 0xffc00a00 +#define DMA_TC_PER 0xffc00b0c +#define DMA_TC_CNT 0xffc00b10 +#define DMA_BASE_ADDRESS 0xffc00c00 +#define DMA_CHANNELS 12 +#define DMA_PITCH 0x40 +#define DMA0_BASE_ADDRESS 0xffc00c00 +#define DMA1_BASE_ADDRESS 0xffc00c40 +#define DMA2_BASE_ADDRESS 0xffc00c80 +#define DMA3_BASE_ADDRESS 0xffc00cc0 +#define DMA4_BASE_ADDRESS 0xffc00d00 +#define DMA5_BASE_ADDRESS 0xffc00d40 +#define DMA6_BASE_ADDRESS 0xffc00d80 +#define DMA7_BASE_ADDRESS 0xffc00dc0 +#define DMA8_BASE_ADDRESS 0xffc00e00 +#define DMA9_BASE_ADDRESS 0xffc00e40 +#define DMA10_BASE_ADDRESS 0xffc00e80 +#define DMA11_BASE_ADDRESS 0xffc00ec0 +#define MDMA_BASE_ADDRESS 0xffc00f00 +#define MDMA_CHANNELS 2 +#define MDMA_D_S 0x40 +#define MDMA_PITCH 0x80 +#define MDMA0D_BASE_ADDRESS 0xffc00f00 +#define MDMA0S_BASE_ADDRESS 0xffc00f40 +#define MDMA1D_BASE_ADDRESS 0xffc00f80 +#define MDMA1S_BASE_ADDRESS 0xffc00fc0 +#define PPI_BASE_ADDRESS 0xffc01000 +#define TWI_BASE_ADDRESS 0xffc01400 +#define PORTGIO_BASE_ADDRESS 0xffc01500 +#define PORTHIO_BASE_ADDRESS 0xffc01700 +#define UART1_BASE_ADDRESS 0xffc02000 +#define CAN_BASE_ADDRESS 0xffc02a00 +#define CAN_AM_BASE_ADDRESS 0xffc02b00 +#define CAN_MB_BASE_ADDRESS 0xffc02c00 +#define EMAC_BASE_ADDRESS 0xffc03000 +#define PORTF_FER 0xffc03200 +#define PORTG_FER 0xffc03204 +#define PORTH_FER 0xffc03208 +#define PORT_MUX 0xffc0320c +#define HMDMA0_BASE_ADDRESS 0xffc03300 +#define HMDMA1_BASE_ADDRESS 0xffc03340 + + +/* register fields */ + +#define DMA_TC_PER_MDMA_ROUND_ROBIN_PERIOD_MASK 0xf800 +#define DMA_TC_PER_MDMA_ROUND_ROBIN_PERIOD_SHIFT 11 +#define DMA_TC_PER_DAB_TRAFFIC_PERIOD_MASK 0x0700 +#define DMA_TC_PER_DAB_TRAFFIC_PERIOD_SHIFT 8 +#define DMA_TC_PER_DEB_TRAFFIC_PERIOD_MASK 0x00f0 +#define DMA_TC_PER_DEB_TRAFFIC_PERIOD_SHIFT 4 +#define DMA_TC_PER_DCB_TRAFFIC_PERIOD_MASK 0x000f +#define DMA_TC_PER_DCB_TRAFFIC_PERIOD_SHIFT 0 + +#define DMA_TC_CNT_MDMA_ROUND_ROBIN_COUNT_MASK 0xf800 +#define DMA_TC_CNT_MDMA_ROUND_ROBIN_COUNT_SHIFT 11 +#define DMA_TC_CNT_DAB_TRAFFIC_COUNT_MASK 0x0700 +#define DMA_TC_CNT_DAB_TRAFFIC_COUNT_SHIFT 8 +#define DMA_TC_CNT_DEB_TRAFFIC_COUNT_MASK 0x00f0 +#define DMA_TC_CNT_DEB_TRAFFIC_COUNT_SHIFT 4 +#define DMA_TC_CNT_DCB_TRAFFIC_COUNT_MASK 0x000f +#define DMA_TC_CNT_DCB_TRAFFIC_COUNT_SHIFT 0 + +#define TIMER_ENABLE_TIMEN7 0x0080 +#define TIMER_ENABLE_TIMEN6 0x0040 +#define TIMER_ENABLE_TIMEN5 0x0020 +#define TIMER_ENABLE_TIMEN4 0x0010 +#define TIMER_ENABLE_TIMEN3 0x0008 +#define TIMER_ENABLE_TIMEN2 0x0004 +#define TIMER_ENABLE_TIMEN1 0x0002 +#define TIMER_ENABLE_TIMEN0 0x0001 + +#define TIMER_DISABLE_TIMDIS7 0x0080 +#define TIMER_DISABLE_TIMDIS6 0x0040 +#define TIMER_DISABLE_TIMDIS5 0x0020 +#define TIMER_DISABLE_TIMDIS4 0x0010 +#define TIMER_DISABLE_TIMDIS3 0x0008 +#define TIMER_DISABLE_TIMDIS2 0x0004 +#define TIMER_DISABLE_TIMDIS1 0x0002 +#define TIMER_DISABLE_TIMDIS0 0x0001 + +#define TIMER_STATUS_TRUN7 0x80000000 +#define TIMER_STATUS_TRUN6 0x40000000 +#define TIMER_STATUS_TRUN5 0x20000000 +#define TIMER_STATUS_TRUN4 0x10000000 +#define TIMER_STATUS_TOVF_ERR7 0x00800000 +#define TIMER_STATUS_TOVF_ERR6 0x00400000 +#define TIMER_STATUS_TOVF_ERR5 0x00200000 +#define TIMER_STATUS_TOVF_ERR4 0x00100000 +#define TIMER_STATUS_TIMIL7 0x00080000 +#define TIMER_STATUS_TIMIL6 0x00040000 +#define TIMER_STATUS_TIMIL5 0x00020000 +#define TIMER_STATUS_TIMIL4 0x00010000 +#define TIMER_STATUS_TRUN3 0x00008000 +#define TIMER_STATUS_TRUN2 0x00004000 +#define TIMER_STATUS_TRUN1 0x00002000 +#define TIMER_STATUS_TRUN0 0x00001000 +#define TIMER_STATUS_TOVF_ERR3 0x00000080 +#define TIMER_STATUS_TOVF_ERR2 0x00000040 +#define TIMER_STATUS_TOVF_ERR1 0x00000020 +#define TIMER_STATUS_TOVF_ERR0 0x00000010 +#define TIMER_STATUS_TIMIL3 0x00000008 +#define TIMER_STATUS_TIMIL2 0x00000004 +#define TIMER_STATUS_TIMIL1 0x00000002 +#define TIMER_STATUS_TIMIL0 0x00000001 + +#define PORT_MUX_PGTE 0x0800 +#define PORT_MUX_PGRE 0x0400 +#define PORT_MUX_PGSE 0x0200 +#define PORT_MUX_PFFE 0x0100 +#define PORT_MUX_PFS4E 0x0080 +#define PORT_MUX_PFS5E 0x0040 +#define PORT_MUX_PFS6E 0x0020 +#define PORT_MUX_PFTE 0x0010 +#define PORT_MUX_PFDE 0x0008 +#define PORT_MUX_PJCE_MASK 0x0006 +#define PORT_MUX_PJCE_DR0SEC_DTOSEC 0x0000 +#define PORT_MUX_PJCE_CANRX_CANTX 0x0002 +#define PORT_MUX_PJCE_SPISSEL7 0x0004 +#define PORT_MUX_PJSE 0x0001 + + +/* Core Event Controller vectors */ + +#define CEC_EMULATION_VECTOR 0 +#define CEC_RESET_VECTOR 1 +#define CEC_NMI_VECTOR 2 +#define CEC_EXCEPTIONS_VECTOR 3 +#define CEC_HARDWARE_ERROR_VECTOR 5 +#define CEC_CORE_TIMER_VECTOR 6 +#define CEC_INTERRUPT_BASE_VECTOR 7 +#define CEC_INTERRUPT_COUNT 9 + + +/* System Interrupt Controller vectors */ + +#define SIC_PLL_WAKEUP_VECTOR 0 +#define SIC_DMA_ERROR_VECTOR 1 +#define SIC_DMAR0_BLOCK_DONE_VECTOR 1 +#define SIC_DMAR1_BLOCK_DONE_VECTOR 1 +#define SIC_DMAR0_OVERFLOW_VECTOR 1 +#define SIC_DMAR1_OVERFLOW_VECTOR 1 +#define SIC_CAN_ERROR_VECTOR 2 +#define SIC_MAC_ERROR_VECTOR 2 +#define SIC_SPORT0_ERROR_VECTOR 2 +#define SIC_SPORT1_ERROR_VECTOR 2 +#define SIC_PPI_ERROR_VECTOR 2 +#define SIC_SPI_ERROR_VECTOR 2 +#define SIC_UART0_ERROR_VECTOR 2 +#define SIC_UART1_ERROR_VECTOR 2 +#define SIC_RTC_VECTOR 3 +#define SIC_DMA0_PPI_VECTOR 4 +#define SIC_DMA3_SPORT0_RX_VECTOR 5 +#define SIC_DMA4_SPORT0_TX_VECTOR 6 +#define SIC_DMA5_SPORT1_RX_VECTOR 7 +#define SIC_DMA5_SPORT1_TX_VECTOR 8 +#define SIC_TWI_VECTOR 9 +#define SIC_DMA7_SPI_VECTOR 10 +#define SIC_DMA8_UART0_RX_VECTOR 11 +#define SIC_DMA9_UART0_TX_VECTOR 12 +#define SIC_DMA10_UART1_RX_VECTOR 13 +#define SIC_DMA11_UART1_TX_VECTOR 14 +#define SIC_CAN_RX_VECTOR 15 +#define SIC_CAN_TX_VECTOR 16 +#define SIC_DMA1_MAC_RX_VECTOR 17 +#define SIC_PORTH_IRQ_A_VECTOR 17 +#define SIC_DMA2_MAC_TX_VECTOR 18 +#define SIC_PORTH_IRQ_B_VECTOR 18 +#define SIC_TIMER0_VECTOR 19 +#define SIC_TIMER1_VECTOR 20 +#define SIC_TIMER2_VECTOR 21 +#define SIC_TIMER3_VECTOR 22 +#define SIC_TIMER4_VECTOR 23 +#define SIC_TIMER5_VECTOR 24 +#define SIC_TIMER6_VECTOR 25 +#define SIC_TIMER7_VECTOR 26 +#define SIC_PORTF_IRQ_A_VECTOR 27 +#define SIC_PORTG_IRQ_A_VECTOR 27 +#define SIC_PORTG_IRQ_B_VECTOR 28 +#define SIC_MDMA0_VECTOR 29 +#define SIC_MDMA1_VECTOR 30 +#define SIC_WATCHDOG_VECTOR 31 +#define SIC_PORTF_IRQ_B_VECTOR 31 + + +#endif /* _bf537_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/cecRegs.h b/c/src/lib/libcpu/bfin/include/cecRegs.h new file mode 100644 index 0000000000..58916735fe --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/cecRegs.h @@ -0,0 +1,49 @@ +/* Blackfin Core Event Controller Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _cecRegs_h_ +#define _cecRegs_h_ + +/* register addresses */ +#define CEC_EVT_BASE 0xffe02000 +#define CEC_EVT_COUNT 16 +#define CEC_EVT_PITCH 0x04 +#define CEC_EVT0 0xffe02000 +#define CEC_EVT1 0xffe02004 +#define CEC_EVT2 0xffe02008 +#define CEC_EVT3 0xffe0200c +#define CEC_EVT4 0xffe02010 +#define CEC_EVT5 0xffe02014 +#define CEC_EVT6 0xffe02018 +#define CEC_EVT7 0xffe0201c +#define CEC_EVT8 0xffe02020 +#define CEC_EVT9 0xffe02024 +#define CEC_EVT10 0xffe02028 +#define CEC_EVT11 0xffe0202c +#define CEC_EVT12 0xffe02030 +#define CEC_EVT13 0xffe02034 +#define CEC_EVT14 0xffe02038 +#define CEC_EVT15 0xffe0203c +#define CEC_IMASK 0xffe02104 +#define CEC_IPEND 0xffe02108 +#define CEC_ILAT 0xffe0210c +#define CEC_IPRIO 0xffe02110 + + +/* register fields */ + +#define CEC_IPRIO_IPRIO_MARK_MASK 0x0000000f +#define CEC_IPRIO_IPRIO_MARK_SHIFT 0 + + +#endif /* _cecRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/coreTimerRegs.h b/c/src/lib/libcpu/bfin/include/coreTimerRegs.h new file mode 100644 index 0000000000..393720f4dd --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/coreTimerRegs.h @@ -0,0 +1,32 @@ +/* Blackfin Core Timer Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _coreTimerRegs_h_ +#define _coreTimerRegs_h_ + +/* register addresses */ + +#define TCNTL 0xffe03000 +#define TPERIOD 0xffe03004 +#define TSCALE 0xffe03008 +#define TCOUNT 0xffe0300c + + +/* register fields */ + +#define TCNTL_TINT 0x00000008 +#define TCNTL_TAUTORLD 0x00000004 +#define TCNTL_TMREN 0x00000002 +#define TCNTL_TMPWR 0x00000001 + +#endif /* _coreTimerRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/dmaRegs.h b/c/src/lib/libcpu/bfin/include/dmaRegs.h new file mode 100644 index 0000000000..0fc62019d8 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/dmaRegs.h @@ -0,0 +1,100 @@ +/* Blackfin DMA Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _dmaRegs_h_ +#define _dmaRegs_h_ + + +/* register addresses */ + +#define DMA_NEXT_DESC_PTR_OFFSET 0x0000 +#define DMA_START_ADDR_OFFSET 0x0004 +#define DMA_CONFIG_OFFSET 0x0008 +#define DMA_X_COUNT_OFFSET 0x0010 +#define DMA_X_MODIFY_OFFSET 0x0014 +#define DMA_Y_COUNT_OFFSET 0x0018 +#define DMA_Y_MODIFY_OFFSET 0x001c +#define DMA_CURR_DESC_PTR_OFFSET 0x0020 +#define DMA_CURR_ADDR_OFFSET 0x0024 +#define DMA_IRQ_STATUS_OFFSET 0x0028 +#define DMA_PERIPHERAL_MAP_OFFSET 0x002c +#define DMA_CURR_X_COUNT_OFFSET 0x0030 +#define DMA_CURR_Y_COUNT_OFFSET 0x0038 + +#define HMDMA_CONTROL_OFFSET 0x0000 +#define HMDMA_ECINIT_OFFSET 0x0004 +#define HMDMA_BCINIT_OFFSET 0x0008 +#define HMDMA_ECURGENT_OFFSET 0x000c +#define HMDMA_ECOVERFLOW_OFFSET 0x0010 +#define HMDMA_ECOUNT_OFFSET 0x0014 +#define HMDMA_BCOUNT_OFFSET 0x0018 + + +/* register fields */ + +#define DMA_CONFIG_FLOW_MASK 0x7000 +#define DMA_CONFIG_FLOW_STOP 0x0000 +#define DMA_CONFIG_FLOW_AUTOBUFFER 0x1000 +#define DMA_CONFIG_FLOW_DESC_ARRAY 0x4000 +#define DMA_CONFIG_FLOW_DESC_SMALL 0x6000 +#define DMA_CONFIG_FLOW_DESC_LARGE 0x7000 +#define DMA_CONFIG_NDSIZE_MASK 0x0f00 +#define DMA_CONFIG_NDSIZE_SHIFT 8 +#define DMA_CONFIG_DI_EN 0x0080 +#define DMA_CONFIG_DI_SEL 0x0040 +#define DMA_CONFIG_SYNC 0x0020 +#define DMA_CONFIG_DMA2D 0x0010 +#define DMA_CONFIG_WDSIZE_MASK 0x000c +#define DMA_CONFIG_WDSIZE_8 0x0000 +#define DMA_CONFIG_WDSIZE_16 0x0004 +#define DMA_CONFIG_WDSIZE_32 0x0008 +#define DMA_CONFIG_WNR 0x0002 +#define DMA_CONFIG_DMAEN 0x0001 + +#define DMA_IRQ_STATUS_DMA_RUN 0x0008 +#define DMA_IRQ_STATUS_DFETCH 0x0004 +#define DMA_IRQ_STATUS_DMA_ERR 0x0002 +#define DMA_IRQ_STATUS_DMA_DONE 0x0001 + +#define DMA_PERIPHERAL_MAP_PMAP_MASK 0xf000 +#define DMA_PERIPHERAL_MAP_PMAP_PPI 0x0000 +#define DMA_PERIPHERAL_MAP_PMAP_ETHRX 0x1000 +#define DMA_PERIPHERAL_MAP_PMAP_ETHTX 0x2000 +#define DMA_PERIPHERAL_MAP_PMAP_SPORT0RX 0x3000 +#define DMA_PERIPHERAL_MAP_PMAP_SPORT0TX 0x4000 +#define DMA_PERIPHERAL_MAP_PMAP_SPORT1RX 0x5000 +#define DMA_PERIPHERAL_MAP_PMAP_SPORT1TX 0x6000 +#define DMA_PERIPHERAL_MAP_PMAP_SPI 0x7000 +#define DMA_PERIPHERAL_MAP_PMAP_UART0RX 0x8000 +#define DMA_PERIPHERAL_MAP_PMAP_UART0TX 0x9000 +#define DMA_PERIPHERAL_MAP_PMAP_UART1RX 0xa000 +#define DMA_PERIPHERAL_MAP_PMAP_UART1TX 0xb000 +#define DMA_PERIPHERAL_MAP_CTYPE 0x0040 + +#define HMDMA_CONTROL_BDI 0x8000 +#define HMDMA_CONTROL_OI 0x4000 +#define HMDMA_CONTROL_PS 0x2000 +#define HMDMA_CONTROL_RBC 0x1000 +#define HMDMA_CONTROL_DRQ_MASK 0x0300 +#define HMDMA_CONTROL_DRQ_NONE 0x0000 +#define HMDMA_CONTROL_DRQ_SINGLE 0x0100 +#define HMDMA_CONTROL_DRQ_MULTIPLE 0x0200 +#define HMDMA_CONTROL_DRQ_URGENT_MULTIPLE 0x0300 +#define HMDMA_CONTROL_MBDI 0x0040 +#define HMDMA_CONTROL_BDIE 0x0020 +#define HMDMA_CONTROL_OIE 0x0010 +#define HMDMA_CONTROL_UTE 0x0008 +#define HMDMA_CONTROL_REP 0x0002 +#define HMDMA_CONTROL_HMDMAEN 0x0001 + +#endif /* _dmaRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/ebiuRegs.h b/c/src/lib/libcpu/bfin/include/ebiuRegs.h new file mode 100644 index 0000000000..5b07822fbd --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/ebiuRegs.h @@ -0,0 +1,136 @@ +/* Blackfin External Peripheral Interface Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _ebiuRegs_h_ +#define _ebiuRegs_h_ + +/* register addresses */ + +#define EBIU_AMGCTL (EBIU_BASE_ADDRESS + 0x0000) +#define EBIU_AMBCTL0 (EBIU_BASE_ADDRESS + 0x0004) +#define EBIU_AMBCTL1 (EBIU_BASE_ADDRESS + 0x0008) +#define EBIU_SDGCTL (EBIU_BASE_ADDRESS + 0x0010) +#define EBIU_SDBCTL (EBIU_BASE_ADDRESS + 0x0014) +#define EBIU_SDRRC (EBIU_BASE_ADDRESS + 0x0018) +#define EBIU_SDSTAT (EBIU_BASE_ADDRESS + 0x001c) + +/* register fields */ + +#define EBIU_AMGCTL_CDPRIO 0x0100 +#define EBIU_AMGCTL_AMBEN_MASK 0x000e +#define EBIU_AMGCTL_AMBEN_SHIFT 1 +#define EBIU_AMGCTL_AMCKEN 0x0001 + +#define EBIU_AMBCTL0_B1WAT_MASK 0xf0000000 +#define EBIU_AMBCTL0_B1WAT_SHIFT 28 +#define EBIU_AMBCTL0_B1RAT_MASK 0x0f000000 +#define EBIU_AMBCTL0_B1RAT_SHIFT 24 +#define EBIU_AMBCTL0_B1HT_MASK 0x00c00000 +#define EBIU_AMBCTL0_B1HT_SHIFT 22 +#define EBIU_AMBCTL0_B1ST_MASK 0x00300000 +#define EBIU_AMBCTL0_B1ST_SHIFT 20 +#define EBIU_AMBCTL0_B1TT_MASK 0x000c0000 +#define EBIU_AMBCTL0_B1TT_SHIFT 18 +#define EBIU_AMBCTL0_B1RDYPOL 0x00020000 +#define EBIU_AMBCTL0_B1RDYEN 0x00010000 +#define EBIU_AMBCTL0_B0WAT_MASK 0x0000f000 +#define EBIU_AMBCTL0_B0WAT_SHIFT 12 +#define EBIU_AMBCTL0_B0RAT_MASK 0x00000f00 +#define EBIU_AMBCTL0_B0RAT_SHIFT 8 +#define EBIU_AMBCTL0_B0HT_MASK 0x000000c0 +#define EBIU_AMBCTL0_B0HT_SHIFT 6 +#define EBIU_AMBCTL0_B0ST_MASK 0x00000030 +#define EBIU_AMBCTL0_B0ST_SHIFT 4 +#define EBIU_AMBCTL0_B0TT_MASK 0x0000000c +#define EBIU_AMBCTL0_B0TT_SHIFT 2 +#define EBIU_AMBCTL0_B0RDYPOL 0x00000002 +#define EBIU_AMBCTL0_B0RDYEN 0x00000001 + +#define EBIU_AMBCTL1_B3WAT_MASK 0xf0000000 +#define EBIU_AMBCTL1_B3WAT_SHIFT 28 +#define EBIU_AMBCTL1_B3RAT_MASK 0x0f000000 +#define EBIU_AMBCTL1_B3RAT_SHIFT 24 +#define EBIU_AMBCTL1_B3HT_MASK 0x00c00000 +#define EBIU_AMBCTL1_B3HT_SHIFT 22 +#define EBIU_AMBCTL1_B3ST_MASK 0x00300000 +#define EBIU_AMBCTL1_B3ST_SHIFT 20 +#define EBIU_AMBCTL1_B3TT_MASK 0x000c0000 +#define EBIU_AMBCTL1_B3TT_SHIFT 18 +#define EBIU_AMBCTL1_B3RDYPOL 0x00020000 +#define EBIU_AMBCTL1_B3RDYEN 0x00010000 +#define EBIU_AMBCTL1_B2WAT_MASK 0x0000f000 +#define EBIU_AMBCTL1_B2WAT_SHIFT 12 +#define EBIU_AMBCTL1_B2RAT_MASK 0x00000f00 +#define EBIU_AMBCTL1_B2RAT_SHIFT 8 +#define EBIU_AMBCTL1_B2HT_MASK 0x000000c0 +#define EBIU_AMBCTL1_B2HT_SHIFT 6 +#define EBIU_AMBCTL1_B2ST_MASK 0x00000030 +#define EBIU_AMBCTL1_B2ST_SHIFT 4 +#define EBIU_AMBCTL1_B2TT_MASK 0x0000000c +#define EBIU_AMBCTL1_B2TT_SHIFT 2 +#define EBIU_AMBCTL1_B2RDYPOL 0x00000002 +#define EBIU_AMBCTL1_B2RDYEN 0x00000001 + +#define EBIU_SDGCTL_CDDBG 0x40000000 +#define EBIU_SDGCTL_TCSR 0x20000000 +#define EBIU_SDGCTL_EMREN 0x10000000 +#define EBIU_SDGCTL_FBBRW 0x04000000 +#define EBIU_SDGCTL_EBUFE 0x02000000 +#define EBIU_SDGCTL_SRFS 0x01000000 +#define EBIU_SDGCTL_PSSE 0x00800000 +#define EBIU_SDGCTL_PSM 0x00400000 +#define EBIU_SDGCTL_PUPSD 0x00200000 +#define EBIU_SDGCTL_TWR_MASK 0x00180000 +#define EBIU_SDGCTL_TWR_SHIFT 19 +#define EBIU_SDGCTL_TRCD_MASK 0x00038000 +#define EBIU_SDGCTL_TRCD_SHIFT 15 +#define EBIU_SDGCTL_TRP_MASK 0x00003800 +#define EBIU_SDGCTL_TRP_SHIFT 11 +#define EBIU_SDGCTL_TRAS_MASK 0x000003c0 +#define EBIU_SDGCTL_TRAS_SHIFT 6 +#define EBIU_SDGCTL_PASR_MASK 0x00000030 +#define EBIU_SDGCTL_PASR_ALL 0x00000000 +#define EBIU_SDGCTL_PASR_0_1 0x00000010 +#define EBIU_SDGCTL_PASR_0 0x00000020 +#define EBIU_SDGCTL_CL_MASK 0x0000000c +#define EBIU_SDGCTL_CL_SHIFT 2 +#define EBIU_SDGCTL_SCTLE 0x00000001 + +#define EBIU_SDBCTL_EBCAW_MASK 0x0030 +#define EBIU_SDBCTL_SHIFT 4 +#define EBIU_SDBCTL_EBCAW_8 0x0000 +#define EBIU_SDBCTL_EBCAW_9 0x0010 +#define EBIU_SDBCTL_EBCAW_10 0x0020 +#define EBIU_SDBCTL_EBCAW_11 0x0030 +#define EBIU_SDBCTL_EBSZ_MASK 0x000e +#define EBIU_SDBCTL_EBSZ_SHIFT 1 +#define EBIU_SDBCTL_EBSZ_16M 0x0000 +#define EBIU_SDBCTL_EBSZ_32M 0x0002 +#define EBIU_SDBCTL_EBSZ_64M 0x0004 +#define EBIU_SDBCTL_EBSZ_128M 0x0006 +#define EBIU_SDBCTL_EBSZ_256M 0x0008 +#define EBIU_SDBCTL_EBSZ_512M 0x000a +#define EBIU_SDBCTL_EBE 0x0001 + +#define EBIU_SDRRC_RDIV_MASK 0x0fff +#define EBIU_SDRRC_RDIV_SHIFT 0 + +#define EBIU_SDSTAT_BGSTAT 0x0020 +#define EBIU_SDSTAT_SDEASE 0x0010 +#define EBIU_SDSTAT_SDRS 0x0008 +#define EBIU_SDSTAT_SDPUA 0x0004 +#define EBIU_SDSTAT_SDSRA 0x0002 +#define EBIU_SDSTAT_SDCI 0x0001 + + +#endif /* _ebiuRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/ethernetRegs.h b/c/src/lib/libcpu/bfin/include/ethernetRegs.h new file mode 100644 index 0000000000..dc4b3fbc8f --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/ethernetRegs.h @@ -0,0 +1,422 @@ +/* Blackfin Ethernet Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _ethernetRegs_h_ +#define _ethernetRegs_h_ + +/* register addresses */ + +#define EMAC_OPMODE_OFFSET 0x0000 +#define EMAC_ADDRLO_OFFSET 0x0004 +#define EMAC_ADDRHI_OFFSET 0x0008 +#define EMAC_HASHLO_OFFSET 0x000c +#define EMAC_HASHHI_OFFSET 0x0010 +#define EMAC_STAADD_OFFSET 0x0014 +#define EMAC_STADAT_OFFSET 0x0018 +#define EMAC_FLC_OFFSET 0x001c +#define EMAC_VLAN1_OFFSET 0x0020 +#define EMAC_VLAN2_OFFSET 0x0024 +#define EMAC_WKUP_CTL_OFFSET 0x002c +#define EMAC_WKUP_FFMSK0_OFFSET 0x0030 +#define EMAC_WKUP_FFMSK1_OFFSET 0x0034 +#define EMAC_WKUP_FFMSK2_OFFSET 0x0038 +#define EMAC_WKUP_FFMSK3_OFFSET 0x003c +#define EMAC_WKUP_FFCMD_OFFSET 0x0040 +#define EMAC_WKUP_FFOFF_OFFSET 0x0044 +#define EMAC_WKUP_FFCRC01_OFFSET 0x0048 +#define EMAC_WKUP_FFCRC23_OFFSET 0x004c +#define EMAC_SYSCTL_OFFSET 0x0060 +#define EMAC_SYSTAT_OFFSET 0x0064 +#define EMAC_RX_STAT_OFFSET 0x0068 +#define EMAC_RX_STKY_OFFSET 0x006c +#define EMAC_RX_IRQE_OFFSET 0x0070 +#define EMAC_TX_STAT_OFFSET 0x0074 +#define EMAC_TX_STKY_OFFSET 0x0078 +#define EMAC_TX_IRQE_OFFSET 0x007c +#define EMAC_MMC_CTL_OFFSET 0x0080 +#define EMAC_MMC_RIRQS_OFFSET 0x0084 +#define EMAC_MMC_RIRQE_OFFSET 0x0088 +#define EMAC_MMC_TIRQS_OFFSET 0x008c +#define EMAC_MMC_TIRQE_OFFSET 0x0090 + +#define EMAC_RXC_OK_OFFSET 0x0100 +#define EMAC_RXC_FCS_OFFSET 0x0104 +#define EMAC_RXC_ALIGN_OFFSET 0x0108 +#define EMAC_RXC_OCTET_OFFSET 0x010c +#define EMAC_RXC_DMAOVF_OFFSET 0x0110 +#define EMAC_RXC_UNICST_OFFSET 0x0114 +#define EMAC_RXC_MULTI_OFFSET 0x0118 +#define EMAC_RXC_BROAD_OFFSET 0x011c +#define EMAC_RXC_LNERRI_OFFSET 0x0120 +#define EMAC_RXC_LNERRO_OFFSET 0x0124 +#define EMAC_RXC_LONG_OFFSET 0x0128 +#define EMAC_RXC_MACCTL_OFFSET 0x012c +#define EMAC_RXC_OPCODE_OFFSET 0x0130 +#define EMAC_RXC_PAUSE_OFFSET 0x0134 +#define EMAC_RXC_ALLFRM_OFFSET 0x0138 +#define EMAC_RXC_ALLOCT_OFFSET 0x013c +#define EMAC_RXC_TYPED_OFFSET 0x0140 +#define EMAC_RXC_SHORT_OFFSET 0x0144 +#define EMAC_RXC_EQ64_OFFSET 0x0148 +#define EMAC_RXC_LT128_OFFSET 0x014c +#define EMAC_RXC_LT256_OFFSET 0x0150 +#define EMAC_RXC_LT512_OFFSET 0x0154 +#define EMAC_RXC_LT1024_OFFSET 0x0158 +#define EMAC_RXC_GE1024_OFFSET 0x015c + +#define EMAC_TXC_OK_OFFSET 0x0180 +#define EMAC_TXC_1COL_OFFSET 0x0184 +#define EMAC_TXC_GT1COL_OFFSET 0x0188 +#define EMAC_TXC_OCTET_OFFSET 0x018c +#define EMAC_TXC_DEFER_OFFSET 0x0190 +#define EMAC_TXC_LATECL_OFFSET 0x0194 +#define EMAC_TXC_XS_COL_OFFSET 0x0198 +#define EMAC_TXC_DMAUND_OFFSET 0x019c +#define EMAC_TXC_CRSERR_OFFSET 0x01a0 +#define EMAC_TXC_UNICST_OFFSET 0x01a4 +#define EMAC_TXC_MULTI_OFFSET 0x01a8 +#define EMAC_TXC_BROAD_OFFSET 0x01ac +#define EMAC_TXC_ES_DFR_OFFSET 0x01b0 +#define EMAC_TXC_MACCTL_OFFSET 0x01b4 +#define EMAC_TXC_ALLFRM_OFFSET 0x01b8 +#define EMAC_TXC_ALLOCT_OFFSET 0x01bc +#define EMAC_TXC_EQ64_OFFSET 0x01c0 +#define EMAC_TXC_LT128_OFFSET 0x01c4 +#define EMAC_TXC_LT256_OFFSET 0x01c8 +#define EMAC_TXC_LT512_OFFSET 0x01cc +#define EMAC_TXC_LT1024_OFFSET 0x01d0 +#define EMAC_TXC_GE1024_OFFSET 0x01d4 +#define EMAC_TXC_ABORT_OFFSET 0x01d8 + + +/* register fields */ + +#define EMAC_OPMODE_DRO 0x10000000 +#define EMAC_OPMODE_LB 0x08000000 +#define EMAC_OPMODE_FDMODE 0x04000000 +#define EMAC_OPMODE_RMII_10 0x02000000 +#define EMAC_OPMODE_RMII 0x01000000 +#define EMAC_OPMODE_LCTRE 0x00800000 +#define EMAC_OPMODE_DRTY 0x00400000 +#define EMAC_OPMODE_BOLMT_MASK 0x00300000 +#define EMAC_OPMODE_BOLMT_1023 0x00000000 +#define EMAC_OPMODE_BOLMT_255 0x00100000 +#define EMAC_OPMODE_BOLMT_15 0x00200000 +#define EMAC_OPMODE_BOLMT_1 0x00300000 +#define EMAC_OPMODE_DC 0x00080000 +#define EMAC_OPMODE_DTXCRC 0x00040000 +#define EMAC_OPMODE_DTXPAD 0x00020000 +#define EMAC_OPMODE_TE 0x00010000 +#define EMAC_OPMODE_RAF 0x00001000 +#define EMAC_OPMODE_PSF 0x00000800 +#define EMAC_OPMODE_PBF 0x00000400 +#define EMAC_OPMODE_DBF 0x00000200 +#define EMAC_OPMODE_IFE 0x00000100 +#define EMAC_OPMODE_PR 0x00000080 +#define EMAC_OPMODE_PAM 0x00000040 +#define EMAC_OPMODE_HM 0x00000020 +#define EMAC_OPMODE_HU 0x00000010 +#define EMAC_OPMODE_ASTP 0x00000002 +#define EMAC_OPMODE_RE 0x00000001 + +#define EMAC_STAADD_PHYAD_MASK 0x0000f800 +#define EMAC_STAADD_PHYAD_SHIFT 11 +#define EMAC_STAADD_REGAD_MASK 0x000007c0 +#define EMAC_STAADD_REGAD_SHIFT 6 +#define EMAC_STAADD_STAIE 0x00000008 +#define EMAC_STAADD_STADISPRE 0x00000004 +#define EMAC_STAADD_STAOP 0x00000002 +#define EMAC_STAADD_STABUSY 0x00000001 + +#define EMAC_FLC_FLCPAUSE_MASK 0xffff0000 +#define EMAC_FLC_FLCPAUSE_SHIFT 16 +#define EMAC_FLC_BKPRSEN 0x00000008 +#define EMAC_FLC_PCF 0x00000004 +#define EMAC_FLC_FLCE 0x00000002 +#define EMAC_FLC_FLCBUSY 0x00000001 + +#define EMAC_WKUP_CTL_RWKS_MASK 0x00000f00 +#define EMAC_WKUP_CTL_RWKS_SHIFT 8 +#define EMAC_WKUP_CTL_MPKS 0x00000020 +#define EMAC_WKUP_CTL_GUWKE 0x00000008 +#define EMAC_WKUP_CTL_RWKE 0x00000004 +#define EMAC_WKUP_CTL_MPKE 0x00000002 +#define EMAC_WKUP_CTL_CAPWKFRM 0x00000001 + +#define EMAC_WKUP_FFCMD_3_TYPE 0x08000000 +#define EMAC_WKUP_FFCMD_3_EN 0x01000000 +#define EMAC_WKUP_FFCMD_2_TYPE 0x00080000 +#define EMAC_WKUP_FFCMD_2_EN 0x00010000 +#define EMAC_WKUP_FFCMD_1_TYPE 0x00000800 +#define EMAC_WKUP_FFCMD_1_EN 0x00000100 +#define EMAC_WKUP_FFCMD_0_TYPE 0x00000008 +#define EMAC_WKUP_FFCMD_0_EN 0x00000001 + +#define EMAC_WKUP_FFOFF_3_MASK 0xff000000 +#define EMAC_WKUP_FFOFF_3_SHIFT 24 +#define EMAC_WKUP_FFOFF_2_MASK 0x00ff0000 +#define EMAC_WKUP_FFOFF_2_SHIFT 16 +#define EMAC_WKUP_FFOFF_1_MASK 0x0000ff00 +#define EMAC_WKUP_FFOFF_1_SHIFT 8 +#define EMAC_WKUP_FFOFF_0_MASK 0x000000ff +#define EMAC_WKUP_FFOFF_0_SHIFT 0 + +#define EMAC_WKUP_FFCRC01_1_MASK 0xffff0000 +#define EMAC_WKUP_FFCRC01_1_SHIFT 16 +#define EMAC_WKUP_FFCRC01_0_MASK 0x0000ffff +#define EMAC_WKUP_FFCRC01_0_SHIFT 0 + +#define EMAC_WKUP_FFCRC23_3_MASK 0xffff0000 +#define EMAC_WKUP_FFCRC23_3_SHIFT 16 +#define EMAC_WKUP_FFCRC23_2_MASK 0x0000ffff +#define EMAC_WKUP_FFCRC23_2_SHIFT 0 + +#define EMAC_SYSCTL_MDCDIV_MASK 0x00003f00 +#define EMAC_SYSCTL_MDCDIV_SHIFT 8 +#define EMAC_SYSCTL_TXDWA 0x00000010 +#define EMAC_SYSCTL_RXCKS 0x00000004 +#define EMAC_SYSCTL_RXDWA 0x00000002 +#define EMAC_SYSCTL_PHYIE 0x00000001 + +#define EMAC_SYSTAT_STMDONE 0x00000080 +#define EMAC_SYSTAT_TXDMAERR 0x00000040 +#define EMAC_SYSTAT_RXDMAERR 0x00000020 +#define EMAC_SYSTAT_WAKEDET 0x00000010 +#define EMAC_SYSTAT_TXFSINT 0x00000008 +#define EMAC_SYSTAT_RXFSINT 0x00000004 +#define EMAC_SYSTAT_MMCINT 0x00000002 +#define EMAC_SYSTAT_PHYINT 0x00000001 + +#define EMAC_RX_STAT_RX_ACCEPT 0x80000000 +#define EMAC_RX_STAT_RX_VLAN2 0x40000000 +#define EMAC_RX_STAT_RX_VLAN1 0x20000000 +#define EMAC_RX_STAT_RX_TYPE 0x10000000 +#define EMAC_RX_STAT_RX_UCTL 0x08000000 +#define EMAC_RX_STAT_RX_CTL 0x04000000 +#define EMAC_RX_STAT_RX_BROAD_MULTI_MASK 0x03000000 +#define EMAC_RX_STAT_RX_BROAD_MULTI_ILLEGAL 0x03000000 +#define EMAC_RX_STAT_RX_BROAD_MULTI_BROADCAST 0x02000000 +#define EMAC_RX_STAT_RX_BROAD_MULTI_GROUP 0x01000000 +#define EMAC_RX_STAT_RX_BROAD_MULTI_UNICAST 0x00000000 +#define EMAC_RX_STAT_RX_RANGE 0x00800000 +#define EMAC_RX_STAT_RX_LATE 0x00400000 +#define EMAC_RX_STAT_RX_PHY 0x00200000 +#define EMAC_RX_STAT_RX_DMAO 0x00100000 +#define EMAC_RX_STAT_RX_ADDR 0x00080000 +#define EMAC_RX_STAT_RX_FRAG 0x00040000 +#define EMAC_RX_STAT_RX_LEN 0x00020000 +#define EMAC_RX_STAT_RX_CRC 0x00010000 +#define EMAC_RX_STAT_RX_ALIGN 0x00008000 +#define EMAC_RX_STAT_RX_LONG 0x00004000 +#define EMAC_RX_STAT_RX_OK 0x00002000 +#define EMAC_RX_STAT_RX_COMP 0x00001000 +#define EMAC_RX_STAT_RX_FRLEN_MASK 0x000007ff +#define EMAC_RX_STAT_RX_FRLEN_SHIFT 0 + +#define EMAC_RX_STKY_RX_ACCEPT 0x80000000 +#define EMAC_RX_STKY_RX_VLAN2 0x40000000 +#define EMAC_RX_STKY_RX_VLAN1 0x20000000 +#define EMAC_RX_STKY_RX_TYPE 0x10000000 +#define EMAC_RX_STKY_RX_UCTL 0x08000000 +#define EMAC_RX_STKY_RX_CTL 0x04000000 +#define EMAC_RX_STKY_RX_BROAD 0x02000000 +#define EMAC_RX_STKY_RX_MULTI 0x01000000 +#define EMAC_RX_STKY_RX_RANGE 0x00800000 +#define EMAC_RX_STKY_RX_LATE 0x00400000 +#define EMAC_RX_STKY_RX_PHY 0x00200000 +#define EMAC_RX_STKY_RX_DMAO 0x00100000 +#define EMAC_RX_STKY_RX_ADDR 0x00080000 +#define EMAC_RX_STKY_RX_FRAG 0x00040000 +#define EMAC_RX_STKY_RX_LEN 0x00020000 +#define EMAC_RX_STKY_RX_CRC 0x00010000 +#define EMAC_RX_STKY_RX_ALIGN 0x00008000 +#define EMAC_RX_STKY_RX_LONG 0x00004000 +#define EMAC_RX_STKY_RX_OK 0x00002000 +#define EMAC_RX_STKY_RX_COMP 0x00001000 + +#define EMAC_RX_IRQE_RX_ACCEPT 0x80000000 +#define EMAC_RX_IRQE_RX_VLAN2 0x40000000 +#define EMAC_RX_IRQE_RX_VLAN1 0x20000000 +#define EMAC_RX_IRQE_RX_TYPE 0x10000000 +#define EMAC_RX_IRQE_RX_UCTL 0x08000000 +#define EMAC_RX_IRQE_RX_CTL 0x04000000 +#define EMAC_RX_IRQE_RX_BROAD 0x02000000 +#define EMAC_RX_IRQE_RX_MULTI 0x01000000 +#define EMAC_RX_IRQE_RX_RANGE 0x00800000 +#define EMAC_RX_IRQE_RX_LATE 0x00400000 +#define EMAC_RX_IRQE_RX_PHY 0x00200000 +#define EMAC_RX_IRQE_RX_DMAO 0x00100000 +#define EMAC_RX_IRQE_RX_ADDR 0x00080000 +#define EMAC_RX_IRQE_RX_FRAG 0x00040000 +#define EMAC_RX_IRQE_RX_LEN 0x00020000 +#define EMAC_RX_IRQE_RX_CRC 0x00010000 +#define EMAC_RX_IRQE_RX_ALIGN 0x00008000 +#define EMAC_RX_IRQE_RX_LONG 0x00004000 +#define EMAC_RX_IRQE_RX_OK 0x00002000 +#define EMAC_RX_IRQE_RX_COMP 0x00001000 + +#define EMAC_TX_STAT_TX_FRLEN_MASK 0x07ff0000 +#define EMAC_TX_STAT_TX_FRLEN_SHIFT 16 +#define EMAC_TX_STAT_TX_RETRY 0x00008000 +#define EMAC_TX_STAT_TX_LOSS 0x00004000 +#define EMAC_TX_STAT_TX_CRS 0x00002000 +#define EMAC_TX_STAT_TX_DEFER 0x00001000 +#define EMAC_TX_STAT_TX_CCNT_MASK 0x00000f00 +#define EMAC_TX_STAT_TX_CCNT_SHIFT 8 +#define EMAC_TX_STAT_TX_MULTI_BROAD_MASK 0x000000c0 +#define EMAC_TX_STAT_TX_MULTI_BROAD_ILLEGAL 0x000000c0 +#define EMAC_TX_STAT_TX_MULTI_BROAD_GROUP 0x00000080 +#define EMAC_TX_STAT_TX_MULTI_BROAD_BROADCAST 0x00000040 +#define EMAC_TX_STAT_TX_MULTI_BROAD_UNICAST 0x00000000 +#define EMAC_TX_STAT_TX_EDEFER 0x00000020 +#define EMAC_TX_STAT_TX_DMAU 0x00000010 +#define EMAC_TX_STAT_TX_LATE 0x00000008 +#define EMAC_TX_STAT_TX_ECOLL 0x00000004 +#define EMAC_TX_STAT_TX_OK 0x00000002 +#define EMAC_TX_STAT_TX_COMP 0x00000001 + +#define EMAC_TX_STKY_TX_RETRY 0x00008000 +#define EMAC_TX_STKY_TX_LOSS 0x00004000 +#define EMAC_TX_STKY_TX_CRS 0x00002000 +#define EMAC_TX_STKY_TX_DEFER 0x00001000 +#define EMAC_TX_STKY_TX_CCNT_MASK 0x00000f00 +#define EMAC_TX_STKY_TX_CCNT_SHIFT 8 +#define EMAC_TX_STKY_TX_MULTI 0x00000080 +#define EMAC_TX_STKY_TX_BROAD 0x00000040 +#define EMAC_TX_STKY_TX_EDEFER 0x00000020 +#define EMAC_TX_STKY_TX_DMAU 0x00000010 +#define EMAC_TX_STKY_TX_LATE 0x00000008 +#define EMAC_TX_STAT_TX_ECOLL 0x00000004 +#define EMAC_TX_STAT_TX_OK 0x00000002 +#define EMAC_TX_STAT_TX_COMP 0x00000001 + +#define EMAC_TX_IRQE_TX_RETRY 0x00008000 +#define EMAC_TX_IRQE_TX_LOSS 0x00004000 +#define EMAC_TX_IRQE_TX_CRS 0x00002000 +#define EMAC_TX_IRQE_TX_DEFER 0x00001000 +#define EMAC_TX_IRQE_TX_CCNT_MASK 0x00000f00 +#define EMAC_TX_IRQE_TX_CCNT_SHIFT 8 +#define EMAC_TX_IRQE_TX_MULTI 0x00000080 +#define EMAC_TX_IRQE_TX_BROAD 0x00000040 +#define EMAC_TX_IRQE_TX_EDEFER 0x00000020 +#define EMAC_TX_IRQE_TX_DMAU 0x00000010 +#define EMAC_TX_IRQE_TX_LATE 0x00000008 +#define EMAC_TX_IRQE_TX_ECOLL 0x00000004 +#define EMAC_TX_IRQE_TX_OK 0x00000002 +#define EMAC_TX_IRQE_TX_COMP 0x00000001 + +#define EMAC_MMC_RIRQS_RX_GE1024_CNT 0x00800000 +#define EMAC_MMC_RIRQS_RX_LT1024_CNT 0x00400000 +#define EMAC_MMC_RIRQS_RX_LT512_CNT 0x00200000 +#define EMAC_MMC_RIRQS_RX_LT256_CNT 0x00100000 +#define EMAC_MMC_RIRQS_RX_LT128_CNT 0x00080000 +#define EMAC_MMC_RIRQS_RX_EQ64_CNT 0x00040000 +#define EMAC_MMC_RIRQS_RX_SHORT_CNT 0x00020000 +#define EMAC_MMC_RIRQS_RX_TYPED_CNT 0x00010000 +#define EMAC_MMC_RIRQS_RX_ALLO_CNT 0x00008000 +#define EMAC_MMC_RIRQS_RX_ALLF_CNT 0x00004000 +#define EMAC_MMC_RIRQS_RX_PAUSE_CNT 0x00002000 +#define EMAC_MMC_RIRQS_RX_OPCODE_CNT 0x00001000 +#define EMAC_MMC_RIRQS_RX_MACCTL_CNT 0x00000800 +#define EMAC_MMC_RIRQS_RX_LONG_CNT 0x00000400 +#define EMAC_MMC_RIRQS_RX_ORL_CNT 0x00000200 +#define EMAC_MMC_RIRQS_RX_IRL_CNT 0x00000100 +#define EMAC_MMC_RIRQS_RX_BROAD_CNT 0x00000080 +#define EMAC_MMC_RIRQS_RX_MULTI_CNT 0x00000040 +#define EMAC_MMC_RIRQS_RX_UNI_CNT 0x00000020 +#define EMAC_MMC_RIRQS_RX_LOST_CNT 0x00000010 +#define EMAC_MMC_RIRQS_RX_OCTET_CNT 0x00000008 +#define EMAC_MMC_RIRQS_RX_ALIGN_CNT 0x00000004 +#define EMAC_MMC_RIRQS_RX_FCS_CNT 0x00000002 +#define EMAC_MMC_RIRQS_RX_OK_CNT 0x00000001 + +#define EMAC_MMC_RIRQE_RX_GE1024_CNT 0x00800000 +#define EMAC_MMC_RIRQE_RX_LT1024_CNT 0x00400000 +#define EMAC_MMC_RIRQE_RX_LT512_CNT 0x00200000 +#define EMAC_MMC_RIRQE_RX_LT256_CNT 0x00100000 +#define EMAC_MMC_RIRQE_RX_LT128_CNT 0x00080000 +#define EMAC_MMC_RIRQE_RX_EQ64_CNT 0x00040000 +#define EMAC_MMC_RIRQE_RX_SHORT_CNT 0x00020000 +#define EMAC_MMC_RIRQE_RX_TYPED_CNT 0x00010000 +#define EMAC_MMC_RIRQE_RX_ALLO_CNT 0x00008000 +#define EMAC_MMC_RIRQE_RX_ALLF_CNT 0x00004000 +#define EMAC_MMC_RIRQE_RX_PAUSE_CNT 0x00002000 +#define EMAC_MMC_RIRQE_RX_OPCODE_CNT 0x00001000 +#define EMAC_MMC_RIRQE_RX_MACCTL_CNT 0x00000800 +#define EMAC_MMC_RIRQE_RX_LONG_CNT 0x00000400 +#define EMAC_MMC_RIRQE_RX_ORL_CNT 0x00000200 +#define EMAC_MMC_RIRQE_RX_IRL_CNT 0x00000100 +#define EMAC_MMC_RIRQE_RX_BROAD_CNT 0x00000080 +#define EMAC_MMC_RIRQE_RX_MULTI_CNT 0x00000040 +#define EMAC_MMC_RIRQE_RX_UNI_CNT 0x00000020 +#define EMAC_MMC_RIRQE_RX_LOST_CNT 0x00000010 +#define EMAC_MMC_RIRQE_RX_OCTET_CNT 0x00000008 +#define EMAC_MMC_RIRQE_RX_ALIGN_CNT 0x00000004 +#define EMAC_MMC_RIRQE_RX_FCS_CNT 0x00000002 +#define EMAC_MMC_RIRQE_RX_OK_CNT 0x00000001 + +#define EMAC_MMC_TIRQS_TX_ABORT_CNT 0x00400000 +#define EMAC_MMC_TIRQS_TX_GE1024_CNT 0x00200000 +#define EMAC_MMC_TIRQS_TX_LT1024_CNT 0x00100000 +#define EMAC_MMC_TIRQS_TX_LT512_CNT 0x00080000 +#define EMAC_MMC_TIRQS_TX_LT256_CNT 0x00040000 +#define EMAC_MMC_TIRQS_TX_LT128_CNT 0x00020000 +#define EMAC_MMC_TIRQS_TX_EQ64_CNT 0x00010000 +#define EMAC_MMC_TIRQS_TX_ALLO_CNT 0x00008000 +#define EMAC_MMC_TIRQS_TX_ALLF_CNT 0x00004000 +#define EMAC_MMC_TIRQS_TX_MACCTL_CNT 0x00002000 +#define EMAC_MMC_TIRQS_TX_EXDEF_CNT 0x00001000 +#define EMAC_MMC_TIRQS_TX_BROAD_CNT 0x00000800 +#define EMAC_MMC_TIRQS_TX_MULTI_CNT 0x00000400 +#define EMAC_MMC_TIRQS_TX_UNI_CNT 0x00000200 +#define EMAC_MMC_TIRQS_TX_CRS_CNT 0x00000100 +#define EMAC_MMC_TIRQS_TX_LOST_CNT 0x00000080 +#define EMAC_MMC_TIRQS_TX_ABORTC_CNT 0x00000040 +#define EMAC_MMC_TIRQS_TX_LATE_CNT 0x00000020 +#define EMAC_MMC_TIRQS_TX_DEFER_CNT 0x00000010 +#define EMAC_MMC_TIRQS_TX_OCTET_CNT 0x00000008 +#define EMAC_MMC_TIRQS_TX_MCOLL_CNT 0x00000004 +#define EMAC_MMC_TIRQS_TX_SCOLL_CNT 0x00000002 +#define EMAC_MMC_TIRQS_TX_OK_CNT 0x00000001 + +#define EMAC_MMC_TIRQE_TX_ABORT_CNT 0x00400000 +#define EMAC_MMC_TIRQE_TX_GE1024_CNT 0x00200000 +#define EMAC_MMC_TIRQE_TX_LT1024_CNT 0x00100000 +#define EMAC_MMC_TIRQE_TX_LT512_CNT 0x00080000 +#define EMAC_MMC_TIRQE_TX_LT256_CNT 0x00040000 +#define EMAC_MMC_TIRQE_TX_LT128_CNT 0x00020000 +#define EMAC_MMC_TIRQE_TX_EQ64_CNT 0x00010000 +#define EMAC_MMC_TIRQE_TX_ALLO_CNT 0x00008000 +#define EMAC_MMC_TIRQE_TX_ALLF_CNT 0x00004000 +#define EMAC_MMC_TIRQE_TX_MACCTL_CNT 0x00002000 +#define EMAC_MMC_TIRQE_TX_EXDEF_CNT 0x00001000 +#define EMAC_MMC_TIRQE_TX_BROAD_CNT 0x00000800 +#define EMAC_MMC_TIRQE_TX_MULTI_CNT 0x00000400 +#define EMAC_MMC_TIRQE_TX_UNI_CNT 0x00000200 +#define EMAC_MMC_TIRQE_TX_CRS_CNT 0x00000100 +#define EMAC_MMC_TIRQE_TX_LOST_CNT 0x00000080 +#define EMAC_MMC_TIRQE_TX_ABORTC_CNT 0x00000040 +#define EMAC_MMC_TIRQE_TX_LATE_CNT 0x00000020 +#define EMAC_MMC_TIRQE_TX_DEFER_CNT 0x00000010 +#define EMAC_MMC_TIRQE_TX_OCTET_CNT 0x00000008 +#define EMAC_MMC_TIRQE_TX_MCOLL_CNT 0x00000004 +#define EMAC_MMC_TIRQE_TX_SCOLL_CNT 0x00000002 +#define EMAC_MMC_TIRQE_TX_OK_CNT 0x00000001 + +#define EMAC_MMC_CTL_MMCE 0x00000008 +#define EMAC_MMC_CTL_CCOR 0x00000004 +#define EMAC_MMC_CTL_CROLL 0x00000002 +#define EMAC_MMC_CTL_RSTC 0x00000001 + + +#endif /* _ethernetRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/gpioRegs.h b/c/src/lib/libcpu/bfin/include/gpioRegs.h new file mode 100644 index 0000000000..19db75ea7a --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/gpioRegs.h @@ -0,0 +1,39 @@ +/* Blackfin GPIO Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _gpioRegs_h_ +#define _gpioRegs_h_ + + +/* register addresses */ + +#define PORTIO_OFFSET 0x0000 +#define PORTIO_CLEAR_OFFSET 0x0004 +#define PORTIO_SET_OFFSET 0x0008 +#define PORTIO_TOGGLE_OFFSET 0x000c +#define PORTIO_MASKA_OFFSET 0x0010 +#define PORTIO_MASKA_CLEAR_OFFSET 0x0014 +#define PORTIO_MASKA_SET_OFFSET 0x0018 +#define PORTIO_MASKA_TOGGLE_OFFSET 0x001c +#define PORTIO_MASKB_OFFSET 0x0020 +#define PORTIO_MASKB_CLEAR_OFFSET 0x0024 +#define PORTIO_MASKB_SET_OFFSET 0x0028 +#define PORTIO_MASKB_TOGGLE_OFFSET 0x002c +#define PORTIO_DIR_OFFSET 0x0030 +#define PORTIO_POLAR_OFFSET 0x0034 +#define PORTIO_EDGE_OFFSET 0x0038 +#define PORTIO_BOTH_OFFSET 0x003c +#define PORTIO_INEN_OFFSET 0x0040 + + +#endif /* _gpioRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/memoryRegs.h b/c/src/lib/libcpu/bfin/include/memoryRegs.h new file mode 100644 index 0000000000..616d0381fc --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/memoryRegs.h @@ -0,0 +1,61 @@ +/* Blackfin Memory Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _memoryRegs_h_ +#define _memoryRegs_h_ + +/* register addresses */ +#define DMEM_CONTROL 0xffe00004 +#define DTEST_COMMAND 0xffe00300 +#define DTEST_DATA0 0xffe00400 +#define DTEST_DATA1 0xffe00404 + +#define IMEM_CONTROL 0xffe01004 + + +/* register fields */ +#define DMEM_CONTROL_PORT_PREF1 0x00002000 +#define DMEM_CONTROL_PORT_PREF0 0x00001000 +#define DMEM_CONTROL_DCBS 0x00000010 +#define DMEM_CONTROL_DMC_MASK 0x0000000c +#define DMEM_CONTROL_DMC_SHIFT 2 +#define DMEM_CONTROL_ENDCPLB 0x00000002 + +#define DTEST_COMMAND_ACCESS_WAY1 0x02000000 +#define DTEST_COMMAND_ACCESS_INSTRUCTION 0x01000000 +#define DTEST_COMMAND_ACCESS_BANKB 0x00800000 +#define DTEST_COMMAND_SRAM_ADDR_13_12_MASK 0x00030000 +#define DTEST_COMMAND_SRAM_ADDR_13_12_SHIFT 16 +#define DTEST_COMMAND_DATA_CACHE_SELECT 0x00004000 +#define DTEST_COMMAND_SET_INDEX_MASK 0x000007e0 +#define DTEST_COMMAND_SET_INDEX_SHIFT 5 +#define DTEST_COMMAND_DOUBLE_WORD_INDEX_MASK 0x00000018 +#define DTEST_COMMAND_DOUBLE_WORD_INDEX_SHIFT 3 +#define DTEST_COMMAND_ACCESS_DATA_ARRAY 0x00000004 +#define DTEST_COMMAND_WRITE_ACCESS 0x00000002 + +#define DTEST_DATA0_TAG_19_2_MASK 0xffffc000 +#define DTEST_DATA0_TAG_19_2_SHIFT 14 +#define DTEST_DATA0_TAG 0x00000800 +#define DTEST_DATA0_LRU 0x00000004 +#define DTEST_DATA0_DIRTY 0x00000002 +#define DTEST_DATA0_VALID 0x00000001 + +#define IMEM_CONTROL_LRUPRIORST 0x00002000 +#define IMEM_CONTROL_ILOC_MASK 0x00000078 +#define IMEM_CONTROL_ILOC_SHIFT 3 +#define IMEM_CONTROL_IMC 0x00000004 +#define IMEM_CONTROL_ENICPLB 0x00000002 + + +#endif /* _memoryRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/mmuRegs.h b/c/src/lib/libcpu/bfin/include/mmuRegs.h new file mode 100644 index 0000000000..bee11ce0e9 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/mmuRegs.h @@ -0,0 +1,57 @@ +/* Blackfin MMU Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _mmuRegs_h_ +#define _mmuRegs_h_ + +/* register addresses */ +#define DCPLB_ADDR0 0xffe00100 +#define DCPLB_DATA0 0xffe00200 +#define DCPLB_COUNT 16 +#define DCPLB_ADDR_PITCH 4 +#define DCPLB_DATA_PITCH 4 +#define ICPLB_ADDR0 0xffe01100 +#define ICPLB_DATA0 0xffe01200 +#define ICPLB_COUNT 16 +#define ICPLB_ADDR_PITCH 4 +#define ICPLB_DATA_PITCH 4 + + +/* register fields */ +#define DCPLB_DATA_PAGE_SIZE_MASK 0x00030000 +#define DCPLB_DATA_PAGE_SIZE_1KB 0x00000000 +#define DCPLB_DATA_PAGE_SIZE_4KB 0x00010000 +#define DCPLB_DATA_PAGE_SIZE_1MB 0x00020000 +#define DCPLB_DATA_PAGE_SIZE_4MB 0x00030000 +#define DCPLB_DATA_CPLB_L1_AOW 0x00008000 +#define DCPLB_DATA_CPLB_WT 0x00004000 +#define DCPLB_DATA_CPLB_L1_CHBL 0x00001000 +#define DCPLB_DATA_CPLB_DIRTY 0x00000080 +#define DCPLB_DATA_CPLB_SUPV_WR 0x00000010 +#define DCPLB_DATA_CPLB_USER_WR 0x00000008 +#define DCPLB_DATA_CPLB_USER_RD 0x00000004 +#define DCPLB_DATA_CPLB_LOCK 0x00000002 +#define DCPLB_DATA_CPLB_VALID 0x00000001 + +#define ICPLB_DATA_PAGE_SIZE_MASK 0x00030000 +#define ICPLB_DATA_PAGE_SIZE_1KB 0x00000000 +#define ICPLB_DATA_PAGE_SIZE_4KB 0x00010000 +#define ICPLB_DATA_PAGE_SIZE_1MB 0x00020000 +#define ICPLB_DATA_PAGE_SIZE_4MB 0x00030000 +#define ICPLB_DATA_CPLB_L1_CHBL 0x00001000 +#define ICPLB_DATA_CPLB_LRUPRIO 0x00000100 +#define ICPLB_DATA_CPLB_USER_RD 0x00000004 +#define ICPLB_DATA_CPLB_CPLB_LOCK 0x00000002 +#define ICPLB_DATA_CPLB_CPLB_VALID 0x00000001 + +#endif /* _mmuRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/ppiRegs.h b/c/src/lib/libcpu/bfin/include/ppiRegs.h new file mode 100644 index 0000000000..0b7fdd28a4 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/ppiRegs.h @@ -0,0 +1,61 @@ +/* Blackfin Parallel Peripheral Interface Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _ppiRegs_h_ +#define _ppiRegs_h_ + + +/* register addresses */ + +#define PPI_CONTROL_OFFSET 0x0000 +#define PPI_STATUS_OFFSET 0x0004 +#define PPI_COUNT_OFFSET 0x0008 +#define PPI_DELAY_OFFSET 0x000c +#define PPI_FRAME_OFFSET 0x0010 + + +/* register fields */ + +#define PPI_CONTROL_POLS 0x8000 +#define PPI_CONTROL_POLC 0x4000 +#define PPI_CONTROL_DLEN_MASK 0x3800 +#define PPI_CONTROL_DLEN_8 0x0000 +#define PPI_CONTROL_DLEN_10 0x0800 +#define PPI_CONTROL_DLEN_11 0x1000 +#define PPI_CONTROL_DLEN_12 0x1800 +#define PPI_CONTROL_DLEN_13 0x2000 +#define PPI_CONTROL_DLEN_14 0x2800 +#define PPI_CONTROL_DLEN_15 0x3000 +#define PPI_CONTROL_DLEN_16 0x3800 +#define PPI_CONTROL_SKIP_EO 0x0400 +#define PPI_CONTROL_SKIP_EN 0x0200 +#define PPI_CONTROL_PACK_EN 0x0080 +#define PPI_CONTROL_FLD_SEL 0x0040 +#define PPI_CONTROL_PORT_CFG_MASK 0x0030 +#define PPI_CONTROL_PORT_CFG_SHIFT 4 +#define PPI_CONTROL_XFR_TYPE_MASK 0x000c +#define PPI_CONTROL_XFR_TYPE_SHIFT 2 +#define PPI_CONTROL_PORT_DIR 0x0002 +#define PPI_CONTROL_PORT_EN 0x0001 + +#define PPI_STATUS_ERR_NCOR 0x8000 +#define PPI_STATUS_ERR_DET 0x4000 +#define PPI_STATUS_UNDR 0x2000 +#define PPI_STATUS_OVR 0x1000 +#define PPI_STATUS_FT_ERR 0x0800 +#define PPI_STATUS_FLD 0x0400 +#define PPI_STATUS_LT_ERR_UNDR 0x0200 +#define PPI_STATUS_LT_ERR_OVR 0x0100 + + +#endif /* _ppiRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/rtcRegs.h b/c/src/lib/libcpu/bfin/include/rtcRegs.h new file mode 100644 index 0000000000..f71372a9f4 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/rtcRegs.h @@ -0,0 +1,68 @@ +/* Blackfin RTC Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _rtcRegs_h_ +#define _rtcRegs_h_ + +/* register addresses */ + +#define RTC_STAT (RTC_BASE_ADDRESS + 0x0000) +#define RTC_ICTL (RTC_BASE_ADDRESS + 0x0004) +#define RTC_ISTAT (RTC_BASE_ADDRESS + 0x0008) +#define RTC_SWCNT (RTC_BASE_ADDRESS + 0x000c) +#define RTC_ALARM (RTC_BASE_ADDRESS + 0x0010) +#define RTC_PREN (RTC_BASE_ADDRESS + 0x0014) + + +/* register fields */ + +#define RTC_STAT_DAYS_MASK 0xfffe0000 +#define RTC_STAT_DAYS_SHIFT 17 +#define RTC_STAT_HOURS_MASK 0x0001f000 +#define RTC_STAT_HOURS_SHIFT 12 +#define RTC_STAT_MINUTES_MASK 0x00000fc0 +#define RTC_STAT_MINUTES_SHIFT 6 +#define RTC_STAT_SECONDS_MASK 0x0000003f +#define RTC_STAT_SECONDS_SHIFT 0 + +#define RTC_ICTL_WCIE 0x8000 +#define RTC_ICTL_DAIE 0x0040 +#define RTC_ICTL_24HIE 0x0020 +#define RTC_ICTL_HIE 0x0010 +#define RTC_ICTL_MIE 0x0008 +#define RTC_ICTL_SIE 0x0004 +#define RTC_ICTL_AIE 0x0002 +#define RTC_ICTL_SWIE 0x0001 + +#define RTC_ISTAT_WC 0x8000 +#define RTC_ISTAT_WP 0x4000 +#define RTC_ISTAT_DAEF 0x0040 +#define RTC_ISTAT_24HE 0x0020 +#define RTC_ISTAT_HEF 0x0010 +#define RTC_ISTAT_MEF 0x0008 +#define RTC_ISTAT_SEF 0x0004 +#define RTC_ISTAT_AEF 0x0002 +#define RTC_ISTAT_SWEF 0x0001 + +#define RTC_ALARM_DAYS_MASK 0xfff70000 +#define RTC_ALARM_DAYS_SHIFT 17 +#define RTC_ALARM_HOURS_MASK 0x0001f000 +#define RTC_ALARM_HOURS_SHIFT 12 +#define RTC_ALARM_MINUTES_MASK 0x00000fc0 +#define RTC_ALARM_MINUTES_SHIFT 10 +#define RTC_ALARM_SECONDS_MASK 0x0000003f +#define RTC_ALARM_SECONDS_SHIFT 0 + +#define RTC_PREN_PREN 0x0001 + +#endif /* _rtcRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/sicRegs.h b/c/src/lib/libcpu/bfin/include/sicRegs.h new file mode 100644 index 0000000000..a3c6c391e1 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/sicRegs.h @@ -0,0 +1,35 @@ +/* Blackfin System Interrupt Controller Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _sicRegs_h_ +#define _sicRegs_h_ + +/* register addresses */ + +#define SIC_IMASK (SIC_BASE_ADDRESS + 0x000c) +#define SIC_IAR_BASE_ADDRESS (SIC_BASE_ADDRESS + 0x0010) +#define SIC_IAR_COUNT 4 +#define SIC_IAR_PITCH 0x04 +#define SIC_IAR0 (SIC_BASE_ADDRESS + 0x0010) +#define SIC_IAR1 (SIC_BASE_ADDRESS + 0x0014) +#define SIC_IAR2 (SIC_BASE_ADDRESS + 0x0018) +#define SIC_IAR3 (SIC_BASE_ADDRESS + 0x001c) +#define SIC_ISR (SIC_BASE_ADDRESS + 0x0020) +#define SIC_IWR (SIC_BASE_ADDRESS + 0x0024) + + +/* register fields */ + + + +#endif /* _sicRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/spiRegs.h b/c/src/lib/libcpu/bfin/include/spiRegs.h new file mode 100644 index 0000000000..183ee557c7 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/spiRegs.h @@ -0,0 +1,72 @@ +/* Blackfin SPI Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _spiRegs_h_ +#define _spiRegs_h_ + + +/* register addresses */ + +#define SPI_CTL_OFFSET 0x0000 +#define SPI_FLG_OFFSET 0x0004 +#define SPI_STAT_OFFSET 0x0008 +#define SPI_TDBR_OFFSET 0x000c +#define SPI_RDBR_OFFSET 0x0010 +#define SPI_BAUD_OFFSET 0x0014 +#define SPI_SHADOW 0x0018 + + +/* register fields */ + +#define SPI_CTL_SPE 0x4000 +#define SPI_CTL_WOM 0x2000 +#define SPI_CTL_MSTR 0x1000 +#define SPI_CTL_CPOL 0x0800 +#define SPI_CTL_CPHA 0x0400 +#define SPI_CTL_LSBF 0x0200 +#define SPI_CTL_SIZE 0x0100 +#define SPI_CTL_EMISO 0x0020 +#define SPI_CTL_PSSE 0x0010 +#define SPI_CTL_GM 0x0008 +#define SPI_CTL_SZ 0x0004 +#define SPI_CTL_TIMOD_MASK 0x0003 +#define SPI_CTL_TIMOD_RDBR 0x0000 +#define SPI_CTL_TIMOD_TDBR 0x0001 +#define SPI_CTL_TIMOD_DMA_RDBR 0x0002 +#define SPI_CTL_TIMOD_DMA_TDBR 0x0003 + +#define SPI_FLG_FLG7 0x8000 +#define SPI_FLG_FLG6 0x4000 +#define SPI_FLG_FLG5 0x2000 +#define SPI_FLG_FLG4 0x1000 +#define SPI_FLG_FLG3 0x0800 +#define SPI_FLG_FLG2 0x0400 +#define SPI_FLG_FLG1 0x0200 +#define SPI_FLG_FLS7 0x0080 +#define SPI_FLG_FLS6 0x0040 +#define SPI_FLG_FLS5 0x0020 +#define SPI_FLG_FLS4 0x0010 +#define SPI_FLG_FLS3 0x0008 +#define SPI_FLG_FLS2 0x0004 +#define SPI_FLG_FLS1 0x0002 + +#define SPI_STAT_TXCOL 0x0040 +#define SPI_STAT_RXS 0x0020 +#define SPI_STAT_RBSY 0x0010 +#define SPI_STAT_TXS 0x0008 +#define SPI_STAT_TXE 0x0004 +#define SPI_STAT_MODF 0x0002 +#define SPI_STAT_SPIF 0x0001 + + +#endif /* _spiRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/sportRegs.h b/c/src/lib/libcpu/bfin/include/sportRegs.h new file mode 100644 index 0000000000..fd7770ad46 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/sportRegs.h @@ -0,0 +1,114 @@ +/* Blackfin SPORT Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _sportRegs_h_ +#define _sportRegs_h_ + + +/* register addresses */ + +#define SPORT_TCR1_OFFSET 0x0000 +#define SPORT_TCR2_OFFSET 0x0004 +#define SPORT_TCLKDIV_OFFSET 0x0008 +#define SPORT_TFSDIV_OFFSET 0x000c +#define SPORT_TX_OFFSET 0x0010 +#define SPORT_RX_OFFSET 0x0018 +#define SPORT_RCR1_OFFSET 0x0020 +#define SPORT_RCR2_OFFSET 0x0024 +#define SPORT_RCLKDIV_OFFSET 0x0028 +#define SPORT_RFSDIV_OFFSET 0x002c +#define SPORT_STAT_OFFSET 0x0030 +#define SPORT_CHNL_OFFSET 0x0034 +#define SPORT_MCMC1_OFFSET 0x0038 +#define SPORT_MCMC2_OFFSET 0x003c +#define SPORT_MTCS0_OFFSET 0x0040 +#define SPORT_MTCS1_OFFSET 0x0044 +#define SPORT_MTCS2_OFFSET 0x0048 +#define SPORT_MTCS3_OFFSET 0x004c +#define SPORT_MRCS0_OFFSET 0x0050 +#define SPORT_MRCS1_OFFSET 0x0054 +#define SPORT_MRCS2_OFFSET 0x0058 +#define SPORT_MRCS3_OFFSET 0x005c + + +/* register fields */ + +#define SPORT_TCR1_TCKFE 0x4000 +#define SPORT_TCR1_LATFS 0x2000 +#define SPORT_TCR1_LTFS 0x1000 +#define SPORT_TCR1_DITFS 0x0800 +#define SPORT_TCR1_TFSR 0x0400 +#define SPORT_TCR1_ITFS 0x0200 +#define SPORT_TCR1_TLSBIT 0x0010 +#define SPORT_TCR1_TDTYPE_MASK 0x000c +#define SPORT_TCR1_TDTYPE_NORMAL 0x0000 +#define SPORT_TCR1_TDTYPE_ULAW 0x0008 +#define SPORT_TCR1_TDTYPE_ALAW 0x000c +#define SPORT_TCR1_ITCLK 0x0002 +#define SPORT_TCR1_TSPEN 0x0001 + +#define SPORT_TCR2_TRFST 0x0400 +#define SPORT_TCR2_TSFSE 0x0200 +#define SPORT_TCR2_TXSE 0x0100 +#define SPORT_TCR2_SLEN_MASK 0x001f +#define SPORT_TCR2_SLEN_SHIFT 0 + +#define SPORT_RCR1_RCKFE 0x4000 +#define SPORT_RCR1_LARFS 0x2000 +#define SPORT_RCR1_LRFS 0x1000 +#define SPORT_RCR1_RFSR 0x0400 +#define SPORT_RCR1_IRFS 0x0200 +#define SPORT_RCR1_RLSBIT 0x0010 +#define SPORT_RCR1_RDTYPE_MASK 0x000c +#define SPORT_RCR1_RDTYPE_ZEROFILL 0x0000 +#define SPORT_RCR1_RDTYPE_SIGNEXTEND 0x0004 +#define SPORT_RCR1_RDTYPE_ULAW 0x0008 +#define SPORT_RCR1_RDTYPE_ALAW 0x000c +#define SPORT_RCR1_IRCLK 0x0002 +#define SPORT_RCR1_RSPEN 0x0001 + +#define SPORT_RCR2_RRFST 0x0400 +#define SPORT_RCR2_RSFSE 0x0200 +#define SPORT_RCR2_RXSE 0x0100 +#define SPORT_RCR2_SLEN_MASK 0x001f +#define SPORT_RCR2_SLEN_SHIFT 0 + +#define SPORT_STAT_TXHRE 0x0040 +#define SPORT_STAT_TOVF 0x0020 +#define SPORT_STAT_TUVF 0x0010 +#define SPORT_STAT_TXF 0x0008 +#define SPORT_STAT_ROVF 0x0004 +#define SPORT_STAT_RUVF 0x0002 +#define SPORT_STAT_RXNE 0x0001 + +#define SPORT_CHNL_CHNL_MASK 0x03ff +#define SPORT_CHNL_CHNL_SHIFT 0 + +#define SPORT_MCMC1_WSIZE_MASK 0xf000 +#define SPORT_MCMC1_WSIZE_SHIFT 12 +#define SPORT_MCMC1_WOFF_MASK 0x03ff +#define SPORT_MCMC1_WOFF_SHIFT 0 + +#define SPORT_MCMC2_MFD_MASK 0xf000 +#define SPORT_MCMC2_MFD_SHIFT 12 +#define SPORT_MCMC2_FSDR 0x0080 +#define SPORT_MCMC2_MCMEN 0x0010 +#define SPORT_MCMC2_MCDRXPE 0x0008 +#define SPORT_MCMC2_MCDTXPE 0x0004 +#define SPORT_MCMC2_MCCRM_MASK 0x0003 +#define SPORT_MCMC2_MCCRM_BYPASS 0x0000 +#define SPORT_MCMC2_MCCRM_2_4 0x0002 +#define SPORT_MCMC2_MCCRM_8_16 0x0003 + + +#endif /* _sportRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/timerRegs.h b/c/src/lib/libcpu/bfin/include/timerRegs.h new file mode 100644 index 0000000000..db7e13fbcb --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/timerRegs.h @@ -0,0 +1,48 @@ +/* Blackfin General Purpose Timer Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _timerRegs_h_ +#define _timerRegs_h_ + + +/* register addresses */ + +#define TIMER_CONFIG_OFFSET 0x00 +#define TIMER_WIDTH_OFFSET 0x04 +#define TIMER_PERIOD_OFFSET 0x08 +#define TIMER_COUNTER_OFFSET 0x0c + + +/* register fields */ + +#define TIMER_CONFIG_ERR_TYP_MASK 0xc000 +#define TIMER_CONFIG_ERR_TYP_NONE 0x0000 +#define TIMER_CONFIG_ERR_TYP_OVERFLOW 0x4000 +#define TIMER_CONFIG_ERR_TYP_PERIOD 0x8000 +#define TIMER_CONFIG_ERR_TYP_WIDTH 0xc000 +#define TIMER_CONFIG_EMU_RUN 0x0200 +#define TIMER_CONFIG_TOGGLE_HI 0x0100 +#define TIMER_CONFIG_CLK_SEL 0x0080 +#define TIMER_CONFIG_OUT_DIS 0x0040 +#define TIMER_CONFIG_TIN_SEL 0x0020 +#define TIMER_CONFIG_IRQ_ENA 0x0010 +#define TIMER_CONFIG_PERIOD_CNT 0x0008 +#define TIMER_CONFIG_PULSE_HI 0x0004 +#define TIMER_CONFIG_TMODE_MASK 0x0003 +#define TIMER_CONFIG_TMODE_RESET 0x0000 +#define TIMER_CONFIG_TMODE_PWM_OUT 0x0001 +#define TIMER_CONFIG_TMODE_WDTH_CAP 0x0002 +#define TIMER_CONFIG_TMODE_EXT_CLK 0x0003 + + +#endif /* _timerRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/twiRegs.h b/c/src/lib/libcpu/bfin/include/twiRegs.h new file mode 100644 index 0000000000..a5df911908 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/twiRegs.h @@ -0,0 +1,121 @@ +/* Blackfin Two Wire Interface Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _twiRegs_h_ +#define _twiRegs_h_ + + +/* register addresses */ + +#define TWI_CLKDIV_OFFSET 0x0000 +#define TWI_CONTROL_OFFSET 0x0004 +#define TWI_SLAVE_CTL_OFFSET 0x0008 +#define TWI_SLAVE_STAT_OFFSET 0x000c +#define TWI_SLAVE_ADDR_OFFSET 0x0010 +#define TWI_MASTER_CTL_OFFSET 0x0014 +#define TWI_MASTER_STAT_OFFSET 0x0018 +#define TWI_MASTER_ADDR_OFFSET 0x001c +#define TWI_INT_STAT_OFFSET 0x0020 +#define TWI_INT_MASK_OFFSET 0x0024 +#define TWI_FIFO_CTL_OFFSET 0x0028 +#define TWI_FIFO_STAT_OFFSET 0x002c +#define TWI_XMT_DATA8_OFFSET 0x0080 +#define TWI_XMT_DATA16_OFFSET 0x0084 +#define TWI_RCV_DATA8_OFFSET 0x0088 +#define TWI_RCV_DATA16_OFFSET 0x008c + + +/* register fields */ + +#define TWI_CLKDIV_CLKHI_MASK 0xff00 +#define TWI_CLKDIV_CLKHI_SHIFT 8 +#define TWI_CLKDIV_CLKLOW_MASK 0x00ff +#define TWI_CLKDIV_CLKLOW_SHIFT 0 + +#define TWI_CONTROL_SCCB 0x0200 +#define TWI_CONTROL_TWI_ENA 0x0080 +#define TWI_CONTROL_PRESCALE_MASK 0x007f +#define TWI_CONTROL_PRESCALE_SHIFT 0 + +#define TWI_SLAVE_CTL_GEN 0x0010 +#define TWI_SLAVE_CTL_NAK 0x0008 +#define TWI_SLAVE_CTL_STDVAL 0x0004 +#define TWI_SLAVE_CTL_SEN 0x0001 + +#define TWI_SLAVE_STAT_GCALL 0x0002 +#define TWI_SLAVE_STAT_SDIR 0x0001 + +#define TWI_SLAVE_ADDR_SADDR_MASK 0x007f +#define TWI_SLAVE_ADDR_SADDR_SHIFT 0 + +#define TWI_MASTER_CTL_SCLOVR 0x8000 +#define TWI_MASTER_CTL_SDAOVR 0x4000 +#define TWI_MASTER_CTL_DCNT_MASK 0x3fc0 +#define TWI_MASTER_CTL_DCNT_SHIFT 6 +#define TWI_MASTER_CTL_RSTART 0x0020 +#define TWI_MASTER_CTL_STOP 0x0010 +#define TWI_MASTER_CTL_FAST 0x0008 +#define TWI_MASTER_CTL_MDIR 0x0004 +#define TWI_MASTER_CTL_MEN 0x0001 + +#define TWI_MASTER_STAT_BUSBUSY 0x0100 +#define TWI_MASTER_STAT_SCLSEN 0x0080 +#define TWI_MASTER_STAT_SDASEN 0x0040 +#define TWI_MASTER_STAT_BUFWRERR 0x0020 +#define TWI_MASTER_STAT_BUFRDERR 0x0010 +#define TWI_MASTER_STAT_DNAK 0x0008 +#define TWI_MASTER_STAT_ANAK 0x0004 +#define TWI_MASTER_STAT_LOSTARB 0x0002 +#define TWI_MASTER_STAT_MPROG 0x0001 + +#define TWI_MASTER_ADDR_MADDR_MASK 0x007f +#define TWI_MASTER_ADDR_MADDR_SHIFT 0 + +#define TWI_INT_STAT_RCVSERV 0x0080 +#define TWI_INT_STAT_XMTSERV 0x0040 +#define TWI_INT_STAT_MERR 0x0020 +#define TWI_INT_STAT_MCOMP 0x0010 +#define TWI_INT_STAT_SOVF 0x0008 +#define TWI_INT_STAT_SERR 0x0004 +#define TWI_INT_STAT_SCOMP 0x0002 +#define TWI_INT_STAT_SINIT 0x0001 + +#define TWI_INT_MASK_RCVSERVM 0x0080 +#define TWI_INT_MASK_XMTSERVM 0x0040 +#define TWI_INT_MASK_MERRM 0x0020 +#define TWI_INT_MASK_MCOMPM 0x0010 +#define TWI_INT_MASK_SOVFM 0x0008 +#define TWI_INT_MASK_SERRM 0x0004 +#define TWI_INT_MASK_SCOMPM 0x0002 +#define TWI_INT_MASK_SINITM 0x0001 + +#define TWI_FIFO_CTL_RCVINTLEN 0x0008 +#define TWI_FIFO_CTL_XMTINTLEN 0x0004 +#define TWI_FIFO_CTL_RCVFLUSH 0x0002 +#define TWI_FIFO_CTL_XMTFLUSH 0x0001 + +#define TWI_FIFO_STAT_RCVSTAT_MASK 0x000c +#define TWI_FIFO_STAT_RCVSTAT_EMPTY 0x0000 +#define TWI_FIFO_STAT_RCVSTAT_SHIFT 2 +#define TWI_FIFO_STAT_XMTSTAT_MASK 0x0003 +#define TWI_FIFO_STAT_XMTSTAT_FULL 0x0003 +#define TWI_FIFO_STAT_XMTSTAT_SHIFT 0 + +#define TWI_XMT_DATA8_XMTDATA8_MASK 0x00ff +#define TWI_XMT_DATA8_XMTDATA8_SHIFT 0 + +#define TWI_RCV_DATA8_RCVDATA8_MASK 0x00ff +#define TWI_RCV_DATA8_RCVDATA8_SHIFT 0 + + +#endif /* _twiRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/uartRegs.h b/c/src/lib/libcpu/bfin/include/uartRegs.h new file mode 100644 index 0000000000..d921b17723 --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/uartRegs.h @@ -0,0 +1,73 @@ +/* Blackfin UART Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _uartRegs_h_ +#define _uartRegs_h_ + +/* register addresses */ + +#define UART_RBR_OFFSET 0x0000 +#define UART_THR_OFFSET 0x0000 +#define UART_DLL_OFFSET 0x0000 +#define UART_IER_OFFSET 0x0004 +#define UART_DLH_OFFSET 0x0004 +#define UART_IIR_OFFSET 0x0008 +#define UART_LCR_OFFSET 0x000c +#define UART_MCR_OFFSET 0x0010 +#define UART_LSR_OFFSET 0x0014 +#define UART_SCR_OFFSET 0x001c +#define UART_GCTL_OFFSET 0x0024 + + +/* register fields */ + +#define UART_LCR_DLAB 0x80 +#define UART_LCR_SB 0x40 +#define UART_LCR_STP 0x20 +#define UART_LCR_EPS 0x10 +#define UART_LCR_PEN 0x08 +#define UART_LCR_STB 0x04 +#define UART_LCR_WLS_MASK 0x03 +#define UART_LCR_WLS_5 0x00 +#define UART_LCR_WLS_6 0x01 +#define UART_LCR_WLS_7 0x02 +#define UART_LCR_WLS_8 0x03 + +#define UART_MCR_LOOP 0x10 + +#define UART_LSR_TEMT 0x40 +#define UART_LSR_THRE 0x20 +#define UART_LSR_BI 0x10 +#define UART_LSR_FE 0x08 +#define UART_LSR_PE 0x04 +#define UART_LSR_OE 0x02 +#define UART_LSR_DR 0x01 + +#define UART_IER_ELSI 0x04 +#define UART_IER_ETBEI 0x02 +#define UART_IER_ERBFI 0x01 + +#define UART_IIR_STATUS_MASK 0x06 +#define UART_IIR_STATUS_THRE 0x02 +#define UART_IIR_STATUS_RDR 0x04 +#define UART_IIR_STATUS_LS 0x06 +#define UART_IIR_NINT 0x01 + +#define UART_GCTL_FFE 0x20 +#define UART_GCTL_FPE 0x10 +#define UART_GCTL_RPOLC 0x08 +#define UART_GCTL_TPOLC 0x04 +#define UART_GCTL_IREN 0x02 +#define UART_GCTL_UCEN 0x01 + +#endif /* _uartRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/include/wdogRegs.h b/c/src/lib/libcpu/bfin/include/wdogRegs.h new file mode 100644 index 0000000000..f56073276c --- /dev/null +++ b/c/src/lib/libcpu/bfin/include/wdogRegs.h @@ -0,0 +1,36 @@ +/* Blackfin Watchdog Registers + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _wdogRegs_h_ +#define _wdogRegs_h_ + +/* register addresses */ + +#define WDOG_CTL (WDOG_BASE_ADDRESS + 0x0000) +#define WDOG_CNT (WDOG_BASE_ADDRESS + 0x0004) +#define WDOG_STAT (WDOG_BASE_ADDRESS + 0x0008) + + +/* register fields */ + +#define WDOG_CTL_WDRO 0x8000 +#define WDOG_CTL_WDEN_MASK 0x0ff0 +#define WDOG_CTL_WDEN_DISABLE 0x0ad0 +#define WDOG_CTL_WDEV_MASK 0x0006 +#define WDOG_CTL_WDEV_RESET 0x0000 +#define WDOG_CTL_WDEV_NMI 0x0002 +#define WDOG_CTL_WDEV_GPI 0x0004 +#define WDOG_CTL_WDEV_DISABLE 0x0006 + + +#endif /* _wdogRegs_h_ */ + diff --git a/c/src/lib/libcpu/bfin/interrupt/interrupt.c b/c/src/lib/libcpu/bfin/interrupt/interrupt.c new file mode 100644 index 0000000000..77437c4b56 --- /dev/null +++ b/c/src/lib/libcpu/bfin/interrupt/interrupt.c @@ -0,0 +1,197 @@ +/* Support for Blackfin interrupt controller + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include + +#include +#include +#include +#include "interrupt.h" + + +static struct { + uint32_t mask; + bfin_isr_t *head; +} vectors[CEC_INTERRUPT_COUNT]; + +static uint32_t globalMask; + + +static rtems_isr interruptHandler(rtems_vector_number vector) { + bfin_isr_t *isr; + uint32_t sourceMask; + + vector -= CEC_INTERRUPT_BASE_VECTOR; + if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) { + isr = vectors[vector].head; + sourceMask = *(uint32_t volatile *) SIC_ISR & + *(uint32_t volatile *) SIC_IMASK; + while (isr) { + if (sourceMask & isr->mask) { + isr->isr(isr->source); + sourceMask = *(uint32_t volatile *) SIC_ISR & + *(uint32_t volatile *) SIC_IMASK; + } + isr = isr->next; + } + } +} + +void bfin_interrupt_init(void) { + int source; + int vector; + uint32_t r; + int i; + int j; + + globalMask = ~(uint32_t) 0; + *(uint32_t volatile *) SIC_IMASK = 0; + memset(vectors, 0, sizeof(vectors)); + /* build mask showing what SIC sources drive each CEC vector */ + source = 0; + for (i = 0; i < SIC_IAR_COUNT; i++) { + r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS + i * SIC_IAR_PITCH); + for (j = 0; j < 8; j++) { + vector = r & 0x0f; + if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) { + if (vectors[vector].mask == 0) + /* install our local handler */ + set_vector(interruptHandler, vector + CEC_INTERRUPT_BASE_VECTOR, 1); + vectors[vector].mask |= (1 << source); + } + r >>= 4; + source++; + } + } +} + +/* modify SIC_IMASK based on ISR list for a particular CEC vector */ +static void setMask(int vector) { + bfin_isr_t *isr; + uint32_t mask; + uint32_t r; + + mask = 0; + isr = vectors[vector].head; + while (isr) { + mask |= isr->mask; + isr = isr->next; + } + r = *(uint32_t volatile *) SIC_IMASK; + r &= ~vectors[vector].mask; + r |= mask; + r &= globalMask; + *(uint32_t volatile *) SIC_IMASK = r; +} + +/* add an ISR to the list for whichever vector it belongs to */ +void bfin_interrupt_register(bfin_isr_t *isr) { + bfin_isr_t *walk; + rtems_interrupt_level isrLevel; + + /* find the appropriate vector */ + for (isr->vector = 0; isr->vector < CEC_INTERRUPT_COUNT; isr->vector++) + if (vectors[isr->vector].mask & (1 << isr->source)) + break; + if (isr->vector < CEC_INTERRUPT_COUNT) { + isr->next = NULL; + isr->mask = 0; + rtems_interrupt_disable(isrLevel); + /* find the current end of the list */ + walk = vectors[isr->vector].head; + while (walk && walk->next) + walk = walk->next; + /* append new isr to list */ + if (walk) + walk->next = isr; + else + vectors[isr->vector].head = isr; + rtems_interrupt_enable(isrLevel); + } else + /* we failed, but make vector a legal value so other calls into + this module with this isr descriptor won't do anything bad */ + isr->vector = 0; +} + +void bfin_interrupt_unregister(bfin_isr_t *isr) { + bfin_isr_t *walk, *prev; + rtems_interrupt_level isrLevel; + + rtems_interrupt_disable(isrLevel); + walk = vectors[isr->vector].head; + prev = NULL; + /* find this isr in our list */ + while (walk && walk != isr) { + prev = walk; + walk = walk->next; + } + if (walk) { + /* if found, remove it */ + if (prev) + prev->next = walk->next; + else + vectors[isr->vector].head = walk->next; + /* fix up SIC_IMASK if necessary */ + setMask(isr->vector); + } + rtems_interrupt_enable(isrLevel); +} + +void bfin_interrupt_enable(bfin_isr_t *isr, boolean enable) { + rtems_interrupt_level isrLevel; + + rtems_interrupt_disable(isrLevel); + isr->mask = enable ? (1 << isr->source) : 0; + setMask(isr->vector); + rtems_interrupt_enable(isrLevel); +} + +void bfin_interrupt_enable_all(int source, boolean enable) { + rtems_interrupt_level isrLevel; + int vector; + bfin_isr_t *walk; + + for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++) + if (vectors[vector].mask & (1 << source)) + break; + if (vector < CEC_INTERRUPT_COUNT) { + rtems_interrupt_disable(isrLevel); + walk = vectors[vector].head; + while (walk) { + walk->mask = enable ? (1 << source) : 0; + walk = walk->next; + } + setMask(vector); + rtems_interrupt_enable(isrLevel); + } +} + +void bfin_interrupt_enable_global(int source, boolean enable) { + int vector; + rtems_interrupt_level isrLevel; + + for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++) + if (vectors[vector].mask & (1 << source)) + break; + if (vector < CEC_INTERRUPT_COUNT) { + rtems_interrupt_disable(isrLevel); + if (enable) + globalMask |= 1 << source; + else + globalMask &= ~(1 << source); + setMask(vector); + rtems_interrupt_enable(isrLevel); + } +} + diff --git a/c/src/lib/libcpu/bfin/interrupt/interrupt.h b/c/src/lib/libcpu/bfin/interrupt/interrupt.h new file mode 100644 index 0000000000..71507774e1 --- /dev/null +++ b/c/src/lib/libcpu/bfin/interrupt/interrupt.h @@ -0,0 +1,82 @@ +/* + * RTEMS support for Blackfin interrupt controller + * + * COPYRIGHT (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _interrupt_h_ +#define _interrupt_h_ + +/* Some rules for using this module: + + SIC_IARx registers must not be changed after calling + bfin_interrupt_init(). + + The bfin_isr structures must stick around for as long as the isr is + registered. + + For any interrupt source (SIC bit) that could be shared, it is only + safe to disable an ISR through this module if the ultimate source is + also disabled (the ultimate source must be disabled prior to disabling + it through this module, and must remain disabled until after enabling + it through this module). + + For any source that is shared with modules that cannot be disabled, + give careful thought to the control of those interrupts. + bfin_interrupt_enable_all() or bfin_interrupt_enable_global() can + be used to help solve the problems caused by that. + + + Note that this module does not provide prioritization. It is assumed + that the priorities afforded by the CEC are sufficient. If finer + grained priority control is required then this wlll need to be + redesigned. +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* source is the source to the SIC (the bit number in SIC_ISR). isr is + the function that will be called when the interrupt is active. */ +typedef struct bfin_isr_s { + int source; + void (*isr)(int source); + /* the following are for internal use only */ + uint32_t mask; + int vector; + struct bfin_isr_s *next; +} bfin_isr_t; + +/* If non-default mapping is desired, the BSP should set the SIC_IARx + registers prior to calling this. */ +void bfin_interrupt_init(void); + +/* ISR starts out disabled */ +void bfin_interrupt_register(bfin_isr_t *isr); +void bfin_interrupt_unregister(bfin_isr_t *isr); + +/* enable/disable specific ISR */ +void bfin_interrupt_enable(bfin_isr_t *isr, boolean enable); + +/* atomically enable/disable all ISRs attached to specified source */ +void bfin_interrupt_enable_all(int source, boolean enable); + +/* disable a source independently of the individual ISR enables (starts + out all enabled) */ +void bfin_interrupt_enable_global(int source, boolean enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _interrupt_h_ */ + diff --git a/c/src/lib/libcpu/bfin/mmu/mmu.c b/c/src/lib/libcpu/bfin/mmu/mmu.c new file mode 100644 index 0000000000..6c3943b55e --- /dev/null +++ b/c/src/lib/libcpu/bfin/mmu/mmu.c @@ -0,0 +1,44 @@ +/* Blackfin MMU Support + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 + +#include "mmu.h" + + +/* NOTE: see notes in mmu.h */ + +void bfin_mmu_init(bfin_mmu_config_t *config) { + intptr_t addr; + intptr_t data; + int i; + + addr = (intptr_t) ICPLB_ADDR0; + data = (intptr_t) ICPLB_DATA0; + for (i = 0; i < sizeof(config->instruction) / sizeof(config->instruction[0]); + i++) { + *(uint32_t volatile *) addr = (uint32_t) config->instruction[i].address; + addr += ICPLB_ADDR_PITCH; + *(uint32_t volatile *) data = config->instruction[i].flags; + data += ICPLB_DATA_PITCH; + } + addr = (intptr_t) DCPLB_ADDR0; + data = (intptr_t) DCPLB_DATA0; + for (i = 0; i < sizeof(config->data) / sizeof(config->data[0]); i++) { + *(uint32_t volatile *) addr = (uint32_t) config->data[i].address; + addr += DCPLB_ADDR_PITCH; + *(uint32_t volatile *) data = config->data[i].flags; + data += DCPLB_DATA_PITCH; + } +} + diff --git a/c/src/lib/libcpu/bfin/mmu/mmu.h b/c/src/lib/libcpu/bfin/mmu/mmu.h new file mode 100644 index 0000000000..8a57750ba5 --- /dev/null +++ b/c/src/lib/libcpu/bfin/mmu/mmu.h @@ -0,0 +1,65 @@ +/* Blackfin MMU Support + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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$ + */ + + +/* NOTE: this currently only implements a static table. It should be made + to handle more regions than fit in the CPLBs, with an exception handler + to do replacements as needed. This would of course require great care + to insure any storage required by the exception handler, including any + stack space, the exception handler itself, and the region descriptors + it needs to update the CPLBs, are in regions that will never be + replaced. */ + +#ifndef _mmu_h_ +#define _mmu_h_ + +#include + + +#define INSTR_CACHEABLE (ICPLB_DATA_CPLB_L1_CHBL | \ + ICPLB_DATA_CPLB_USER_RD | \ + ICPLB_DATA_CPLB_VALID) + +#define DATA_WRITEBACK (DCPLB_DATA_CPLB_L1_AOW | \ + DCPLB_DATA_CPLB_L1_CHBL | \ + DCPLB_DATA_CPLB_SUPV_WR | \ + DCPLB_DATA_CPLB_USER_WR | \ + DCPLB_DATA_CPLB_USER_RD | \ + DCPLB_DATA_CPLB_VALID) + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + struct { + void *address; + uint32_t flags; + } instruction[ICPLB_COUNT]; + struct { + void *address; + uint32_t flags; + } data[DCPLB_COUNT]; +} bfin_mmu_config_t; + + +void bfin_mmu_init(bfin_mmu_config_t *config); + + +#ifdef __cplusplus +} +#endif + +#endif /* _mmu_h_ */ + diff --git a/c/src/lib/libcpu/bfin/network/ethernet.c b/c/src/lib/libcpu/bfin/network/ethernet.c new file mode 100644 index 0000000000..3b9c8fb32f --- /dev/null +++ b/c/src/lib/libcpu/bfin/network/ethernet.c @@ -0,0 +1,884 @@ +/* + * RTEMS network driver for Blackfin ethernet controller + * + * COPYRIGHT (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include "ethernet.h" + +#if (BFIN_ETHERNET_DEBUG & BFIN_ETHERNET_DEBUG_DUMP_MBUFS) +#include +#endif + +/* + * Number of devices supported by this driver + */ +#ifndef N_BFIN_ETHERNET +# define N_BFIN_ETHERNET 1 +#endif + + +/* #define BFIN_IPCHECKSUMS */ + + +/* + * RTEMS event used by interrupt handler to signal daemons. + */ +#define INTERRUPT_EVENT RTEMS_EVENT_1 + +/* + * RTEMS event used to start transmit daemon. + */ +#define START_TRANSMIT_EVENT RTEMS_EVENT_2 + + +/* largest Ethernet frame MAC will handle */ +#define BFIN_ETHERNET_MAX_FRAME_LENGTH 1556 + +#if MCLBYTES < (BFIN_ETHERNET_MAX_FRAME_LENGTH + 2) +#error MCLBYTES too small +#endif + +#define BFIN_REG16(base, offset) \ + (*((uint16_t volatile *) ((char *)(base) + (offset)))) +#define BFIN_REG32(base, offset) \ + (*((uint32_t volatile *) ((char *)(base) + (offset)))) + + +#define DMA_MODE_RX (DMA_CONFIG_FLOW_DESC_LARGE | \ + (5 << DMA_CONFIG_NDSIZE_SHIFT) | \ + DMA_CONFIG_WDSIZE_32 | \ + DMA_CONFIG_WNR | \ + DMA_CONFIG_DMAEN) + +#define DMA_MODE_TX (DMA_CONFIG_FLOW_DESC_LARGE | \ + (5 << DMA_CONFIG_NDSIZE_SHIFT) | \ + DMA_CONFIG_WDSIZE_32 | \ + DMA_CONFIG_DMAEN) + +#define DMA_MODE_STATUS (DMA_CONFIG_FLOW_DESC_LARGE | \ + (5 << DMA_CONFIG_NDSIZE_SHIFT) | \ + DMA_CONFIG_DI_EN | \ + DMA_CONFIG_WDSIZE_32 | \ + DMA_CONFIG_WNR | \ + DMA_CONFIG_DMAEN) + +#define DMA_MODE_STATUS_NO_INT (DMA_CONFIG_FLOW_DESC_LARGE | \ + (5 << DMA_CONFIG_NDSIZE_SHIFT) | \ + DMA_CONFIG_WDSIZE_32 | \ + DMA_CONFIG_WNR | \ + DMA_CONFIG_DMAEN) + +#define DMA_MODE_STATUS_LAST (DMA_CONFIG_FLOW_STOP | \ + (0 << DMA_CONFIG_NDSIZE_SHIFT) | \ + DMA_CONFIG_DI_EN | \ + DMA_CONFIG_WDSIZE_32 | \ + DMA_CONFIG_WNR | \ + DMA_CONFIG_DMAEN) + +/* five 16 bit words */ +typedef struct dmaDescS { + struct dmaDescS *next; + void *addr; + uint16_t dmaConfig; +} dmaDescT; + +typedef struct { + uint32_t status; +} txStatusT; + +#ifdef BFIN_IPCHECKSUMS +typedef struct { + uint16_t ipHeaderChecksum; + uint16_t ipPayloadChecksum; + uint32_t status; +} rxStatusT; +#else +typedef struct { + uint32_t status; +} rxStatusT; +#endif + +typedef struct { + dmaDescT data; + dmaDescT status; + struct mbuf *m; +} rxPacketDescT; + +typedef struct { + dmaDescT data; + dmaDescT status; + boolean inUse; + union { + uint32_t dummy; /* try to force 32 bit alignment */ + struct { + uint16_t length; + char data[BFIN_ETHERNET_MAX_FRAME_LENGTH]; + } packet; + } buffer; +} txPacketDescT; + + +/* hardware-specific storage */ +struct bfin_ethernetSoftc { + struct arpcom arpcom; /* this entry must be first */ + + uint32_t sclk; + + void *ethBase; + void *rxdmaBase; + void *txdmaBase; + + int acceptBroadcast; + + rtems_id rxDaemonTid; + rtems_id txDaemonTid; + + void *status; + int rxDescCount; + rxPacketDescT *rx; + int txDescCount; + txPacketDescT *tx; + + boolean rmii; + int phyAddr; + + /* statistics */ +#ifdef BISON + unsigned long Interrupts; + unsigned long rxInterrupts; + unsigned long rxMissed; + unsigned long rxGiant; + unsigned long rxNonOctet; + unsigned long rxBadCRC; + unsigned long rxCollision; + + unsigned long txInterrupts; + unsigned long txSingleCollision; + unsigned long txMultipleCollision; + unsigned long txCollision; + unsigned long txDeferred; + unsigned long txUnderrun; + unsigned long txLateCollision; + unsigned long txExcessiveCollision; + unsigned long txExcessiveDeferral; + unsigned long txLostCarrier; + unsigned long txRawWait; +#endif +}; + +static struct bfin_ethernetSoftc ethernetSoftc[N_BFIN_ETHERNET]; + + +/* Shut down the interface. */ +static void ethernetStop(struct bfin_ethernetSoftc *sc) { + struct ifnet *ifp; + void *ethBase; + + ifp = &sc->arpcom.ac_if; + ethBase = sc->ethBase; + + ifp->if_flags &= ~IFF_RUNNING; + + /* stop the transmitter and receiver. */ + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) &= ~(EMAC_OPMODE_TE | + EMAC_OPMODE_RE); +} + +/* Show interface statistics */ +static void bfin_ethernetStats(struct bfin_ethernetSoftc *sc) { +#ifdef BISON + printf(" Total Interrupts:%-8lu", sc->Interrupts); + printf(" Rx Interrupts:%-8lu", sc->rxInterrupts); + printf(" Giant:%-8lu", sc->rxGiant); + printf(" Non-octet:%-8lu\n", sc->rxNonOctet); + printf(" Bad CRC:%-8lu", sc->rxBadCRC); + printf(" Collision:%-8lu", sc->rxCollision); + printf(" Missed:%-8lu\n", sc->rxMissed); + + printf( " Tx Interrupts:%-8lu", sc->txInterrupts); + printf( " Deferred:%-8lu", sc->txDeferred); + printf(" Lost Carrier:%-8lu\n", sc->txLostCarrier); + printf( "Single Collisions:%-8lu", sc->txSingleCollision); + printf( "Multiple Collisions:%-8lu", sc->txMultipleCollision); + printf("Excessive Collisions:%-8lu\n", sc->txExcessiveCollision); + printf( " Total Collisions:%-8lu", sc->txCollision); + printf( " Late Collision:%-8lu", sc->txLateCollision); + printf(" Underrun:%-8lu\n", sc->txUnderrun); + printf( " Raw output wait:%-8lu\n", sc->txRawWait); +#endif /*BISON*/ +} + +void bfin_ethernet_rxdma_isr(int vector) { + struct bfin_ethernetSoftc *sc; + void *rxdmaBase; + uint16_t status; + int i; + + for (i = 0; i < N_BFIN_ETHERNET; i++) { + sc = ðernetSoftc[i]; + rxdmaBase = sc->rxdmaBase; + status = BFIN_REG16(rxdmaBase, DMA_IRQ_STATUS_OFFSET); + if (status & DMA_IRQ_STATUS_DMA_DONE) + rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT); + BFIN_REG16(rxdmaBase, DMA_IRQ_STATUS_OFFSET) = status; + } +} + +void bfin_ethernet_txdma_isr(int vector) { + struct bfin_ethernetSoftc *sc; + void *txdmaBase; + uint16_t status; + int i; + + for (i = 0; i < N_BFIN_ETHERNET; i++) { + sc = ðernetSoftc[i]; + txdmaBase = sc->txdmaBase; + status = BFIN_REG16(txdmaBase, DMA_IRQ_STATUS_OFFSET); + if (status & DMA_IRQ_STATUS_DMA_DONE) + rtems_event_send (sc->txDaemonTid, INTERRUPT_EVENT); + BFIN_REG16(txdmaBase, DMA_IRQ_STATUS_OFFSET) = status; + } +} + +void bfin_ethernet_mac_isr(int vector) { + struct bfin_ethernetSoftc *sc; + void *ethBase; + int i; + + for (i = 0; i < N_BFIN_ETHERNET; i++) { + sc = ðernetSoftc[i]; + ethBase = sc->ethBase; + BFIN_REG32(ethBase, EMAC_SYSTAT_OFFSET) = ~(uint32_t) 0; + } +} + +static boolean txFree(struct bfin_ethernetSoftc *sc, int index) { + boolean freed; + txStatusT *status; + + freed = FALSE; + if (sc->tx[index].inUse) { + status = (txStatusT *) sc->tx[index].status.addr; + rtems_cache_invalidate_multiple_data_lines(status, sizeof(*status)); + if (status->status != 0) { + /* update statistics */ + + sc->tx[index].inUse = FALSE; + freed = TRUE; + } + } + + return freed; +} + +static void txDaemon(void *arg) { + struct bfin_ethernetSoftc *sc; + struct ifnet *ifp; + struct mbuf *m, *first; + rtems_event_set events; + void *ethBase; + void *txdmaBase; + txStatusT *status; + int head; + int prevHead; + int tail; + int length; + char *ptr; + + sc = (struct bfin_ethernetSoftc *) arg; + ifp = &sc->arpcom.ac_if; + + ethBase = sc->ethBase; + txdmaBase = sc->txdmaBase; + head = 0; + prevHead = sc->txDescCount - 1; + tail = 0; + + while (1) { + /* wait for packet or isr */ + rtems_bsdnet_event_receive(START_TRANSMIT_EVENT | INTERRUPT_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, &events); + + /* if no descriptors are available, try to free one. To reduce + transmit latency only do one here. */ + if (sc->tx[head].inUse && txFree(sc, tail)) { + if (++tail == sc->txDescCount) + tail = 0; + } + /* send packets until the queue is empty or we run out of tx + descriptors */ + while (!sc->tx[head].inUse && (ifp->if_flags & IFF_OACTIVE)) { + /* get the next mbuf chain to transmit */ + IF_DEQUEUE(&ifp->if_snd, m); + if (m != NULL) { + /* copy packet into our buffer */ + ptr = sc->tx[head].buffer.packet.data; + length = 0; + first = m; + while (m && length <= BFIN_ETHERNET_MAX_FRAME_LENGTH) { + length += m->m_len; + if (length <= BFIN_ETHERNET_MAX_FRAME_LENGTH) + memcpy(ptr, m->m_data, m->m_len); + ptr += m->m_len; + m = m->m_next; + } + m_freem(first); /* all done with mbuf */ + if (length <= BFIN_ETHERNET_MAX_FRAME_LENGTH) { + sc->tx[head].buffer.packet.length = length; + + /* setup tx dma */ + status = (txStatusT *) sc->tx[head].status.addr; + status->status = 0; + sc->tx[head].inUse = TRUE; + rtems_cache_flush_multiple_data_lines(status, sizeof(*status)); + + /* configure dma to stop after sending this packet */ + sc->tx[head].status.dmaConfig = DMA_MODE_STATUS_LAST; + rtems_cache_flush_multiple_data_lines( + &sc->tx[head].status.dmaConfig, + sizeof(sc->tx[head].status.dmaConfig)); + rtems_cache_flush_multiple_data_lines( + &sc->tx[head].buffer.packet, + length + sizeof(uint16_t)); + + /* modify previous descriptor to let it continue + automatically */ + sc->tx[prevHead].status.dmaConfig = DMA_MODE_STATUS; + rtems_cache_flush_multiple_data_lines( + &sc->tx[prevHead].status.dmaConfig, + sizeof(sc->tx[prevHead].status.dmaConfig)); + + /* restart dma if it stopped before the packet we just + added. this is purely to reduce transmit latency, + as it would be restarted anyway after this loop (and + needs to be, as there's a very small chance that the + dma controller had started the last status transfer + before the new dmaConfig word was written above and + is still doing that status transfer when we check the + status below. this will be caught by the check + outside the loop as that is guaranteed to run at least + once after the last dma complete interrupt. */ + if ((BFIN_REG16(txdmaBase, DMA_IRQ_STATUS_OFFSET) & + DMA_IRQ_STATUS_DMA_RUN) == 0 && + BFIN_REG32(txdmaBase, DMA_NEXT_DESC_PTR_OFFSET) != + (uint32_t) sc->tx[head].data.next) { + BFIN_REG16(txdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_TX; + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_TE; + } + + if (++head == sc->txDescCount) + head = 0; + if (++prevHead == sc->txDescCount) + prevHead = 0; + + /* if no descriptors are available, try to free one */ + if (sc->tx[head].inUse && txFree(sc, tail)) { + if (++tail == sc->txDescCount) + tail = 0; + } + } else { + /* dropping packet: too large */ + + } + } else { + /* no packets queued */ + ifp->if_flags &= ~IFF_OACTIVE; + } + } + + /* if dma stopped and there's more to do, restart it */ + if ((BFIN_REG16(txdmaBase, DMA_IRQ_STATUS_OFFSET) & + DMA_IRQ_STATUS_DMA_RUN) == 0 && + BFIN_REG32(txdmaBase, DMA_NEXT_DESC_PTR_OFFSET) != + (uint32_t) &sc->tx[head].data) { + BFIN_REG16(txdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_TX; + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_TE; + } + + /* free up any additional tx descriptors */ + while (txFree(sc, tail)) { + if (++tail == sc->txDescCount) + tail = 0; + } + } +} + + +static void rxDaemon(void *arg) { + struct bfin_ethernetSoftc *sc; + struct ifnet *ifp; + struct mbuf *m; + struct mbuf *rxPacket; + void *dataPtr; + rtems_event_set events; + struct ether_header *eh; + rxStatusT *status; + uint32_t rxStatus; + int head; + int prevHead; + int length; + void *ethBase; + void *rxdmaBase; + + sc = (struct bfin_ethernetSoftc *) arg; + rxdmaBase = sc->rxdmaBase; + ethBase = sc->ethBase; + ifp = &sc->arpcom.ac_if; + prevHead = sc->rxDescCount - 1; + head = 0; + + BFIN_REG16(rxdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_RX; + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_RE; + + while (1) { + status = sc->rx[head].status.addr; + rtems_cache_invalidate_multiple_data_lines(status, sizeof(*status)); + while (status->status != 0) { + if (status->status & EMAC_RX_STAT_RX_OK) { + /* get new cluster to replace this one */ + MGETHDR(m, M_WAIT, MT_DATA); + MCLGET(m, M_WAIT); + m->m_pkthdr.rcvif = ifp; + } else + m = NULL; + + rxStatus = status->status; + /* update statistics */ + + + if (m) { + /* save received packet to send up a little later */ + rxPacket = sc->rx[head].m; + dataPtr = sc->rx[head].data.addr; + + /* setup dma for new cluster */ + sc->rx[head].m = m; + sc->rx[head].data.addr = (void *) (((intptr_t) m->m_data + 3) & ~3); + /* invalidate cache for new data buffer, in case any lines + are dirty from previous owner */ + rtems_cache_invalidate_multiple_data_lines( + sc->rx[head].data.addr, + BFIN_ETHERNET_MAX_FRAME_LENGTH + 2); + } else + rxPacket = NULL; + + sc->rx[head].status.dmaConfig = DMA_MODE_STATUS_LAST; + rtems_cache_flush_multiple_data_lines(&sc->rx[head], + sizeof(sc->rx[head])); + + /* mark descriptor as empty */ + status->status = 0; + rtems_cache_flush_multiple_data_lines(&status->status, + sizeof(status->status)); + + /* allow dma to continue from previous descriptor into this + one */ + sc->rx[prevHead].status.dmaConfig = DMA_MODE_STATUS; + rtems_cache_flush_multiple_data_lines( + &sc->rx[prevHead].status.dmaConfig, + sizeof(sc->rx[prevHead].status.dmaConfig)); + + if (rxPacket) { + /* send it up */ + eh = (struct ether_header *) ((intptr_t) dataPtr + 2); + rxPacket->m_data = (caddr_t) ((intptr_t) dataPtr + 2 + 14); + length = (rxStatus & EMAC_RX_STAT_RX_FRLEN_MASK) >> + EMAC_RX_STAT_RX_FRLEN_SHIFT; + rxPacket->m_len = length - 14; + rxPacket->m_pkthdr.len = rxPacket->m_len; + /* invalidate packet buffer cache again (even though it + was invalidated prior to giving it to dma engine), + because speculative reads might cause cache lines to + be filled at any time */ + rtems_cache_invalidate_multiple_data_lines(eh, length); + ether_input(ifp, eh, rxPacket); + } + + if (++prevHead == sc->rxDescCount) + prevHead = 0; + if (++head == sc->rxDescCount) + head = 0; + status = sc->rx[head].status.addr; + rtems_cache_invalidate_multiple_data_lines(status, sizeof(*status)); + } + + /* if dma stopped before the next descriptor, restart it */ + if ((BFIN_REG16(rxdmaBase, DMA_IRQ_STATUS_OFFSET) & + DMA_IRQ_STATUS_DMA_RUN) == 0 && + BFIN_REG32(rxdmaBase, DMA_NEXT_DESC_PTR_OFFSET) != + (uint32_t) &sc->rx[head].data) { + BFIN_REG16(rxdmaBase, DMA_CONFIG_OFFSET) = DMA_MODE_RX; + } + + rtems_bsdnet_event_receive(INTERRUPT_EVENT, RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, &events); + } + +} + +/* + ****************************************************************** + * * + * Initialization Routines * + * * + ****************************************************************** + */ + +static void resetHardware(struct bfin_ethernetSoftc *sc) { + void *ethBase; + void *rxdmaBase; + void *txdmaBase; + + ethBase = sc->ethBase; + rxdmaBase = sc->rxdmaBase; + txdmaBase = sc->txdmaBase; + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) = 0; + BFIN_REG16(rxdmaBase, DMA_CONFIG_OFFSET) = 0; + BFIN_REG16(txdmaBase, DMA_CONFIG_OFFSET) = 0; +} + +static void initializeHardware(struct bfin_ethernetSoftc *sc) { + struct ifnet *ifp; + struct mbuf *m; + unsigned char *hwaddr; + int cacheAlignment; + int rxStatusSize; + int txStatusSize; + char *ptr; + int i; + void *ethBase; + void *rxdmaBase; + void *txdmaBase; + uint32_t divisor; + + ifp = &sc->arpcom.ac_if; + ethBase = sc->ethBase; + rxdmaBase = sc->rxdmaBase; + txdmaBase = sc->txdmaBase; + + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) = 0; + BFIN_REG32(ethBase, EMAC_FLC_OFFSET) = 0; + divisor = (sc->sclk / 25000000) / 2 - 1; + BFIN_REG32(ethBase, EMAC_SYSCTL_OFFSET) = (divisor << + EMAC_SYSCTL_MDCDIV_SHIFT) | + EMAC_SYSCTL_RXDWA; +#ifdef BFIN_IPCHECKSUMS + BFIN_REG32(ethBase, EMAC_SYSCTL_OFFSET) |= EMAC_SYSCTL_RXCKS; +#endif + BFIN_REG32(ethBase, EMAC_SYSTAT_OFFSET) = ~(uint32_t) 0; + BFIN_REG32(ethBase, EMAC_RX_IRQE_OFFSET) = 0; + BFIN_REG32(ethBase, EMAC_RX_STKY_OFFSET) = ~(uint32_t) 0; + BFIN_REG32(ethBase, EMAC_TX_IRQE_OFFSET) = 0; + BFIN_REG32(ethBase, EMAC_TX_STKY_OFFSET) = ~(uint32_t) 0; + BFIN_REG32(ethBase, EMAC_MMC_RIRQE_OFFSET) = 0; + BFIN_REG32(ethBase, EMAC_MMC_RIRQS_OFFSET) = ~(uint32_t) 0; + BFIN_REG32(ethBase, EMAC_MMC_TIRQE_OFFSET) = 0; + BFIN_REG32(ethBase, EMAC_MMC_TIRQS_OFFSET) = ~(uint32_t) 0; + BFIN_REG32(ethBase, EMAC_MMC_CTL_OFFSET) = EMAC_MMC_CTL_MMCE | + EMAC_MMC_CTL_CCOR | + EMAC_MMC_CTL_RSTC; + BFIN_REG32(ethBase, EMAC_MMC_CTL_OFFSET) = EMAC_MMC_CTL_MMCE | + EMAC_MMC_CTL_CCOR; + + BFIN_REG16(rxdmaBase, DMA_CONFIG_OFFSET) = 0; + BFIN_REG16(txdmaBase, DMA_CONFIG_OFFSET) = 0; + BFIN_REG16(rxdmaBase, DMA_X_COUNT_OFFSET) = 0; + BFIN_REG16(txdmaBase, DMA_X_COUNT_OFFSET) = 0; + BFIN_REG16(rxdmaBase, DMA_X_MODIFY_OFFSET) = 4; + BFIN_REG16(txdmaBase, DMA_X_MODIFY_OFFSET) = 4; + BFIN_REG16(rxdmaBase, DMA_Y_COUNT_OFFSET) = 0; + BFIN_REG16(txdmaBase, DMA_Y_COUNT_OFFSET) = 0; + BFIN_REG16(rxdmaBase, DMA_Y_MODIFY_OFFSET) = 0; + BFIN_REG16(txdmaBase, DMA_Y_MODIFY_OFFSET) = 0; + BFIN_REG16(rxdmaBase, DMA_IRQ_STATUS_OFFSET) = DMA_IRQ_STATUS_DMA_ERR | + DMA_IRQ_STATUS_DMA_DONE; + + /* The status structures cannot share cache lines with anything else, + including other status structures, so we can safely manage both the + processor and DMA writing to them. So this rounds up the structure + sizes to a multiple of the cache line size. */ + cacheAlignment = rtems_cache_get_data_line_size(); + if (cacheAlignment == 0) + cacheAlignment = 1; + rxStatusSize = cacheAlignment * ((sizeof(rxStatusT) + cacheAlignment - 1) / + cacheAlignment); + txStatusSize = cacheAlignment * ((sizeof(txStatusT) + cacheAlignment - 1) / + cacheAlignment); + /* Allocate enough extra to allow structures to start at cache aligned + boundary. */ + sc->status = malloc(sc->rxDescCount * rxStatusSize + + sc->txDescCount * txStatusSize + + cacheAlignment - 1, M_DEVBUF, M_NOWAIT); + sc->rx = malloc(sc->rxDescCount * sizeof(*sc->rx), M_DEVBUF, M_NOWAIT); + sc->tx = malloc(sc->txDescCount * sizeof(*sc->tx), M_DEVBUF, M_NOWAIT); + if (sc->status == NULL || sc->rx == NULL || sc->tx == NULL) + rtems_panic("No memory!\n"); + + /* Start status structures at cache aligned boundary. */ + ptr = (char *) (((intptr_t) sc->status + cacheAlignment - 1) & + ~(cacheAlignment - 1)); + memset(ptr, 0, sc->rxDescCount * rxStatusSize + + sc->txDescCount * txStatusSize); + memset(sc->rx, 0, sc->rxDescCount * sizeof(*sc->rx)); + memset(sc->tx, 0, sc->txDescCount * sizeof(*sc->tx)); + rtems_cache_flush_multiple_data_lines(ptr, sc->rxDescCount * rxStatusSize + + sc->txDescCount * txStatusSize); + for (i = 0; i < sc->rxDescCount; i++) { + MGETHDR(m, M_WAIT, MT_DATA); + MCLGET(m, M_WAIT); + m->m_pkthdr.rcvif = ifp; + sc->rx[i].m = m; + /* start dma at 32 bit boundary */ + sc->rx[i].data.addr = (void *) (((intptr_t) m->m_data + 3) & ~3); + rtems_cache_invalidate_multiple_data_lines( + sc->rx[i].data.addr, + BFIN_ETHERNET_MAX_FRAME_LENGTH + 2); + sc->rx[i].data.dmaConfig = DMA_MODE_RX; + sc->rx[i].data.next = &(sc->rx[i].status); + sc->rx[i].status.addr = ptr; + if (i < sc->rxDescCount - 1) { + sc->rx[i].status.dmaConfig = DMA_MODE_STATUS; + sc->rx[i].status.next = &(sc->rx[i + 1].data); + } else { + sc->rx[i].status.dmaConfig = DMA_MODE_STATUS_LAST; + sc->rx[i].status.next = &(sc->rx[0].data); + } + ptr += rxStatusSize; + } + rtems_cache_flush_multiple_data_lines(sc->rx, sc->rxDescCount * + sizeof(*sc->rx)); + for (i = 0; i < sc->txDescCount; i++) { + sc->tx[i].data.addr = &sc->tx[i].buffer.packet; + sc->tx[i].data.dmaConfig = DMA_MODE_TX; + sc->tx[i].data.next = &(sc->tx[i].status); + sc->tx[i].status.addr = ptr; + sc->tx[i].status.dmaConfig = DMA_MODE_STATUS_LAST; + if (i < sc->txDescCount - 1) + sc->tx[i].status.next = &(sc->tx[i + 1].data); + else + sc->tx[i].status.next = &(sc->tx[0].data); + sc->tx[i].inUse = FALSE; + ptr += txStatusSize; + } + rtems_cache_flush_multiple_data_lines(sc->tx, sc->txDescCount * + sizeof(*sc->tx)); + + BFIN_REG32(rxdmaBase, DMA_NEXT_DESC_PTR_OFFSET) = (uint32_t) &sc->rx[0].data; + BFIN_REG32(txdmaBase, DMA_NEXT_DESC_PTR_OFFSET) = (uint32_t) &sc->tx[0].data; + + hwaddr = sc->arpcom.ac_enaddr; + BFIN_REG16(ethBase, EMAC_ADDRHI_OFFSET) = ((uint16_t) hwaddr[5] << 8) | + hwaddr[4]; + BFIN_REG32(ethBase, EMAC_ADDRLO_OFFSET) = ((uint32_t) hwaddr[3] << 24) | + ((uint32_t) hwaddr[2] << 16) | + ((uint32_t) hwaddr[1] << 8) | + hwaddr[0]; + + if (sc->acceptBroadcast) + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) &= ~EMAC_OPMODE_DBF; + else + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_DBF; + +} + +/* send packet (caller provides header) */ +static void ethernetStart(struct ifnet *ifp) { + struct bfin_ethernetSoftc *sc; + + sc = ifp->if_softc; + + ifp->if_flags |= IFF_OACTIVE; + rtems_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT); +} + +/* initialize and start the device */ +static void ethernetInit(void *arg) { + struct bfin_ethernetSoftc *sc; + struct ifnet *ifp; + void *ethBase; + void *rxdmaBase; + void *txdmaBase; + + sc = arg; + ifp = &sc->arpcom.ac_if; + ethBase = sc->ethBase; + rxdmaBase = sc->rxdmaBase; + txdmaBase = sc->txdmaBase; + + if (sc->txDaemonTid == 0) { + initializeHardware(sc); + + /* start driver tasks */ + sc->rxDaemonTid = rtems_bsdnet_newproc("BFrx", 4096, rxDaemon, sc); + sc->txDaemonTid = rtems_bsdnet_newproc("BFtx", 4096, txDaemon, sc); + + } + + if (ifp->if_flags & IFF_PROMISC) + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) |= EMAC_OPMODE_PR; + else + BFIN_REG32(ethBase, EMAC_OPMODE_OFFSET) &= ~EMAC_OPMODE_PR; + + /* + * Tell the world that we're running. + */ + ifp->if_flags |= IFF_RUNNING; + +} + +/* driver ioctl handler */ +static int ethernetIoctl(struct ifnet *ifp, ioctl_command_t command, + caddr_t data) { + int result; + struct bfin_ethernetSoftc *sc = ifp->if_softc; + + result = 0; + switch (command) { + case SIOCGIFADDR: + case SIOCSIFADDR: + ether_ioctl(ifp, command, data); + break; + case SIOCSIFFLAGS: + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + case IFF_RUNNING: + ethernetStop(sc); + break; + case IFF_UP: + ethernetInit(sc); + break; + case IFF_UP | IFF_RUNNING: + ethernetStop(sc); + ethernetInit(sc); + break; + default: + break; + } + break; + case SIO_RTEMS_SHOW_STATS: + bfin_ethernetStats(sc); + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + default: + result = EINVAL; + break; + } + + return result; +} + +/* attach a BFIN ETHERNET driver to the system */ +int bfin_ethernet_driver_attach(struct rtems_bsdnet_ifconfig *config, + int attaching, + bfin_ethernet_configuration_t *chip) { + struct bfin_ethernetSoftc *sc; + struct ifnet *ifp; + int mtu; + int unitNumber; + char *unitName; + + if ((unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0) + return 0; + + if ((unitNumber <= 0) || (unitNumber > N_BFIN_ETHERNET)) { + printf("Bad bfin ethernet unit number %d.\n", unitNumber); + return 0; + } + sc = ðernetSoftc[unitNumber - 1]; + ifp = &sc->arpcom.ac_if; + if (ifp->if_softc != NULL) { + printf("Driver already in use.\n"); + return 0; + } + + memset(sc, 0, sizeof(*sc)); + + /* process options */ + if (config->hardware_address) + memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN); + else + memset(sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN); + if (config->mtu) + mtu = config->mtu; + else + mtu = ETHERMTU; + if (config->rbuf_count) + sc->rxDescCount = config->rbuf_count; + else + sc->rxDescCount = chip->rxDescCount; + if (config->xbuf_count) + sc->txDescCount = config->xbuf_count; + else + sc->txDescCount = chip->txDescCount; + /* minimum two of each type descriptor */ + if (sc->rxDescCount <= 1) + sc->rxDescCount = 2; + if (sc->txDescCount <= 1) + sc->txDescCount = 2; + + sc->acceptBroadcast = !config->ignore_broadcast; + + sc->sclk = chip->sclk; + sc->ethBase = chip->ethBaseAddress; + sc->rxdmaBase = chip->rxdmaBaseAddress; + sc->txdmaBase = chip->txdmaBaseAddress; + + /* make sure we should not have any interrupts asserted */ + resetHardware(sc); + + sc->rmii = (chip->phyType == rmii); + sc->phyAddr = chip->phyAddr; + + /* set up network interface values */ + ifp->if_softc = sc; + ifp->if_unit = unitNumber; + ifp->if_name = unitName; + ifp->if_mtu = mtu; + ifp->if_init = ethernetInit; + ifp->if_ioctl = ethernetIoctl; + ifp->if_start = ethernetStart; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; + if (ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + if_attach(ifp); + ether_ifattach(ifp); + + return 1; +} + diff --git a/c/src/lib/libcpu/bfin/network/ethernet.h b/c/src/lib/libcpu/bfin/network/ethernet.h new file mode 100644 index 0000000000..0c019bc976 --- /dev/null +++ b/c/src/lib/libcpu/bfin/network/ethernet.h @@ -0,0 +1,56 @@ +/* + * RTEMS network driver for Blackfin embedded ethernet controller + * + * COPYRIGHT (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _ethernet_h_ +#define _ethernet_h_ + + +#define BFIN_ETHERNET_DEBUG_NONE 0x0000 +#define BFIN_ETHERNET_DEBUG_ALL 0xFFFF + +#define BFIN_ETHERNET_DEBUG (BFIN_ETHERNET_DEBUG_NONE) + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + uint32_t sclk; + void *ethBaseAddress; + void *rxdmaBaseAddress; + void *txdmaBaseAddress; + int rxDescCount; + int txDescCount; + enum {rmii, mii} phyType; + int phyAddr; +} bfin_ethernet_configuration_t; + + +void bfin_ethernet_rxdma_isr(int vector); +void bfin_ethernet_txdma_isr(int vector); +void bfin_ethernet_mac_isr(int vector); + +int bfin_ethernet_driver_attach(struct rtems_bsdnet_ifconfig *config, + int attaching, + bfin_ethernet_configuration_t *chip); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ethernet_h_ */ + diff --git a/c/src/lib/libcpu/bfin/preinstall.am b/c/src/lib/libcpu/bfin/preinstall.am new file mode 100644 index 0000000000..b14978e4ff --- /dev/null +++ b/c/src/lib/libcpu/bfin/preinstall.am @@ -0,0 +1,129 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES = $(PREINSTALL_DIRS) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES = $(PREINSTALL_FILES) + +$(PROJECT_INCLUDE)/libcpu/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/libcpu + @: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + +$(PROJECT_INCLUDE)/libcpu/bf533.h: include/bf533.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/bf533.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/bf533.h + +$(PROJECT_INCLUDE)/libcpu/bf537.h: include/bf537.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/bf537.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/bf537.h + +$(PROJECT_INCLUDE)/libcpu/cecRegs.h: include/cecRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cecRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cecRegs.h + +$(PROJECT_INCLUDE)/libcpu/memoryRegs.h: include/memoryRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/memoryRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/memoryRegs.h + +$(PROJECT_INCLUDE)/libcpu/mmuRegs.h: include/mmuRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmuRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmuRegs.h + +$(PROJECT_INCLUDE)/libcpu/sicRegs.h: include/sicRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/sicRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/sicRegs.h + +$(PROJECT_INCLUDE)/libcpu/ebiuRegs.h: include/ebiuRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/ebiuRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/ebiuRegs.h + +$(PROJECT_INCLUDE)/libcpu/ppiRegs.h: include/ppiRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/ppiRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/ppiRegs.h + +$(PROJECT_INCLUDE)/libcpu/coreTimerRegs.h: include/coreTimerRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/coreTimerRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/coreTimerRegs.h + +$(PROJECT_INCLUDE)/libcpu/wdogRegs.h: include/wdogRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/wdogRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/wdogRegs.h + +$(PROJECT_INCLUDE)/libcpu/timerRegs.h: include/timerRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/timerRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/timerRegs.h + +$(PROJECT_INCLUDE)/libcpu/dmaRegs.h: include/dmaRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/dmaRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/dmaRegs.h + +$(PROJECT_INCLUDE)/libcpu/ethernetRegs.h: include/ethernetRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/ethernetRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/ethernetRegs.h + +$(PROJECT_INCLUDE)/libcpu/uartRegs.h: include/uartRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/uartRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/uartRegs.h + +$(PROJECT_INCLUDE)/libcpu/sportRegs.h: include/sportRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/sportRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/sportRegs.h + +$(PROJECT_INCLUDE)/libcpu/twiRegs.h: include/twiRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/twiRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/twiRegs.h + +$(PROJECT_INCLUDE)/libcpu/spiRegs.h: include/spiRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/spiRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/spiRegs.h + +$(PROJECT_INCLUDE)/libcpu/rtcRegs.h: include/rtcRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/rtcRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/rtcRegs.h + +$(PROJECT_INCLUDE)/libcpu/gpioRegs.h: include/gpioRegs.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/gpioRegs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/gpioRegs.h + +$(PROJECT_INCLUDE)/libcpu/cache.h: ../shared/include/cache.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cache.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cache.h + +$(PROJECT_INCLUDE)/libcpu/mmu.h: mmu/mmu.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/mmu.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/mmu.h + +$(PROJECT_INCLUDE)/libcpu/interrupt.h: interrupt/interrupt.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/interrupt.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/interrupt.h + +$(PROJECT_INCLUDE)/libcpu/uart.h: serial/uart.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/uart.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/uart.h + +$(PROJECT_INCLUDE)/libcpu/sport.h: serial/sport.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/sport.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/sport.h + +$(PROJECT_INCLUDE)/libcpu/spi.h: serial/spi.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/spi.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/spi.h + +$(PROJECT_INCLUDE)/libcpu/twi.h: serial/twi.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/twi.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/twi.h + +if HAS_NETWORKING +$(PROJECT_INCLUDE)/libcpu/ethernet.h: network/ethernet.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/ethernet.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/ethernet.h +endif diff --git a/c/src/lib/libcpu/bfin/serial/spi.c b/c/src/lib/libcpu/bfin/serial/spi.c new file mode 100644 index 0000000000..42c2a5250f --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/spi.c @@ -0,0 +1,109 @@ +/* placeholder (just a shell) */ + +/* SPI driver for Blackfin + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include +#include + +#include +#include "spi.h" + + +static rtems_status_code spiInit(rtems_libi2c_bus_t *bus) { + bfin_spi_softc_t *softc; + rtems_status_code status; + + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + status = rtems_semaphore_create(rtems_build_name('s','p','i','s'), + 0, + RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &softc->irq_sema_id); + + return status; +} + +static rtems_status_code spiSendStart(rtems_libi2c_bus_t *bus) { + bfin_spi_softc_t *softc; + rtems_status_code status; + + status = RTEMS_SUCCESSFUL; + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + return status; +} + +static rtems_status_code spiSendStop(rtems_libi2c_bus_t *bus) { + bfin_spi_softc_t *softc; + rtems_status_code status; + + status = RTEMS_SUCCESSFUL; + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + return status; +} + +static rtems_status_code spiSendAddr(rtems_libi2c_bus_t *bus, + uint32_t addr, int rw) { + bfin_spi_softc_t *softc; + rtems_status_code status; + + status = RTEMS_SUCCESSFUL; + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + return status; +} + +static int spiReadBytes(rtems_libi2c_bus_t *bus, + unsigned char *buf, int len) { + bfin_spi_softc_t *softc; + + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + return 0; +} + +static int spiWriteBytes(rtems_libi2c_bus_t *bus, + unsigned char *buf, int len) { + bfin_spi_softc_t *softc; + + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + return 0; +} + +static int spiIoctl(rtems_libi2c_bus_t *bus, int cmd, void *arg) { + bfin_spi_softc_t *softc; + + softc = &(((bfin_spi_desc_t *)(bus))->softc); + + + return 0; +} + +void bfin_spi_isr(int source) { +} + +rtems_libi2c_bus_ops_t bfin_spi_libi2c_bus_ops = { + init: spiInit, + send_start: spiSendStart, + send_stop: spiSendStop, + send_addr: spiSendAddr, + read_bytes: spiReadBytes, + write_bytes: spiWriteBytes, + ioctl: spiIoctl +}; + diff --git a/c/src/lib/libcpu/bfin/serial/spi.h b/c/src/lib/libcpu/bfin/serial/spi.h new file mode 100644 index 0000000000..01180aac15 --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/spi.h @@ -0,0 +1,52 @@ +/* placeholder (just a shell) */ + +/* + * RTEMS driver for Blackfin SPI + * + * COPYRIGHT (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _spi_h_ +#define _spi_h_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + /* parameters provided by bsp */ + uint32_t freq; + void *base; + boolean fast; + /* internal use */ + rtems_id irq_sema_id; +} bfin_spi_softc_t; + +typedef struct { + rtems_libi2c_bus_t bus; + bfin_spi_softc_t softc; +} bfin_spi_desc_t; + + +extern rtems_libi2c_bus_ops_t bfin_spi_libi2c_bus_ops; + + +void bfin_spi_isr(int source); + + +#ifdef __cplusplus +} +#endif + +#endif /* _spi_h_ */ + diff --git a/c/src/lib/libcpu/bfin/serial/sport.c b/c/src/lib/libcpu/bfin/serial/sport.c new file mode 100644 index 0000000000..6ed481b593 --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/sport.c @@ -0,0 +1,2 @@ +/* placeholder */ + diff --git a/c/src/lib/libcpu/bfin/serial/sport.h b/c/src/lib/libcpu/bfin/serial/sport.h new file mode 100644 index 0000000000..6ed481b593 --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/sport.h @@ -0,0 +1,2 @@ +/* placeholder */ + diff --git a/c/src/lib/libcpu/bfin/serial/twi.c b/c/src/lib/libcpu/bfin/serial/twi.c new file mode 100644 index 0000000000..5bdb9ef742 --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/twi.c @@ -0,0 +1,256 @@ +/* this is not much more than a shell; it does not do anything useful yet */ + +/* TWI (I2C) driver for Blackfin + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include + +#include +#include "twi.h" + + +#ifndef N_BFIN_TWI +#define N_BFIN_TWI 1 +#endif + +#define BFIN_REG16(base, offset) \ + (*((uint16_t volatile *) ((char *)(base) + (offset)))) + + +static struct { + void *base; + rtems_id irqSem; + rtems_id mutex; + bfin_twi_callback_t callback; + void *callbackArg; + bfin_twi_request_t volatile *req; + uint8_t volatile *dataPtr; + int volatile count; + boolean volatile masterActive; + rtems_status_code volatile masterResult; + boolean volatile slaveActive; +} twi[N_BFIN_TWI]; + + +rtems_status_code bfin_twi_init(int channel, bfin_twi_config_t *config) { + rtems_status_code result; + void *base; + + if (channel < 0 || channel >= N_BFIN_TWI) + return RTEMS_INVALID_NUMBER; + + base = config->base; + twi[channel].base = base; + + result = rtems_semaphore_create(rtems_build_name('t','w','i','s'), + 0, + RTEMS_FIFO | + RTEMS_SIMPLE_BINARY_SEMAPHORE | + RTEMS_NO_INHERIT_PRIORITY | + RTEMS_NO_PRIORITY_CEILING | + RTEMS_LOCAL, + 0, + &twi[channel].irqSem); + result = rtems_semaphore_create(rtems_build_name('t','w','i','m'), + 1, + RTEMS_PRIORITY | + RTEMS_SIMPLE_BINARY_SEMAPHORE | + RTEMS_INHERIT_PRIORITY | + RTEMS_NO_PRIORITY_CEILING | + RTEMS_LOCAL, + 0, + &twi[channel].mutex); + BFIN_REG16(base, TWI_CONTROL_OFFSET) = + (uint16_t) (((config->sclk +9999999) / 10000000) << + TWI_CONTROL_PRESCALE_SHIFT) | + TWI_CONTROL_TWI_ENA; + BFIN_REG16(base, TWI_CLKDIV_OFFSET) = config->fast ? + ((8 << TWI_CLKDIV_CLKHI_SHIFT) | + (17 << TWI_CLKDIV_CLKLOW_SHIFT)) : + ((33 << TWI_CLKDIV_CLKHI_SHIFT) | + (67 << TWI_CLKDIV_CLKLOW_SHIFT)); + BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = 0; + BFIN_REG16(base, TWI_MASTER_CTL_OFFSET) = config->fast ? + TWI_MASTER_CTL_FAST : + 0; + BFIN_REG16(base, TWI_SLAVE_ADDR_OFFSET) = (uint16_t) config->slave_address << + TWI_SLAVE_ADDR_SADDR_SHIFT; + BFIN_REG16(base, TWI_MASTER_STAT_OFFSET) = TWI_MASTER_STAT_BUFWRERR | + TWI_MASTER_STAT_BUFRDERR | + TWI_MASTER_STAT_DNAK | + TWI_MASTER_STAT_ANAK | + TWI_MASTER_STAT_LOSTARB; + BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = TWI_FIFO_CTL_XMTFLUSH | + TWI_FIFO_CTL_RCVFLUSH; + BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = 0; + BFIN_REG16(base, TWI_INT_STAT_OFFSET) = TWI_INT_STAT_RCVSERV | + TWI_INT_STAT_XMTSERV | + TWI_INT_STAT_MERR | + TWI_INT_STAT_MCOMP | + TWI_INT_STAT_SOVF | + TWI_INT_STAT_SERR | + TWI_INT_STAT_SCOMP | + TWI_INT_STAT_SINIT; + BFIN_REG16(base, TWI_INT_MASK_OFFSET) = TWI_INT_MASK_RCVSERVM | + TWI_INT_MASK_XMTSERVM; + + return result; +} + +rtems_status_code bfin_twi_register_callback(int channel, + bfin_twi_callback_t callback, + void *arg) { + void *base; + int level; + + if (channel < 0 || channel >= N_BFIN_TWI) + return RTEMS_INVALID_NUMBER; + + base = twi[channel].base; + if (callback == NULL) + BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = 0; + rtems_interrupt_disable(level); + twi[channel].callback = callback; + twi[channel].callbackArg = arg; + rtems_interrupt_enable(level); + if (callback != NULL) + BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = TWI_SLAVE_CTL_GEN | + TWI_SLAVE_CTL_SEN; + + return RTEMS_SUCCESSFUL; +} + +void bfin_twi_isr(int source) { + void *base; + int i; + uint16_t r; + uint16_t stat; + uint8_t data; + + for (i = 0; i < N_BFIN_TWI; i++) { + base = twi[i].base; + if (base) { + stat = BFIN_REG16(base, TWI_INT_STAT_OFFSET); + if (stat) { + BFIN_REG16(base, TWI_INT_STAT_OFFSET) = stat; + if ((stat & TWI_INT_STAT_SINIT) && !twi[i].slaveActive) { + twi[i].slaveActive = TRUE; + r = BFIN_REG16(base, TWI_FIFO_CTL_OFFSET); + BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r | TWI_FIFO_CTL_XMTFLUSH; + BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r; + r = BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET); + BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = r | TWI_SLAVE_CTL_STDVAL; + } + if (twi[i].slaveActive) { + + + if (stat & (TWI_INT_STAT_SCOMP | TWI_INT_STAT_SERR)) { + + + r = BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET); + BFIN_REG16(base, TWI_SLAVE_CTL_OFFSET) = r & ~TWI_SLAVE_CTL_STDVAL; + twi[i].slaveActive = FALSE; + + + } + } + if (twi[i].masterActive && !twi[i].slaveActive) { + + + if (stat & (TWI_INT_STAT_MCOMP | TWI_INT_STAT_MERR)) { + if (!(stat & TWI_INT_STAT_MERR)) { + + + rtems_semaphore_release(twi[i].irqSem); + + + } else + rtems_semaphore_release(twi[i].irqSem); + } + } + } + } + } +} + +rtems_status_code bfin_twi_request(int channel, uint8_t address, + bfin_twi_request_t *request, + rtems_interval timeout) { + rtems_status_code result; + void *base; + rtems_interrupt_level level; + uint16_t r; + uint16_t masterMode; + + if (channel < 0 || channel >= N_BFIN_TWI) + return RTEMS_INVALID_NUMBER; + result = rtems_semaphore_obtain(twi[channel].mutex, + RTEMS_WAIT, RTEMS_NO_TIMEOUT); + if (result == RTEMS_SUCCESSFUL) { + base = twi[channel].base; + twi[channel].req = request; + + if (request->write) { + twi[channel].dataPtr = request->data; + twi[channel].count = request->count; + } else + twi[channel].count = 0; + + BFIN_REG16(base, TWI_MASTER_ADDR_OFFSET) = (uint16_t) address << + TWI_MASTER_ADDR_MADDR_SHIFT; + masterMode = BFIN_REG16(base, TWI_MASTER_CTL_OFFSET); + masterMode |= (request->count << TWI_MASTER_CTL_DCNT_SHIFT); + if (request->next) + masterMode |= TWI_MASTER_CTL_RSTART; + if (!request->write) + masterMode |= TWI_MASTER_CTL_MDIR; + masterMode |= TWI_MASTER_CTL_MEN; + rtems_interrupt_disable(level); + if (!twi[channel].slaveActive) { + r = BFIN_REG16(base, TWI_FIFO_CTL_OFFSET); + BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r | TWI_FIFO_CTL_XMTFLUSH; + BFIN_REG16(base, TWI_FIFO_CTL_OFFSET) = r; + if (request->write) { + while (twi[channel].count && + (BFIN_REG16(base, TWI_FIFO_STAT_OFFSET) & + TWI_FIFO_STAT_XMTSTAT_MASK) != + TWI_FIFO_STAT_XMTSTAT_FULL) { + BFIN_REG16(base, TWI_XMT_DATA8_OFFSET) = + (uint16_t) *twi[channel].dataPtr++; + twi[channel].count--; + } + } + twi[channel].masterActive = TRUE; + BFIN_REG16(base, TWI_MASTER_CTL_OFFSET) = masterMode; + } else { + twi[channel].masterActive = FALSE; + twi[channel].masterResult = -1; /* BISON (code should be equiv to lost arbitration) */ + } + rtems_interrupt_enable(level); + while (result == RTEMS_SUCCESSFUL && twi[channel].masterActive) + result = rtems_semaphore_obtain(twi[channel].irqSem, + RTEMS_WAIT, timeout); + if (result == RTEMS_SUCCESSFUL) + result = twi[channel].masterResult; + else { + /* BISON abort */ + + + + } + rtems_semaphore_release(twi[channel].mutex); + } + return result; +} + diff --git a/c/src/lib/libcpu/bfin/serial/twi.h b/c/src/lib/libcpu/bfin/serial/twi.h new file mode 100644 index 0000000000..ca8a4a393b --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/twi.h @@ -0,0 +1,70 @@ +/* not yet implemented */ + +/* + * RTEMS driver for Blackfin TWI (I2C) + * + * COPYRIGHT (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _twi_h_ +#define _twi_h_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + uint32_t sclk; + void *base; + boolean fast; + int8_t slave_address; +} bfin_twi_config_t; + +typedef struct bfin_twi_request_s { + boolean write; + int count; + void *data; + /* Chained requests are done with repeated start conditions in between. + These are useful for atomic address write/data read transactions + (which can be important in multi-master configurations), and for + doing 10-bit addressing. */ + struct bfin_twi_request_s *next; +} bfin_twi_request_t; + +typedef rtems_status_code (*bfin_twi_callback_t)(int channel, + void *arg, + boolean general_call, + boolean write, + boolean done, + int read_count, + uint8_t *data); + + +rtems_status_code bfin_twi_init(int channel, bfin_twi_config_t *config); + +rtems_status_code bfin_twi_register_callback(int channel, + bfin_twi_callback_t callback, + void *arg); + +void bfin_twi_isr(int source); + +rtems_status_code bfin_twi_request(int channel, uint8_t address, + bfin_twi_request_t *request, + rtems_interval timeout); + + +#ifdef __cplusplus +} +#endif + +#endif /* _twi_h_ */ + diff --git a/c/src/lib/libcpu/bfin/serial/uart.c b/c/src/lib/libcpu/bfin/serial/uart.c new file mode 100644 index 0000000000..8637830e61 --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/uart.c @@ -0,0 +1,412 @@ +/* UART driver for Blackfin + * + * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 +#include +#include +#include +#include + +#include +#include "uart.h" + + +/* flags */ +#define BFIN_UART_XMIT_BUSY 0x01 + + +static bfin_uart_config_t *uartsConfig; + + +static void initializeHardware(int minor) { + uint16_t divisor; + char *base; + uint16_t r; + + base = uartsConfig->channels[minor].base_address; + + *(uint16_t volatile *) (base + UART_IER_OFFSET) = 0; + + if (uartsConfig->channels[minor].force_baud) + divisor = (uint16_t) (uartsConfig->freq / + (uartsConfig->channels[minor].force_baud * 16)); + else + divisor = (uint16_t) (uartsConfig->freq / (9600 * 16)); + *(uint16_t volatile *) (base + UART_LCR_OFFSET) = UART_LCR_DLAB; + *(uint16_t volatile *) (base + UART_DLL_OFFSET) = (divisor & 0xff); + *(uint16_t volatile *) (base + UART_DLH_OFFSET) = ((divisor >> 8) & 0xff); + + *(uint16_t volatile *) (base + UART_LCR_OFFSET) = UART_LCR_WLS_8; + + *(uint16_t volatile *) (base + UART_GCTL_OFFSET) = UART_GCTL_UCEN; + + r = *(uint16_t volatile *) (base + UART_LSR_OFFSET); + r = *(uint16_t volatile *) (base + UART_RBR_OFFSET); + r = *(uint16_t volatile *) (base + UART_IIR_OFFSET); + + return; +} + +static int pollRead(int minor) { + int c; + char *base; + + base = uartsConfig->channels[minor].base_address; + + /* check to see if driver is using interrupts so this call will be + harmless (though non-functional) in case some debug code tries to + use it */ + if (!uartsConfig->channels[minor].use_interrupts && + *((uint16_t volatile *) (base + UART_LSR_OFFSET)) & UART_LSR_DR) + c = *((uint16_t volatile *) (base + UART_RBR_OFFSET)); + else + c = -1; + + return c; +} + +char bfin_uart_poll_read(int minor) { + int c; + + do { + c = pollRead(minor); + } while (c == -1); + + return c; +} + +void bfin_uart_poll_write(int minor, char c) { + char *base; + + base = uartsConfig->channels[minor].base_address; + + while (!(*((uint16_t volatile *) (base + UART_LSR_OFFSET)) & UART_LSR_THRE)) + ; + *(uint16_t volatile *) (base + UART_THR_OFFSET) = c; +} + +/* begin BISON */ +void debug_write_char(char c) { + bfin_uart_poll_write(0, c); +} + +void debug_write_string(char *s) { + + while (s && *s) { + if (*s == '\n') + debug_write_char('\r'); + debug_write_char(*s++); + } +} + +void debug_write_crlf(void) { + + debug_write_char('\r'); + debug_write_char('\n'); +} + +void debug_write_nybble(int nybble) { + + nybble &= 0x0f; + debug_write_char((nybble > 9) ? 'a' + (nybble - 10) : '0' + nybble); +} + +void debug_write_byte(int byte) { + + byte &= 0xff; + debug_write_nybble(byte >> 4); + debug_write_nybble(byte & 0x0f); +} + +void debug_write_half(int half) { + + half &= 0xffff; + debug_write_byte(half >> 8); + debug_write_byte(half & 0xff); +} + +void debug_write_word(int word) { + + word &= 0xffffffff; + debug_write_half(word >> 16); + debug_write_half(word & 0xffff); +} +/* end BISON */ + +/* + * Console Termios Support Entry Points + * + */ + +static int pollWrite(int minor, const char *buf, int len) { + + while (len-- > 0) + bfin_uart_poll_write(minor, *buf++); + + return 0; +} + +static void enableInterrupts(int minor) { + char *base; + + base = uartsConfig->channels[minor].base_address; + + *(uint16_t volatile *) (base + UART_IER_OFFSET) = UART_IER_ETBEI | + UART_IER_ERBFI; +} + +static void disableAllInterrupts(void) { + int i; + char *base; + + for (i = 0; i < uartsConfig->num_channels; i++) { + base = uartsConfig->channels[i].base_address; + *(uint16_t volatile *) (base + UART_IER_OFFSET) = 0; + } +} + +static int interruptWrite(int minor, const char *buf, int len) { + char *base; + + base = uartsConfig->channels[minor].base_address; + + uartsConfig->channels[minor].flags |= BFIN_UART_XMIT_BUSY; + *(uint16_t volatile *) (base + UART_THR_OFFSET) = *buf; + + return 0; +} + +static int setAttributes(int minor, const struct termios *termios) { + char *base; + int baud; + uint16_t divisor; + uint16_t lcr; + + base = uartsConfig->channels[minor].base_address; + switch (termios->c_cflag & CBAUD) { + case B0: + baud = 0; + break; + case B50: + baud = 50; + break; + case B75: + baud = 75; + break; + case B110: + baud = 110; + break; + case B134: + baud = 134; + break; + case B150: + baud = 150; + break; + case B200: + baud = 200; + break; + case B300: + baud = 300; + break; + case B600: + baud = 600; + break; + case B1200: + baud = 1200; + break; + case B1800: + baud = 1800; + break; + case B2400: + baud = 2400; + break; + case B4800: + baud = 4800; + break; + case B9600: + baud = 9600; + break; + case B19200: + baud = 19200; + break; + case B38400: + baud = 38400; + break; + case B57600: + baud = 57600; + break; + case B115200: + baud = 115200; + break; + case B230400: + baud = 230400; + break; + case B460800: + baud = 460800; + break; + default: + baud = -1; + break; + } + if (baud > 0 && uartsConfig->channels[minor].force_baud) + baud = uartsConfig->channels[minor].force_baud; + switch (termios->c_cflag & CSIZE) { + case CS5: + lcr = UART_LCR_WLS_5; + break; + case CS6: + lcr = UART_LCR_WLS_6; + break; + case CS7: + lcr = UART_LCR_WLS_7; + break; + case CS8: + default: + lcr = UART_LCR_WLS_8; + break; + } + switch (termios->c_cflag & (PARENB | PARODD)) { + case PARENB: + lcr |= UART_LCR_PEN | UART_LCR_EPS; + break; + case PARENB | PARODD: + lcr |= UART_LCR_PEN; + break; + default: + break; + } + if (termios->c_cflag & CSTOPB) + lcr |= UART_LCR_STB; + + if (baud > 0) { + divisor = (uint16_t) (uartsConfig->freq / (baud * 16)); + *(uint16_t volatile *) (base + UART_LCR_OFFSET) = lcr | UART_LCR_DLAB; + *(uint16_t volatile *) (base + UART_DLL_OFFSET) = (divisor & 0xff); + *(uint16_t volatile *) (base + UART_DLH_OFFSET) = ((divisor >> 8) & 0xff); + } + *(uint16_t volatile *) (base + UART_LCR_OFFSET) = lcr; + + return 0; +} + +void bfin_uart_isr(int source) { + int i; + char *base; + uint16_t uartStat; + char c; + uint8_t uartLSR; + + /* Just use one ISR and check for all UART interrupt sources in it. + This is less efficient than making use of the vector to narrow down + the things we need to check, but not all Blackfins separate the + UART interrupt sources in the same ways. This way we don't have + to make this code dependent on the type of Blackfin. */ + for (i = 0; i < uartsConfig->num_channels; i++) { + if (uartsConfig->channels[i].use_interrupts) { + base = uartsConfig->channels[i].base_address; + uartStat = *(uint16_t volatile *) (base + UART_IIR_OFFSET); + if ((uartStat & UART_IIR_NINT) == 0) { + switch (uartStat & UART_IIR_STATUS_MASK) { + case UART_IIR_STATUS_THRE: + if (uartsConfig->channels[i].termios && + (uartsConfig->channels[i].flags & BFIN_UART_XMIT_BUSY)) { + uartsConfig->channels[i].flags &= ~BFIN_UART_XMIT_BUSY; + rtems_termios_dequeue_characters(uartsConfig->channels[i].termios, + 1); + } + break; + case UART_IIR_STATUS_RDR: + c = *(uint16_t volatile *) (base + UART_RBR_OFFSET); + if (uartsConfig->channels[i].termios) + rtems_termios_enqueue_raw_characters( + uartsConfig->channels[i].termios, &c, 1); + break; + case UART_IIR_STATUS_LS: + uartLSR = *(uint16_t volatile *) (base + UART_LSR_OFFSET); + /* break, framing error, parity error, or overrun error + has been detected */ + break; + default: + break; + } + } + } + } +} + +rtems_status_code bfin_uart_initialize(rtems_device_major_number major, + bfin_uart_config_t *config) { + rtems_status_code status; + int i; + + status = RTEMS_SUCCESSFUL; + + rtems_termios_initialize(); + + /* + * Register Device Names + */ + + uartsConfig = config; + for (i = 0; i < config->num_channels; i++) { + config->channels[i].termios = NULL; + config->channels[i].flags = 0; + initializeHardware(i); + status = rtems_io_register_name(config->channels[i].name, major, i); + } + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver bfin_uart_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) { + rtems_status_code sc; + rtems_libio_open_close_args_t *args; + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + pollRead, /* pollRead */ + pollWrite, /* write */ + setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_POLLED /* outputUsesInterrupts */ + }; + static const rtems_termios_callbacks interruptCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + interruptWrite, /* write */ + setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ + }; + + if (uartsConfig == NULL || minor < 0 || minor >= uartsConfig->num_channels) + return RTEMS_INVALID_NUMBER; + + sc = rtems_termios_open(major, minor, arg, + uartsConfig->channels[minor].use_interrupts ? + &interruptCallbacks : &pollCallbacks); + args = arg; + uartsConfig->channels[minor].termios = args->iop->data1; + + if (uartsConfig->channels[minor].use_interrupts) + enableInterrupts(minor); + atexit(disableAllInterrupts); + + return sc; +} + diff --git a/c/src/lib/libcpu/bfin/serial/uart.h b/c/src/lib/libcpu/bfin/serial/uart.h new file mode 100644 index 0000000000..dfff3cc17c --- /dev/null +++ b/c/src/lib/libcpu/bfin/serial/uart.h @@ -0,0 +1,59 @@ +/* + * RTEMS driver for Blackfin UARTs + * + * COPYRIGHT (c) 2008 Kallisti Labs, Los Gatos, CA, USA + * written by Allan Hessenflow + * + * 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 _uart_h_ +#define _uart_h_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + const char *name; + void *base_address; + boolean use_interrupts; + int force_baud; + /* the following are for internal use */ + void *termios; + uint8_t volatile flags; +} bfin_uart_channel_t; + +typedef struct { + uint32_t freq; + int num_channels; + bfin_uart_channel_t *channels; +} bfin_uart_config_t; + + +char bfin_uart_poll_read(int minor); + +void bfin_uart_poll_write(int minor, char c); + +rtems_status_code bfin_uart_initialize(rtems_device_major_number major, + bfin_uart_config_t *config); + +rtems_device_driver bfin_uart_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg); + +void bfin_uart_isr(int source); + + +#ifdef __cplusplus +} +#endif + +#endif /* _uart_h_ */ + diff --git a/c/src/lib/libcpu/bfin/timer/timer.c b/c/src/lib/libcpu/bfin/timer/timer.c new file mode 100644 index 0000000000..703c265c06 --- /dev/null +++ b/c/src/lib/libcpu/bfin/timer/timer.c @@ -0,0 +1,106 @@ +/* Timer for Blackfin + * + * 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. + * + * Copyright (c) 2006 by Atos Automacao Industrial Ltda. + * written by Alain Schaefer + * and Antonio Giovanini + * + * 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 +#include + + +uint32_t Timer_interrupts; +rtems_boolean Timer_driver_Find_average_overhead; + +/* + * Timer_initialize + * + * Blackfin processor has a counter for clock cycles. + */ +void Timer_initialize( void ) +{ + + /*reset counters*/ + asm ("R2 = 0;"); + asm ("CYCLES = R2;"); + asm ("CYCLES2 = R2;"); + /*start counters*/ + asm ("R2 = SYSCFG;"); + asm ("BITSET(R2,1);"); + asm ("SYSCFG = R2"); + +} + +/* + * 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 clicks; + uint32_t total; + register uint32_t cycles asm ("R2"); + + /* stop counter */ + asm("R2 = SYSCFG;"); + asm("BITCLR(R2,1);"); + asm("SYSCFG = R2;"); + asm("R2 = CYCLES;"); + + + clicks = cycles; /* Clock cycles */ + + /* converting to microseconds */ + total = clicks / (CCLK/1000000); + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + /* + * Somehow convert total into microseconds + */ + return (total - AVG_OVERHEAD); + } +} + +/* + * 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( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} -- cgit v1.2.3