summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/amba/ambapp.c')
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp.c455
1 files changed, 0 insertions, 455 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
deleted file mode 100644
index e3c777a5f5..0000000000
--- a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * AMBA Plug & Play routines
- *
- * COPYRIGHT (c) 2011.
- * Aeroflex Gaisler.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <ambapp.h>
-#include <bsp.h>
-
-#define AMBA_CONF_AREA 0xff000
-#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
-#define AMBA_APB_SLAVES 16
-
-/* Allocate one AMBA device */
-static struct ambapp_dev *ambapp_alloc_dev_struct(int dev_type)
-{
- struct ambapp_dev *dev;
- size_t size = sizeof(*dev);
-
- if (dev_type == DEV_APB_SLV)
- size += sizeof(struct ambapp_apb_info);
- else
- size += sizeof(struct ambapp_ahb_info); /* AHB */
- dev = (struct ambapp_dev *)calloc(1, size);
- if (dev != NULL)
- dev->dev_type = dev_type;
- return dev;
-}
-
-static unsigned int
-ambapp_addr_from (struct ambapp_mmap *mmaps, unsigned int address)
-{
- /* no translation? */
- if (!mmaps)
- return address;
-
- while (mmaps->size) {
- if ((address >= mmaps->remote_adr) &&
- (address <= (mmaps->remote_adr + (mmaps->size - 1)))) {
- return (address - mmaps->remote_adr) + mmaps->local_adr;
- }
- mmaps++;
- }
- return 1;
-}
-
-static void ambapp_ahb_dev_init(
- unsigned int ioarea,
- struct ambapp_mmap *mmaps,
- struct ambapp_pnp_ahb *ahb,
- struct ambapp_dev *dev,
- int ahbidx
- )
-{
- int bar;
- struct ambapp_ahb_info *ahb_info;
- unsigned int addr, mask, mbar;
-
- /* Setup device struct */
- dev->vendor = ambapp_pnp_vendor(ahb->id);
- dev->device = ambapp_pnp_device(ahb->id);
- ahb_info = DEV_TO_AHB(dev);
- ahb_info->ver = ambapp_pnp_ver(ahb->id);
- ahb_info->irq = ambapp_pnp_irq(ahb->id);
- ahb_info->ahbidx = ahbidx;
- ahb_info->custom[0] = (unsigned int)ahb->custom[0];
- ahb_info->custom[1] = (unsigned int)ahb->custom[1];
- ahb_info->custom[2] = (unsigned int)ahb->custom[2];
-
- /* Memory BARs */
- for (bar=0; bar<4; bar++) {
- mbar = ahb->mbar[bar];
- if (mbar == 0) {
- addr = 0;
- mask = 0;
- } else {
- addr = ambapp_pnp_start(mbar);
- if (ambapp_pnp_mbar_type(mbar) == AMBA_TYPE_AHBIO) {
- /* AHB I/O area is releative IO_AREA */
- addr = AMBA_TYPE_AHBIO_ADDR(addr, ioarea);
- mask = (((unsigned int)(ambapp_pnp_mbar_mask(~mbar) << 8) | 0xff)) + 1;
- } else {
- /* AHB memory area, absolute address */
- addr = ambapp_addr_from(mmaps, addr);
- mask = (~((unsigned int)(ambapp_pnp_mbar_mask(mbar) << 20))) + 1;
- }
- }
- ahb_info->start[bar] = addr;
- ahb_info->mask[bar] = mask;
- ahb_info->type[bar] = ambapp_pnp_mbar_type(mbar);
- }
-}
-
-static void ambapp_apb_dev_init(
- unsigned int base,
- struct ambapp_mmap *mmaps,
- struct ambapp_pnp_apb *apb,
- struct ambapp_dev *dev,
- int ahbidx
- )
-{
- struct ambapp_apb_info *apb_info;
-
- /* Setup device struct */
- dev->vendor = ambapp_pnp_vendor(apb->id);
- dev->device = ambapp_pnp_device(apb->id);
- apb_info = DEV_TO_APB(dev);
- apb_info->ver = ambapp_pnp_ver(apb->id);
- apb_info->irq = ambapp_pnp_irq(apb->id);
- apb_info->ahbidx = ahbidx;
- apb_info->start = ambapp_pnp_apb_start(apb->iobar, base);
- apb_info->mask = ambapp_pnp_apb_mask(apb->iobar);
-}
-
-static int ambapp_add_ahbbus(
- struct ambapp_bus *abus,
- unsigned int ioarea
- )
-{
- int i;
- for (i=0; i<AHB_BUS_MAX; i++) {
- if (abus->ahbs[i].ioarea == 0) {
- abus->ahbs[i].ioarea = ioarea;
- return i;
- } else if (abus->ahbs[i].ioarea == ioarea) {
- /* Bus already added */
- return -1;
- }
- }
- return -1;
-}
-
-/* Internal AMBA Scanning Function */
-static int ambapp_scan2(
- struct ambapp_bus *abus,
- unsigned int ioarea,
- ambapp_memcpy_t memfunc,
- struct ambapp_dev *parent,
- struct ambapp_dev **root
- )
-{
- struct ambapp_pnp_ahb *ahb, ahb_buf;
- struct ambapp_pnp_apb *apb, apb_buf;
- struct ambapp_dev *dev, *prev, *prevapb, *apbdev;
- struct ambapp_ahb_info *ahb_info;
- int maxloops = 64;
- unsigned int apbbase, bridge_adr;
- int i, j, ahbidx;
-
- *root = NULL;
-
- if (parent) {
- /* scan first bus for 64 devices, rest for 16 devices */
- maxloops = 16;
- }
-
- ahbidx = ambapp_add_ahbbus(abus, ioarea);
- if (ahbidx < 0) {
- /* Bus already scanned, stop */
- return 0;
- }
-
- prev = parent;
-
- /* AHB MASTERS */
- ahb = (struct ambapp_pnp_ahb *) (ioarea | AMBA_CONF_AREA);
- for (i = 0; i < maxloops; i++, ahb++) {
- memfunc(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
- if (ahb_buf.id == 0)
- continue;
-
- /* An AHB device present here */
- dev = ambapp_alloc_dev_struct(DEV_AHB_MST);
- if (!dev)
- return -1;
-
- ambapp_ahb_dev_init(ioarea, abus->mmaps, &ahb_buf, dev, ahbidx);
-
- if (*root == NULL)
- *root = dev;
-
- if (prev != parent)
- prev->next = dev;
- dev->prev = prev;
- prev = dev;
- }
-
- /* AHB SLAVES */
- ahb = (struct ambapp_pnp_ahb *)
- (ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
- for (i = 0; i < maxloops; i++, ahb++) {
- memfunc(&ahb_buf, ahb, sizeof(struct ambapp_pnp_ahb), abus);
- if (ahb_buf.id == 0)
- continue;
-
- /* An AHB device present here */
- dev = ambapp_alloc_dev_struct(DEV_AHB_SLV);
- if (!dev)
- return -1;
-
- ambapp_ahb_dev_init(ioarea, abus->mmaps, &ahb_buf, dev, ahbidx);
-
- if (*root == NULL)
- *root = dev;
-
- if (prev != parent)
- prev->next = dev;
- dev->prev = prev;
- prev = dev;
-
- ahb_info = DEV_TO_AHB(dev);
-
- /* Is it a AHB/AHB Bridge ? */
- if (((dev->device == GAISLER_AHB2AHB) &&
- (dev->vendor == VENDOR_GAISLER) && (ahb_info->ver > 0)) ||
- ((dev->device == GAISLER_L2CACHE) &&
- (dev->vendor == VENDOR_GAISLER)) ||
- ((dev->device == GAISLER_GRIOMMU) &&
- (dev->vendor == VENDOR_GAISLER))) {
- /* AHB/AHB Bridge Found, recurse down the
- * Bridge
- */
- if (ahb_info->custom[1] != 0) {
- bridge_adr = ambapp_addr_from(abus->mmaps,
- ahb_info->custom[1]);
- /* Scan next bus if not already scanned */
- if (ambapp_scan2(abus, bridge_adr, memfunc, dev,
- &dev->children))
- return -1;
- }
- } else if ((dev->device == GAISLER_APBMST) &&
- (dev->vendor == VENDOR_GAISLER)) {
- /* AHB/APB Bridge Found, add the APB devices to this
- * AHB Slave's children
- */
- prevapb = dev;
- apbbase = ahb_info->start[0];
-
- /* APB SLAVES */
- apb = (struct ambapp_pnp_apb *)
- (apbbase | AMBA_CONF_AREA);
- for (j=0; j<AMBA_APB_SLAVES; j++, apb++) {
- memfunc(&apb_buf, apb, sizeof(*apb), abus);
- if (apb_buf.id == 0)
- continue;
-
- apbdev = ambapp_alloc_dev_struct(DEV_APB_SLV);
- if (!apbdev)
- return -1;
-
- ambapp_apb_dev_init(apbbase, abus->mmaps,
- &apb_buf, apbdev, ahbidx);
-
- if (prevapb != dev)
- prevapb->next = apbdev;
- else
- dev->children = apbdev;
- apbdev->prev = prevapb;
- prevapb = apbdev;
- }
- }
- }
-
- /* Remember first AHB MST/SLV device on bus and Parent Bridge */
- abus->ahbs[ahbidx].dev = *root;
- abus->ahbs[ahbidx].bridge = parent;
-
- return 0;
-}
-
-/* Build AMBA Plug & Play device graph */
-int ambapp_scan(
- struct ambapp_bus *abus,
- unsigned int ioarea,
- ambapp_memcpy_t memfunc,
- struct ambapp_mmap *mmaps
- )
-{
- memset(abus, 0, sizeof(*abus));
- abus->mmaps = mmaps;
-
- /* Default to memcpy() */
- if (!memfunc)
- memfunc = (ambapp_memcpy_t)memcpy;
-
- return ambapp_scan2(abus, ioarea, memfunc, NULL, &abus->root);
-}
-
-/* Match search options againt device */
-static int ambapp_dev_match_options(struct ambapp_dev *dev, unsigned int options, int vendor, int device)
-{
- if ((((options & (OPTIONS_ALL_DEVS)) == OPTIONS_ALL_DEVS) || /* TYPE */
- ((options & OPTIONS_AHB_MSTS) && (dev->dev_type == DEV_AHB_MST)) ||
- ((options & OPTIONS_AHB_SLVS) && (dev->dev_type == DEV_AHB_SLV)) ||
- ((options & OPTIONS_APB_SLVS) && (dev->dev_type == DEV_APB_SLV))) &&
- ((vendor == -1) || (vendor == dev->vendor)) && /* VENDOR/DEV ID */
- ((device == -1) || (device == dev->device)) &&
- (((options & OPTIONS_ALL) == OPTIONS_ALL) || /* Allocated State */
- ((options & OPTIONS_FREE) && DEV_IS_FREE(dev)) ||
- ((options & OPTIONS_ALLOCATED) && DEV_IS_ALLOCATED(dev)))) {
- return 1;
- }
- return 0;
-}
-
-/* If device is an APB bridge all devices on the APB bridge is processed */
-static int ambapp_for_each_apb(
- struct ambapp_dev *dev,
- unsigned int options,
- int vendor,
- int device,
- ambapp_func_t func,
- void *arg)
-{
- int index, ret;
- struct ambapp_dev *apbslv;
-
- ret = 0;
- if (dev->children && (dev->children->dev_type == DEV_APB_SLV)) {
- /* Found a APB Bridge */
- index = 0;
- apbslv = dev->children;
- while (apbslv) {
- if (ambapp_dev_match_options(apbslv, options,
- vendor, device) == 1) {
- ret = func(apbslv, index, arg);
- if (ret != 0)
- break; /* Signalled stopped */
- }
- index++;
- apbslv = apbslv->next;
- }
- }
-
- return ret;
-}
-
-/* Traverse the prescanned device information */
-static int ambapp_for_each_dev(
- struct ambapp_dev *root,
- unsigned int options,
- int vendor,
- int device,
- ambapp_func_t func,
- void *arg)
-{
- struct ambapp_dev *dev;
- int ahb_slave = 0;
- int index, ret;
-
- /* Start at device 'root' and process downwards.
- *
- * Breadth first search, search order
- * 1. AHB MSTS
- * 2. AHB SLVS
- * 3. APB SLVS on primary bus
- * 4. AHB/AHB secondary... -> step to 1.
- */
-
- /* AHB MST / AHB SLV */
- if (options & (OPTIONS_AHB_MSTS|OPTIONS_AHB_SLVS|OPTIONS_DEPTH_FIRST)) {
- index = 0;
- dev = root;
- while (dev) {
- if ((dev->dev_type == DEV_AHB_SLV) && !ahb_slave) {
- /* First AHB Slave */
- ahb_slave = 1;
- index = 0;
- }
-
- /* Conditions must be fullfilled for function to be
- * called
- */
- if (ambapp_dev_match_options(dev, options, vendor, device) == 1) {
- /* Correct device and vendor ID */
- ret = func(dev, index, arg);
- if (ret != 0)
- return ret; /* Signalled stopped */
- }
-
- if ((options & OPTIONS_DEPTH_FIRST) && (options & OPTIONS_APB_SLVS)) {
- /* Check is APB bridge, and process all APB
- * Slaves in that case
- */
- ret = ambapp_for_each_apb(dev, options, vendor, device, func, arg);
- if (ret != 0)
- return ret; /* Signalled stopped */
- }
-
- if (options & OPTIONS_DEPTH_FIRST) {
- if (dev->children && (dev->children->dev_type != DEV_APB_SLV)) {
- /* Found AHB Bridge, recurse */
- ret = ambapp_for_each_dev(dev->children, options, vendor, device,
- func, arg);
- if (ret != 0)
- return ret;
- }
- }
-
- index++;
- dev = dev->next;
- }
- }
-
- /* Find APB Bridges */
- if ((options & OPTIONS_APB_SLVS) && !(options & OPTIONS_DEPTH_FIRST)) {
- dev = root;
- while (dev) {
- /* Check is APB bridge, and process all APB Slaves in
- * that case
- */
- ret = ambapp_for_each_apb(dev, options, vendor, device, func, arg);
- if (ret != 0)
- return ret; /* Signalled stopped */
- dev = dev->next;
- }
- }
-
- /* Find AHB Bridges */
- if (!(options & OPTIONS_DEPTH_FIRST)) {
- dev = root;
- while (dev) {
- if (dev->children && (dev->children->dev_type != DEV_APB_SLV)) {
- /* Found AHB Bridge, recurse */
- ret = ambapp_for_each_dev(dev->children, options, vendor, device,
- func, arg);
- if (ret != 0)
- return ret;
- }
- dev = dev->next;
- }
- }
-
- return 0;
-}
-
-int ambapp_for_each(
- struct ambapp_bus *abus,
- unsigned int options,
- int vendor,
- int device,
- ambapp_func_t func,
- void *arg)
-{
- return ambapp_for_each_dev(abus->root, options, vendor, device, func, arg);
-}