summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/amba
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2012-04-17 16:25:38 +0200
committerGedare Bloom <gedare@rtems.org>2012-04-17 22:01:46 -0400
commit9ea65119f400d5ad9acc3c52bdfd978fb96b930c (patch)
tree7b1175a757256e3772f9c8afb3f366591a5c093c /c/src/lib/libbsp/sparc/shared/amba
parentno_cpu: replace no_cpu_isr with rtems_isr (diff)
downloadrtems-9ea65119f400d5ad9acc3c52bdfd978fb96b930c.tar.bz2
LEON: updated AMBA PnP API
The old layer had some limitations/problems for multiple AHB buses since the data structure containing all AMBA devices were allocated before scanning. The new layer create devices as they are found and memory is allocated using malloc() or bsp_early_malloc() during booting. The old 8 functions for finding a specific AHB-Slave or APB-Slave device has been replaced with one function, ambapp_for_each(), which iterates over all devices matching the specified search options and calls a user provided function. The new way lowers the footprint and makes searching more flexible. The frequency information is now supported, if the frequency of one device is reported by the user. More AHB-to-AHB bridges are supported. The API has been split into several parts in order to lower the footprint. The API also introduces the AMBAPP CORE concept, where one ambapp_core can be created from one AHB Master, AHB Slave and one APB Slave, at least one device is required for creating a core. Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/amba')
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp.c794
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_alloc.c25
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_count.c23
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_depth.c25
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_find_by_idx.c39
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_freq.c109
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_names.c392
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_old.c112
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_parent.c23
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp_show.c71
10 files changed, 1195 insertions, 418 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
index 814ee8c28e..504a3e7e75 100644
--- a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
+++ b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
@@ -1,499 +1,457 @@
/*
- * AMBA Plag & Play Bus Driver
+ * AMBA Plug & Play routines
*
- * This driver hook performs bus scanning.
- *
- * COPYRIGHT (c) 2004.
- * Gaisler Research
+ * 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.com/license/LICENSE.
- *
- * $Id$
*/
-#include <bsp.h>
-#include <rtems/bspIo.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+
#include <ambapp.h>
+#include <bsp.h>
-#define amba_insert_device(tab, address) \
-{ \
- if (*(address)) \
- { \
- (tab)->addr[(tab)->devnr] = (address); \
- (tab)->devnr ++; \
- } \
-} while(0)
-
-#define amba_insert_apb_device(tab, address, apbmst) \
-{ \
- if (*(address)) \
- { \
- (tab)->addr[(tab)->devnr] = (address); \
- (tab)->apbmst[(tab)->devnr] = (apbmst); \
- (tab)->devnr ++; \
- } \
-} while(0)
-
-static unsigned int
-addr_from (struct amba_mmap *mmaps, unsigned int address)
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
+#define AMBA_APB_SLAVES 16
+
+/* Allocate one AMBA device */
+struct ambapp_dev *ambapp_alloc_dev_struct(int dev_type)
+{
+ int size = sizeof(struct ambapp_dev);
+ struct ambapp_dev *dev;
+
+ if (dev_type == DEV_APB_SLV)
+ size += sizeof(struct ambapp_apb_info);
+ else
+ size += sizeof(struct ambapp_ahb_info); /* AHB */
+ dev = (struct ambapp_dev *)bsp_early_malloc(size);
+ if (dev == NULL)
+ return NULL;
+ memset(dev, 0 , size);
+ dev->dev_type = dev_type;
+ return dev;
+}
+
+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_amba_adr)
- && (address <= (mmaps->remote_amba_adr + (mmaps->size - 1)))) {
- return (address - mmaps->remote_amba_adr) + mmaps->cpu_adr;
+ if ((address >= mmaps->remote_adr) &&
+ (address <= (mmaps->remote_adr + (mmaps->size - 1)))) {
+ return (address - mmaps->remote_adr) + mmaps->local_adr;
}
mmaps++;
}
return 1;
}
-
-void
-amba_scan (amba_confarea_type * amba_conf, unsigned int ioarea,
- struct amba_mmap *mmaps)
+void ambapp_ahb_dev_init(
+ unsigned int ioarea,
+ struct ambapp_mmap *mmaps,
+ struct ambapp_pnp_ahb *ahb,
+ struct ambapp_dev *dev,
+ int ahbidx
+ )
{
- unsigned int *cfg_area; /* address to configuration area */
- unsigned int mbar, conf, custom;
- int i, j;
- unsigned int apbmst;
- int maxloops = amba_conf->notroot ? 16 : 64; /* scan first bus for 64 devices, rest for 16 devices */
-
- amba_conf->ahbmst.devnr = 0;
- amba_conf->ahbslv.devnr = 0;
- amba_conf->apbslv.devnr = 0;
- cfg_area = (unsigned int *) (ioarea | AMBA_CONF_AREA);
- amba_conf->ioarea = ioarea;
- amba_conf->mmaps = mmaps;
-
- for (i = 0; i < maxloops; i++) {
- amba_insert_device (&amba_conf->ahbmst, cfg_area);
- cfg_area += AMBA_AHB_CONF_WORDS;
- }
-
- cfg_area =
- (unsigned int *) (ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
- for (i = 0; i < maxloops; i++) {
- amba_insert_device (&amba_conf->ahbslv, cfg_area);
- cfg_area += AMBA_AHB_CONF_WORDS;
- }
-
- for (i = 0; i < amba_conf->ahbslv.devnr; i++){
- conf = amba_get_confword(amba_conf->ahbslv, i, 0);
- mbar = amba_ahb_get_membar(amba_conf->ahbslv, i, 0);
- if ( (amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_AHB2AHB) ){
- /* Found AHB->AHB bus bridge, scan it if more free amba_confarea_type:s available
- * Custom config 1 contain ioarea.
- */
- custom = amba_ahb_get_custom(amba_conf->ahbslv,i,1);
-
- if ( amba_ver(conf) && amba_conf->next ){
- amba_conf->next->notroot = 1;
- amba_scan(amba_conf->next,custom,mmaps);
- }
- }else if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBMST))
- {
- apbmst = amba_membar_start(mbar);
- if ( (apbmst=addr_from(mmaps,apbmst)) == 1 )
- continue; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB/APB bridge. Skip it.
- */
- cfg_area = (unsigned int *)( apbmst | AMBA_CONF_AREA);
- for (j=0; (amba_conf->apbslv.devnr<AMBA_APB_SLAVES) && (j<AMBA_APB_SLAVES); j++){
- amba_insert_apb_device(&amba_conf->apbslv, cfg_area, apbmst);
- cfg_area += AMBA_APB_CONF_WORDS;
+ 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);
}
}
-void
-amba_print_dev(int devno, unsigned int conf){
- int irq = amba_irq(conf);
- if ( irq > 0 ){
- printk("%x.%x.%x: irq %d\n",devno,amba_vendor(conf),amba_device(conf),irq);
- }else{
- printk("%x.%x.%x: no irq\n",devno,amba_vendor(conf),amba_device(conf));
- }
-}
-
-void
-amba_apb_print_dev(int devno, unsigned int conf, unsigned int address){
- int irq = amba_irq(conf);
- if ( irq > 0 ){
- printk("%x.%x.%x: irq %d, apb: 0x%lx\n",devno,amba_vendor(conf),amba_device(conf),irq,address);
- }else{
- printk("%x.%x.%x: no irq, apb: 0x%lx\n",devno,amba_vendor(conf),amba_device(conf),address);
- }
+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);
}
-/* Print AMBA Plug&Play info on terminal */
-void
-amba_print_conf (amba_confarea_type * amba_conf)
+int ambapp_add_ahbbus(
+ struct ambapp_bus *abus,
+ unsigned int ioarea
+ )
{
- int i,base=0;
- unsigned int conf, iobar, address;
- unsigned int apbmst;
-
- /* print all ahb masters */
- printk("--- AMBA AHB Masters ---\n");
- for(i=0; i<amba_conf->ahbmst.devnr; i++){
- conf = amba_get_confword(amba_conf->ahbmst, i, 0);
- amba_print_dev(i,conf);
- }
-
- /* print all ahb slaves */
- printk("--- AMBA AHB Slaves ---\n");
- for(i=0; i<amba_conf->ahbslv.devnr; i++){
- conf = amba_get_confword(amba_conf->ahbslv, i, 0);
- amba_print_dev(i,conf);
- }
-
- /* print all apb slaves */
- apbmst = 0;
- for(i=0; i<amba_conf->apbslv.devnr; i++){
- if ( apbmst != amba_conf->apbslv.apbmst[i] ){
- apbmst = amba_conf->apbslv.apbmst[i];
- printk("--- AMBA APB Slaves on 0x%x ---\n",apbmst);
- base=i;
- }
- conf = amba_get_confword(amba_conf->apbslv, i, 0);
- iobar = amba_apb_get_membar(amba_conf->apbslv, i);
- address = amba_iobar_start(amba_conf->apbslv.apbmst[i], iobar);
- amba_apb_print_dev(i-base,conf,address);
- }
-
+ 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;
}
-/**** APB Slaves ****/
-/* Return number of APB Slave devices which has given vendor and device */
-int
-amba_get_number_apbslv_devices (amba_confarea_type * amba_conf, int vendor,
- int device)
+/* 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
+ )
{
- unsigned int conf;
- int cnt, i;
+ 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;
+ }
- for (cnt = i = 0; i < amba_conf->apbslv.devnr; i++) {
- conf = amba_get_confword (amba_conf->apbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
- cnt++;
+ ahbidx = ambapp_add_ahbbus(abus, ioarea);
+ if (ahbidx < 0) {
+ /* Bus already scanned, stop */
+ return 0;
}
- return cnt;
-}
-/* Get First APB Slave device of this vendor&device id */
-int
-amba_find_apbslv (amba_confarea_type * amba_conf, int vendor, int device,
- amba_apb_device * dev)
-{
- unsigned int conf, iobar;
- int i;
+ prev = parent;
- for (i = 0; i < amba_conf->apbslv.devnr; i++) {
- conf = amba_get_confword (amba_conf->apbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- iobar = amba_apb_get_membar (amba_conf->apbslv, i);
- dev->start = amba_iobar_start (amba_conf->apbslv.apbmst[i], iobar);
- dev->irq = amba_irq (conf);
- return 1;
- }
+ /* 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;
}
- return 0;
-}
-/* Get APB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_apbslv() ) */
-int
-amba_find_next_apbslv (amba_confarea_type * amba_conf, int vendor, int device,
- amba_apb_device * dev, int index)
-{
- unsigned int conf, iobar;
- int cnt, i;
-
- for (cnt = i = 0; i < amba_conf->apbslv.devnr; i++) {
- conf = amba_get_confword (amba_conf->apbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- if (cnt == index) {
- /* found device */
- iobar = amba_apb_get_membar (amba_conf->apbslv, i);
- dev->start = amba_iobar_start (amba_conf->apbslv.apbmst[i], iobar);
- dev->irq = amba_irq (conf);
- return 1;
+ /* 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 (!dev)
+ 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;
}
- cnt++;
}
}
+
+ /* Remember first AHB MST/SLV device on bus and Parent Bridge */
+ abus->ahbs[ahbidx].dev = *root;
+ abus->ahbs[ahbidx].bridge = parent;
+
return 0;
}
-/* Get first nr APB Slave devices, put them into dev (which is an array of nr length) */
-int
-amba_find_apbslvs (amba_confarea_type * amba_conf, int vendor, int device,
- amba_apb_device * devs, int maxno)
+/* Build AMBA Plug & Play device graph */
+int ambapp_scan(
+ struct ambapp_bus *abus,
+ unsigned int ioarea,
+ ambapp_memcpy_t memfunc,
+ struct ambapp_mmap *mmaps
+ )
{
- unsigned int conf, iobar;
- int cnt, i;
-
- for (cnt = i = 0; (i < amba_conf->apbslv.devnr) && (cnt < maxno); i++) {
- conf = amba_get_confword (amba_conf->apbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- /* found device */
- iobar = amba_apb_get_membar (amba_conf->apbslv, i);
- devs[cnt].start = amba_iobar_start (amba_conf->apbslv.apbmst[i], iobar);
- devs[cnt].irq = amba_irq (conf);
- cnt++;
- }
- }
- return cnt;
-}
+ memset(abus, 0, sizeof(*abus));
+ abus->mmaps = mmaps;
-/***** AHB SLAVES *****/
+ /* Default to memcpy() */
+ if (!memfunc)
+ memfunc = (ambapp_memcpy_t)memcpy;
-/* Return number of AHB Slave devices which has given vendor and device */
-int
-amba_get_number_ahbslv_devices (amba_confarea_type * amba_conf, int vendor,
- int device)
-{
- unsigned int conf;
- int cnt, i;
-
- for (cnt = i = 0; i < amba_conf->ahbslv.devnr; i++) {
- conf = amba_get_confword (amba_conf->ahbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
- cnt++;
- }
- return cnt;
+ return ambapp_scan2(abus, ioarea, memfunc, NULL, &abus->root);
}
-/* Get First AHB Slave device of this vendor&device id */
-int
-amba_find_ahbslv (amba_confarea_type * amba_conf, int vendor, int device,
- amba_ahb_device * dev)
+/* Match search options againt device */
+int ambapp_dev_match_options(struct ambapp_dev *dev, unsigned int options, int vendor, int device)
{
- unsigned int conf, mbar, addr;
- int j, i;
-
- for (i = 0; i < amba_conf->ahbslv.devnr; i++) {
- conf = amba_get_confword (amba_conf->ahbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- for (j = 0; j < 4; j++) {
- mbar = amba_ahb_get_membar (amba_conf->ahbslv, i, j);
- addr = amba_membar_start (mbar);
- if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
- addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
- } else { /* convert address if needed */
- if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
- addr = 0; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB address. Skip it.
- */
- }
- }
- dev->start[j] = addr;
- }
- dev->irq = amba_irq (conf);
- dev->ver = amba_ver (conf);
- return 1;
- }
+ 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;
}
-/* Get AHB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbslv() ) */
-int
-amba_find_next_ahbslv (amba_confarea_type * amba_conf, int vendor, int device,
- amba_ahb_device * dev, int index)
+/* 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)
{
- unsigned int conf, mbar, addr;
- int i, j, cnt;
-
- for (cnt = i = 0; i < amba_conf->ahbslv.devnr; i++) {
- conf = amba_get_confword (amba_conf->ahbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- if (cnt == index) {
- for (j = 0; j < 4; j++) {
- mbar = amba_ahb_get_membar (amba_conf->ahbslv, i, j);
- addr = amba_membar_start (mbar);
- if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
- addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
- } else {
- /* convert address if needed */
- if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
- addr = 0; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB address. Skip it.
- */
- }
- }
- dev->start[j] = addr;
- }
- dev->irq = amba_irq (conf);
- dev->ver = amba_ver (conf);
- return 1;
+ 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 */
}
- cnt++;
+ index++;
+ apbslv = apbslv->next;
}
}
- return 0;
+
+ return ret;
}
-/* Get first nr AHB Slave devices, put them into dev (which is an array of nr length) */
-int
-amba_find_ahbslvs (amba_confarea_type * amba_conf, int vendor, int device,
- amba_ahb_device * devs, int maxno)
+/* 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)
{
- unsigned int conf, mbar, addr;
- int i, j, cnt;
-
- for (cnt = i = 0; (i < amba_conf->ahbslv.devnr) && (maxno < cnt); i++) {
- conf = amba_get_confword (amba_conf->ahbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- for (j = 0; j < 4; j++) {
- mbar = amba_ahb_get_membar (amba_conf->ahbslv, i, j);
- addr = amba_membar_start (mbar);
- if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
- addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
- } else {
- /* convert address if needed */
- if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
- addr = 0; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB address. Skip it.
- */
- }
- }
- devs[cnt].start[j] = addr;
+ 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;
}
- devs[cnt].irq = amba_irq (conf);
- devs[cnt].ver = amba_ver (conf);
- cnt++;
- }
- }
- return cnt;
-}
+ /* 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 */
+ }
-/***** AHB Masters *****/
+ 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 */
+ }
-/* Return number of AHB Slave devices which has given vendor and device */
-int
-amba_get_number_ahbmst_devices (amba_confarea_type * amba_conf, int vendor,
- int device)
-{
- unsigned int conf;
- int cnt, i;
+ 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;
+ }
+ }
- for (cnt = i = 0; i < amba_conf->ahbmst.devnr; i++) {
- conf = amba_get_confword (amba_conf->ahbmst, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
- cnt++;
+ index++;
+ dev = dev->next;
+ }
}
- return cnt;
-}
-/* Get First AHB Slave device of this vendor&device id */
-int
-amba_find_ahbmst (amba_confarea_type * amba_conf, int vendor, int device,
- amba_ahb_device * dev)
-{
- unsigned int conf, mbar, addr;
- int j, i;
-
- for (i = 0; i < amba_conf->ahbmst.devnr; i++) {
- conf = amba_get_confword (amba_conf->ahbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- for (j = 0; j < 4; j++) {
- mbar = amba_ahb_get_membar (amba_conf->ahbmst, i, j);
- addr = amba_membar_start (mbar);
- if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
- addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
- } else {
- /* convert address if needed */
- if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
- addr = 0; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB address. Skip it.
- */
- }
- }
- dev->start[j] = addr;
- }
- dev->irq = amba_irq (conf);
- dev->ver = amba_ver (conf);
- return 1;
+ /* 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;
}
}
- return 0;
-}
-/* Get AHB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbslv() ) */
-int
-amba_find_next_ahbmst (amba_confarea_type * amba_conf, int vendor, int device,
- amba_ahb_device * dev, int index)
-{
- unsigned int conf, mbar, addr;
- int i, j, cnt;
-
- for (cnt = i = 0; i < amba_conf->ahbmst.devnr; i++) {
- conf = amba_get_confword (amba_conf->ahbmst, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- if (cnt == index) {
- for (j = 0; j < 4; j++) {
- mbar = amba_ahb_get_membar (amba_conf->ahbmst, i, j);
- addr = amba_membar_start (mbar);
- if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
- addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
- } else {
- /* convert address if needed */
- if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
- addr = 0; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB address. Skip it.
- */
- }
- }
- dev->start[j] = addr;
- }
- dev->irq = amba_irq (conf);
- dev->ver = amba_ver (conf);
- return 1;
+ /* 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;
}
- cnt++;
+ dev = dev->next;
}
}
+
return 0;
}
-/* Get first nr AHB Slave devices, put them into dev (which is an array of nr length) */
-int
-amba_find_ahbmsts (amba_confarea_type * amba_conf, int vendor, int device,
- amba_ahb_device * devs, int maxno)
+int ambapp_for_each(
+ struct ambapp_bus *abus,
+ unsigned int options,
+ int vendor,
+ int device,
+ ambapp_func_t func,
+ void *arg)
{
- unsigned int conf, mbar, addr;
- int i, j, cnt;
-
- for (cnt = i = 0; (i < amba_conf->ahbmst.devnr) && (maxno < cnt); i++) {
- conf = amba_get_confword (amba_conf->ahbslv, i, 0);
- if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
- for (j = 0; j < 4; j++) {
- mbar = amba_ahb_get_membar (amba_conf->ahbmst, i, j);
- addr = amba_membar_start (mbar);
- if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
- addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
- } else {
- /* convert address if needed */
- if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
- addr = 0; /* no available memory translation available, will not be able to access
- * Plug&Play information for this AHB address. Skip it.
- */
- }
- }
- devs[cnt].start[j] = addr;
- }
- devs[cnt].irq = amba_irq (conf);
- devs[cnt].ver = amba_ver (conf);
- cnt++;
- }
- }
- return cnt;
+ return ambapp_for_each_dev(abus->root, options, vendor, device, func, arg);
}
diff --git a/c/src/lib/libbsp/sparc/shared/amba/ambapp_alloc.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_alloc.c
new file mode 100644
index 0000000000..16962a7af7
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <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/c/src/lib/libbsp/sparc/shared/amba/ambapp_count.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_count.c
new file mode 100644
index 0000000000..8e0708b4e9
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <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/c/src/lib/libbsp/sparc/shared/amba/ambapp_depth.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_depth.c
new file mode 100644
index 0000000000..02fa76743b
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <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/c/src/lib/libbsp/sparc/shared/amba/ambapp_find_by_idx.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_find_by_idx.c
new file mode 100644
index 0000000000..7c6db627b1
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <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/c/src/lib/libbsp/sparc/shared/amba/ambapp_freq.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_freq.c
new file mode 100644
index 0000000000..03c0f68303
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <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.
+ */
+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/c/src/lib/libbsp/sparc/shared/amba/ambapp_names.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_names.c
new file mode 100644
index 0000000000..4a47366379
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/amba/ambapp_names.c
@@ -0,0 +1,392 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#include <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_APBUART, "APBUART"},
+ {GAISLER_IRQMP, "IRQMP"},
+ {GAISLER_AHBRAM, "AHBRAM"},
+ {GAISLER_AHBDPRAM, "AHBDPRAM"},
+ {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_LEON4, "LEON4"},
+ {GAISLER_LEON4DSU, "LEON4DSU"},
+ {GAISLER_GRPWM, "GRPWM"},
+ {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_APBPS2, "APBPS2"},
+ {GAISLER_VGACTRL, "VGACTRL"},
+ {GAISLER_LOGAN, "LOGAN"},
+ {GAISLER_SVGACTRL, "SVGACTRL"},
+ {GAISLER_T1AHB, "T1AHB"},
+ {GAISLER_MP7WRAP, "MP7WRAP"},
+ {GAISLER_GRSYSMON, "GRSYSMON"},
+ {GAISLER_GRACECTRL, "GRACECTRL"},
+ {GAISLER_B1553BC, "B1553BC"},
+ {GAISLER_B1553RT, "B1553RT"},
+ {GAISLER_B1553BRM, "B1553BRM"},
+ {GAISLER_SATCAN, "SATCAN"},
+ {GAISLER_CANMUX, "CANMUX"},
+ {GAISLER_GRTMRX, "GRTMRX"},
+ {GAISLER_GRTCTX, "GRTCTX"},
+ {GAISLER_GRTMDESC, "GRTMDESC"},
+ {GAISLER_GRTMVC, "GRTMVC"},
+ {GAISLER_GEFFE, "GEFFE"},
+ {GAISLER_AES, "AES"},
+ {GAISLER_GRAESDMA, "GRAESDMA"},
+ {GAISLER_ECC, "ECC"},
+ {GAISLER_PCIF, "PCIF"},
+ {GAISLER_CLKMOD, "CLKMOD"},
+ {GAISLER_HAPSTRAK, "HAPSTRAK"},
+ {GAISLER_TEST_1X2, "TEST_1X2"},
+ {GAISLER_WILD2AHB, "WILD2AHB"},
+ {GAISLER_BIO1, "BIO1"},
+ {GAISLER_GR1553B, "GR1553B"},
+ {GAISLER_L2CACHE, "L2CACHE"},
+ {GAISLER_L4STAT, "L4STAT"},
+ {GAISLER_GRPCI2, "GRPCI2"},
+ {GAISLER_GRPCI2_DMA, "GRPCI2_DMA"},
+ {GAISLER_GRIOMMU, "GRIOMMU"},
+ {GAISLER_SPW2_DMA, "SPW2_DMA"},
+ {GAISLER_SPW_ROUTER, "SPW_ROUTER"},
+ {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/c/src/lib/libbsp/sparc/shared/amba/ambapp_old.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_old.c
new file mode 100644
index 0000000000..15aebe58a1
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <ambapp.h>
+
+struct ambapp_dev_find_match_arg {
+ int index;
+ int count;
+ int type;
+ void *dev;
+};
+
+/* AMBA PP find routines */
+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/c/src/lib/libbsp/sparc/shared/amba/ambapp_parent.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_parent.c
new file mode 100644
index 0000000000..ef6f7e2f0b
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/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.com/license/LICENSE.
+ */
+
+#include <stdlib.h>
+#include <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/c/src/lib/libbsp/sparc/shared/amba/ambapp_show.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp_show.c
new file mode 100644
index 0000000000..f73ec1d768
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/amba/ambapp_show.c
@@ -0,0 +1,71 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#include <stdio.h>
+#include <ambapp.h>
+
+extern char *ambapp_device_id2str(int vendor, int id);
+extern char *ambapp_vendor_id2str(int vendor);
+
+struct ambapp_dev_print_arg {
+ int show_depth;
+};
+
+static char *unknown = "unknown";
+
+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);
+}