diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-12-22 18:31:04 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-01-22 12:46:33 +0100 |
commit | 7eb606d393306da25fd6e6aa7f8595ffb2e924fc (patch) | |
tree | 085befd6fe5e29d229fec9683735516d48e9d41e /bsps/shared/grlib/amba | |
parent | grlib: Move header files (diff) | |
download | rtems-7eb606d393306da25fd6e6aa7f8595ffb2e924fc.tar.bz2 |
grlib: Move source files
Update #3678.
Diffstat (limited to 'bsps/shared/grlib/amba')
-rw-r--r-- | bsps/shared/grlib/amba/ahbstat.c | 239 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp.c | 457 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_alloc.c | 25 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_count.c | 23 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_depth.c | 25 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_find_by_idx.c | 39 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_freq.c | 109 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_names.c | 447 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_old.c | 112 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_parent.c | 23 | ||||
-rw-r--r-- | bsps/shared/grlib/amba/ambapp_show.c | 68 |
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); +} |