Changeset 3feae3b in rtems


Ignore:
Timestamp:
May 10, 2017, 8:46:01 AM (3 years ago)
Author:
Daniel Hellstrom <daniel@…>
Branches:
master
Children:
6fdded2c
Parents:
84e4d10c
git-author:
Daniel Hellstrom <daniel@…> (05/10/17 08:46:01)
git-committer:
Daniel Hellstrom <daniel@…> (05/14/17 10:32:00)
Message:

leon, gr1553bc: SMP support by using spin-locks

Since DMA buffers are managed by the user, responsibility is put on
the user to cope with SMP in the application.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/1553/gr1553bc.c

    r84e4d10c r3feae3b  
    1111#include <stdlib.h>
    1212#include <string.h>
     13#include <rtems.h>
    1314#include <drvmgr/drvmgr.h>
    1415#include <drvmgr/ambapp_bus.h>
     
    1718#include <bsp/gr1553bc.h>
    1819
     20/* Use interrupt lock privmitives compatible with SMP defined in
     21 * RTEMS 4.11.99 and higher.
     22 */
     23#if (((__RTEMS_MAJOR__ << 16) | (__RTEMS_MINOR__ << 8) | __RTEMS_REVISION__) >= 0x040b63)
     24
     25/* map via rtems_interrupt_lock_* API: */
     26#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
     27#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
     28#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
     29#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
     30#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
     31#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
     32#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
     33#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
     34#define SPIN_FREE(lock) rtems_interrupt_lock_destroy(lock)
     35
     36#else
     37
     38/* maintain single-core compatibility with older versions of RTEMS: */
     39#define SPIN_DECLARE(name)
     40#define SPIN_INIT(lock, name)
     41#define SPIN_LOCK(lock, level)
     42#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_disable(level)
     43#define SPIN_UNLOCK(lock, level)
     44#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_enable(level)
     45#define SPIN_IRQFLAGS(k) rtems_interrupt_level k
     46#define SPIN_ISR_IRQFLAGS(k)
     47#define SPIN_FREE(lock)
     48
     49#ifdef RTEMS_SMP
     50#error SMP mode not compatible with these interrupt lock primitives
     51#endif
     52
     53#endif
     54
    1955#define GR1553BC_WRITE_MEM(adr, val) *(volatile uint32_t *)(adr) = (uint32_t)(val)
    2056#define GR1553BC_READ_MEM(adr) (*(volatile uint32_t *)(adr))
     
    2258#define GR1553BC_WRITE_REG(adr, val) *(volatile uint32_t *)(adr) = (uint32_t)(val)
    2359#define GR1553BC_READ_REG(adr) (*(volatile uint32_t *)(adr))
    24 
    25 #ifndef IRQ_GLOBAL_PREPARE
    26  #define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
    27 #endif
    28 
    29 #ifndef IRQ_GLOBAL_DISABLE
    30  #define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
    31 #endif
    32 
    33 #ifndef IRQ_GLOBAL_ENABLE
    34  #define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
    35 #endif
    3660
    3761/* Needed by list for data pinter and BD translation */
     
    4266        struct gr1553bc_list *alist;
    4367        int started;
     68        SPIN_DECLARE(devlock);
    4469
    4570        /* IRQ log management */
     
    12771302        priv->regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
    12781303
     1304        SPIN_INIT(&priv->devlock, "gr1553bc");
     1305
    12791306        gr1553bc_device_init(priv);
    12801307
     
    13111338        /* Free device */
    13121339        gr1553_bc_close(priv->pdev);
     1340        SPIN_FREE(&priv->devlock);
    13131341        free(priv->irq_log_p);
    13141342        free(priv);
     
    13411369        union gr1553bc_bd *bd = NULL, *bd_async = NULL;
    13421370        uint32_t ctrl, irqmask;
    1343         IRQ_GLOBAL_PREPARE(oldLevel);
     1371        SPIN_IRQFLAGS(irqflags);
    13441372
    13451373        if ( (list == NULL) && (list_async == NULL) )
     
    13661394
    13671395        /* Do "hot-swapping" of lists */
    1368         IRQ_GLOBAL_DISABLE(oldLevel);
     1396        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
     1397
    13691398        if ( list ) {
    13701399                priv->list = list;
     
    13871416        }
    13881417
    1389         IRQ_GLOBAL_ENABLE(oldLevel);
     1418        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    13901419
    13911420        return 0;
     
    13971426        struct gr1553bc_priv *priv = bc;
    13981427        uint32_t ctrl;
    1399         IRQ_GLOBAL_PREPARE(oldLevel);
     1428        SPIN_IRQFLAGS(irqflags);
    14001429
    14011430        /* Do "hot-swapping" of lists */
    1402         IRQ_GLOBAL_DISABLE(oldLevel);
     1431        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    14031432        ctrl = GR1553BC_KEY | GR1553B_BC_ACT_SCSUS;
    14041433        GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, ctrl);
    1405         IRQ_GLOBAL_ENABLE(oldLevel);
     1434        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    14061435
    14071436        return 0;
     
    14131442        struct gr1553bc_priv *priv = bc;
    14141443        uint32_t ctrl;
    1415         IRQ_GLOBAL_PREPARE(oldLevel);
    1416 
    1417         IRQ_GLOBAL_DISABLE(oldLevel);
     1444        SPIN_IRQFLAGS(irqflags);
     1445
     1446        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    14181447        ctrl = GR1553BC_KEY | GR1553B_BC_ACT_SCSRT;
    14191448        GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, ctrl);
    1420         IRQ_GLOBAL_ENABLE(oldLevel);
     1449        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    14211450
    14221451        return 0;
     
    14281457        struct gr1553bc_priv *priv = bc;
    14291458        uint32_t ctrl;
    1430         IRQ_GLOBAL_PREPARE(oldLevel);
     1459        SPIN_IRQFLAGS(irqflags);
    14311460
    14321461        ctrl = GR1553BC_KEY;
     
    14361465                ctrl |= GR1553B_BC_ACT_ASSTP;
    14371466
    1438         IRQ_GLOBAL_DISABLE(oldLevel);
     1467        SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    14391468        GR1553BC_WRITE_REG(&priv->regs->bc_ctrl, ctrl);
    14401469        priv->started = 0;
    1441         IRQ_GLOBAL_ENABLE(oldLevel);
     1470        SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    14421471
    14431472        return 0;
     
    15131542        void *data;
    15141543        int handled, irq;
     1544        SPIN_ISR_IRQFLAGS(irqflags);
    15151545
    15161546        /* Did core make IRQ */
     
    15321562        /* Get current posistion in hardware */
    15331563        pos = (uint32_t *)GR1553BC_READ_REG(&priv->regs->bc_irqptr);
    1534         /* Convertin into CPU address */
     1564        /* Converting into CPU address */
    15351565        pos = priv->irq_log_base +
    15361566                ((unsigned int)pos - (unsigned int)priv->irq_log_base_hw)/4;
     
    15481578                 * descriptor table area.
    15491579                 */
     1580                SPIN_LOCK(&priv->devlock, irqflags);
    15501581                if ( priv->alist && ((unsigned int)bd>=priv->alist->table_hw) &&
    15511582                     ((unsigned int)bd <
     
    15531584                        /* BD in async list */
    15541585                        bd = gr1553bc_bd_hw2cpu(priv->alist, bd);
    1555                 } else {
     1586                } else if (priv->list &&
     1587                           ((unsigned int)bd >= priv->list->table_hw) &&
     1588                           ((unsigned int)bd <
     1589                           (priv->list->table_hw + priv->list->table_size))) {
    15561590                        /* BD in sync list */
    15571591                        bd = gr1553bc_bd_hw2cpu(priv->list, bd);
     1592                } else {
     1593                        /* error - unknown BD. Should not happen but could
     1594                         * if user has switched list. Ignore IRQ entry and
     1595                         * continue to next entry.
     1596                         */
     1597                        bd = NULL;
    15581598                }
    15591599
     
    15641604                 * we let the standard IRQ handle handle it.
    15651605                 */
    1566                 word0 = GR1553BC_READ_MEM(&bd->raw.words[0]);
    1567                 if ( word0 == GR1553BC_UNCOND_IRQ ) {
     1606                if ( bd ) {
     1607                        word0 = GR1553BC_READ_MEM(&bd->raw.words[0]);
    15681608                        word2 = GR1553BC_READ_MEM(&bd->raw.words[2]);
    1569                         if ( (word2 & 0x3) == 0 ) {
    1570                                 func = (bcirq_func_t)(word2 & ~0x3);
    1571                                 data = (void *)
    1572                                         GR1553BC_READ_MEM(&bd->raw.words[3]);
    1573                                 func(bd, data);
    1574                                 handled = 1;
     1609                        SPIN_UNLOCK(&priv->devlock, irqflags);
     1610                        if ( word0 == GR1553BC_UNCOND_IRQ ) {
     1611                                if ( (word2 & 0x3) == 0 ) {
     1612                                        func = (bcirq_func_t)(word2 & ~0x3);
     1613                                        data = (void *)
     1614                                          GR1553BC_READ_MEM(&bd->raw.words[3]);
     1615                                        func(bd, data);
     1616                                        handled = 1;
     1617                                }
    15751618                        }
    1576                 }
    1577 
    1578                 if ( handled == 0 ) {
    1579                         /* Let standard IRQ handle handle it */
    1580                         priv->irq_func(bd, priv->irq_data);
     1619
     1620                        if ( handled == 0 ) {
     1621                                /* Let standard IRQ handle handle it */
     1622                                priv->irq_func(bd, priv->irq_data);
     1623                        } else {
     1624                                handled = 0;
     1625                        }
    15811626                } else {
    1582                         handled = 0;
     1627                        SPIN_UNLOCK(&priv->devlock, irqflags);
    15831628                }
    15841629
Note: See TracChangeset for help on using the changeset viewer.