[rtems commit] LEON: updated AMBA PnP API

gedare at rtems.org gedare at rtems.org
Wed Apr 18 01:59:50 UTC 2012


Module:    rtems
Branch:    master
Commit:    9ea65119f400d5ad9acc3c52bdfd978fb96b930c
Changeset: http://git.rtems.org/rtems/commit/?id=9ea65119f400d5ad9acc3c52bdfd978fb96b930c

Author:    Daniel Hellstrom <daniel at gaisler.com>
Date:      Tue Apr 17 16:25:38 2012 +0200

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 at gaisler.com>

---

 c/src/lib/libbsp/sparc/Makefile.am                 |   10 +
 c/src/lib/libbsp/sparc/leon2/Makefile.am           |   15 +-
 c/src/lib/libbsp/sparc/leon2/preinstall.am         |   12 +-
 c/src/lib/libbsp/sparc/leon3/Makefile.am           |   15 +-
 c/src/lib/libbsp/sparc/leon3/amba/amba.c           |   47 +-
 c/src/lib/libbsp/sparc/leon3/include/amba.h        |    2 +-
 c/src/lib/libbsp/sparc/leon3/preinstall.am         |    4 +
 c/src/lib/libbsp/sparc/shared/amba/ambapp.c        |  794 +++++++++----------
 c/src/lib/libbsp/sparc/shared/amba/ambapp_alloc.c  |   25 +
 c/src/lib/libbsp/sparc/shared/amba/ambapp_count.c  |   23 +
 c/src/lib/libbsp/sparc/shared/amba/ambapp_depth.c  |   25 +
 .../libbsp/sparc/shared/amba/ambapp_find_by_idx.c  |   39 +
 c/src/lib/libbsp/sparc/shared/amba/ambapp_freq.c   |  109 +++
 c/src/lib/libbsp/sparc/shared/amba/ambapp_names.c  |  392 ++++++++++
 c/src/lib/libbsp/sparc/shared/amba/ambapp_old.c    |  112 +++
 c/src/lib/libbsp/sparc/shared/amba/ambapp_parent.c |   23 +
 c/src/lib/libbsp/sparc/shared/amba/ambapp_show.c   |   71 ++
 c/src/lib/libbsp/sparc/shared/include/ambapp.h     |  510 ++++++++-----
 c/src/lib/libbsp/sparc/shared/include/ambapp_ids.h |  245 ++++++
 19 files changed, 1839 insertions(+), 634 deletions(-)

diff --git a/c/src/lib/libbsp/sparc/Makefile.am b/c/src/lib/libbsp/sparc/Makefile.am
index 4f445ba..2b9909c 100644
--- a/c/src/lib/libbsp/sparc/Makefile.am
+++ b/c/src/lib/libbsp/sparc/Makefile.am
@@ -17,7 +17,17 @@ EXTRA_DIST += shared/irq/irq-shared.c
 
 # AMBA Plug&Play bus
 EXTRA_DIST += shared/include/ambapp.h
+EXTRA_DIST += shared/include/ambapp_ids.h
 EXTRA_DIST += shared/amba/ambapp.c
+EXTRA_DIST += shared/amba/ambapp_alloc.c
+EXTRA_DIST += shared/amba/ambapp_count.c
+EXTRA_DIST += shared/amba/ambapp_depth.c
+EXTRA_DIST += shared/amba/ambapp_find_by_idx.c
+EXTRA_DIST += shared/amba/ambapp_freq.c
+EXTRA_DIST += shared/amba/ambapp_parent.c
+EXTRA_DIST += shared/amba/ambapp_names.c
+EXTRA_DIST += shared/amba/ambapp_old.c
+EXTRA_DIST += shared/amba/ambapp_show.c
 
 # PCI bus
 EXTRA_DIST += shared/include/pci.h
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index 2acca78..c2310bc 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -14,7 +14,6 @@ include_HEADERS = include/bsp.h
 include_HEADERS += include/tm27.h
 include_HEADERS += include/rasta.h
 include_HEADERS += include/cchip.h
-include_HEADERS += ../../sparc/shared/include/ambapp.h
 include_HEADERS += ../../sparc/shared/include/grspw.h
 include_HEADERS += ../../sparc/shared/include/grspw_pci.h
 include_HEADERS += ../../sparc/shared/include/grspw_rasta.h
@@ -79,8 +78,20 @@ libbsp_a_SOURCES += \
     ../../shared/src/irq-legacy.c \
     ../../shared/src/irq-server.c \
     ../../shared/src/irq-shell.c
-# AMBA PnP Scanning
+
+# AMBA bus
+include_HEADERS += ../../sparc/shared/include/ambapp.h
+include_HEADERS += ../../sparc/shared/include/ambapp_ids.h
 libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_alloc.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_count.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_depth.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_find_by_idx.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_freq.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_parent.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_old.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_names.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_show.c
 # PCI
 libbsp_a_SOURCES += pci/pci.c ../../sparc/shared/pci/pcifinddevice.c
 # RASTA Kit
diff --git a/c/src/lib/libbsp/sparc/leon2/preinstall.am b/c/src/lib/libbsp/sparc/leon2/preinstall.am
index 00ed05e..2978d58 100644
--- a/c/src/lib/libbsp/sparc/leon2/preinstall.am
+++ b/c/src/lib/libbsp/sparc/leon2/preinstall.am
@@ -53,10 +53,6 @@ $(PROJECT_INCLUDE)/cchip.h: include/cchip.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/cchip.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/cchip.h
 
-$(PROJECT_INCLUDE)/ambapp.h: ../../sparc/shared/include/ambapp.h $(PROJECT_INCLUDE)/$(dirstamp)
-	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ambapp.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp.h
-
 $(PROJECT_INCLUDE)/grspw.h: ../../sparc/shared/include/grspw.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/grspw.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/grspw.h
@@ -157,6 +153,14 @@ $(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstam
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
 
+$(PROJECT_INCLUDE)/ambapp.h: ../../sparc/shared/include/ambapp.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ambapp.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp.h
+
+$(PROJECT_INCLUDE)/ambapp_ids.h: ../../sparc/shared/include/ambapp_ids.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ambapp_ids.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp_ids.h
+
 $(PROJECT_INCLUDE)/i2cmst.h: ../../sparc/shared/include/i2cmst.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i2cmst.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2cmst.h
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index ebbeb46..6bcc53f 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -44,10 +44,21 @@ libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
 libbsp_a_SOURCES += ../../sparc/shared/irq_asm.S
 # gnatsupp
 libbsp_a_SOURCES += gnatsupp/gnatsupp.c ../../sparc/shared/gnatcommon.c
-# amba
+# AMBA bus
 include_HEADERS += include/amba.h
 include_HEADERS += ../../sparc/shared/include/ambapp.h
-libbsp_a_SOURCES += amba/amba.c ../../sparc/shared/amba/ambapp.c
+include_HEADERS += ../../sparc/shared/include/ambapp_ids.h
+libbsp_a_SOURCES += amba/amba.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_alloc.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_count.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_depth.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_find_by_idx.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_freq.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_parent.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_old.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_names.c
+libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp_show.c
 # console
 libbsp_a_SOURCES += console/console.c
 # debugio
diff --git a/c/src/lib/libbsp/sparc/leon3/amba/amba.c b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
index 16fb8de..e41d0aa 100644
--- a/c/src/lib/libbsp/sparc/leon3/amba/amba.c
+++ b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
@@ -1,10 +1,10 @@
 /*
- *  AMBA Plag & Play Bus Driver
+ *  AMBA Plug & Play Bus Driver
  *
  *  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
@@ -14,9 +14,14 @@
  */
 
 #include <bsp.h>
+#include <ambapp.h>
 
-/* Structure containing address to devices found on the Amba Plug&Play bus */
-amba_confarea_type amba_conf;
+/* AMBA Plug&Play information description.
+ *
+ * After software has scanned AMBA PnP it builds a tree to make
+ * it easier for drivers to work with the bus architecture.
+ */
+struct ambapp_bus ambapp_plb;
 
 /* GRLIB extended IRQ controller register */
 extern void leon3_ext_irq_init(void);
@@ -38,16 +43,21 @@ extern int scan_uarts(void);
 
 void amba_initialize(void)
 {
-  int i;
   int icsel;
-  amba_apb_device dev;
+  struct ambapp_dev *adev;
 
-  /* Scan the AMBA Plug&Play info at the default LEON3 area */
-  amba_scan(&amba_conf,LEON3_IO_AREA,NULL);
+  /* Scan AMBA Plug&Play read-only information. The routine builds a PnP
+   * tree into ambapp_plb in RAM, after this we never access the PnP
+   * information in hardware directly any more.
+   * Since on Processor Local Bus (PLB) memory mapping is 1:1
+   */
+  ambapp_scan(&ambapp_plb, LEON3_IO_AREA, NULL, NULL);
 
   /* Find LEON3 Interrupt controller */
-  i = amba_find_apbslv(&amba_conf,VENDOR_GAISLER,GAISLER_IRQMP,&dev);
-  if (i <= 0){
+  adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS),
+                                 VENDOR_GAISLER, GAISLER_IRQMP,
+                                 ambapp_find_by_idx, NULL);
+  if (adev == NULL) {
     /* PANIC IRQ controller not found!
      *
      *  What else can we do but stop ...
@@ -55,7 +65,8 @@ void amba_initialize(void)
     asm volatile( "mov 1, %g1; ta 0x0" );
   }
 
-  LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *) dev.start;
+  LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *)
+                       DEV_TO_APB(adev)->start;
   if ((LEON3_IrqCtrl_Regs->ampctrl >> 28) > 0) {
     /* IRQ Controller has support for multiple IRQ Controllers, each
      * CPU can be routed to different Controllers, we find out which
@@ -74,9 +85,15 @@ void amba_initialize(void)
   leon3_ext_irq_init();
 
   /* find GP Timer */
-  i = amba_find_apbslv(&amba_conf,VENDOR_GAISLER,GAISLER_GPTIMER,&dev);
-  if ( i > 0 ) {
-    LEON3_Timer_Regs = (volatile LEON3_Timer_Regs_Map *) dev.start;
+  adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS),
+                                 VENDOR_GAISLER, GAISLER_GPTIMER,
+                                 ambapp_find_by_idx, NULL);
+  if (adev) {
+    LEON3_Timer_Regs = (volatile LEON3_Timer_Regs_Map *)DEV_TO_APB(adev)->start;
+
+    /* Register AMBA Bus Frequency */
+    ambapp_freq_init(&ambapp_plb, adev,
+                     (LEON3_Timer_Regs->scaler_reload + 1) * 1000000);
   }
 
   /* find UARTS */
diff --git a/c/src/lib/libbsp/sparc/leon3/include/amba.h b/c/src/lib/libbsp/sparc/leon3/include/amba.h
index 9167ff1..aa13f2c 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/amba.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/amba.h
@@ -34,7 +34,7 @@ extern "C" {
 #endif
 
 /* The AMBA Plug&Play info of the bus that the LEON3 sits on */
-extern amba_confarea_type amba_conf;
+extern struct ambapp_bus ambapp_plb;
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/sparc/leon3/preinstall.am b/c/src/lib/libbsp/sparc/leon3/preinstall.am
index 8c27b81..540e37b 100644
--- a/c/src/lib/libbsp/sparc/leon3/preinstall.am
+++ b/c/src/lib/libbsp/sparc/leon3/preinstall.am
@@ -85,6 +85,10 @@ $(PROJECT_INCLUDE)/ambapp.h: ../../sparc/shared/include/ambapp.h $(PROJECT_INCLU
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ambapp.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp.h
 
+$(PROJECT_INCLUDE)/ambapp_ids.h: ../../sparc/shared/include/ambapp_ids.h $(PROJECT_INCLUDE)/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ambapp_ids.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp_ids.h
+
 $(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
diff --git a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
index 814ee8c..504a3e7 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 0000000..16962a7
--- /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 0000000..8e0708b
--- /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 0000000..02fa767
--- /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 0000000..7c6db62
--- /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 0000000..03c0f68
--- /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 0000000..4a47366
--- /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 0000000..15aebe5
--- /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 0000000..ef6f7e2
--- /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 0000000..f73ec1d
--- /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);
+}
diff --git a/c/src/lib/libbsp/sparc/shared/include/ambapp.h b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
index 7ca2d13..651b7bf 100644
--- a/c/src/lib/libbsp/sparc/shared/include/ambapp.h
+++ b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
@@ -1,240 +1,366 @@
 /*
- *  AMBA Plag & Play Bus Driver Macros for LEON2
+ *  AMBA Plug & Play routines
  *
- *  Macros used for AMBA Plug & Play bus scanning
- *
- *  COPYRIGHT (c) 2007.
- *  Gaisler Research
+ *  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.
- *
- *  $Id$
  */
 
 #ifndef __AMBAPP_H__
 #define __AMBAPP_H__
 
+/* Include VENDOR and DEVICE definitions */
+#include <ambapp_ids.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define AMBA_CONF_AREA 0xff000
-#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
-
-#define AMBA_AHB_CONF_WORDS 8
-#define AMBA_APB_CONF_WORDS 2
-#define AMBA_AHB_MASTERS 16
-#define AMBA_AHB_SLAVES 16
-#define AMBA_APB_SLAVES 16
-#define AMBA_APBUARTS 8
-
-/* Vendor codes */
-#define VENDOR_GAISLER   1
-#define VENDOR_PENDER    2
-#define VENDOR_ESA       4
-#define VENDOR_OPENCORES 8
-
-/* Gaisler Research device id's */
-#define GAISLER_LEON3     0x03
-#define GAISLER_LEON3DSU  0x04
-#define GAISLER_ETHAHB    0x05
-#define GAISLER_APBMST    0x06
-#define GAISLER_AHBUART   0x07
-#define GAISLER_SRCTRL    0x08
-#define GAISLER_SDCTRL    0x09
-#define GAISLER_APBUART   0x0C
-#define GAISLER_IRQMP     0x0D
-#define GAISLER_AHBRAM    0x0E
-#define GAISLER_GPTIMER   0x11
-#define GAISLER_PCITRG    0x12
-#define GAISLER_PCISBRG   0x13
-#define GAISLER_PCIFBRG   0x14
-#define GAISLER_PCITRACE  0x15
-#define GAISLER_DMACTRL   0x16
-#define GAISLER_OCCAN     0x19
-#define GAISLER_PIOPORT   0x1A
-#define GAISLER_ETHMAC    0x1D
-#define GAISLER_SPACEWIRE 0x1f
-#define GAISLER_AHB2AHB   0x20
-#define GAISLER_I2CMST    0x28
-#define GAISLER_GRSPW2    0x29
-#define GAISLER_GRCAN     0x34
-#define GAISLER_GRHCAN    0x3d
-#define GAISLER_GRFIFO    0x35
-#define GAISLER_GRADCDAC  0x36
-#define GAISLER_GRPULSE   0x37
-#define GAISLER_GRTIMER   0x38
-#define GAISLER_FTAHBRAM  0x50
-#define GAISLER_FTMCTRL   0x54
-#define GAISLER_BRM       0x72
-
-
-/* European Space Agency device id's */
-#define ESA_LEON2        0x2
-#define ESA_MCTRL        0xF
-#define ESA_SPW2         0x12
-
-/* Opencores device id's */
-#define OPENCORES_PCIBR  0x4
-#define OPENCORES_ETHMAC 0x5
+/* Max supported AHB buses */
+#define AHB_BUS_MAX 6
+
+struct ambapp_dev;
+struct ambapp_core;
+struct ambapp_apb_info;
+struct ambapp_ahb_info;
+
+struct ambapp_dev {
+  struct ambapp_dev *next;      /* Next */
+  struct ambapp_dev *prev;      /* Previous Device. If (this == 
+                                 * rev->child) prev is bus bridge */
+  struct ambapp_dev *children;  /* Points to first device on sub-bus */
+  void *owner;                  /* Owner of this AMBA device */
+  unsigned char dev_type;       /* AHB MST, AHB SLV or APB SLV*/
+  unsigned char vendor;         /* Vendor ID */
+  unsigned short device;        /* Device ID */
+  int devinfo[0];               /* Device info (APB/AHB dep. on type) */
+};
 
-/*
- *
- * Macros for manipulating Configuration registers
- *
- */
-#define amba_get_confword(tab, index, word) (*((tab).addr[(index)]+(word)))
+#define AMBAPP_FLAG_FFACT_DIR  0x100  /* Frequency factor direction, 0=down, 1=up */
+#define AMBAPP_FLAG_FFACT  0x0f0  /* Frequency factor against top bus */
+#define AMBAPP_FLAG_MBUS  0x00c
+#define AMBAPP_FLAG_SBUS  0x003
+
+/* Get APB or AHB information from a AMBA device */
+#define DEV_TO_APB(adev) ((struct ambapp_apb_info *)((adev)->devinfo))
+#define DEV_TO_AHB(adev) ((struct ambapp_ahb_info *)((adev)->devinfo))
+#define DEV_TO_COMMON(adev) ((struct ambapp_common_info *)((adev)->devinfo))
+/* Convert address of ambapp_apb_info/ambapp_ahb_info into ambapp_dev */
+#define APB_TO_DEV(apb_info) ((struct ambapp_dev *)(unsigned int(apb_info) - \
+        offsetof(struct ambapp_dev, devinfo)))
+#define AHB_TO_DEV(ahb_info) ((struct ambapp_dev *)(unsigned int(ahb_info) - \
+        offsetof(struct ambapp_dev, devinfo)))
+
+struct ambapp_common_info {
+  unsigned char irq;
+  unsigned char ver;
+  unsigned char ahbidx;   /* AHB Bus Index */
+};
 
-#define amba_vendor(x) (((x) >> 24) & 0xff)
+struct ambapp_apb_info {
+  /* COMMON */
+  unsigned char irq;
+  unsigned char ver;
+  unsigned char ahbidx;   /* AHB Bus Index */
 
-#define amba_device(x) (((x) >> 12) & 0xfff)
+  /* APB SPECIFIC */
+  unsigned int start;
+  unsigned int mask;
+};
 
-#define amba_ahb_get_membar(tab, index, nr) (*((tab).addr[(index)]+4+(nr)))
+struct ambapp_ahb_info {
+  /* COMMON */
+  unsigned char irq;
+  unsigned char ver;
+  unsigned char ahbidx;   /* AHB Bus Index */
+
+  /* AHB SPECIFIC */
+  unsigned int start[4];
+  unsigned int mask[4];
+  char type[4];           /* type[N] Determine type of start[N]-mask[N],
+                           * 2=AHB Memory Space, 3=AHB I/O Space */
+  unsigned int custom[3];
+};
 
-#define amba_ahb_get_custom(tab, index, nr) (*((tab).addr[(index)]+1+(nr)))
+/* Describes a complete AMBA Core. Each device may consist of 3 interfaces */
+struct ambapp_core {
+  char irq;               /* irq=-1 indicate no IRQ */
+  unsigned char vendor;
+  unsigned short device;
+  int index;              /* Core index */
+  struct ambapp_ahb_info  *ahb_mst;
+  struct ambapp_ahb_info  *ahb_slv;
+  struct ambapp_apb_info  *apb_slv;
+};
 
-#define amba_apb_get_membar(tab, index) (*((tab).addr[(index)]+1))
+struct ambapp_ahb_bus {
+  unsigned int ioarea;        /* AHB Bus IOAREA */
+  unsigned int freq_hz;       /* Frequency of AHB Bus */
+  struct ambapp_dev *bridge;  /* Bridge Device on Parent AHB Bus */
+  struct ambapp_dev *dev;     /* First Device on AHB Bus */
+};
 
-#define amba_membar_start(mbar) (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
+struct ambapp_mmap {
+  unsigned int size;
+  unsigned int local_adr;
+  unsigned int remote_adr;
+};
 
-#define amba_iobar_start(base, iobar) ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
+/* Complete AMBA PnP information */
+struct ambapp_bus {
+  struct ambapp_dev *root;                  /* AHB/APB Device Tree*/
+  struct ambapp_mmap *mmaps;                /* Memory MAP Array */
+  struct ambapp_ahb_bus ahbs[AHB_BUS_MAX];  /* AHB Buses */
+};
 
-#define amba_irq(conf) ((conf) & 0x1f)
+/* 
+ * Return values
+ *  0 - continue
+ *  1 - stop scanning
+ */
+typedef int (*ambapp_func_t)(struct ambapp_dev *dev, int index, void *arg);
+
+#define DEV_IS_FREE(dev) (dev->owner == NULL)
+#define DEV_IS_ALLOCATED(dev) (dev->owner != NULL)
+
+/* Options to ambapp_for_each */
+#define OPTIONS_AHB_MSTS  0x00000001
+#define OPTIONS_AHB_SLVS  0x00000002
+#define OPTIONS_APB_SLVS  0x00000004
+#define OPTIONS_ALL_DEVS  (OPTIONS_AHB_MSTS|OPTIONS_AHB_SLVS|OPTIONS_APB_SLVS)
+
+#define OPTIONS_FREE    0x00000010
+#define OPTIONS_ALLOCATED  0x00000020
+#define OPTIONS_ALL    (OPTIONS_FREE|OPTIONS_ALLOCATED)
+
+/* Depth first search, Defualt is breath first search. */
+#define OPTIONS_DEPTH_FIRST  0x00000100
+
+#define DEV_AHB_NONE 0
+#define DEV_AHB_MST  1
+#define DEV_AHB_SLV  2
+#define DEV_APB_SLV 3
+
+/* Structures used to access Plug&Play information directly */
+struct ambapp_pnp_ahb {
+  const unsigned int id;        /* VENDOR, DEVICE, VER, IRQ, */
+  const unsigned int custom[3];
+  const unsigned int mbar[4];   /* MASK, ADDRESS, TYPE, CACHABLE/PREFETCHABLE */
+};
+
+struct ambapp_pnp_apb {
+  const unsigned int id;        /* VENDOR, DEVICE, VER, IRQ, */
+  const unsigned int iobar;     /* MASK, ADDRESS, TYPE, CACHABLE/PREFETCHABLE */
+};
 
-#define amba_ver(conf) (((conf)>>5) & 0x1f)
+#define ambapp_pnp_vendor(id) (((id) >> 24) & 0xff)
+#define ambapp_pnp_device(id) (((id) >> 12) & 0xfff)
+#define ambapp_pnp_ver(id) (((id)>>5) & 0x1f)
+#define ambapp_pnp_irq(id) ((id) & 0x1f)
 
-#define amba_membar_type(mbar) ((mbar) & 0xf)
+#define ambapp_pnp_start(mbar)  (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16)) 
+#define ambapp_pnp_mbar_mask(mbar) (((mbar)>>4) & 0xfff)
+#define ambapp_pnp_mbar_type(mbar) ((mbar) & 0xf)
+
+#define ambapp_pnp_apb_start(iobar, base) ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
+#define ambapp_pnp_apb_mask(iobar) ((~(ambapp_pnp_mbar_mask(iobar)<<8) & 0x000fffff) + 1)
+
+#define AMBA_TYPE_AHBIO_ADDR(addr, base_ioarea) ((unsigned int)(base_ioarea) | ((addr) >> 12))
 
 #define AMBA_TYPE_APBIO 0x1
 #define AMBA_TYPE_MEM   0x2
 #define AMBA_TYPE_AHBIO 0x3
 
-#define AMBA_TYPE_AHBIO_ADDR(addr,base_ioarea) ((unsigned int)(base_ioarea) | ((addr) >> 12))
-
-/*
- *  Types and structure used for AMBA Plug & Play bus scanning
+/* Copy Data from AMBA PnP I/O Area */
+typedef void *(*ambapp_memcpy_t)(
+  void *dest,               /* Destination RAM copy */
+  const void *src,          /* Source AMBA PnP Address to copy from */
+  int n,                    /* Number of bytes to be copied */
+  struct ambapp_bus *abus   /* Optional AMBA Bus pointer */
+  );
+
+/* Scan a AMBA Plug & Play bus and create all device structures describing the 
+ * the devices. The devices will form a tree, where every node describes one
+ * interface. The resulting tree is placed in the location pointed to by root.
+ *
+ * Since it the tree is located in RAM it is easier to work with AMBA buses
+ * that is located over PCI and SpaceWire etc.
+ *
+ * \param ioarea   The IO-AREA where Plug & Play information can be found.
+ * \param parent   Used internally when recursing down a bridge. Set to NULL.
+ * \param mmaps    Is used to perform address translation if needed.
+ * \param root     Resulting device node tree root is stored here.
  *
  */
-typedef struct amba_device_table {
-  int devnr;                    /* numbrer of devices on AHB or APB bus */
-  unsigned int *addr[16];       /* addresses to the devices configuration tables */
-} amba_device_table;
-
-typedef struct {
-  int devnr;
-  unsigned int *addr[AMBA_APB_SLAVES];  /* addresses to the devices configuration tables */
-  unsigned int apbmst[AMBA_APB_SLAVES]; /* pointer to AHB slave (which is a APB master) */
-} amba_apb_dev;
-
-struct amba_mmap {
-  unsigned int cpu_adr;
-  unsigned int size;
-  unsigned int remote_amba_adr;
-};
-
-typedef struct _amba_confarea_type amba_confarea_type;
-
-struct _amba_confarea_type {
-  amba_confarea_type  *next;   /* next bus in chain */
-  int                 notroot; /* is root of a bus (mother AHB has 64 masters/slaves rest 16) */
-	unsigned int        ioarea;
-  struct amba_mmap    *mmaps;
-  amba_device_table   ahbmst;
-  amba_device_table   ahbslv;
-  amba_apb_dev        apbslv;
-};
-
-typedef struct {
-  unsigned int start, irq, bus_id;
-} amba_apb_device;
-
-typedef struct {
-  unsigned int start[4], irq, ver;
-} amba_ahb_device;
-
-/* Scans AMBA Plug&Play Information and convers that information
- * to a more readable format in RAM.
+extern int ambapp_scan(
+  struct ambapp_bus *abus,
+  unsigned int ioarea,
+  ambapp_memcpy_t memfunc,
+  struct ambapp_mmap *mmaps
+  );
+
+/* Initialize the frequency [Hz] of all AHB Buses from knowing the frequency
+ * of one particular APB/AHB Device.
+ */
+extern void ambapp_freq_init(
+  struct ambapp_bus *abus,
+  struct ambapp_dev *dev,
+  unsigned int freq);
+
+/* Returns the frequency [Hz] of a AHB/APB device */
+extern unsigned int ambapp_freq_get(
+  struct ambapp_bus *abus,
+  struct ambapp_dev *dev);
+
+/* Iterates through all AMBA devices previously found, it calls func 
+ * once for every device that match the search arguments.
+ *
+ * SEARCH OPTIONS
+ * All search options must be fulfilled, type of devices searched (options)
+ * and AMBA Plug&Play ID [VENDOR,DEVICE], before func() is called. The options
+ * can be use to search only for AMBA APB or AHB Slaves or AHB Masters for
+ * example. Note that when VENDOR=-1 or DEVICE=-1 it will match any vendor or
+ * device ID, this means setting both VENDOR and DEVICE to -1 will result in
+ * calling all devices matches the options argument.
  *
- * Will scan for - AHB Masters
- *               - AHB Slaves
- *               - APB Slaves (if a AHB/APB bridge is found)
+ * \param abus     AMBAPP Bus to search
+ * \param options  Search options, see OPTIONS_* above
+ * \param vendor   AMBAPP VENDOR ID to search for
+ * \param device   AMBAPP DEVICE ID to search for
+ * \param func     Function called for every device matching search options
+ * \param arg      Optional argument passed on to func
  *
- * \param amba_conf AMBA P&P device info is placed here.
- * \param ioarea address of AMBA Plug&Play information,
- *             on LEON3 systems default is 0xfff00000
- * \param mmaps Memory mmap specific to this amba bus,
- *              if NULL no translation will be made (default).
- *              A array of maps, ending with a entry with size=0.
+ * func return value affects the search, returning a non-zero value will
+ * stop the search and ambapp_for_each will return immediately returning the
+ * same non-zero value.
+ *
+ * Return Values
+ *  0 - all devices was scanned
+ *  non-zero - stopped by user function returning the non-zero value
  */
-void amba_scan (amba_confarea_type * amba_conf, unsigned int ioarea,
-                struct amba_mmap *mmaps);
-
-/* Print AMBA Plug&Play info on terminal */
-void amba_print_conf (amba_confarea_type * amba_conf);
-
-
-
-
-/***** 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);
-
-/* 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);
-
-/* 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);
-
-/* 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);
-
-
-
-/***** AHB SLAVES *****/
-
-/* 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);
-
-/* 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);
-
-/* 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);
+extern int ambapp_for_each(
+  struct ambapp_bus *abus,
+  unsigned int options,
+  int vendor,
+  int device,
+  ambapp_func_t func,
+  void *arg);
+
+/* Helper function for ambapp_for_each(), find a device by index. If pcount
+ * is NULL the first device is returned, else pcount is interpreted as index
+ * by decrementing the value until zero is reaced: *count=0 first device,
+ * *count=1 second device etc.
+ *
+ * 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
+ */
+extern int ambapp_find_by_idx(struct ambapp_dev *dev, int index, void *pcount);
 
-/* 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);
+/* Get number of devices matching the options/vendor/device arguments, the
+ * arguments are passed onto ambapp_for_each().
+ */
+extern int ambapp_dev_count(struct ambapp_bus *abus, unsigned int options,
+                            int vendor, int device);
 
+/* Print short information about devices on the AMBA bus onto the console */
+extern void ambapp_print(struct ambapp_bus *abus, int show_depth);
 
+/* Mark a device taken (allocate), Owner field is set with owner Data. Returns
+ * -1 if device has already been allocated.
+ */
+extern int ambapp_alloc_dev(struct ambapp_dev *dev, void *owner);
 
-/***** AHB MASTERS *****/
+/* Owner field is cleared, which indicates that device is not allocated */
+extern void ambapp_free_dev(struct ambapp_dev *dev);
 
-/* Return number of AHB Master devices which has given vendor and device */
-int amba_get_number_ahbmst_devices (amba_confarea_type * amba_conf, int vendor,
-                                    int device);
+/* Find AHB/APB Bridge or AHB/AHB Bridge Parent */
+extern struct ambapp_dev *ambapp_find_parent(struct ambapp_dev *dev);
 
-/* Get First AHB Master device of this vendor&device id */
-int amba_find_ahbmst (amba_confarea_type * amba_conf, int vendor, int device,
-                      amba_ahb_device * dev);
+/* Returns bus depth (number of sub AHB buses) of device from root bus */
+extern int ambapp_depth(struct ambapp_dev *dev);
 
-/* Get AHB Master device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbmst() ) */
-int amba_find_next_ahbmst (amba_confarea_type * amba_conf, int vendor,
-                           int device, amba_ahb_device * dev, int index);
+/* Get Device Name from AMBA PnP name database */
+extern char *ambapp_device_id2str(int vendor, int id);
 
-/* Get first nr AHB Master 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);
+/* Get Vendor Name from AMBA PnP name database */
+extern char *ambapp_vendor_id2str(int vendor);
 
+/* Set together VENDOR_DEVICE Name from AMBA PnP name database. Return length
+ * of C-string stored in buf not including string termination '\0'.
+ */
+extern int ambapp_vendev_id2str(int vendor, int id, char *buf);
+
+/* Help functions for backwards compability */
+
+extern int ambapp_find_apbslv(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_apb_info *dev);
+
+extern int ambapp_find_apbslv_next(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_apb_info *dev,
+  int index);
+
+extern int ambapp_find_apbslvs_next(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_apb_info *dev,
+  int index,
+  int maxno);
+
+extern int ambapp_find_apbslvs(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_apb_info *dev,
+  int maxno);
+
+extern int ambapp_get_number_apbslv_devices(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device);
+
+extern int ambapp_find_ahbslv(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_ahb_info *dev);
+
+extern int ambapp_find_ahbslv_next(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_ahb_info *dev,
+  int index);
+
+extern int ambapp_find_ahbslvs_next(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_ahb_info *dev,
+  int index,
+  int maxno);
+
+extern int ambapp_find_ahbslvs(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device,
+  struct ambapp_ahb_info *dev,
+  int maxno);
+
+extern int ambapp_get_number_ahbslv_devices(
+  struct ambapp_bus *abus,
+  int vendor,
+  int device);
 
 /******** AMBA DEVICES *******/
 
diff --git a/c/src/lib/libbsp/sparc/shared/include/ambapp_ids.h b/c/src/lib/libbsp/sparc/shared/include/ambapp_ids.h
new file mode 100644
index 0000000..e6f3601
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/include/ambapp_ids.h
@@ -0,0 +1,245 @@
+/*  AMBA Plug & Play Bus Vendor and Device IDs.
+ *
+ *  COPYRIGHT (c) 2008.
+ *  Gaisler Research
+ *
+ *  This header file provide all known VENDOR and DEVICE IDs available 
+ *  in the AMBA Plug & Play information. Taken from GRLIB 3386.
+ *
+ *  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.
+ *
+ */
+
+
+#ifndef __AMBAPP_DEVS_H__
+#define __AMBAPP_DEVS_H__
+
+/* Vendor codes */
+#define VENDOR_GAISLER       1
+#define VENDOR_PENDER        2
+#define VENDOR_ESA           4
+#define VENDOR_ASTRIUM       6
+#define VENDOR_OPENCHIP      7
+#define VENDOR_OPENCORES     8
+#define VENDOR_CONTRIB       9
+#define VENDOR_EONIC         11
+#define VENDOR_RADIONOR      15
+#define VENDOR_GLEICHMANN    16
+#define VENDOR_MENTA         17
+#define VENDOR_SUN           19
+#define VENDOR_MOVIDIA       20
+#define VENDOR_ORBITA        23
+#define VENDOR_SYNOPSYS      33
+#define VENDOR_NASA          34
+#define VENDOR_ACTEL         172
+#define VENDOR_CAL           202
+#define VENDOR_EMBEDDIT      234
+#define VENDOR_CETON         203
+
+/* Gaisler Research device id's */
+#define GAISLER_LEON2DSU     0x002
+#define GAISLER_LEON3        0x003
+#define GAISLER_LEON3DSU     0x004
+#define GAISLER_ETHAHB       0x005
+#define GAISLER_APBMST       0x006
+#define GAISLER_AHBUART      0x007
+#define GAISLER_SRCTRL       0x008
+#define GAISLER_SDCTRL       0x009
+#define GAISLER_SSRCTRL      0x00a
+#define GAISLER_APBUART      0x00c
+#define GAISLER_IRQMP        0x00d
+#define GAISLER_AHBRAM       0x00e
+#define GAISLER_AHBDPRAM     0x00f
+#define GAISLER_GPTIMER      0x011
+#define GAISLER_PCITRG       0x012
+#define GAISLER_PCISBRG      0x013
+#define GAISLER_PCIFBRG      0x014
+#define GAISLER_PCITRACE     0x015
+#define GAISLER_DMACTRL      0x016
+#define GAISLER_AHBTRACE     0x017
+#define GAISLER_DSUCTRL      0x018
+#define GAISLER_CANAHB       0x019
+#define GAISLER_GPIO         0x01a
+#define GAISLER_AHBROM       0x01b
+#define GAISLER_AHBJTAG      0x01c
+#define GAISLER_ETHMAC       0x01d
+#define GAISLER_SWNODE       0x01e
+#define GAISLER_SPW          0x01f
+#define GAISLER_AHB2AHB      0x020
+#define GAISLER_USBDC        0x021
+#define GAISLER_USB_DCL      0x022
+#define GAISLER_DDRMP        0x023
+#define GAISLER_ATACTRL      0x024
+#define GAISLER_DDRSP        0x025
+#define GAISLER_EHCI         0x026
+#define GAISLER_UHCI         0x027
+#define GAISLER_I2CMST       0x028
+#define GAISLER_SPW2         0x029
+#define GAISLER_AHBDMA       0x02a
+#define GAISLER_NUHOSP3      0x02b
+#define GAISLER_CLKGATE      0x02c
+#define GAISLER_SPICTRL      0x02d
+#define GAISLER_DDR2SP       0x02e
+#define GAISLER_SLINK        0x02f
+#define GAISLER_GRTM         0x030
+#define GAISLER_GRTC         0x031
+#define GAISLER_GRPW         0x032
+#define GAISLER_GRCTM        0x033
+#define GAISLER_GRHCAN       0x034
+#define GAISLER_GRFIFO       0x035
+#define GAISLER_GRADCDAC     0x036
+#define GAISLER_GRPULSE      0x037
+#define GAISLER_GRTIMER      0x038
+#define GAISLER_AHB2PP       0x039
+#define GAISLER_GRVERSION    0x03a
+#define GAISLER_APB2PW       0x03b
+#define GAISLER_PW2APB       0x03c
+#define GAISLER_GRCAN        0x03d
+#define GAISLER_I2CSLV       0x03e
+#define GAISLER_U16550       0x03f
+#define GAISLER_AHBMST_EM    0x040
+#define GAISLER_AHBSLV_EM    0x041
+#define GAISLER_GRTESTMOD    0x042
+#define GAISLER_ASCS         0x043
+#define GAISLER_IPMVBCTRL    0x044
+#define GAISLER_SPIMCTRL     0x045
+#define GAISLER_L4STAT       0x047
+#define GAISLER_LEON4        0x048
+#define GAISLER_LEON4DSU     0x049
+#define GAISLER_GRPWM        0x04a
+#define GAISLER_L2CACHE      0x04b
+#define GAISLER_GR1553B      0x04d
+#define GAISLER_GRIOMMU      0x04f
+#define GAISLER_FTAHBRAM     0x050
+#define GAISLER_FTSRCTRL     0x051
+#define GAISLER_AHBSTAT      0x052
+#define GAISLER_LEON3FT      0x053
+#define GAISLER_FTMCTRL      0x054
+#define GAISLER_FTSDCTRL     0x055
+#define GAISLER_FTSRCTRL8    0x056
+#define GAISLER_MEMSCRUB     0x057
+#define GAISLER_APBPS2       0x060
+#define GAISLER_VGACTRL      0x061
+#define GAISLER_LOGAN        0x062
+#define GAISLER_SVGACTRL     0x063
+#define GAISLER_T1AHB        0x064
+#define GAISLER_MP7WRAP      0x065
+#define GAISLER_GRSYSMON     0x066
+#define GAISLER_GRACECTRL    0x067
+#define GAISLER_B1553BC      0x070
+#define GAISLER_B1553RT      0x071
+#define GAISLER_B1553BRM     0x072
+#define GAISLER_GRAES        0x073
+#define GAISLER_SATCAN       0x080
+#define GAISLER_CANMUX       0x081
+#define GAISLER_GRTMRX       0x082
+#define GAISLER_GRTCTX       0x083
+#define GAISLER_GRTMDESC     0x084
+#define GAISLER_GRTMVC       0x085
+#define GAISLER_GEFFE        0x086
+#define GAISLER_AES          0x073
+#define GAISLER_ECC          0x074
+#define GAISLER_PCIF         0x075
+#define GAISLER_CLKMOD       0x076
+#define GAISLER_HAPSTRAK     0x077
+#define GAISLER_TEST_1X2     0x078
+#define GAISLER_WILD2AHB     0x079
+#define GAISLER_BIO1         0x07a
+#define GAISLER_GRAESDMA     0x07b
+#define GAISLER_GRPCI2       0x07c
+#define GAISLER_GRPCI2_DMA   0x07d
+#define GAISLER_SPWCUC       0x089
+#define GAISLER_SPW2_DMA     0x08a
+#define GAISLER_SPW_ROUTER   0x08b
+
+
+#define GAISLER_PIPEWRAPPER  0xffa
+#define GAISLER_L2TIME       0xffd  /* internal device: leon2 timer */
+#define GAISLER_L2C          0xffe  /* internal device: leon2compat */
+#define GAISLER_PLUGPLAY     0xfff  /* internal device: plug & play configarea */
+
+/* European Space Agency device id's */
+#define ESA_LEON2            0x002
+#define ESA_LEON2APB         0x003
+#define ESA_IRQ              0x005
+#define ESA_TIMER            0x006
+#define ESA_UART             0x007
+#define ESA_CFG              0x008
+#define ESA_IO               0x009
+#define ESA_MCTRL            0x00f
+#define ESA_PCIARB           0x010
+#define ESA_HURRICANE        0x011
+#define ESA_SPW_RMAP         0x012
+#define ESA_SPW2             0x012
+#define ESA_AHBUART          0x013
+#define ESA_SPWA             0x014
+#define ESA_BOSCHCAN         0x015
+#define ESA_IRQ2             0x016
+#define ESA_AHBSTAT          0x017
+#define ESA_WPROT            0x018
+#define ESA_WPROT2           0x019
+#define ESA_PDEC3AMBA        0x020
+#define ESA_PTME3AMBA        0x021
+
+#define OPENCHIP_APBGPIO     0x001
+#define OPENCHIP_APBI2C      0x002
+#define OPENCHIP_APBSPI      0x003
+#define OPENCHIP_APBCHARLCD  0x004
+#define OPENCHIP_APBPWM      0x005
+#define OPENCHIP_APBPS2      0x006
+#define OPENCHIP_APBMMCSD    0x007
+#define OPENCHIP_APBNAND     0x008
+#define OPENCHIP_APBLPC      0x009
+#define OPENCHIP_APBCF       0x00a
+#define OPENCHIP_APBSYSACE   0x00b
+#define OPENCHIP_APB1WIRE    0x00c
+#define OPENCHIP_APBJTAG     0x00d
+#define OPENCHIP_APBSUI      0x00e
+
+
+#define CONTRIB_CORE1        0x001
+#define CONTRIB_CORE2        0x002
+
+#define GLEICHMANN_CUSTOM    0x001
+#define GLEICHMANN_GEOLCD01  0x002
+#define GLEICHMANN_DAC       0x003
+#define GLEICHMANN_HPI       0x004
+#define GLEICHMANN_SPI       0x005
+#define GLEICHMANN_HIFC      0x006
+#define GLEICHMANN_ADCDAC    0x007
+#define GLEICHMANN_SPIOC     0x008
+#define GLEICHMANN_AC97      0x009
+
+#define SUN_T1               0x001
+#define SUN_S1               0x011
+
+#define ORBITA_1553B         0x001
+#define ORBITA_429           0x002
+#define ORBITA_SPI           0x003
+#define ORBITA_I2C           0x004
+#define ORBITA_SMARTCARD     0x064
+#define ORBITA_SDCARD        0x065
+#define ORBITA_UART16550     0x066
+#define ORBITA_CRYPTO        0x067
+#define ORBITA_SYSIF         0x068
+#define ORBITA_PIO           0x069
+#define ORBITA_RTC           0x0c8
+#define ORBITA_COLORLCD      0x12c
+#define ORBITA_PCI           0x190
+#define ORBITA_DSP           0x1f4
+#define ORBITA_USBHOST       0x258
+#define ORBITA_USBDEV        0x2bc
+
+#define NASA_EP32            0x001
+
+#define CAL_DDRCTRL          0x188
+
+#define ACTEL_COREMP7        0x001
+
+/* Opencores device id's */
+#define OPENCORES_PCIBR  0x4
+#define OPENCORES_ETHMAC 0x5
+
+#endif




More information about the vc mailing list