mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-17 13:24:59 +08:00
239
bsps/shared/grlib/amba/ahbstat.c
Normal file
239
bsps/shared/grlib/amba/ahbstat.c
Normal file
@@ -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;
|
||||
}
|
||||
457
bsps/shared/grlib/amba/ambapp.c
Normal file
457
bsps/shared/grlib/amba/ambapp.c
Normal file
@@ -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);
|
||||
}
|
||||
25
bsps/shared/grlib/amba/ambapp_alloc.c
Normal file
25
bsps/shared/grlib/amba/ambapp_alloc.c
Normal file
@@ -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;
|
||||
}
|
||||
23
bsps/shared/grlib/amba/ambapp_count.c
Normal file
23
bsps/shared/grlib/amba/ambapp_count.c
Normal file
@@ -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;
|
||||
}
|
||||
25
bsps/shared/grlib/amba/ambapp_depth.c
Normal file
25
bsps/shared/grlib/amba/ambapp_depth.c
Normal file
@@ -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;
|
||||
}
|
||||
39
bsps/shared/grlib/amba/ambapp_find_by_idx.c
Normal file
39
bsps/shared/grlib/amba/ambapp_find_by_idx.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
109
bsps/shared/grlib/amba/ambapp_freq.c
Normal file
109
bsps/shared/grlib/amba/ambapp_freq.c
Normal file
@@ -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;
|
||||
}
|
||||
447
bsps/shared/grlib/amba/ambapp_names.c
Normal file
447
bsps/shared/grlib/amba/ambapp_names.c
Normal file
@@ -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);
|
||||
}
|
||||
112
bsps/shared/grlib/amba/ambapp_old.c
Normal file
112
bsps/shared/grlib/amba/ambapp_old.c
Normal file
@@ -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);
|
||||
}
|
||||
23
bsps/shared/grlib/amba/ambapp_parent.c
Normal file
23
bsps/shared/grlib/amba/ambapp_parent.c
Normal file
@@ -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;
|
||||
}
|
||||
68
bsps/shared/grlib/amba/ambapp_show.c
Normal file
68
bsps/shared/grlib/amba/ambapp_show.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user