Ticket #2014: 0001-GRETH-added-support-for-non-snooping-GRETH-10-100-sy_v1.patch

File 0001-GRETH-added-support-for-non-snooping-GRETH-10-100-sy_v1.patch, 8.0 KB (added by Daniel Hellstrom, on 03/22/12 at 07:21:06)

patch v4 for HEAD

  • c/src/lib/libbsp/sparc/leon2/include/bsp.h

    From eb4b0a37eef110359736a01fe9cdb03e38bb1db9 Mon Sep 17 00:00:00 2001
    From: Daniel Hellstrom <daniel@gaisler.com>
    Date: Fri, 2 Dec 2011 10:53:35 +0100
    Subject: [PATCH 1/1] GRETH: added support for non-snooping GRETH 10/100 systems
    
    When data cache snooping is not present the cache needs
    flushing, the SPARC LEON CPUs does not have to ability
    to flush individual cache rows and flushing all cache is
    expensive. Instead the LDA instruction is used to force
    cache miss on individual loads during the IP-align copy
    operation required anyway.
    
    GRETH GBIT non-snooping systems are still unsupported,
    since it use zero-copy (can deal with unaligned DMA).
    
    Let the bsp.h select if the GRETH driver is supported.
    Currently only the LEON2/LEON3 platforms BSPs builds the
    driver.
    
    Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
    ---
     c/src/lib/libbsp/sparc/leon2/include/bsp.h  |    4 ++
     c/src/lib/libbsp/sparc/leon2/include/leon.h |    8 +++
     c/src/lib/libbsp/sparc/leon3/include/bsp.h  |    4 ++
     c/src/lib/libbsp/sparc/leon3/include/leon.h |    8 +++
     c/src/libchip/network/greth.c               |   68 ++++++++++++++++++++++++---
     5 files changed, 85 insertions(+), 7 deletions(-)
    
    diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
    index b855347..0784ba4 100644
    a b extern int rtems_smc91111_driver_attach_leon2( 
    6060
    6161#define HAS_SMC91111
    6262
     63/* Configure GRETH driver */
     64#define GRETH_SUPPORTED
     65#define GRETH_MEM_LOAD(addr) leon_r32_no_cache(addr)
     66
    6367/*
    6468 *  The synchronous trap is an arbitrarily chosen software trap.
    6569 */
  • c/src/lib/libbsp/sparc/leon2/include/leon.h

    diff --git a/c/src/lib/libbsp/sparc/leon2/include/leon.h b/c/src/lib/libbsp/sparc/leon2/include/leon.h
    index 168ebe5..c183c90 100644
    a b extern LEON_Register_Map LEON_REG; 
    369369#define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003
    370370#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003
    371371
     372/* Load 32-bit word by forcing a cache-miss */
     373static inline unsigned int leon_r32_no_cache(uintptr_t addr)
     374{
     375        unsigned int tmp;
     376        asm volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
     377        return tmp;
     378}
     379
    372380#endif /* !ASM */
    373381
    374382#ifdef __cplusplus
  • c/src/lib/libbsp/sparc/leon3/include/bsp.h

    diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
    index 2286ad6..e47ddda 100644
    a b extern int rtems_leon_greth_driver_attach( 
    7373
    7474#define HAS_SMC91111
    7575
     76/* Configure GRETH driver */
     77#define GRETH_SUPPORTED
     78#define GRETH_MEM_LOAD(addr) leon_r32_no_cache(addr)
     79
    7680extern int   CPU_SPARC_HAS_SNOOPING;
    7781
    7882
  • c/src/lib/libbsp/sparc/leon3/include/leon.h

    diff --git a/c/src/lib/libbsp/sparc/leon3/include/leon.h b/c/src/lib/libbsp/sparc/leon3/include/leon.h
    index b953e59..cd50629 100644
    a b extern int LEON3_Cpu_Index; 
    326326#define LEON_REG_TIMER_COUNTER_DEFINED_MASK       0x00000003
    327327#define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK  0x00000003
    328328
     329/* Load 32-bit word by forcing a cache-miss */
     330static inline unsigned int leon_r32_no_cache(uintptr_t addr)
     331{
     332        unsigned int tmp;
     333        asm volatile (" lda [%1] 1, %0\n" : "=r"(tmp) : "r"(addr));
     334        return tmp;
     335}
     336
    329337#endif /* !ASM */
    330338
    331339#ifdef __cplusplus
  • c/src/libchip/network/greth.c

    diff --git a/c/src/libchip/network/greth.c b/c/src/libchip/network/greth.c
    index aff4d0f..df3c143 100644
    a b  
    1212 */
    1313
    1414#include <rtems.h>
    15 
    16 #define GRETH_SUPPORTED
    1715#include <bsp.h>
    1816
     17#ifdef GRETH_SUPPORTED
     18
    1919#include <inttypes.h>
    2020#include <errno.h>
    2121#include <rtems/bspIo.h>
    extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int ); 
    5757extern void ipalign(struct mbuf *m);
    5858#endif
    5959
     60/* Used when reading from memory written by GRETH DMA unit */
     61#ifndef GRETH_MEM_LOAD
     62#define GRETH_MEM_LOAD(addr) (*(volatile unsigned int *)(addr))
     63#endif
     64
    6065/*
    6166 * Number of OCs supported by this driver
    6267 */
    auto_neg_done: 
    499504    print_init_info(sc);
    500505}
    501506
     507#ifdef CPU_U32_FIX
     508
     509/*
     510 * Routine to align the received packet so that the ip header
     511 * is on a 32-bit boundary. Necessary for cpu's that do not
     512 * allow unaligned loads and stores and when the 32-bit DMA
     513 * mode is used.
     514 *
     515 * Transfers are done on word basis to avoid possibly slow byte
     516 * and half-word writes.
     517 */
     518
     519void ipalign(struct mbuf *m)
     520{
     521  unsigned int *first, *last, data;
     522  unsigned int tmp;
     523
     524  if ((((int) m->m_data) & 2) && (m->m_len)) {
     525    last = (unsigned int *) ((((int) m->m_data) + m->m_len + 8) & ~3);
     526    first = (unsigned int *) (((int) m->m_data) & ~3);
     527    tmp = GRETH_MEM_LOAD(first);
     528    tmp = tmp << 16;
     529    first++;
     530    do {
     531      /* When snooping is not available the LDA instruction must be used
     532       * to avoid the cache to return an illegal value.
     533       * Load with forced cache miss
     534       */
     535      data = GRETH_MEM_LOAD(first);
     536      *first = tmp | (data >> 16);
     537      tmp = data << 16;
     538      first++;
     539    } while (first <= last);
     540
     541    m->m_data = (caddr_t)(((int) m->m_data) + 2);
     542  }
     543}
     544#endif
     545
    502546void
    503547greth_Daemon (void *arg)
    504548{
    greth_Daemon (void *arg) 
    510554    rtems_event_set events;
    511555    rtems_interrupt_level level;
    512556    int first;
     557    unsigned int tmp;
    513558
    514559    for (;;)
    515560      {
    greth_Daemon (void *arg) 
    539584    /* Scan for Received packets */
    540585again:
    541586    while (!((len_status =
    542                     dp->rxdesc[dp->rx_ptr].ctrl) & GRETH_RXD_ENABLE))
     587                    GRETH_MEM_LOAD(&dp->rxdesc[dp->rx_ptr].ctrl)) & GRETH_RXD_ENABLE))
    543588            {
    544589                    bad = 0;
    545590                    if (len_status & GRETH_RXD_TOOLONG)
    again: 
    583628                                    len - sizeof (struct ether_header);
    584629
    585630                            eh = mtod (m, struct ether_header *);
     631
    586632                            m->m_data += sizeof (struct ether_header);
    587633#ifdef CPU_U32_FIX
    588                             if(!(dp->gbit_mac))
     634                            if(!dp->gbit_mac) {
     635                                    /* OVERRIDE CACHED ETHERNET HEADER FOR NON-SNOOPING SYSTEMS */
     636                                    tmp = GRETH_MEM_LOAD((uintptr_t)eh);
     637                                    tmp = GRETH_MEM_LOAD(4+(uintptr_t)eh);
     638                                    tmp = GRETH_MEM_LOAD(8+(uintptr_t)eh);
     639                                    tmp = GRETH_MEM_LOAD(12+(uintptr_t)eh);
     640
    589641                                    ipalign(m); /* Align packet on 32-bit boundary */
     642                            }
    590643#endif
    591644
    592645                            ether_input (ifp, eh, m);
    sendpacket (struct ifnet *ifp, struct mbuf *m) 
    641694    /*
    642695     * Is there a free descriptor available?
    643696     */
    644     if ( dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE ){
     697    if (GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].ctrl) & GRETH_TXD_ENABLE){
    645698            /* No. */
    646699            inside = 0;
    647700            return 1;
    sendpacket (struct ifnet *ifp, struct mbuf *m) 
    651704    n = m;
    652705
    653706    len = 0;
    654     temp = (unsigned char *) dp->txdesc[dp->tx_ptr].addr;
     707    temp = (unsigned char *) GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].addr);
    655708#ifdef GRETH_DEBUG
    656709    printf("TXD: 0x%08x : BUF: 0x%08x\n", (int) m->m_data, (int) temp);
    657710#endif
    int greth_process_tx_gbit(struct greth_softc *sc) 
    814867     */
    815868    for (;;){
    816869        /* Reap Sent packets */
    817         while((sc->tx_cnt > 0) && !(sc->txdesc[sc->tx_dptr].ctrl) && !(sc->txdesc[sc->tx_dptr].ctrl & GRETH_TXD_ENABLE)) {
     870        while((sc->tx_cnt > 0) && !(GRETH_MEM_LOAD(&sc->txdesc[sc->tx_dptr].ctrl) & GRETH_TXD_ENABLE)) {
    818871            m_free(sc->txmbuf[sc->tx_dptr]);
    819872            sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;
    820873            sc->tx_cnt--;
    rtems_greth_driver_attach (struct rtems_bsdnet_ifconfig *config, 
    11461199    return 1;
    11471200};
    11481201
     1202#endif