diff options
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/amba/ahbstat.c')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/amba/ahbstat.c | 245 |
1 files changed, 0 insertions, 245 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/amba/ahbstat.c b/c/src/lib/libbsp/sparc/shared/amba/ahbstat.c deleted file mode 100644 index e624301975..0000000000 --- a/c/src/lib/libbsp/sparc/shared/amba/ahbstat.c +++ /dev/null @@ -1,245 +0,0 @@ -/* AHB Status register driver - * - * COPYRIGHT (c) 2009 - 2017. - * Cobham Gaisler AB. - * - * 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 <stdint.h> -#include <string.h> -#include <rtems.h> -#include <rtems/bspIo.h> -#include <drvmgr/drvmgr.h> -#include <drvmgr/ambapp_bus.h> - -#include <bsp/ahbstat.h> - -#define SPIN_IRQ_DECLARE(name) RTEMS_INTERRUPT_LOCK_DECLARE(, name) -#define SPIN_IRQ_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name) -#define SPIN_IRQ_LOCK(lock, ctx) rtems_interrupt_lock_acquire(lock, &(ctx)) -#define SPIN_IRQ_UNLOCK(lock, ctx) rtems_interrupt_lock_release(lock, &(ctx)) -#define SPIN_IRQ_LOCK_ISR(lock, ctx) rtems_interrupt_lock_acquire_isr(lock, &(ctx)) -#define SPIN_IRQ_UNLOCK_ISR(lock, ctx) rtems_interrupt_lock_release_isr(lock, &(ctx)) -#define SPIN_IRQ_CTX rtems_interrupt_lock_context - -#define REG_WRITE(addr, val) (*(volatile uint32_t *)(addr) = (uint32_t)(val)) -#define REG_READ(addr) (*(volatile uint32_t *)(addr)) - -void ahbstat_isr(void *arg); - -/* AHB fail interrupt callback to user. This function is declared weak so that - * the user can define a function pointer variable containing the address - * responsible for handling errors - * - * minor Index of AHBSTAT hardware - * regs Register address of AHBSTAT - * status AHBSTAT status register at IRQ - * failing_address AHBSTAT Failing address register at IRQ - * - * * User return - * 0: print error onto terminal with printk and reenable AHBSTAT - * 1: just re-enable AHBSTAT - * 2: just print error - * 3: do nothing, let user do custom handling - */ -int (*ahbstat_error)( - int minor, - struct ahbstat_regs *regs, - uint32_t status, - uint32_t failing_address - ) __attribute__((weak)) = NULL; - -#define AHBSTAT_STS_CE_BIT 9 -#define AHBSTAT_STS_NE_BIT 8 -#define AHBSTAT_STS_HW_BIT 7 -#define AHBSTAT_STS_HM_BIT 3 -#define AHBSTAT_STS_HS_BIT 0 - -#define AHBSTAT_STS_CE (1 << AHBSTAT_STS_CE_BIT) -#define AHBSTAT_STS_NE (1 << AHBSTAT_STS_NE_BIT) -#define AHBSTAT_STS_HW (1 << AHBSTAT_STS_HW_BIT) -#define AHBSTAT_STS_HM (0xf << AHBSTAT_STS_HM_BIT) -#define AHBSTAT_STS_HS (0x7 << AHBSTAT_STS_HS_BIT) - -enum { DEVNAME_LEN = 9 }; -struct ahbstat_priv { - struct drvmgr_dev *dev; - struct ahbstat_regs *regs; - char devname[DEVNAME_LEN]; - int minor; - /* Cached error */ - uint32_t last_status; - uint32_t last_address; - /* Spin-lock ISR protection */ - SPIN_IRQ_DECLARE(devlock); -}; - -static int ahbstat_init2(struct drvmgr_dev *dev); - -struct drvmgr_drv_ops ahbstat_ops = -{ - .init = {NULL, ahbstat_init2, NULL, NULL}, - .remove = NULL, - .info = NULL -}; - -struct amba_dev_id ahbstat_ids[] = -{ - {VENDOR_GAISLER, GAISLER_AHBSTAT}, - {0, 0} /* Mark end of table */ -}; - -struct amba_drv_info ahbstat_drv_info = -{ - { - DRVMGR_OBJ_DRV, /* Driver */ - NULL, /* Next driver */ - NULL, /* Device list */ - DRIVER_AMBAPP_GAISLER_AHBSTAT_ID,/* Driver ID */ - "AHBSTAT_DRV", /* Driver Name */ - DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */ - &ahbstat_ops, - NULL, /* Funcs */ - 0, /* No devices yet */ - sizeof(struct ahbstat_priv), - }, - &ahbstat_ids[0] -}; - -void ahbstat_register_drv (void) -{ - drvmgr_drv_register(&ahbstat_drv_info.general); -} - -static int ahbstat_init2(struct drvmgr_dev *dev) -{ - struct ahbstat_priv *priv; - struct amba_dev_info *ambadev; - - priv = dev->priv; - if (!priv) - return DRVMGR_NOMEM; - priv->dev = dev; - - /* Get device information from AMBA PnP information */ - ambadev = (struct amba_dev_info *)dev->businfo; - if (ambadev == NULL) - return DRVMGR_FAIL; - priv->regs = (struct ahbstat_regs *)ambadev->info.apb_slv->start; - priv->minor = dev->minor_drv; - - strncpy(&priv->devname[0], "ahbstat0", DEVNAME_LEN); - priv->devname[7] += priv->minor; - /* - * Initialize spinlock for AHBSTAT Device. It is used to protect user - * API calls involivng priv structure from updates in ISR. - */ - SPIN_IRQ_INIT(&priv->devlock, priv->devname); - - /* Initialize hardware */ - REG_WRITE(&priv->regs->status, 0); - - /* Install IRQ handler */ - drvmgr_interrupt_register(dev, 0, priv->devname, ahbstat_isr, priv); - - return DRVMGR_OK; -} - -void ahbstat_isr(void *arg) -{ - struct ahbstat_priv *priv = arg; - uint32_t fadr, status; - int rc; - SPIN_IRQ_CTX lock_context; - - /* Get hardware status */ - status = REG_READ(&priv->regs->status); - if ((status & AHBSTAT_STS_NE) == 0) - return; - - /* IRQ generated by AHBSTAT core... handle it here */ - - /* Get Failing address */ - fadr = REG_READ(&priv->regs->failing); - - SPIN_IRQ_LOCK_ISR(&priv->devlock, lock_context); - priv->last_status = status; - priv->last_address = fadr; - SPIN_IRQ_UNLOCK_ISR(&priv->devlock, lock_context); - - /* Let user handle error, default to print the error and reenable HW - * - * User return - * 0: print error and reenable AHBSTAT - * 1: just reenable AHBSTAT - * 2: just print error - * 3: do nothing - */ - rc = 0; - if (ahbstat_error != NULL) - rc = ahbstat_error(priv->minor, priv->regs, status, fadr); - - if ((rc & 0x1) == 0) { - printk("\n### AHBSTAT: %s %s error of size %ld by master %ld" - " at 0x%08lx\n", - status & AHBSTAT_STS_CE ? "single" : "non-correctable", - status & AHBSTAT_STS_HW ? "write" : "read", - (status & AHBSTAT_STS_HS) >> AHBSTAT_STS_HS_BIT, - (status & AHBSTAT_STS_HM) >> AHBSTAT_STS_HM_BIT, - fadr); - } - - if ((rc & 0x2) == 0) { - /* Trigger new interrupts */ - REG_WRITE(&priv->regs->status, 0); - } -} - -/* Get Last received AHB Error - * - * Return - * 0: No error received - * 1: Error Received, last status and address stored into argument pointers - * -1: No such AHBSTAT device - */ -int ahbstat_last_error(int minor, uint32_t *status, uint32_t *address) -{ - struct drvmgr_dev *dev; - struct ahbstat_priv *priv; - uint32_t last_status; - uint32_t last_address; - SPIN_IRQ_CTX lock_context; - - if (drvmgr_get_dev(&ahbstat_drv_info.general, minor, &dev)) { - return -1; - } - priv = (struct ahbstat_priv *)dev->priv; - - /* Read information cached by ISR */ - SPIN_IRQ_LOCK(&priv->devlock, lock_context); - last_status = REG_READ(&priv->last_status); - last_address = REG_READ(&priv->last_address); - SPIN_IRQ_UNLOCK(&priv->devlock, lock_context); - - *status = last_status; - *address = last_address; - - return (last_status & AHBSTAT_STS_NE) >> AHBSTAT_STS_NE_BIT; -} - -/* Get AHBSTAT registers address from minor. NULL returned if no such device */ -struct ahbstat_regs *ahbstat_get_regs(int minor) -{ - struct drvmgr_dev *dev; - struct ahbstat_priv *priv; - - if (drvmgr_get_dev(&ahbstat_drv_info.general, minor, &dev)) { - return NULL; - } - priv = (struct ahbstat_priv *)dev->priv; - - return priv->regs; -} |