summaryrefslogtreecommitdiffstats
path: root/bsps/shared/grlib/amba
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-12-22 18:31:04 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-01-22 12:46:33 +0100
commit7eb606d393306da25fd6e6aa7f8595ffb2e924fc (patch)
tree085befd6fe5e29d229fec9683735516d48e9d41e /bsps/shared/grlib/amba
parentgrlib: Move header files (diff)
downloadrtems-7eb606d393306da25fd6e6aa7f8595ffb2e924fc.tar.bz2
grlib: Move source files
Update #3678.
Diffstat (limited to 'bsps/shared/grlib/amba')
-rw-r--r--bsps/shared/grlib/amba/ahbstat.c239
-rw-r--r--bsps/shared/grlib/amba/ambapp.c457
-rw-r--r--bsps/shared/grlib/amba/ambapp_alloc.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_count.c23
-rw-r--r--bsps/shared/grlib/amba/ambapp_depth.c25
-rw-r--r--bsps/shared/grlib/amba/ambapp_find_by_idx.c39
-rw-r--r--bsps/shared/grlib/amba/ambapp_freq.c109
-rw-r--r--bsps/shared/grlib/amba/ambapp_names.c447
-rw-r--r--bsps/shared/grlib/amba/ambapp_old.c112
-rw-r--r--bsps/shared/grlib/amba/ambapp_parent.c23
-rw-r--r--bsps/shared/grlib/amba/ambapp_show.c68
11 files changed, 1567 insertions, 0 deletions
diff --git a/bsps/shared/grlib/amba/ahbstat.c b/bsps/shared/grlib/amba/ahbstat.c
new file mode 100644
index 0000000000..af3d778feb
--- /dev/null
+++ b/bsps/shared/grlib/amba/ahbstat.c
@@ -0,0 +1,239 @@
+/* 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 <inttypes.h>
+#include <string.h>
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <drvmgr/drvmgr.h>
+#include <grlib/ambapp_bus.h>
+
+#include <grlib/ahbstat.h>
+
+#include <grlib/grlib_impl.h>
+
+#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_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_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_ISR_IRQFLAGS(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_LOCK(&priv->devlock, lock_context);
+ priv->last_status = status;
+ priv->last_address = fadr;
+ SPIN_UNLOCK(&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 %" PRId32
+ " by master %" PRId32 " at 0x%08" PRIx32 "\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_IRQFLAGS(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_LOCK_IRQ(&priv->devlock, lock_context);
+ last_status = REG_READ(&priv->last_status);
+ last_address = REG_READ(&priv->last_address);
+ SPIN_UNLOCK_IRQ(&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;
+}
diff --git a/bsps/shared/grlib/amba/ambapp.c b/bsps/shared/grlib/amba/ambapp.c
new file mode 100644
index 0000000000..69018f47e7
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp.c
@@ -0,0 +1,457 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011.
+ * Aeroflex Gaisler.
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <grlib/ambapp.h>
+#include <bsp.h>
+
+#include <grlib/grlib_impl.h>
+
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
+#define AMBA_APB_SLAVES 16
+
+/* Allocate one AMBA device */
+static struct ambapp_dev *ambapp_alloc_dev_struct(int dev_type)
+{
+ struct ambapp_dev *dev;
+ size_t size = sizeof(*dev);
+
+ if (dev_type == DEV_APB_SLV)
+ size += sizeof(struct ambapp_apb_info);
+ else
+ size += sizeof(struct ambapp_ahb_info); /* AHB */
+ dev = grlib_calloc(1, size);
+ if (dev != NULL)
+ dev->dev_type = dev_type;
+ return dev;
+}
+
+static unsigned int
+ambapp_addr_from (struct ambapp_mmap *mmaps, unsigned int address)
+{
+ /* no translation? */
+ if (!mmaps)
+ return address;
+
+ while (mmaps->size) {
+ if ((address >= mmaps->remote_adr) &&
+ (address <= (mmaps->remote_adr + (mmaps->size - 1)))) {
+ return (address - mmaps->remote_adr) + mmaps->local_adr;
+ }
+ mmaps++;
+ }
+ return 1;
+}
+
+static void ambapp_ahb_dev_init(
+ unsigned int ioarea,
+ struct ambapp_mmap *mmaps,
+ struct ambapp_pnp_ahb *ahb,
+ struct ambapp_dev *dev,
+ int ahbidx
+ )
+{
+ int bar;
+ struct ambapp_ahb_info *ahb_info;
+ unsigned int addr, mask, mbar;
+
+ /* Setup device struct */
+ dev->vendor = ambapp_pnp_vendor(ahb->id);
+ dev->device = ambapp_pnp_device(ahb->id);
+ ahb_info = DEV_TO_AHB(dev);
+ ahb_info->ver = ambapp_pnp_ver(ahb->id);
+ ahb_info->irq = ambapp_pnp_irq(ahb->id);
+ ahb_info->ahbidx = ahbidx;
+ ahb_info->custom[0] = (unsigned int)ahb->custom[0];
+ ahb_info->custom[1] = (unsigned int)ahb->custom[1];
+ ahb_info->custom[2] = (unsigned int)ahb->custom[2];
+
+ /* Memory BARs */
+ for (bar=0; bar<4; bar++) {
+ mbar = ahb->mbar[bar];
+ if (mbar == 0) {
+ addr = 0;
+ mask = 0;
+ } else {
+ addr = ambapp_pnp_start(mbar);
+ if (ambapp_pnp_mbar_type(mbar) == AMBA_TYPE_AHBIO) {
+ /* AHB I/O area is releative IO_AREA */
+ addr = AMBA_TYPE_AHBIO_ADDR(addr, ioarea);
+ mask = (((unsigned int)(ambapp_pnp_mbar_mask(~mbar) << 8) | 0xff)) + 1;
+ } else {
+ /* AHB memory area, absolute address */
+ addr = ambapp_addr_from(mmaps, addr);
+ mask = (~((unsigned int)(ambapp_pnp_mbar_mask(mbar) << 20))) + 1;
+ }
+ }
+ ahb_info->start[bar] = addr;
+ ahb_info->mask[bar] = mask;
+ ahb_info->type[bar] = ambapp_pnp_mbar_type(mbar);
+ }
+}
+
+static void ambapp_apb_dev_init(
+ unsigned int base,
+ struct ambapp_mmap *mmaps,
+ struct ambapp_pnp_apb *apb,
+ struct ambapp_dev *dev,
+ int ahbidx
+ )
+{
+ struct ambapp_apb_info *apb_info;
+
+ /* Setup device struct */
+ dev->vendor = ambapp_pnp_vendor(apb->id);
+ dev->device = ambapp_pnp_device(apb->id);
+ apb_info = DEV_TO_APB(dev);
+ apb_info->ver = ambapp_pnp_ver(apb->id);
+ apb_info->irq = ambapp_pnp_irq(apb->id);
+ apb_info->ahbidx = ahbidx;
+ apb_info->start = ambapp_pnp_apb_start(apb->iobar, base);
+ apb_info->mask = ambapp_pnp_apb_mask(apb->iobar);
+}
+
+static int ambapp_add_ahbbus(
+ struct ambapp_bus *abus,
+ unsigned int ioarea
+ )
+{
+ int i;
+ for (i=0; i<AHB_BUS_MAX; i++) {
+ if (abus->ahbs[i].ioarea == 0) {
+ abus->ahbs[i].ioarea = ioarea;
+ return i;
+ } else if (abus->ahbs[i].ioarea == ioarea) {
+ /* Bus already added */
+ return -1;
+ }
+ }
+ return -1;
+}
+
+/* Internal AMBA Scanning Function */
+static int ambapp_scan2(
+ struct ambapp_bus *abus,
+ unsigned int ioarea,
+ ambapp_memcpy_t memfunc,
+ struct ambapp_dev *parent,
+ struct ambapp_dev **root
+ )
+{
+ struct ambapp_pnp_ahb *ahb, ahb_buf;
+ struct ambapp_pnp_apb *apb, apb_buf;
+ struct ambapp_dev *dev, *prev, *prevapb, *apbdev;
+ struct ambapp_ahb_info *ahb_info;
+ int maxloops = 64;
+ unsigned int apbbase, bridge_adr;
+ int i, j, ahbidx;
+
+ *root = NULL;
+
+ if (parent) {
+ /* scan first bus for 64 devices, rest for 16 devices */
+ maxloops = 16;
+ }
+
+ ahbidx = ambapp_add_ahbbus(abus, ioarea);
+ if (ahbidx < 0) {
+ /* Bus already scanned, stop */
+ return 0;
+ }
+
+ prev = parent;
+
+ /* AHB MASTERS */
+ ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
+ for (i = 0; i < maxloops; i++, ahb++) {
+ memfunc(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
+ if (ahb_buf.id == 0)
+ continue;
+
+ /* An AHB device present here */
+ dev = ambapp_alloc_dev_struct(DEV_AHB_MST);
+ if (!dev)
+ return -1;
+
+ ambapp_ahb_dev_init(ioarea, abus->mmaps, &ahb_buf, dev, ahbidx);
+
+ if (*root == NULL)
+ *root = dev;
+
+ if (prev != parent)
+ prev->next = dev;
+ dev->prev = prev;
+ prev = dev;
+ }
+
+ /* AHB SLAVES */
+ ahb = (struct ambapp_pnp_ahb *)
+ (ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
+ for (i = 0; i < maxloops; i++, ahb++) {
+ memfunc(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
+ if (ahb_buf.id == 0)
+ continue;
+
+ /* An AHB device present here */
+ dev = ambapp_alloc_dev_struct(DEV_AHB_SLV);
+ if (!dev)
+ return -1;
+
+ ambapp_ahb_dev_init(ioarea, abus->mmaps, &ahb_buf, dev, ahbidx);
+
+ if (*root == NULL)
+ *root = dev;
+
+ if (prev != parent)
+ prev->next = dev;
+ dev->prev = prev;
+ prev = dev;
+
+ ahb_info = DEV_TO_AHB(dev);
+
+ /* Is it a AHB/AHB Bridge ? */
+ if (((dev->device == GAISLER_AHB2AHB) &&
+ (dev->vendor == VENDOR_GAISLER) && (ahb_info->ver > 0)) ||
+ ((dev->device == GAISLER_L2CACHE) &&
+ (dev->vendor == VENDOR_GAISLER)) ||
+ ((dev->device == GAISLER_GRIOMMU) &&
+ (dev->vendor == VENDOR_GAISLER))) {
+ /* AHB/AHB Bridge Found, recurse down the
+ * Bridge
+ */
+ if (ahb_info->custom[1] != 0) {
+ bridge_adr = ambapp_addr_from(abus->mmaps,
+ ahb_info->custom[1]);
+ /* Scan next bus if not already scanned */
+ if (ambapp_scan2(abus, bridge_adr, memfunc, dev,
+ &dev->children))
+ return -1;
+ }
+ } else if ((dev->device == GAISLER_APBMST) &&
+ (dev->vendor == VENDOR_GAISLER)) {
+ /* AHB/APB Bridge Found, add the APB devices to this
+ * AHB Slave's children
+ */
+ prevapb = dev;
+ apbbase = ahb_info->start[0];
+
+ /* APB SLAVES */
+ apb = (struct ambapp_pnp_apb *)
+ (apbbase | AMBA_CONF_AREA);
+ for (j=0; j<AMBA_APB_SLAVES; j++, apb++) {
+ memfunc(&apb_buf, apb, sizeof(*apb), abus);
+ if (apb_buf.id == 0)
+ continue;
+
+ apbdev = ambapp_alloc_dev_struct(DEV_APB_SLV);
+ if (!apbdev)
+ return -1;
+
+ ambapp_apb_dev_init(apbbase, abus->mmaps,
+ &apb_buf, apbdev, ahbidx);
+
+ if (prevapb != dev)
+ prevapb->next = apbdev;
+ else
+ dev->children = apbdev;
+ apbdev->prev = prevapb;
+ prevapb = apbdev;
+ }
+ }
+ }
+
+ /* Remember first AHB MST/SLV device on bus and Parent Bridge */
+ abus->ahbs[ahbidx].dev = *root;
+ abus->ahbs[ahbidx].bridge = parent;
+
+ return 0;
+}
+
+/* Build AMBA Plug & Play device graph */
+int ambapp_scan(
+ struct ambapp_bus *abus,
+ unsigned int ioarea,
+ ambapp_memcpy_t memfunc,
+ struct ambapp_mmap *mmaps
+ )
+{
+ memset(abus, 0, sizeof(*abus));
+ abus->mmaps = mmaps;
+
+ /* Default to memcpy() */
+ if (!memfunc)
+ memfunc = (ambapp_memcpy_t)memcpy;
+
+ return ambapp_scan2(abus, ioarea, memfunc, NULL, &abus->root);
+}
+
+/* Match search options againt device */
+static int ambapp_dev_match_options(struct ambapp_dev *dev, unsigned int options, int vendor, int device)
+{
+ if ((((options & (OPTIONS_ALL_DEVS)) == OPTIONS_ALL_DEVS) || /* TYPE */
+ ((options & OPTIONS_AHB_MSTS) && (dev->dev_type == DEV_AHB_MST)) ||
+ ((options & OPTIONS_AHB_SLVS) && (dev->dev_type == DEV_AHB_SLV)) ||
+ ((options & OPTIONS_APB_SLVS) && (dev->dev_type == DEV_APB_SLV))) &&
+ ((vendor == -1) || (vendor == dev->vendor)) && /* VENDOR/DEV ID */
+ ((device == -1) || (device == dev->device)) &&
+ (((options & OPTIONS_ALL) == OPTIONS_ALL) || /* Allocated State */
+ ((options & OPTIONS_FREE) && DEV_IS_FREE(dev)) ||
+ ((options & OPTIONS_ALLOCATED) && DEV_IS_ALLOCATED(dev)))) {
+ return 1;
+ }
+ return 0;
+}
+
+/* If device is an APB bridge all devices on the APB bridge is processed */
+static int ambapp_for_each_apb(
+ struct ambapp_dev *dev,
+ unsigned int options,
+ int vendor,
+ int device,
+ ambapp_func_t func,
+ void *arg)
+{
+ int index, ret;
+ struct ambapp_dev *apbslv;
+
+ ret = 0;
+ if (dev->children && (dev->children->dev_type == DEV_APB_SLV)) {
+ /* Found a APB Bridge */
+ index = 0;
+ apbslv = dev->children;
+ while (apbslv) {
+ if (ambapp_dev_match_options(apbslv, options,
+ vendor, device) == 1) {
+ ret = func(apbslv, index, arg);
+ if (ret != 0)
+ break; /* Signalled stopped */
+ }
+ index++;
+ apbslv = apbslv->next;
+ }
+ }
+
+ return ret;
+}
+
+/* Traverse the prescanned device information */
+static int ambapp_for_each_dev(
+ struct ambapp_dev *root,
+ unsigned int options,
+ int vendor,
+ int device,
+ ambapp_func_t func,
+ void *arg)
+{
+ struct ambapp_dev *dev;
+ int ahb_slave = 0;
+ int index, ret;
+
+ /* Start at device 'root' and process downwards.
+ *
+ * Breadth first search, search order
+ * 1. AHB MSTS
+ * 2. AHB SLVS
+ * 3. APB SLVS on primary bus
+ * 4. AHB/AHB secondary... -> step to 1.
+ */
+
+ /* AHB MST / AHB SLV */
+ if (options & (OPTIONS_AHB_MSTS|OPTIONS_AHB_SLVS|OPTIONS_DEPTH_FIRST)) {
+ index = 0;
+ dev = root;
+ while (dev) {
+ if ((dev->dev_type == DEV_AHB_SLV) && !ahb_slave) {
+ /* First AHB Slave */
+ ahb_slave = 1;
+ index = 0;
+ }
+
+ /* Conditions must be fullfilled for function to be
+ * called
+ */
+ if (ambapp_dev_match_options(dev, options, vendor, device) == 1) {
+ /* Correct device and vendor ID */
+ ret = func(dev, index, arg);
+ if (ret != 0)
+ return ret; /* Signalled stopped */
+ }
+
+ if ((options & OPTIONS_DEPTH_FIRST) && (options & OPTIONS_APB_SLVS)) {
+ /* Check is APB bridge, and process all APB
+ * Slaves in that case
+ */
+ ret = ambapp_for_each_apb(dev, options, vendor, device, func, arg);
+ if (ret != 0)
+ return ret; /* Signalled stopped */
+ }
+
+ if (options & OPTIONS_DEPTH_FIRST) {
+ if (dev->children && (dev->children->dev_type != DEV_APB_SLV)) {
+ /* Found AHB Bridge, recurse */
+ ret = ambapp_for_each_dev(dev->children, options, vendor, device,
+ func, arg);
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ index++;
+ dev = dev->next;
+ }
+ }
+
+ /* Find APB Bridges */
+ if ((options & OPTIONS_APB_SLVS) && !(options & OPTIONS_DEPTH_FIRST)) {
+ dev = root;
+ while (dev) {
+ /* Check is APB bridge, and process all APB Slaves in
+ * that case
+ */
+ ret = ambapp_for_each_apb(dev, options, vendor, device, func, arg);
+ if (ret != 0)
+ return ret; /* Signalled stopped */
+ dev = dev->next;
+ }
+ }
+
+ /* Find AHB Bridges */
+ if (!(options & OPTIONS_DEPTH_FIRST)) {
+ dev = root;
+ while (dev) {
+ if (dev->children && (dev->children->dev_type != DEV_APB_SLV)) {
+ /* Found AHB Bridge, recurse */
+ ret = ambapp_for_each_dev(dev->children, options, vendor, device,
+ func, arg);
+ if (ret != 0)
+ return ret;
+ }
+ dev = dev->next;
+ }
+ }
+
+ return 0;
+}
+
+int ambapp_for_each(
+ struct ambapp_bus *abus,
+ unsigned int options,
+ int vendor,
+ int device,
+ ambapp_func_t func,
+ void *arg)
+{
+ return ambapp_for_each_dev(abus->root, options, vendor, device, func, arg);
+}
diff --git a/bsps/shared/grlib/amba/ambapp_alloc.c b/bsps/shared/grlib/amba/ambapp_alloc.c
new file mode 100644
index 0000000000..96fcb7961b
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_alloc.c
@@ -0,0 +1,25 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <grlib/ambapp.h>
+
+int ambapp_alloc_dev(struct ambapp_dev *dev, void *owner)
+{
+ if (dev->owner)
+ return -1;
+ dev->owner = owner;
+ return 0;
+}
+
+void ambapp_free_dev(struct ambapp_dev *dev)
+{
+ dev->owner = 0;
+}
diff --git a/bsps/shared/grlib/amba/ambapp_count.c b/bsps/shared/grlib/amba/ambapp_count.c
new file mode 100644
index 0000000000..9da4d93a19
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_count.c
@@ -0,0 +1,23 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <grlib/ambapp.h>
+
+/* Get number of devices matching search options */
+int ambapp_dev_count(struct ambapp_bus *abus, unsigned int options,
+ int vendor, int device)
+{
+ int count = 10000;
+
+ ambapp_for_each(abus, options, vendor, device, ambapp_find_by_idx, &count);
+
+ return 10000 - count;
+}
diff --git a/bsps/shared/grlib/amba/ambapp_depth.c b/bsps/shared/grlib/amba/ambapp_depth.c
new file mode 100644
index 0000000000..2fe0b142e9
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_depth.c
@@ -0,0 +1,25 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <grlib/ambapp.h>
+
+/* Get bus depth a device is located at */
+int ambapp_depth(struct ambapp_dev *dev)
+{
+ int depth = 0;
+
+ do {
+ dev = ambapp_find_parent(dev);
+ depth++;
+ } while (dev);
+
+ return depth - 1;
+}
diff --git a/bsps/shared/grlib/amba/ambapp_find_by_idx.c b/bsps/shared/grlib/amba/ambapp_find_by_idx.c
new file mode 100644
index 0000000000..55d9022881
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_find_by_idx.c
@@ -0,0 +1,39 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <grlib/ambapp.h>
+
+/* AMBAPP helper routine to find a device by index. The function is given to
+ * ambapp_for_each, the argument may be NULL (find first device) or a pointer
+ * to a index which is downcounted until 0 is reached. If the int-pointer
+ * points to a value of:
+ * 0 - first device is returned
+ * 1 - second device is returned
+ * ...
+ *
+ * The matching device is returned, which will stop the ambapp_for_each search.
+ * If zero is returned from ambapp_for_each no device matching the index was
+ * found
+ */
+int ambapp_find_by_idx(struct ambapp_dev *dev, int index, void *pcount)
+{
+ int *pi = pcount;
+
+ if (pi) {
+ if ((*pi)-- == 0)
+ return (int)dev;
+ else
+ return 0;
+ } else {
+ /* Satisfied with first matching device, stop search */
+ return (int)dev;
+ }
+}
diff --git a/bsps/shared/grlib/amba/ambapp_freq.c b/bsps/shared/grlib/amba/ambapp_freq.c
new file mode 100644
index 0000000000..9e6e9c1765
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_freq.c
@@ -0,0 +1,109 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <grlib/ambapp.h>
+
+/* Calculate AHB Bus frequency of
+ * - Bus[0] (inverse=1), relative to the frequency of Bus[ahbidx]
+ * NOTE: set freq_hz to frequency of Bus[ahbidx].
+ * or
+ * - Bus[ahbidx] (inverse=0), relative to the frequency of Bus[0]
+ * NOTE: set freq_hz to frequency of Bus[0].
+ *
+ * If a unsupported bridge is found the invalid frequncy of 0Hz is
+ * returned.
+ */
+static unsigned int ambapp_freq_calc(
+ struct ambapp_bus *abus,
+ int ahbidx,
+ unsigned int freq_hz,
+ int inverse)
+{
+ struct ambapp_ahb_info *ahb;
+ struct ambapp_dev *bridge;
+ unsigned char ffact;
+ int dir;
+
+ /* Found Bus0? */
+ bridge = abus->ahbs[ahbidx].bridge;
+ if (!bridge)
+ return freq_hz;
+
+ /* Find this bus frequency relative to freq_hz */
+ if ((bridge->vendor == VENDOR_GAISLER) &&
+ ((bridge->device == GAISLER_AHB2AHB) ||
+ (bridge->device == GAISLER_L2CACHE))) {
+ ahb = DEV_TO_AHB(bridge);
+ ffact = (ahb->custom[0] & AMBAPP_FLAG_FFACT) >> 4;
+ if (ffact != 0) {
+ dir = ahb->custom[0] & AMBAPP_FLAG_FFACT_DIR;
+
+ /* Calculate frequency by dividing or
+ * multiplying system frequency
+ */
+ if ((dir && !inverse) || (!dir && inverse))
+ freq_hz = freq_hz * ffact;
+ else
+ freq_hz = freq_hz / ffact;
+ }
+ return ambapp_freq_calc(abus, ahb->ahbidx, freq_hz, inverse);
+ } else {
+ /* Unknown bridge, impossible to calc frequency */
+ return 0;
+ }
+}
+
+/* Find the frequency of all AHB Buses from knowing the frequency of one
+ * particular APB/AHB Device.
+ */
+void ambapp_freq_init(
+ struct ambapp_bus *abus,
+ struct ambapp_dev *dev,
+ unsigned int freq_hz)
+{
+ struct ambapp_common_info *info;
+ int i;
+
+ for (i=0; i<AHB_BUS_MAX; i++)
+ abus->ahbs[i].freq_hz = 0;
+
+ /* Register Frequency at the AHB bus that the device the user gave us
+ * is located at.
+ */
+ if (dev) {
+ info = DEV_TO_COMMON(dev);
+ abus->ahbs[info->ahbidx].freq_hz = freq_hz;
+
+ /* Find Frequency of Bus 0 */
+ abus->ahbs[0].freq_hz = ambapp_freq_calc(abus, info->ahbidx, freq_hz, 1);
+ } else {
+ abus->ahbs[0].freq_hz = freq_hz;
+ }
+
+ /* Find Frequency of all except for Bus0 and the bus which frequency
+ * was reported at
+ */
+ for (i=1; i<AHB_BUS_MAX; i++) {
+ if (abus->ahbs[i].ioarea == 0)
+ break;
+ if (abus->ahbs[i].freq_hz != 0)
+ continue;
+ abus->ahbs[i].freq_hz = ambapp_freq_calc(abus, i, abus->ahbs[0].freq_hz, 0);
+ }
+}
+
+/* Assign a AMBA Bus a frequency but reporting the frequency of a
+ * particular AHB/APB device */
+unsigned int ambapp_freq_get(struct ambapp_bus *abus, struct ambapp_dev *dev)
+{
+ struct ambapp_common_info *info = DEV_TO_COMMON(dev);
+ return abus->ahbs[info->ahbidx].freq_hz;
+}
diff --git a/bsps/shared/grlib/amba/ambapp_names.c b/bsps/shared/grlib/amba/ambapp_names.c
new file mode 100644
index 0000000000..8d168f283b
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_names.c
@@ -0,0 +1,447 @@
+/*
+ * AMBA Plug & Play Device and Vendor name database: Created from GRLIB 3386.
+ *
+ * COPYRIGHT (c) 2009.
+ * Aeroflex Gaisler.
+ *
+ * The device and vendor definitions are extracted with a script from
+ * GRLIB.
+ *
+ * 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 <grlib/ambapp.h>
+#include <grlib/ambapp_ids.h>
+#include <string.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+typedef struct {
+ int device_id;
+ char *name;
+} ambapp_device_name;
+
+typedef struct {
+ unsigned int vendor_id;
+ char *name;
+ ambapp_device_name *devices;
+} ambapp_vendor_devnames;
+
+/**************** AUTO GENERATED FROM devices.vhd ****************/
+static ambapp_device_name GAISLER_devices[] =
+{
+ {GAISLER_LEON2DSU, "LEON2DSU"},
+ {GAISLER_LEON3, "LEON3"},
+ {GAISLER_LEON3DSU, "LEON3DSU"},
+ {GAISLER_ETHAHB, "ETHAHB"},
+ {GAISLER_APBMST, "APBMST"},
+ {GAISLER_AHBUART, "AHBUART"},
+ {GAISLER_SRCTRL, "SRCTRL"},
+ {GAISLER_SDCTRL, "SDCTRL"},
+ {GAISLER_SSRCTRL, "SSRCTRL"},
+ {GAISLER_I2C2AHB, "I2C2AHB"},
+ {GAISLER_APBUART, "APBUART"},
+ {GAISLER_IRQMP, "IRQMP"},
+ {GAISLER_AHBRAM, "AHBRAM"},
+ {GAISLER_AHBDPRAM, "AHBDPRAM"},
+ {GAISLER_GRIOMMU2, "GRIOMMU2"},
+ {GAISLER_GPTIMER, "GPTIMER"},
+ {GAISLER_PCITRG, "PCITRG"},
+ {GAISLER_PCISBRG, "PCISBRG"},
+ {GAISLER_PCIFBRG, "PCIFBRG"},
+ {GAISLER_PCITRACE, "PCITRACE"},
+ {GAISLER_DMACTRL, "DMACTRL"},
+ {GAISLER_AHBTRACE, "AHBTRACE"},
+ {GAISLER_DSUCTRL, "DSUCTRL"},
+ {GAISLER_CANAHB, "CANAHB"},
+ {GAISLER_GPIO, "GPIO"},
+ {GAISLER_AHBROM, "AHBROM"},
+ {GAISLER_AHBJTAG, "AHBJTAG"},
+ {GAISLER_ETHMAC, "ETHMAC"},
+ {GAISLER_SWNODE, "SWNODE"},
+ {GAISLER_SPW, "SPW"},
+ {GAISLER_AHB2AHB, "AHB2AHB"},
+ {GAISLER_USBDC, "USBDC"},
+ {GAISLER_USB_DCL, "USB_DCL"},
+ {GAISLER_DDRMP, "DDRMP"},
+ {GAISLER_ATACTRL, "ATACTRL"},
+ {GAISLER_DDRSP, "DDRSP"},
+ {GAISLER_EHCI, "EHCI"},
+ {GAISLER_UHCI, "UHCI"},
+ {GAISLER_I2CMST, "I2CMST"},
+ {GAISLER_SPW2, "SPW2"},
+ {GAISLER_AHBDMA, "AHBDMA"},
+ {GAISLER_NUHOSP3, "NUHOSP3"},
+ {GAISLER_CLKGATE, "CLKGATE"},
+ {GAISLER_SPICTRL, "SPICTRL"},
+ {GAISLER_DDR2SP, "DDR2SP"},
+ {GAISLER_SLINK, "SLINK"},
+ {GAISLER_GRTM, "GRTM"},
+ {GAISLER_GRTC, "GRTC"},
+ {GAISLER_GRPW, "GRPW"},
+ {GAISLER_GRCTM, "GRCTM"},
+ {GAISLER_GRHCAN, "GRHCAN"},
+ {GAISLER_GRFIFO, "GRFIFO"},
+ {GAISLER_GRADCDAC, "GRADCDAC"},
+ {GAISLER_GRPULSE, "GRPULSE"},
+ {GAISLER_GRTIMER, "GRTIMER"},
+ {GAISLER_AHB2PP, "AHB2PP"},
+ {GAISLER_GRVERSION, "GRVERSION"},
+ {GAISLER_APB2PW, "APB2PW"},
+ {GAISLER_PW2APB, "PW2APB"},
+ {GAISLER_GRCAN, "GRCAN"},
+ {GAISLER_I2CSLV, "I2CSLV"},
+ {GAISLER_U16550, "U16550"},
+ {GAISLER_AHBMST_EM, "AHBMST_EM"},
+ {GAISLER_AHBSLV_EM, "AHBSLV_EM"},
+ {GAISLER_GRTESTMOD, "GRTESTMOD"},
+ {GAISLER_ASCS, "ASCS"},
+ {GAISLER_IPMVBCTRL, "IPMVBCTRL"},
+ {GAISLER_SPIMCTRL, "SPIMCTRL"},
+ {GAISLER_L4STAT, "L4STAT"},
+ {GAISLER_LEON4, "LEON4"},
+ {GAISLER_LEON4DSU, "LEON4DSU"},
+ {GAISLER_PWM, "PWM"},
+ {GAISLER_L2CACHE, "L2CACHE"},
+ {GAISLER_SDCTRL64, "SDCTRL64"},
+ {GAISLER_GR1553B, "GR1553B"},
+ {GAISLER_1553TST, "1553TST"},
+ {GAISLER_GRIOMMU, "GRIOMMU"},
+ {GAISLER_FTAHBRAM, "FTAHBRAM"},
+ {GAISLER_FTSRCTRL, "FTSRCTRL"},
+ {GAISLER_AHBSTAT, "AHBSTAT"},
+ {GAISLER_LEON3FT, "LEON3FT"},
+ {GAISLER_FTMCTRL, "FTMCTRL"},
+ {GAISLER_FTSDCTRL, "FTSDCTRL"},
+ {GAISLER_FTSRCTRL8, "FTSRCTRL8"},
+ {GAISLER_MEMSCRUB, "MEMSCRUB"},
+ {GAISLER_FTSDCTRL64, "FTSDCTRL64"},
+ {GAISLER_NANDFCTRL, "NANDFCTRL"},
+ {GAISLER_N2DLLCTRL, "N2DLLCTRL"},
+ {GAISLER_N2PLLCTRL, "N2PLLCTRL"},
+ {GAISLER_SPI2AHB, "SPI2AHB"},
+ {GAISLER_DDRSDMUX, "DDRSDMUX"},
+ {GAISLER_AHBFROM, "AHBFROM"},
+ {GAISLER_PCIEXP, "PCIEXP"},
+ {GAISLER_APBPS2, "APBPS2"},
+ {GAISLER_VGACTRL, "VGACTRL"},
+ {GAISLER_LOGAN, "LOGAN"},
+ {GAISLER_SVGACTRL, "SVGACTRL"},
+ {GAISLER_T1AHB, "T1AHB"},
+ {GAISLER_MP7WRAP, "MP7WRAP"},
+ {GAISLER_GRSYSMON, "GRSYSMON"},
+ {GAISLER_GRACECTRL, "GRACECTRL"},
+ {GAISLER_ATAHBSLV, "ATAHBSLV"},
+ {GAISLER_ATAHBMST, "ATAHBMST"},
+ {GAISLER_ATAPBSLV, "ATAPBSLV"},
+ {GAISLER_MIGDDR2, "MIGDDR2"},
+ {GAISLER_LCDCTRL, "LCDCTRL"},
+ {GAISLER_SWITCHOVER, "SWITCHOVER"},
+ {GAISLER_FIFOUART, "FIFOUART"},
+ {GAISLER_MUXCTRL, "MUXCTRL"},
+ {GAISLER_B1553BC, "B1553BC"},
+ {GAISLER_B1553RT, "B1553RT"},
+ {GAISLER_B1553BRM, "B1553BRM"},
+ {GAISLER_AES, "AES"},
+ {GAISLER_ECC, "ECC"},
+ {GAISLER_PCIF, "PCIF"},
+ {GAISLER_CLKMOD, "CLKMOD"},
+ {GAISLER_HAPSTRAK, "HAPSTRAK"},
+ {GAISLER_TEST_1X2, "TEST_1X2"},
+ {GAISLER_WILD2AHB, "WILD2AHB"},
+ {GAISLER_BIO1, "BIO1"},
+ {GAISLER_AESDMA, "AESDMA"},
+ {GAISLER_GRPCI2, "GRPCI2"},
+ {GAISLER_GRPCI2_DMA, "GRPCI2_DMA"},
+ {GAISLER_GRPCI2_TB, "GRPCI2_TB"},
+ {GAISLER_MMA, "MMA"},
+ {GAISLER_SATCAN, "SATCAN"},
+ {GAISLER_CANMUX, "CANMUX"},
+ {GAISLER_GRTMRX, "GRTMRX"},
+ {GAISLER_GRTCTX, "GRTCTX"},
+ {GAISLER_GRTMDESC, "GRTMDESC"},
+ {GAISLER_GRTMVC, "GRTMVC"},
+ {GAISLER_GEFFE, "GEFFE"},
+ {GAISLER_GPREG, "GPREG"},
+ {GAISLER_GRTMPAHB, "GRTMPAHB"},
+ {GAISLER_SPWCUC, "SPWCUC"},
+ {GAISLER_SPW2_DMA, "SPW2_DMA"},
+ {GAISLER_SPWROUTER, "SPWROUTER"},
+ {GAISLER_EDCLMST, "EDCLMST"},
+ {GAISLER_GRPWTX, "GRPWTX"},
+ {GAISLER_GRPWRX, "GRPWRX"},
+ {GAISLER_GPREGBANK, "GPREGBANK"},
+ {GAISLER_MIG_7SERIES, "MIG_7SERIES"},
+ {GAISLER_GRSPW2_SIST, "GRSPW2_SIST"},
+ {GAISLER_SGMII, "SGMII"},
+ {GAISLER_RGMII, "RGMII"},
+ {GAISLER_IRQGEN, "IRQGEN"},
+ {GAISLER_GRDMAC, "GRDMAC"},
+ {GAISLER_AHB2AVLA, "AHB2AVLA"},
+ {GAISLER_SPWTDP, "SPWTDP"},
+ {GAISLER_L3STAT, "L3STAT"},
+ {GAISLER_GR740THS, "GR740THS"},
+ {GAISLER_GRRM, "GRRM"},
+ {GAISLER_CMAP, "CMAP"},
+ {GAISLER_CPGEN, "CPGEN"},
+ {GAISLER_AMBAPROT, "AMBAPROT"},
+ {GAISLER_IGLOO2_BRIDGE, "IGLOO2_BRIDGE"},
+ {GAISLER_AHB2AXI, "AHB2AXI"},
+ {GAISLER_AXI2AHB, "AXI2AHB"},
+ {GAISLER_FDIR_RSTCTRL, "FDIR_RSTCTRL"},
+ {GAISLER_APB3MST, "APB3MST"},
+ {GAISLER_LRAM, "LRAM"},
+ {GAISLER_BOOTSEQ, "BOOTSEQ"},
+ {GAISLER_TCCOP, "TCCOP"},
+ {GAISLER_SPIMASTER, "SPIMASTER"},
+ {GAISLER_SPISLAVE, "SPISLAVE"},
+ {GAISLER_GRSRIO, "GRSRIO"},
+ {0, NULL}
+};
+
+static ambapp_device_name PENDER_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name ESA_devices[] =
+{
+ {ESA_LEON2, "LEON2"},
+ {ESA_LEON2APB, "LEON2APB"},
+ {ESA_IRQ, "IRQ"},
+ {ESA_TIMER, "TIMER"},
+ {ESA_UART, "UART"},
+ {ESA_CFG, "CFG"},
+ {ESA_IO, "IO"},
+ {ESA_MCTRL, "MCTRL"},
+ {ESA_PCIARB, "PCIARB"},
+ {ESA_HURRICANE, "HURRICANE"},
+ {ESA_SPW_RMAP, "SPW_RMAP"},
+ {ESA_AHBUART, "AHBUART"},
+ {ESA_SPWA, "SPWA"},
+ {ESA_BOSCHCAN, "BOSCHCAN"},
+ {ESA_IRQ2, "IRQ2"},
+ {ESA_AHBSTAT, "AHBSTAT"},
+ {ESA_WPROT, "WPROT"},
+ {ESA_WPROT2, "WPROT2"},
+ {ESA_PDEC3AMBA, "PDEC3AMBA"},
+ {ESA_PTME3AMBA, "PTME3AMBA"},
+ {0, NULL}
+};
+
+static ambapp_device_name ASTRIUM_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name OPENCHIP_devices[] =
+{
+ {OPENCHIP_APBGPIO, "APBGPIO"},
+ {OPENCHIP_APBI2C, "APBI2C"},
+ {OPENCHIP_APBSPI, "APBSPI"},
+ {OPENCHIP_APBCHARLCD, "APBCHARLCD"},
+ {OPENCHIP_APBPWM, "APBPWM"},
+ {OPENCHIP_APBPS2, "APBPS2"},
+ {OPENCHIP_APBMMCSD, "APBMMCSD"},
+ {OPENCHIP_APBNAND, "APBNAND"},
+ {OPENCHIP_APBLPC, "APBLPC"},
+ {OPENCHIP_APBCF, "APBCF"},
+ {OPENCHIP_APBSYSACE, "APBSYSACE"},
+ {OPENCHIP_APB1WIRE, "APB1WIRE"},
+ {OPENCHIP_APBJTAG, "APBJTAG"},
+ {OPENCHIP_APBSUI, "APBSUI"},
+ {0, NULL}
+};
+
+static ambapp_device_name OPENCORES_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name CONTRIB_devices[] =
+{
+ {CONTRIB_CORE1, "CORE1"},
+ {CONTRIB_CORE2, "CORE2"},
+ {0, NULL}
+};
+
+static ambapp_device_name EONIC_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name RADIONOR_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name GLEICHMANN_devices[] =
+{
+ {GLEICHMANN_CUSTOM, "CUSTOM"},
+ {GLEICHMANN_GEOLCD01, "GEOLCD01"},
+ {GLEICHMANN_DAC, "DAC"},
+ {GLEICHMANN_HPI, "HPI"},
+ {GLEICHMANN_SPI, "SPI"},
+ {GLEICHMANN_HIFC, "HIFC"},
+ {GLEICHMANN_ADCDAC, "ADCDAC"},
+ {GLEICHMANN_SPIOC, "SPIOC"},
+ {GLEICHMANN_AC97, "AC97"},
+ {0, NULL}
+};
+
+static ambapp_device_name MENTA_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name SUN_devices[] =
+{
+ {SUN_T1, "SUN_T1"},
+ {SUN_S1, "SUN_S1"},
+ {0, NULL}
+};
+
+static ambapp_device_name MOVIDIA_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name ORBITA_devices[] =
+{
+ {ORBITA_1553B, "1553B"},
+ {ORBITA_429, "429"},
+ {ORBITA_SPI, "SPI"},
+ {ORBITA_I2C, "I2C"},
+ {ORBITA_SMARTCARD, "SMARTCARD"},
+ {ORBITA_SDCARD, "SDCARD"},
+ {ORBITA_UART16550, "UART16550"},
+ {ORBITA_CRYPTO, "CRYPTO"},
+ {ORBITA_SYSIF, "SYSIF"},
+ {ORBITA_PIO, "PIO"},
+ {ORBITA_RTC, "RTC"},
+ {ORBITA_COLORLCD, "COLORLCD"},
+ {ORBITA_PCI, "PCI"},
+ {ORBITA_DSP, "DSP"},
+ {ORBITA_USBHOST, "USBHOST"},
+ {ORBITA_USBDEV, "USBDEV"},
+ {0, NULL}
+};
+
+static ambapp_device_name SYNOPSYS_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name NASA_devices[] =
+{
+ {NASA_EP32, "EP32"},
+ {0, NULL}
+};
+
+static ambapp_device_name CAL_devices[] =
+{
+ {CAL_DDRCTRL, "DDRCTRL"},
+ {0, NULL}
+};
+
+static ambapp_device_name EMBEDDIT_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name CETON_devices[] =
+{
+ {0, NULL}
+};
+
+static ambapp_device_name ACTEL_devices[] =
+{
+ {ACTEL_COREMP7, "COREMP7"},
+ {0, NULL}
+};
+
+static ambapp_vendor_devnames vendors[] =
+{
+ {VENDOR_GAISLER, "GAISLER", GAISLER_devices},
+ {VENDOR_PENDER, "PENDER", PENDER_devices},
+ {VENDOR_ESA, "ESA", ESA_devices},
+ {VENDOR_ASTRIUM, "ASTRIUM", ASTRIUM_devices},
+ {VENDOR_OPENCHIP, "OPENCHIP", OPENCHIP_devices},
+ {VENDOR_OPENCORES, "OPENCORES", OPENCORES_devices},
+ {VENDOR_CONTRIB, "CONTRIB", CONTRIB_devices},
+ {VENDOR_EONIC, "EONIC", EONIC_devices},
+ {VENDOR_RADIONOR, "RADIONOR", RADIONOR_devices},
+ {VENDOR_GLEICHMANN, "GLEICHMANN", GLEICHMANN_devices},
+ {VENDOR_MENTA, "MENTA", MENTA_devices},
+ {VENDOR_SUN, "SUN", SUN_devices},
+ {VENDOR_MOVIDIA, "MOVIDIA", MOVIDIA_devices},
+ {VENDOR_ORBITA, "ORBITA", ORBITA_devices},
+ {VENDOR_SYNOPSYS, "SYNOPSYS", SYNOPSYS_devices},
+ {VENDOR_NASA, "NASA", NASA_devices},
+ {VENDOR_CAL, "CAL", CAL_devices},
+ {VENDOR_EMBEDDIT, "EMBEDDIT", EMBEDDIT_devices},
+ {VENDOR_CETON, "CETON", CETON_devices},
+ {VENDOR_ACTEL, "ACTEL", ACTEL_devices},
+ {0, NULL, NULL}
+};
+
+/*****************************************************************/
+
+static char *ambapp_get_devname(ambapp_device_name *devs, int id)
+{
+ while (devs->device_id > 0) {
+ if (devs->device_id == id)
+ return devs->name;
+ devs++;
+ }
+ return NULL;
+}
+
+char *ambapp_device_id2str(int vendor, int id)
+{
+ ambapp_vendor_devnames *ven = &vendors[0];
+
+ while (ven->vendor_id > 0) {
+ if (ven->vendor_id == vendor)
+ return ambapp_get_devname(ven->devices, id);
+ ven++;
+ }
+ return NULL;
+}
+
+char *ambapp_vendor_id2str(int vendor)
+{
+ ambapp_vendor_devnames *ven = &vendors[0];
+
+ while (ven->vendor_id > 0) {
+ if (ven->vendor_id == vendor)
+ return ven->name;
+ ven++;
+ }
+ return NULL;
+}
+
+int ambapp_vendev_id2str(int vendor, int id, char *buf)
+{
+ char *dstr, *vstr;
+
+ *buf = '\0';
+
+ vstr = ambapp_vendor_id2str(vendor);
+ if (vstr == NULL)
+ return 0;
+
+ dstr = ambapp_device_id2str(vendor, id);
+ if (dstr == NULL)
+ return 0;
+
+ strcpy(buf, vstr);
+ strcat(buf, "_");
+ strcat(buf, dstr);
+
+ return strlen(buf);
+}
diff --git a/bsps/shared/grlib/amba/ambapp_old.c b/bsps/shared/grlib/amba/ambapp_old.c
new file mode 100644
index 0000000000..a51e692fbf
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_old.c
@@ -0,0 +1,112 @@
+/*
+ * Old AMBA scanning Interface provided for backwards compability
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <grlib/ambapp.h>
+
+struct ambapp_dev_find_match_arg {
+ int index;
+ int count;
+ int type;
+ void *dev;
+};
+
+/* AMBA PP find routines */
+static int ambapp_dev_find_match(struct ambapp_dev *dev, int index, void *arg)
+{
+ struct ambapp_dev_find_match_arg *p = arg;
+
+ if (p->index == 0) {
+ /* Found controller, stop */
+ if (p->type == DEV_APB_SLV) {
+ *(struct ambapp_apb_info *)p->dev = *DEV_TO_APB(dev);
+ p->dev = ((struct ambapp_apb_info *)p->dev)+1;
+ } else {
+ *(struct ambapp_ahb_info *)p->dev = *DEV_TO_AHB(dev);
+ p->dev = ((struct ambapp_ahb_info *)p->dev)+1;
+ }
+ p->count--;
+ if (p->count < 1)
+ return 1;
+ } else {
+ p->index--;
+ }
+ return 0;
+}
+
+int ambapp_find_apbslvs_next(struct ambapp_bus *abus, int vendor, int device, struct ambapp_apb_info *dev, int index, int maxno)
+{
+ struct ambapp_dev_find_match_arg arg;
+
+ arg.index = index;
+ arg.count = maxno;
+ arg.type = DEV_APB_SLV; /* APB */
+ arg.dev = dev;
+
+ ambapp_for_each(abus, (OPTIONS_ALL|OPTIONS_APB_SLVS), vendor, device,
+ ambapp_dev_find_match, &arg);
+
+ return maxno - arg.count;
+}
+
+int ambapp_find_apbslv(struct ambapp_bus *abus, int vendor, int device, struct ambapp_apb_info *dev)
+{
+ return ambapp_find_apbslvs_next(abus, vendor, device, dev, 0, 1);
+}
+
+int ambapp_find_apbslv_next(struct ambapp_bus *abus, int vendor, int device, struct ambapp_apb_info *dev, int index)
+{
+ return ambapp_find_apbslvs_next(abus, vendor, device, dev, index, 1);
+}
+
+int ambapp_find_apbslvs(struct ambapp_bus *abus, int vendor, int device, struct ambapp_apb_info *dev, int maxno)
+{
+ return ambapp_find_apbslvs_next(abus, vendor, device, dev, 0, maxno);
+}
+
+int ambapp_get_number_apbslv_devices(struct ambapp_bus *abus, int vendor, int device)
+{
+ return ambapp_dev_count(abus, (OPTIONS_ALL|OPTIONS_APB_SLVS), vendor, device);
+}
+
+int ambapp_find_ahbslvs_next(struct ambapp_bus *abus, int vendor, int device, struct ambapp_ahb_info *dev, int index, int maxno)
+{
+ struct ambapp_dev_find_match_arg arg;
+
+ arg.index = index;
+ arg.count = maxno;
+ arg.type = DEV_AHB_SLV; /* AHB SLV */
+ arg.dev = dev;
+
+ ambapp_for_each(abus, (OPTIONS_ALL|OPTIONS_AHB_SLVS), vendor, device,
+ ambapp_dev_find_match, &arg);
+
+ return maxno - arg.count;
+}
+
+int ambapp_find_ahbslv_next(struct ambapp_bus *abus, int vendor, int device, struct ambapp_ahb_info *dev, int index)
+{
+ return ambapp_find_ahbslvs_next(abus, vendor, device, dev, index, 1);
+}
+
+int ambapp_find_ahbslv(struct ambapp_bus *abus, int vendor, int device, struct ambapp_ahb_info *dev)
+{
+ return ambapp_find_ahbslvs_next(abus, vendor, device, dev, 0, 1);
+}
+
+int ambapp_find_ahbslvs(struct ambapp_bus *abus, int vendor, int device, struct ambapp_ahb_info *dev, int maxno)
+{
+ return ambapp_find_ahbslvs_next(abus, vendor, device, dev, 0, maxno);
+}
+
+int ambapp_get_number_ahbslv_devices(struct ambapp_bus *abus, int vendor, int device)
+{
+ return ambapp_dev_count(abus, (OPTIONS_ALL|OPTIONS_AHB_SLVS), vendor, device);
+}
diff --git a/bsps/shared/grlib/amba/ambapp_parent.c b/bsps/shared/grlib/amba/ambapp_parent.c
new file mode 100644
index 0000000000..b77b6eec68
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_parent.c
@@ -0,0 +1,23 @@
+/*
+ * AMBA Plug & Play routines
+ *
+ * COPYRIGHT (c) 2011
+ * Aeroflex Gaisler
+ *
+ * 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 <stdlib.h>
+#include <grlib/ambapp.h>
+
+struct ambapp_dev *ambapp_find_parent(struct ambapp_dev *dev)
+{
+ while (dev->prev) {
+ if (dev == dev->prev->children)
+ return dev->prev;
+ dev = dev->prev;
+ }
+ return NULL;
+}
diff --git a/bsps/shared/grlib/amba/ambapp_show.c b/bsps/shared/grlib/amba/ambapp_show.c
new file mode 100644
index 0000000000..12cefa2c0f
--- /dev/null
+++ b/bsps/shared/grlib/amba/ambapp_show.c
@@ -0,0 +1,68 @@
+/*
+ * AMBA Plug & Play routines: device information printing.
+ *
+ * COPYRIGHT (c) 2009.
+ * Aeroflex Gaisler.
+ *
+ * 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 <stdio.h>
+#include <grlib/ambapp.h>
+
+struct ambapp_dev_print_arg {
+ int show_depth;
+};
+
+static char *unknown = "unknown";
+
+static int ambapp_dev_print(struct ambapp_dev *dev, int index, void *arg)
+{
+ char *dev_str, *ven_str, *type_str;
+ struct ambapp_dev_print_arg *p = arg;
+ char dp[32];
+ int i=0;
+ unsigned int basereg;
+
+ if (p->show_depth) {
+ for (i=0; i<ambapp_depth(dev)*2; i+=2) {
+ dp[i] = ' ';
+ dp[i+1] = ' ';
+ }
+ }
+ dp[i] = '\0';
+
+ ven_str = ambapp_vendor_id2str(dev->vendor);
+ if (!ven_str) {
+ ven_str = unknown;
+ dev_str = unknown;
+ } else {
+ dev_str = ambapp_device_id2str(dev->vendor, dev->device);
+ if (!dev_str)
+ dev_str = unknown;
+ }
+ if (dev->dev_type == DEV_APB_SLV) {
+ /* APB */
+ basereg = DEV_TO_APB(dev)->start;
+ type_str = "apb";
+ } else {
+ /* AHB */
+ basereg = DEV_TO_AHB(dev)->start[0];
+ type_str = "ahb";
+ }
+ printf("%s |-> 0x%x:0x%x:0x%x: %s_%s, %s: 0x%x, 0x%x (OWNER: 0x%x)\n",
+ dp, index, dev->vendor, dev->device, ven_str, dev_str, type_str,
+ basereg, (unsigned int)dev, (unsigned int)dev->owner);
+
+ return 0;
+}
+
+void ambapp_print(struct ambapp_bus *abus, int show_depth)
+{
+ struct ambapp_dev_print_arg arg;
+ arg.show_depth = show_depth;
+ ambapp_for_each(abus, (OPTIONS_ALL_DEVS|OPTIONS_ALL|OPTIONS_DEPTH_FIRST), -1,
+ -1, ambapp_dev_print, &arg);
+}