[PATCH 33.0 v2 1/5] LEON: updated AMBA PnP API

Joel Sherrill joel.sherrill at OARcorp.com
Wed Apr 18 00:28:43 UTC 2012


Looks ok to me also.

Please commit

Gedare Bloom <gedare at rtems.org> wrote:

>Looks good.
>
>On Tue, Apr 17, 2012 at 10:25 AM, Daniel Hellstrom <daniel at gaisler.com> wrote:
>> 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(-)
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_alloc.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_count.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_depth.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_find_by_idx.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_freq.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_names.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_old.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_parent.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/amba/ambapp_show.c
>>  create mode 100644 c/src/lib/libbsp/sparc/shared/include/ambapp_ids.h
>>
>> 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
>> --
>> 1.7.0.4
>>




More information about the devel mailing list