From e2bd1f653a3bbf969962082b9ccf1e73b0879819 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 21 Mar 2018 16:38:43 +0100 Subject: bsp/bfin: Move libcpu content to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libcpu/bfin/Makefile.am | 83 -- c/src/lib/libcpu/bfin/README | 11 - c/src/lib/libcpu/bfin/bf52x/interrupt/interrupt.c | 642 ---------------- c/src/lib/libcpu/bfin/clock/clock.c | 81 -- c/src/lib/libcpu/bfin/clock/rtc.c | 258 ------- c/src/lib/libcpu/bfin/configure.ac | 35 - c/src/lib/libcpu/bfin/interrupt/interrupt.c | 196 ----- c/src/lib/libcpu/bfin/mmu/mmu.c | 44 -- c/src/lib/libcpu/bfin/network/ethernet.c | 880 ---------------------- c/src/lib/libcpu/bfin/serial/spi.c | 240 ------ c/src/lib/libcpu/bfin/serial/sport.c | 2 - c/src/lib/libcpu/bfin/serial/twi.c | 253 ------- c/src/lib/libcpu/bfin/serial/uart.c | 528 ------------- c/src/lib/libcpu/bfin/timer/timer.c | 96 --- 14 files changed, 3349 deletions(-) delete mode 100644 c/src/lib/libcpu/bfin/Makefile.am delete mode 100644 c/src/lib/libcpu/bfin/README delete mode 100644 c/src/lib/libcpu/bfin/bf52x/interrupt/interrupt.c delete mode 100644 c/src/lib/libcpu/bfin/clock/clock.c delete mode 100644 c/src/lib/libcpu/bfin/clock/rtc.c delete mode 100644 c/src/lib/libcpu/bfin/configure.ac delete mode 100644 c/src/lib/libcpu/bfin/interrupt/interrupt.c delete mode 100644 c/src/lib/libcpu/bfin/mmu/mmu.c delete mode 100644 c/src/lib/libcpu/bfin/network/ethernet.c delete mode 100644 c/src/lib/libcpu/bfin/serial/spi.c delete mode 100644 c/src/lib/libcpu/bfin/serial/sport.c delete mode 100644 c/src/lib/libcpu/bfin/serial/twi.c delete mode 100644 c/src/lib/libcpu/bfin/serial/uart.c delete mode 100644 c/src/lib/libcpu/bfin/timer/timer.c (limited to 'c/src/lib/libcpu') diff --git a/c/src/lib/libcpu/bfin/Makefile.am b/c/src/lib/libcpu/bfin/Makefile.am deleted file mode 100644 index 8d484480a9..0000000000 --- a/c/src/lib/libcpu/bfin/Makefile.am +++ /dev/null @@ -1,83 +0,0 @@ -ACLOCAL_AMFLAGS = -I ../../../aclocal - -include $(top_srcdir)/../../../automake/compile.am - -EXTRA_DIST = - -noinst_PROGRAMS = - - -############ -# Start of bf52x files -if bf52x - -## INTERRUPT -noinst_PROGRAMS += bf52x/interrupt.rel -bf52x_interrupt_rel_SOURCES = bf52x/interrupt/interrupt.c \ - bf52x/interrupt/interrupt.h -bf52x_interrupt_rel_CPPFLAGS = $(AM_CPPFLAGS) -bf52x_interrupt_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -endif -# endof bf52x -############ - -noinst_PROGRAMS += mmu.rel -mmu_rel_SOURCES = mmu/mmu.c -mmu_rel_CPPFLAGS = $(AM_CPPFLAGS) -mmu_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -if bf52x - -else -noinst_PROGRAMS += interrupt.rel -interrupt_rel_SOURCES = interrupt/interrupt.c -interrupt_rel_CPPFLAGS = $(AM_CPPFLAGS) -interrupt_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -endif - -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 clock/rtc.h -rtc_rel_CPPFLAGS = $(AM_CPPFLAGS) -rtc_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -noinst_PROGRAMS += uart.rel -uart_rel_SOURCES = serial/uart.c -uart_rel_CPPFLAGS = $(AM_CPPFLAGS) -uart_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -noinst_PROGRAMS += sport.rel -sport_rel_SOURCES = serial/sport.c -sport_rel_CPPFLAGS = $(AM_CPPFLAGS) -sport_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -noinst_PROGRAMS += spi.rel -spi_rel_SOURCES = serial/spi.c -spi_rel_CPPFLAGS = $(AM_CPPFLAGS) -spi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) - -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 -noinst_PROGRAMS += network.rel -network_rel_SOURCES = network/ethernet.c -network_rel_CPPFLAGS = $(AM_CPPFLAGS) -network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) -endif - -include $(top_srcdir)/../../../automake/local.am diff --git a/c/src/lib/libcpu/bfin/README b/c/src/lib/libcpu/bfin/README deleted file mode 100644 index da0d642edd..0000000000 --- a/c/src/lib/libcpu/bfin/README +++ /dev/null @@ -1,11 +0,0 @@ -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/sport* is currently just a 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/bf52x/interrupt/interrupt.c b/c/src/lib/libcpu/bfin/bf52x/interrupt/interrupt.c deleted file mode 100644 index 1b69046453..0000000000 --- a/c/src/lib/libcpu/bfin/bf52x/interrupt/interrupt.c +++ /dev/null @@ -1,642 +0,0 @@ -/** - *@file interrupt.c - * - *@brief - * - This file implements interrupt dispatcher. Most of the code is taken from - * the 533 implementation for blackfin. Since 52X supports 56 line and 2 ISR - * registers some portion is written twice. - * - * Target: TLL6527v1-0 - * Compiler: - * - * COPYRIGHT (c) 2010 by ECE Northeastern University. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license - * - * @author Rohan Kangralkar, ECE, Northeastern University - * (kangralkar.r@husky.neu.edu) - * - * LastChange: - */ - -#include -#include - -#include -#include -#include -#include -#include - -#define SIC_IAR_COUNT_SET0 4 -#define SIC_IAR_BASE_ADDRESS_0 0xFFC00150 - -/** - * There are two implementations for the interrupt handler. - * 1. INTERRUPT_USE_TABLE: uses tables for finding the right ISR. - * 2. Uses link list to find the user ISR. - * - * - * 1. INTERRUPT_USE_TABLE - * Space requirement: - * - Array to hold CEC masks size: CEC_INTERRUPT_COUNT(9)*(2*int).9*2*4= 72B - * - Array to hold isr function pointers IRQ_MAX(56)*sizeof(bfin_isr_t)= 896B - * - Array for bit twidlling 32 bytes. - * - Global Mask 8 bytes. - * - Total = 1008 Bytes Aprox - * - * Time requirements - * The worst case time is about the same for jumping to the user ISR. With a - * variance of one conditional statement. - * - * 2. Using link list. - * Space requirement: - * - Array to hold CEC mask CEC_INTERRUPT_COUNT(9)*(sizeof(vectors)). - * 9*3*4= 108B - * - Array to hold isr IRQ_MAX(56)*sizeof(bfin_isr_t) The structure has - * additional pointers 56*7*4=1568B - * - Global Mask 8 bytes. - * Total = 1684. - * Time requirements - * In the worst case all the lines can be on one CEC line to 56 entries have - * to be traversed to find the right user ISR. - * But this implementation has benefit of being flexible, Providing - * additional user assigned priority. and may consume less space - * if all devices are not supported. - */ - -/** - * TODO: To place the dispatcher routine code in L1. - */ - -#if INTERRUPT_USE_TABLE - - -/****************************************************************************** - * Static variables - *****************************************************************************/ -/** - * @var sic_isr0_mask - * @brief copy of the mask of SIC ISR. The SIC ISR is cleared by the device - * the relevant SIC_ISRx bit is not cleared unless the interrupt - * service routine clears the mechanism that generated interrupt - */ -static uint32_t sic_isr0_mask = 0; - -/** - * @var sic_isr0_mask - * @brief copy of the mask of SIC ISR. The SIC ISR is cleared by the device - * the relevant SIC_ISRx bit is not cleared unless the interrupt - * service routine clears the mechanism that generated interrupt - */ -static uint32_t sic_isr1_mask = 0; - - -/** - * @var sic_isr - * @brief An array of sic register mask for each of the 16 core interrupt lines - */ -static struct { - uint32_t mask0; - uint32_t mask1; -} vectors[CEC_INTERRUPT_COUNT]; - -/** - * @var ivt - * @brief Contains a table of ISR and arguments. The ISR jumps directly to - * these ISR. - */ -static bfin_isr_t ivt[IRQ_MAX]; - -/** - * http://graphics.stanford.edu/~seander/bithacks.html for more details - */ -static const char clz_table[32] = -{ - 0, 31, 9, 30, 3, 8, 18, 29, 2, 5, 7, 14, 12, 17, - 22, 28, 1, 10, 4, 19, 6, 15, 13, 23, 11, 20, 16, - 24, 21, 25, 26, 27 -}; - -/** - * finds the first bit set from the left. look at - * http://graphics.stanford.edu/~seander/bithacks.html for more details - * @param n - * @return - */ -static unsigned long clz(unsigned long n) -{ - unsigned long c = 0x7dcd629; /* magic constant... */ - - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - if (n == 0) return 32; - n = c + (c * n); - return 31 - clz_table[n >> 27]; /* For little endian */ -} - - - -/** - * Centralized Interrupt dispatcher routine. This routine dispatches interrupts - * to the user ISR. The priority is according to the blackfin SIC. - * The first level of priority is handled in the hardware at the core event - * controller. The second level of interrupt is handled according to the line - * number that goes in to the SIC. - * * SIC_0 has higher priority than SIC 1. - * * Inside the SIC the priority is assigned according to the line number. - * Lower the line number higher the priority. - * - * In order to change the interrupt priority we may - * 1. change the SIC IAR registers or - * 2. Assign priority and extract it inside this function and call the ISR - * according tot the priority. - * - * @param vector IVG number. - * @return - */ -static rtems_isr interruptHandler(rtems_vector_number vector) { - uint32_t mask = 0; - int id = 0; - /** - * Enable for debugging - * - * static volatile uint32_t spurious_sic0 = 0; - * static volatile uint32_t spurious_source = 0; - * static volatile uint32_t spurious_sic1 = 0; - */ - - /** - * Extract the vector number relative to the SIC start line - */ - vector -= CEC_INTERRUPT_BASE_VECTOR; - - /** - * Check for bounds - */ - if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) { - - /** - * Extract information and execute ISR from SIC 0 - */ - mask = *(uint32_t volatile *) SIC_ISR & - *(uint32_t volatile *) SIC_IMASK & vectors[vector].mask0; - id = clz(mask); - if ( SIC_ISR0_MAX > id ) { - /** Parameter check */ - if( NULL != ivt[id].pFunc) { - /** Call the relevant function with argument */ - ivt[id].pFunc( ivt[id].pArg ); - } else { - /** - * spurious interrupt we should not be getting this - * spurious_sic0++; - * spurious_source = id; - */ - } - } else { - /** - * we look at SIC 1 - */ - } - - - /** - * Extract information and execute ISR from SIC 1 - */ - mask = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) & - *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) & - vectors[vector].mask1; - id = clz(mask)+SIC_ISR0_MAX; - if ( IRQ_MAX > id ) { - /** Parameter Check */ - if( NULL != ivt[id].pFunc ) { - /** Call the relevant function with argument */ - ivt[id].pFunc( ivt[id].pArg ); - } else { - /** - * spurious interrupt we should not be getting this - * - * spurious_sic1++; - * spurious_source = id; - */ - } - } else { - /** - * we continue - */ - } - - } -} - - - -/** - * This routine registers a new ISR. It will write a new entry to the IVT table - * @param isr contains a callback function and source - * @return rtems status code - */ -rtems_status_code bfin_interrupt_register(bfin_isr_t *isr) { - rtems_interrupt_level isrLevel; - int id = 0; - int position = 0; - - /** - * Sanity Check - */ - if ( NULL == isr ){ - return RTEMS_UNSATISFIED; - } - - /** - * Sanity check. The register function should at least provide callback func - */ - if ( NULL == isr->pFunc ) { - return RTEMS_UNSATISFIED; - } - - id = isr->source; - - /** - * Parameter Check. We already have a function registered here. First - * unregister and then a new function can be allocated. - */ - if ( NULL != ivt[id].pFunc ) { - return RTEMS_UNSATISFIED; - } - - rtems_interrupt_disable(isrLevel); - /** - * Assign the new function pointer to the ISR Dispatcher - * */ - ivt[id].pFunc = isr->pFunc; - ivt[id].pArg = isr->pArg; - - - /** find out which isr mask has to be set to enable the interrupt */ - if ( SIC_ISR0_MAX > id ) { - sic_isr0_mask |= 0x1<source; - - rtems_interrupt_disable(isrLevel); - /** - * Assign the new function pointer to the ISR Dispatcher - * */ - ivt[id].pFunc = NULL; - ivt[id].pArg = NULL; - - - /** find out which isr mask has to be set to enable the interrupt */ - if ( SIC_ISR0_MAX > id ) { - sic_isr0_mask &= ~(0x1< i ) { - r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS + i * SIC_IAR_PITCH); - } else { - r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS_0 + - ((i-SIC_IAR_COUNT_SET0) * SIC_IAR_PITCH)); - } - - for (j = 0; j < 8; j++) { - vector = r & 0x0f; - if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) { - /* install our local handler */ - if (vectors[vector].mask0 == 0 && vectors[vector].mask1 == 0){ - set_vector(interruptHandler, vector + CEC_INTERRUPT_BASE_VECTOR, 1); - } - if ( SIC_ISR0_MAX > source ) { - vectors[vector].mask0 |= (1 << source); - } else { - vectors[vector].mask1 |= (1 << (source - SIC_ISR0_MAX)); - } - } - r >>= 4; - source++; - } - } -} - - - - - -#else - -static struct { - uint32_t mask0; - uint32_t mask1; - bfin_isr_t *head; -} vectors[CEC_INTERRUPT_COUNT]; - -static uint32_t globalMask0; -static uint32_t globalMask1; - -static rtems_isr interruptHandler(rtems_vector_number vector) { - bfin_isr_t *isr = NULL; - uint32_t sourceMask0 = 0; - uint32_t sourceMask1 = 0; - rtems_interrupt_level isrLevel; - - rtems_interrupt_disable(isrLevel); - vector -= CEC_INTERRUPT_BASE_VECTOR; - if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) { - isr = vectors[vector].head; - sourceMask0 = *(uint32_t volatile *) SIC_ISR & - *(uint32_t volatile *) SIC_IMASK; - sourceMask1 = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) & - *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH); - while (isr) { - if ((sourceMask0 & isr->mask0) || (sourceMask1 & isr->mask1)) { - isr->isr(isr->_arg); - sourceMask0 = *(uint32_t volatile *) SIC_ISR & - *(uint32_t volatile *) SIC_IMASK; - sourceMask1 = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) & - *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH); - } - isr = isr->next; - } - } - rtems_interrupt_enable(isrLevel); -} - -/** - * Initializes the interrupt module - */ -void bfin_interrupt_init(void) { - int source; - int vector; - uint32_t r; - int i; - int j; - - globalMask0 = ~(uint32_t) 0; - globalMask1 = ~(uint32_t) 0; - *(uint32_t volatile *) SIC_IMASK = 0; - *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) = 0; - - memset(vectors, 0, sizeof(vectors)); - /* build mask0 showing what SIC sources drive each CEC vector */ - source = 0; - - /** - * The bf52x has 8 IAR registers but they do not have a constant pitch. - * - */ - for (i = 0; i < SIC_IAR_COUNT; i++) { - if ( SIC_IAR_COUNT_SET0 > i ) { - r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS + i * SIC_IAR_PITCH); - } else { - r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS_0 + - ((i-SIC_IAR_COUNT_SET0) * SIC_IAR_PITCH)); - } - for (j = 0; j < 8; j++) { - vector = r & 0x0f; - if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) { - /* install our local handler */ - if (vectors[vector].mask0 == 0 && vectors[vector].mask1 == 0){ - set_vector(interruptHandler, vector + CEC_INTERRUPT_BASE_VECTOR, 1); - } - if ( SIC_ISR0_MAX > source ) { - vectors[vector].mask0 |= (1 << source); - } else { - vectors[vector].mask1 |= (1 << (source - SIC_ISR0_MAX)); - } - } - r >>= 4; - source++; - } - } -} - -/* modify SIC_IMASK based on ISR list for a particular CEC vector */ -static void setMask(uint32_t vector) { - bfin_isr_t *isr = NULL; - uint32_t mask = 0; - uint32_t r = 0; - - mask = 0; - isr = vectors[vector].head; - while (isr) { - mask |= isr->mask0; - isr = isr->next; - } - r = *(uint32_t volatile *) SIC_IMASK; - r &= ~vectors[vector].mask0; - r |= mask; - r &= globalMask0; - *(uint32_t volatile *) SIC_IMASK = r; - - - mask = 0; - isr = vectors[vector].head; - while (isr) { - mask |= isr->mask1; - isr = isr->next; - } - r = *(uint32_t volatile *) (SIC_IMASK+ SIC_IMASK_PITCH); - r &= ~vectors[vector].mask1; - r |= mask; - r &= globalMask1; - *(uint32_t volatile *) (SIC_IMASK+ SIC_IMASK_PITCH) = r; -} - -/* add an ISR to the list for whichever vector it belongs to */ -rtems_status_code 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].mask0 & (1 << isr->source) ) || \ - (vectors[isr->vector].mask1 & (1 << (isr->source - SIC_ISR0_MAX)) )) - break; - if (isr->vector < CEC_INTERRUPT_COUNT) { - isr->next = NULL; - isr->mask0 = 0; - isr->mask1 = 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; - return RTEMS_SUCCESSFUL; -} - -rtems_status_code 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); - return RTEMS_SUCCESSFUL; -} - -void bfin_interrupt_enable(bfin_isr_t *isr, bool enable) { - rtems_interrupt_level isrLevel; - - rtems_interrupt_disable(isrLevel); - if ( SIC_ISR0_MAX > isr->source ) { - isr->mask0 = enable ? (1 << isr->source) : 0; - *(uint32_t volatile *) SIC_IMASK |= isr->mask0; - } else { - isr->mask1 = enable ? (1 << (isr->source - SIC_ISR0_MAX)) : 0; - *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) |= isr->mask1; - } - - //setMask(isr->vector); - rtems_interrupt_enable(isrLevel); -} - -void bfin_interrupt_enable_all(int source, bool enable) { - rtems_interrupt_level isrLevel; - int vector; - bfin_isr_t *walk; - - for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++) - if ( (vectors[vector].mask0 & (1 << source) ) || \ - (vectors[vector].mask1 & (1 << (source - SIC_ISR0_MAX)) )) - break; - if (vector < CEC_INTERRUPT_COUNT) { - rtems_interrupt_disable(isrLevel); - walk = vectors[vector].head; - while (walk) { - walk->mask0 = enable ? (1 << source) : 0; - walk = walk->next; - } - - walk = vectors[vector].head; - while (walk) { - walk->mask1 = enable ? (1 << (source - SIC_ISR0_MAX)) : 0; - walk = walk->next; - } - setMask(vector); - rtems_interrupt_enable(isrLevel); - } -} - -void bfin_interrupt_enable_global(int source, bool enable) { - int vector; - rtems_interrupt_level isrLevel; - - for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++) - if ( (vectors[vector].mask0 & (1 << source) ) || \ - (vectors[vector].mask1 & (1 << (source - SIC_ISR0_MAX)) )) - break; - if (vector < CEC_INTERRUPT_COUNT) { - rtems_interrupt_disable(isrLevel); - if ( SIC_ISR0_MAX > source ) { - if (enable) - globalMask0 |= 1 << source; - else - globalMask0 &= ~(1 << source); - }else { - if (enable) - globalMask1 |= 1 << (source - SIC_ISR0_MAX); - else - globalMask1 &= ~(1 << (source - SIC_ISR0_MAX)); - } - setMask(vector); - rtems_interrupt_enable(isrLevel); - } -} - -#endif diff --git a/c/src/lib/libcpu/bfin/clock/clock.c b/c/src/lib/libcpu/bfin/clock/clock.c deleted file mode 100644 index d46ab3581e..0000000000 --- a/c/src/lib/libcpu/bfin/clock/clock.c +++ /dev/null @@ -1,81 +0,0 @@ -/* 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.org/license/LICENSE. - */ - - -#include -#include -#include -#include -#include -#include - - -#include -#include - -#if (BFIN_ON_SKYEYE) -#define CLOCK_DRIVER_USE_FAST_IDLE 1 -#endif - -volatile uint32_t Clock_driver_ticks; - -void Clock_exit(void); - -static rtems_isr clockISR(rtems_vector_number vector) { - - Clock_driver_ticks += 1; - -#if CLOCK_DRIVER_USE_FAST_IDLE - do { - rtems_clock_tick(); - } while ( _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle ); -#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. - */ -void Clock_exit(void) -{ - *(uint32_t volatile *) TCNTL = 0; -} - -/* - * Clock_initialize - * - * This routine initializes the clock driver. - */ -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); - - return RTEMS_SUCCESSFUL; -} diff --git a/c/src/lib/libcpu/bfin/clock/rtc.c b/c/src/lib/libcpu/bfin/clock/rtc.c deleted file mode 100644 index fa340a3c45..0000000000 --- a/c/src/lib/libcpu/bfin/clock/rtc.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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.org/license/LICENSE. - */ - - -#include -#include -#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 */ -} - -/* - * 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_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( - const 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 = { 0, 0, 0 }; - 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; - - (void) 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)); -} - -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( RTC_DEVICE_NAME, major, 0 ); - if (status != RTEMS_SUCCESSFUL) { - rtems_fatal_error_occurred(status); - } - - Init_RTC(); - - setRealTimeToRTEMS(); - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver rtc_read( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - rtems_libio_rw_args_t *rw = arg; - rtems_time_of_day *tod = (rtems_time_of_day *) rw->buffer; - - rw->offset = 0; - rw->bytes_moved = 0; - - if (rw->count != sizeof( rtems_time_of_day)) { - return RTEMS_INVALID_SIZE; - } - - getRealTime( tod); - - rw->bytes_moved = rw->count; - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver rtc_write( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - int rv = 0; - rtems_libio_rw_args_t *rw = arg; - const rtems_time_of_day *tod = (const rtems_time_of_day *) rw->buffer; - - rw->offset = 0; - rw->bytes_moved = 0; - - if (rw->count != sizeof( rtems_time_of_day)) { - return RTEMS_INVALID_SIZE; - } - - rv = setRealTime( tod); - if (rv != 0) { - return RTEMS_IO_ERROR; - } - - rw->bytes_moved = rw->count; - - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver rtc_open( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver rtc_close( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return RTEMS_SUCCESSFUL; -} - -rtems_device_driver rtc_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg -) -{ - return RTEMS_NOT_IMPLEMENTED; -} diff --git a/c/src/lib/libcpu/bfin/configure.ac b/c/src/lib/libcpu/bfin/configure.ac deleted file mode 100644 index 4330957698..0000000000 --- a/c/src/lib/libcpu/bfin/configure.ac +++ /dev/null @@ -1,35 +0,0 @@ -## Process this file with autoconf to produce a configure script. - -AC_PREREQ([2.69]) -AC_INIT([rtems-c-src-lib-libcpu-bfin],[_RTEMS_VERSION],[https://devel.rtems.org/newticket]) -RTEMS_TOP([../../../../..],[../../..]) -RTEMS_SOURCE_TOP -RTEMS_BUILD_TOP - -RTEMS_CANONICAL_TARGET_CPU - -AM_INIT_AUTOMAKE([no-define foreign subdir-objects 1.12.2]) -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") - -# AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "bf52x") -AM_CONDITIONAL(bf52x, test "$RTEMS_CPU_MODEL" = "bf52x") - - -RTEMS_AMPOLISH3 - -# Explicitly list all Makefiles here -AC_CONFIG_FILES([Makefile -]) -AC_OUTPUT diff --git a/c/src/lib/libcpu/bfin/interrupt/interrupt.c b/c/src/lib/libcpu/bfin/interrupt/interrupt.c deleted file mode 100644 index 7fe1eb19f7..0000000000 --- a/c/src/lib/libcpu/bfin/interrupt/interrupt.c +++ /dev/null @@ -1,196 +0,0 @@ -/* 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.org/license/LICENSE. - */ - - -#include -#include - -#include -#include -#include -#include -#include - - -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, bool 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, bool 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, bool 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/mmu/mmu.c b/c/src/lib/libcpu/bfin/mmu/mmu.c deleted file mode 100644 index bf3311b5b4..0000000000 --- a/c/src/lib/libcpu/bfin/mmu/mmu.c +++ /dev/null @@ -1,44 +0,0 @@ -/* 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.org/license/LICENSE. - */ - - -#include - -#include -#include - -/* 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; - } - *(uint32_t volatile *) IMEM_CONTROL |= IMEM_CONTROL_ENICPLB; - 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; - } - *(uint32_t volatile *) DMEM_CONTROL |= DMEM_CONTROL_ENDCPLB; -} - diff --git a/c/src/lib/libcpu/bfin/network/ethernet.c b/c/src/lib/libcpu/bfin/network/ethernet.c deleted file mode 100644 index f08ffdd63b..0000000000 --- a/c/src/lib/libcpu/bfin/network/ethernet.c +++ /dev/null @@ -1,880 +0,0 @@ -/* - * 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.org/license/LICENSE. - * - */ - -#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#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; - bool 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; - - bool 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_bsdnet_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_bsdnet_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 bool txFree(struct bfin_ethernetSoftc *sc, int index) { - bool 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 = (int) 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_bsdnet_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; - - sc = arg; - ifp = &sc->arpcom.ac_if; - ethBase = sc->ethBase; - - 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/serial/spi.c b/c/src/lib/libcpu/bfin/serial/spi.c deleted file mode 100644 index e1024e8d10..0000000000 --- a/c/src/lib/libcpu/bfin/serial/spi.c +++ /dev/null @@ -1,240 +0,0 @@ -/* SPI driver for Blackfin - * - * Copyright (c) 2010 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.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifndef BFIN_REG16 -#define BFIN_REG16(base, offset) \ - (*((uint16_t volatile *) ((uint8_t *)(base) + (offset)))) -#endif - - -static bfin_spi_state_t *bfin_spi; - - -void bfin_spi_isr(int v) { - bfin_spi_state_t *state; - uint16_t r; - - state = bfin_spi; - if (state->len > state->bytes_per_word) { - if (state->wr_ptr) { - if (state->bytes_per_word == 2) - r = *(uint16_t *) state->wr_ptr; - else - r = (uint16_t) *state->wr_ptr; - state->wr_ptr += state->bytes_per_word; - } else - r = state->idle_pattern; - BFIN_REG16(state->base, SPI_TDBR_OFFSET) = r; - } - state->len -= state->bytes_per_word; - if (state->len <= 0) { - /* - The transfers are done, so I don't want to kick off another - transfer or get any more interrupts. Reading the last word from - SPI_SHADOW instead of SPI_RDBR should prevent it from triggering - another transfer, but that doesn't clear the interrupt flag. I - could mask the interrupt in the SIC, but that would preclude ever - using the DMA channel that shares the interrupt independently (and - they might just share it with something more important in some other - member of the Blackfin family). And who knows what problems it - might cause in this code potentially dealing with that still pended - interrupt at the beginning of the next transfer. - - So instead I disable the SPI interface, read the data from RDBR - (thus clearing the interrupt but not triggering another transfer - since the interface is disabled), then re-eanble the interface. - This has the problem that the bf537 tri-states the SPI signals - while the interface is disabled. Either adding pull-ups on at - least the chip select signals, or using GPIOs for them so they're - not controlled by the SPI module, would be correct fixes for that - (really pull-ups/downs should be added to the SPI CLK and MOSI - signals as well to insure they cannot float into some region that - causes input structures to consume excessive power). Or they can - all be left alone, assuming that there's enough capacitance on the - lines to prevent any problems for the short time they're being left - disabled. - - An alternative approach I attempted involved switching TIMOD - between RDBR and TDBR when starting and finishing a transfer, but - I didn't get anywhere with that. In my limited testing TIMOD TDBR - wasn't behaving as I expected it to, but maybe with more - experimentation I'd find some solution there. However I'm out - of time for this project, at least for now. - */ - - BFIN_REG16(state->base, SPI_CTL_OFFSET) &= ~SPI_CTL_SPE; - r = BFIN_REG16(state->base, SPI_RDBR_OFFSET); - BFIN_REG16(state->base, SPI_CTL_OFFSET) |= SPI_CTL_SPE; - rtems_semaphore_release(state->sem); - } else - r = BFIN_REG16(state->base, SPI_RDBR_OFFSET); - - if (state->rd_ptr) { - if (state->bytes_per_word == 2) - *(uint16_t *) state->rd_ptr = r; - else - *state->rd_ptr = (uint8_t) r; - state->rd_ptr += state->bytes_per_word; - } -} - -static rtems_status_code setTFRMode(rtems_libi2c_bus_t *bus, - const rtems_libi2c_tfr_mode_t *tfrMode) { - rtems_status_code result; - bfin_spi_state_t *state; - uint32_t divisor; - uint16_t ctrl; - - result = RTEMS_SUCCESSFUL; - state = &((bfin_spi_bus_t *) bus)->p; - - if (result == RTEMS_SUCCESSFUL) { - if (tfrMode->bits_per_char != 8 && - tfrMode->bits_per_char != 16) - result = RTEMS_INVALID_NUMBER; - if (tfrMode->baudrate <= 0) - result = RTEMS_INVALID_NUMBER; - } - if (result == RTEMS_SUCCESSFUL) { - divisor = (SCLK / 2 + tfrMode->baudrate - 1) / - tfrMode->baudrate; - if (divisor < 2) - divisor = 2; - else if (divisor > 65535) - result = RTEMS_INVALID_NUMBER; - } - if (result == RTEMS_SUCCESSFUL) { - state->idle_pattern = (uint16_t) tfrMode->idle_char; - state->bytes_per_word = (tfrMode->bits_per_char > 8) ? 2 : 1; - BFIN_REG16(state->base, SPI_BAUD_OFFSET) = divisor; - ctrl = BFIN_REG16(state->base, SPI_CTL_OFFSET); - if (tfrMode->lsb_first) - ctrl |= SPI_CTL_LSBF; - else - ctrl &= ~SPI_CTL_LSBF; - if (tfrMode->bits_per_char > 8) - ctrl |= SPI_CTL_SIZE; - else - ctrl &= ~SPI_CTL_SIZE; - if (tfrMode->clock_inv) - ctrl |= SPI_CTL_CPOL; - else - ctrl &= ~SPI_CTL_CPOL; - if (tfrMode->clock_phs) - ctrl |= SPI_CTL_CPHA; - else - ctrl &= ~SPI_CTL_CPHA; - BFIN_REG16(state->base, SPI_CTL_OFFSET) = ctrl; - } - - return result; -} - -static int readWrite(rtems_libi2c_bus_t *bus, uint8_t *rdBuf, - const uint8_t *wrBuf, int len) { - rtems_status_code result; - bfin_spi_state_t *state; - uint16_t r; - - result = RTEMS_SUCCESSFUL; - state = &((bfin_spi_bus_t *) bus)->p; - - if (len) { - state->rd_ptr = rdBuf; - state->wr_ptr = wrBuf; - state->len = len; - if (state->wr_ptr) { - if (state->bytes_per_word == 2) - r = *(uint16_t *) state->wr_ptr; - else - r = (uint16_t) *state->wr_ptr; - state->wr_ptr += state->bytes_per_word; - } else - r = state->idle_pattern; - BFIN_REG16(state->base, SPI_TDBR_OFFSET) = r; - BFIN_REG16(state->base, SPI_RDBR_OFFSET); /* trigger */ - /* wait until done */ - do { - result = rtems_semaphore_obtain(state->sem, RTEMS_WAIT, 100); - } while (result == RTEMS_SUCCESSFUL && state->len > 0); - } - - return (result == RTEMS_SUCCESSFUL) ? len : -result; -} - - -rtems_status_code bfin_spi_init(rtems_libi2c_bus_t *bus) { - rtems_status_code result; - bfin_spi_state_t *state; - - state = &((bfin_spi_bus_t *) bus)->p; - - BFIN_REG16(state->base, SPI_CTL_OFFSET) = SPI_CTL_SPE | - SPI_CTL_MSTR | - SPI_CTL_CPHA | - SPI_CTL_TIMOD_RDBR; - - result = rtems_semaphore_create(rtems_build_name('s','p','i','s'), - 0, - RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, - 0, - &state->sem); - if (result == RTEMS_SUCCESSFUL) - bfin_spi = state; /* for isr */ - - return result; -} - -rtems_status_code bfin_spi_send_start(rtems_libi2c_bus_t *bus) { - - return RTEMS_SUCCESSFUL; -} - -int bfin_spi_read_bytes(rtems_libi2c_bus_t *bus, unsigned char *buf, int len) { - - return readWrite(bus, buf, NULL, len); -} - -int bfin_spi_write_bytes(rtems_libi2c_bus_t *bus, unsigned char *buf, int len) { - - return readWrite(bus, NULL, buf, len); -} - -int bfin_spi_ioctl(rtems_libi2c_bus_t *bus, int cmd, void *arg) { - int result; - - result = -RTEMS_NOT_DEFINED; - switch(cmd) { - case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: - result = -setTFRMode(bus, (const rtems_libi2c_tfr_mode_t *) arg); - break; - case RTEMS_LIBI2C_IOCTL_READ_WRITE: - result = readWrite(bus, - ((rtems_libi2c_read_write_t *) arg)->rd_buf, - ((rtems_libi2c_read_write_t *) arg)->wr_buf, - ((rtems_libi2c_read_write_t *) arg)->byte_cnt); - break; - default: - break; - } - - return result; -} - diff --git a/c/src/lib/libcpu/bfin/serial/sport.c b/c/src/lib/libcpu/bfin/serial/sport.c deleted file mode 100644 index 6ed481b593..0000000000 --- a/c/src/lib/libcpu/bfin/serial/sport.c +++ /dev/null @@ -1,2 +0,0 @@ -/* placeholder */ - diff --git a/c/src/lib/libcpu/bfin/serial/twi.c b/c/src/lib/libcpu/bfin/serial/twi.c deleted file mode 100644 index 0d6e6ca0b1..0000000000 --- a/c/src/lib/libcpu/bfin/serial/twi.c +++ /dev/null @@ -1,253 +0,0 @@ -/* 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.org/license/LICENSE. - */ - - -#include -#include - -#include -#include - - -#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; - bool volatile masterActive; - rtems_status_code volatile masterResult; - bool 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; - - 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/uart.c b/c/src/lib/libcpu/bfin/serial/uart.c deleted file mode 100644 index 18a522e121..0000000000 --- a/c/src/lib/libcpu/bfin/serial/uart.c +++ /dev/null @@ -1,528 +0,0 @@ -/* 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.org/license/LICENSE. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -/* flags */ -#define BFIN_UART_XMIT_BUSY 0x01 - -static bfin_uart_config_t *uartsConfig; - -static int pollRead(int minor) -{ - int c; - uint32_t base; - - base = uartsConfig->channels[minor].uart_baseAddress; - - /* 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].uart_useInterrupts && - *((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(rtems_device_minor_number minor) -{ - int c; - - do { - c = pollRead(minor); - } while (c == -1); - - return c; -} - -void bfin_uart_poll_write(int minor, char c) -{ - uint32_t base; - - base = uartsConfig->channels[minor].uart_baseAddress; - - while (!(*((uint16_t volatile *) (base + UART_LSR_OFFSET)) & UART_LSR_THRE)) - ; - *(uint16_t volatile *) (base + UART_THR_OFFSET) = c; -} - -/* - * Console Termios Support Entry Points - * - */ - -static ssize_t pollWrite(int minor, const char *buf, size_t len) -{ - size_t count; - for ( count = 0; count < len; count++ ) - bfin_uart_poll_write(minor, *buf++); - - return count; -} - -/** - * Routine to initialize the hardware. It initialize the DMA, - * interrupt if required. - * @param channel channel information - */ -static void initializeHardware(bfin_uart_channel_t *channel) -{ - uint16_t divisor = 0; - uint32_t base = 0; - uint32_t tx_dma_base = 0; - - if ( NULL == channel ) { - return; - } - - base = channel->uart_baseAddress; - tx_dma_base = channel->uart_txDmaBaseAddress; - /** - * RX based DMA and interrupt is not supported yet - * uint32_t tx_dma_base = 0; - * - * rx_dma_base = channel->uart_rxDmaBaseAddress; - */ - - - *(uint16_t volatile *) (base + UART_IER_OFFSET) = 0; - - if ( 0 != channel->uart_baud) { - divisor = (uint16_t) (uartsConfig->freq / - (channel->uart_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; - - /** - * To clear previous status - * divisor is a temp variable here - */ - divisor = *(uint16_t volatile *) (base + UART_LSR_OFFSET); - divisor = *(uint16_t volatile *) (base + UART_RBR_OFFSET); - divisor = *(uint16_t volatile *) (base + UART_IIR_OFFSET); - - if ( channel->uart_useDma ) { - *(uint16_t volatile *)(tx_dma_base + DMA_CONFIG_OFFSET) = 0; - *(uint16_t volatile *)(tx_dma_base + DMA_CONFIG_OFFSET) = DMA_CONFIG_DI_EN - | DMA_CONFIG_SYNC ; - *(uint16_t volatile *)(tx_dma_base + DMA_IRQ_STATUS_OFFSET) |= - DMA_IRQ_STATUS_DMA_DONE | DMA_IRQ_STATUS_DMA_ERR; - - } else { - /** - * We use polling or interrupts only sending one char at a time :( - */ - } -} - - -/** - * Set the UART attributes. - * @param minor - * @param termios - * @return - */ -static int setAttributes(int minor, const struct termios *termios) -{ - uint32_t base; - int baud; - uint16_t divisor; - uint16_t lcr; - - base = uartsConfig->channels[minor].uart_baseAddress; - switch (termios->c_ospeed) { - 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].uart_baud) - baud = uartsConfig->channels[minor].uart_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; - default: - case CS8: 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; -} - -/** - * Interrupt based uart tx routine. The routine writes one character at a time. - * - * @param minor Minor number to indicate uart number - * @param buf Character buffer which stores characters to be transmitted. - * @param len Length of buffer to be transmitted. - * @return - */ -static ssize_t uart_interruptWrite(int minor, const char *buf, size_t len) -{ - uint32_t base = 0; - bfin_uart_channel_t* channel = NULL; - - /** - * Sanity Check - */ - if ( - NULL == buf || NULL == channel || NULL == uartsConfig - || minor < 0 || 0 == len - ) { - return 0; - } - - channel = &(uartsConfig->channels[minor]); - - if ( NULL == channel || channel->flags & BFIN_UART_XMIT_BUSY ) { - return 0; - } - - base = channel->uart_baseAddress; - - channel->flags |= BFIN_UART_XMIT_BUSY; - channel->length = 1; - *(uint16_t volatile *) (base + UART_THR_OFFSET) = *buf; - *(uint16_t volatile *) (base + UART_IER_OFFSET) = UART_IER_ETBEI; - - return 0; -} - -/** - * This function implements RX ISR - */ -void bfinUart_rxIsr(void *_arg) -{ - /** - * TODO: UART RX ISR implementation. - */ -} - -/** - * This function implements TX ISR. The function gets called when the TX FIFO is - * empty. It clears the interrupt and dequeues the character. It only tx one - * character at a time. - * - * TODO: error handling. - * @param _arg gets the channel information. - */ -void bfinUart_txIsr(void *_arg) -{ - bfin_uart_channel_t* channel = NULL; - uint32_t base = 0; - - /** - * Sanity check - */ - if (NULL == _arg) { - /** It should never be NULL */ - return; - } - - channel = (bfin_uart_channel_t *) _arg; - - base = channel->uart_baseAddress; - - *(uint16_t volatile *) (base + UART_IER_OFFSET) &= ~UART_IER_ETBEI; - channel->flags &= ~BFIN_UART_XMIT_BUSY; - - rtems_termios_dequeue_characters(channel->termios, channel->length); -} - -/** - * interrupt based DMA write Routine. It configure the DMA to write len bytes. - * The DMA supports 64K data only. - * - * @param minor Identification number of the UART. - * @param buf Character buffer pointer - * @param len length of data items to be written - * @return data already written - */ -static ssize_t uart_DmaWrite(int minor, const char *buf, size_t len) -{ - uint32_t base = 0; - bfin_uart_channel_t* channel = NULL; - uint32_t tx_dma_base = 0; - - /** - * Sanity Check - */ - if ( NULL == buf || 0 > minor || NULL == uartsConfig || 0 == len ) { - return 0; - } - - channel = &(uartsConfig->channels[minor]); - - /** - * Sanity Check and check for transmit busy. - */ - if ( NULL == channel || BFIN_UART_XMIT_BUSY & channel->flags ) { - return 0; - } - - base = channel->uart_baseAddress; - tx_dma_base = channel->uart_txDmaBaseAddress; - - channel->flags |= BFIN_UART_XMIT_BUSY; - channel->length = len; - - *(uint16_t volatile *) (tx_dma_base + DMA_CONFIG_OFFSET) &= ~DMA_CONFIG_DMAEN; - *(uint32_t volatile *) (tx_dma_base + DMA_START_ADDR_OFFSET) = (uint32_t)buf; - *(uint16_t volatile *) (tx_dma_base + DMA_X_COUNT_OFFSET) = channel->length; - *(uint16_t volatile *) (tx_dma_base + DMA_X_MODIFY_OFFSET) = 1; - *(uint16_t volatile *) (tx_dma_base + DMA_CONFIG_OFFSET) |= DMA_CONFIG_DMAEN; - *(uint16_t volatile *) (base + UART_IER_OFFSET) = UART_IER_ETBEI; - - return 0; -} - -/** - * RX DMA ISR. - * The polling route is used for receiving the characters. This is a place - * holder for future implementation. - * @param _arg - */ -void bfinUart_rxDmaIsr(void *_arg) -{ -/** - * TODO: Implementation of RX DMA - */ -} - -/** - * This function implements TX dma ISR. It clears the IRQ and dequeues a char - * The channel argument will have the base address. Since there are two uart - * and both the uarts can use the same tx dma isr. - * - * TODO: 1. Error checking 2. sending correct length ie after looking at the - * number of elements the uart transmitted. - * - * @param _arg argument passed to the interrupt handler. It contains the - * channel argument. - */ -void bfinUart_txDmaIsr(void *_arg) -{ - bfin_uart_channel_t* channel = NULL; - uint32_t tx_dma_base = 0; - - /** - * Sanity check - */ - if (NULL == _arg) { - /** It should never be NULL */ - return; - } - - channel = (bfin_uart_channel_t *) _arg; - - tx_dma_base = channel->uart_txDmaBaseAddress; - - if ((*(uint16_t volatile *) (tx_dma_base + DMA_IRQ_STATUS_OFFSET) - & DMA_IRQ_STATUS_DMA_DONE)) { - - *(uint16_t volatile *) (tx_dma_base + DMA_IRQ_STATUS_OFFSET) - |= DMA_IRQ_STATUS_DMA_DONE | DMA_IRQ_STATUS_DMA_ERR; - channel->flags &= ~BFIN_UART_XMIT_BUSY; - rtems_termios_dequeue_characters(channel->termios, channel->length); - } else { - /* UART DMA did not generate interrupt. - * This routine must not be called. - */ - } -} - -/** - * Function called during exit - */ -static void uart_exit(void) -{ - /** - * TODO: Flushing of quques - */ -} - -/** - * Opens the device in different modes. The supported modes are - * 1. Polling - * 2. Interrupt - * 3. DMA - * At exit the uart_Exit function will be called to flush the device. - * - * @param major Major number of the device - * @param minor Minor number of the device - * @param arg - * @return - */ -rtems_device_driver bfin_uart_open(rtems_device_major_number major, - rtems_device_minor_number minor, void *arg) { - rtems_status_code sc = RTEMS_NOT_DEFINED; - rtems_libio_open_close_args_t *args = NULL; - - /** - * Callback function for polling - */ - static const rtems_termios_callbacks pollCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - pollRead, /* pollRead */ - pollWrite, /* write */ - setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_POLLED /* outputUsesInterrupts */ - }; - - /** - * Callback function for interrupt based transfers without DMA. - * We use interrupts for writing only. For reading we use polling. - */ - static const rtems_termios_callbacks interruptCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - pollRead, /* pollRead */ - uart_interruptWrite, /* write */ - setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ - }; - - /** - * Callback function for interrupt based DMA transfers. - * We use interrupts for writing only. For reading we use polling. - */ - static const rtems_termios_callbacks interruptDmaCallbacks = { - NULL, /* firstOpen */ - NULL, /* lastClose */ - NULL, /* pollRead */ - uart_DmaWrite, /* write */ - setAttributes, /* setAttributes */ - NULL, /* stopRemoteTx */ - NULL, /* startRemoteTx */ - TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */ - }; - - if ( NULL == uartsConfig || 0 > minor || minor >= uartsConfig->num_channels) { - return RTEMS_INVALID_NUMBER; - } - - /** - * Opens device for handling uart send request either by - * 1. interrupt with DMA - * 2. interrupt based - * 3. Polling - */ - if ( uartsConfig->channels[minor].uart_useDma ) { - sc = rtems_termios_open(major, minor, arg, &interruptDmaCallbacks); - } else { - sc = rtems_termios_open(major, minor, arg, - uartsConfig->channels[minor].uart_useInterrupts ? - &interruptCallbacks : &pollCallbacks); - } - - args = arg; - uartsConfig->channels[minor].termios = args->iop->data1; - - atexit(uart_exit); - - return sc; -} - -/** -* Uart initialization function. -* @param major major number of the device -* @param config configuration parameters -* @return rtems status code -*/ -rtems_status_code bfin_uart_initialize( - rtems_device_major_number major, - bfin_uart_config_t *config -) -{ - rtems_status_code sc = RTEMS_NOT_DEFINED; - int i = 0; - - 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(&(config->channels[i])); - sc = rtems_io_register_name(config->channels[i].name, major, i); - if (RTEMS_SUCCESSFUL != sc) { - return sc; - } - } - - return sc; -} diff --git a/c/src/lib/libcpu/bfin/timer/timer.c b/c/src/lib/libcpu/bfin/timer/timer.c deleted file mode 100644 index 02540fe2ce..0000000000 --- a/c/src/lib/libcpu/bfin/timer/timer.c +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file - * @brief 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 - * benchmark_timer_initialize() and benchmark_timer_read(). - * benchmark_timer_read() usually returns the number of microseconds - * since benchmark_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.org/license/LICENSE. - */ - -#include -#include -#include - -uint32_t Timer_interrupts; -bool benchmark_timer_find_average_overhead; - -/* - * benchmark_timer_initialize - * - * Blackfin processor has a counter for clock cycles. - */ -void benchmark_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 benchmark_timer_read(). - * - * 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 */ - -benchmark_timer_t benchmark_timer_read( 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 ( benchmark_timer_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); - } -} - -void benchmark_timer_disable_subtracting_average_overhead(bool find_flag) -{ - benchmark_timer_find_average_overhead = find_flag; -} -- cgit v1.2.3