#
extra-y = start.o
-obj-y = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
+obj-y = cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \
+ interrupts.o prom.o usb_uhci.o
-/* Gaisler AMBA Plug&Play bus scanning. Functions
- * ending on _nomem is inteded to be used only during
- * initialization, only registers are used (no ram).
+/* GRLIB AMBA Plug&Play information scanning, relies on assembler
+ * routines.
*
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
+/* #define DEBUG */
+
#include <common.h>
-#include <command.h>
#include <ambapp.h>
+#include <config.h>
+
+/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/
+struct ambapp_find_apb_info {
+ /* Address of APB device Plug&Play information */
+ struct ambapp_pnp_apb *pnp;
+ /* AHB Bus index of where the APB-Master Bridge device was found */
+ int ahb_bus_index;
+ int dec_index;
+};
-#if defined(CONFIG_CMD_AMBAPP)
-extern void ambapp_print_apb(apbctrl_pp_dev * apb,
- ambapp_ahbdev * apbmst, int index);
-extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
-extern int ambapp_apb_print;
-extern int ambapp_ahb_print;
-#endif
-
-static int ambapp_apb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
- unsigned int driver, /* Plug&Play Device ID */
- ambapp_apbdev * dev, /* Result(s) is placed here */
- int index, /* Index of device to start copying Plug&Play
- * info into dev
- */
- int max_cnt /* Maximal count that dev can hold, if dev
- * is NULL function will stop scanning after
- * max_cnt devices are found.
- */
- )
-{
- int i, cnt = 0;
- unsigned int apbmst_base;
- ambapp_ahbdev apbmst;
- apbctrl_pp_dev *apb;
-
- if (max_cnt == 0)
- return 0;
-
- /* Get AMBA APB Master */
- if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
- return 0;
- }
+struct ambapp_find_ahb_info {
+ /* Address of AHB device Plug&Play information */
+ struct ambapp_pnp_ahb *pnp;
+ /* AHB Bus index of where the AHB device was found */
+ int ahb_bus_index;
+ int dec_index;
+};
- /* Get APB CTRL Plug&Play info area */
- apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
- apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
+extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus);
- for (i = 0; i < LEON3_APB_SLAVES; i++) {
-#if defined(CONFIG_CMD_AMBAPP)
- if (ambapp_apb_print && amba_vendor(apb->conf)
- && amba_device(apb->conf)) {
- ambapp_print_apb(apb, &apbmst, i);
- }
-#endif
- if ((amba_vendor(apb->conf) == vendor) &&
- (amba_device(apb->conf) == driver) && ((index < 0)
- || (index-- == 0))) {
- /* Convert Plug&Play info into a more readable format */
- cnt++;
- if (dev) {
- dev->irq = amba_irq(apb->conf);
- dev->ver = amba_ver(apb->conf);
- dev->address =
- (apbmst_base |
- (((apb->
- bar & 0xfff00000) >> 12))) & (((apb->
- bar &
- 0x0000fff0)
- << 4) |
- 0xfff00000);
- dev++;
- }
- /* found max devices? */
- if (cnt >= max_cnt)
- return cnt;
- }
- /* Get next Plug&Play entry */
- apb++;
- }
- return cnt;
-}
+extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend,
+ int index, struct ambapp_find_apb_info *result);
-unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
- register unsigned int driver, /* Plug&Play Device ID */
- register int index)
-{
- register int i;
- register ahbctrl_pp_dev *apbmst;
- register apbctrl_pp_dev *apb;
- register unsigned int apbmst_base;
-
- /* APBMST is a AHB Slave */
- apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
- if (!apbmst)
- return 0;
-
- apbmst_base = amba_membar_start(apbmst->bars[0]);
- if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
- apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
- apbmst_base &= LEON3_IO_AREA;
-
- /* Find the vendor/driver device on the first APB bus */
- apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
-
- for (i = 0; i < LEON3_APB_SLAVES; i++) {
- if ((amba_vendor(apb->conf) == vendor) &&
- (amba_device(apb->conf) == driver) && ((index < 0)
- || (index-- == 0))) {
- /* Convert Plug&Play info info a more readable format */
- return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
- & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
- }
- /* Get next Plug&Play entry */
- apb++;
- }
- return 0;
-}
+extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend,
+ int index, int type, struct ambapp_find_ahb_info *result);
-/****************************** APB SLAVES ******************************/
+/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/
+struct ambapp_bus ambapp_plb;
-int ambapp_apb_count(unsigned int vendor, unsigned int driver)
+void ambapp_bus_init(
+ unsigned int ioarea,
+ unsigned int freq,
+ struct ambapp_bus *abus)
{
- return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
+ int i;
+
+ ambapp_find_buses(ioarea, abus);
+ for (i = 0; i < 6; i++)
+ if (abus->ioareas[i] == 0)
+ break;
+ abus->buses = i;
+ abus->freq = freq;
}
-int ambapp_apb_first(unsigned int vendor,
- unsigned int driver, ambapp_apbdev * dev)
+/* Parse APB PnP Information */
+void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev)
{
- return ambapp_apb_scan(vendor, driver, dev, 0, 1);
+ struct ambapp_pnp_apb *apb = info->pnp;
+ unsigned int apbbase = (unsigned int)apb & 0xfff00000;
+
+ dev->vendor = amba_vendor(apb->id);
+ dev->device = amba_device(apb->id);
+ dev->irq = amba_irq(apb->id);
+ dev->ver = amba_ver(apb->id);
+ dev->address = (apbbase | (((apb->iobar & 0xfff00000) >> 12))) &
+ (((apb->iobar & 0x0000fff0) << 4) | 0xfff00000);
+ dev->mask = amba_apb_mask(apb->iobar);
+ dev->ahb_bus_index = info->ahb_bus_index - 1;
}
-int ambapp_apb_next(unsigned int vendor,
- unsigned int driver, ambapp_apbdev * dev, int index)
+/* Parse AHB PnP information */
+void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev)
{
- return ambapp_apb_scan(vendor, driver, dev, index, 1);
+ struct ambapp_pnp_ahb *ahb = info->pnp;
+ unsigned int ahbbase = (unsigned int)ahb & 0xfff00000;
+ int i, type;
+ unsigned int addr, mask, mbar;
+
+ dev->vendor = amba_vendor(ahb->id);
+ dev->device = amba_device(ahb->id);
+ dev->irq = amba_irq(ahb->id);
+ dev->ver = amba_ver(ahb->id);
+ dev->userdef[0] = ahb->custom[0];
+ dev->userdef[1] = ahb->custom[1];
+ dev->userdef[2] = ahb->custom[2];
+ dev->ahb_bus_index = info->ahb_bus_index - 1;
+ for (i = 0; i < 4; i++) {
+ mbar = ahb->mbar[i];
+ addr = amba_membar_start(mbar);
+ type = amba_membar_type(mbar);
+ if (type == AMBA_TYPE_AHBIO) {
+ addr = amba_ahbio_adr(addr, ahbbase);
+ mask = (((unsigned int)
+ (amba_membar_mask((~mbar))<<8)|0xff))+1;
+ } else {
+ /* AHB memory area, absolute address */
+ mask = (~((unsigned int)
+ (amba_membar_mask(mbar)<<20)))+1;
+ }
+ dev->address[i] = addr;
+ dev->mask[i] = mask;
+ dev->type[i] = type;
+ }
}
-int ambapp_apbs_first(unsigned int vendor,
- unsigned int driver, ambapp_apbdev * dev, int max_cnt)
+int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device,
+ int index, ambapp_apbdev *dev)
{
- return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
-}
+ unsigned int devid = AMBA_PNP_ID(vendor, device);
+ int found;
+ struct ambapp_find_apb_info apbdev;
-enum {
- AHB_SCAN_MASTER = 0,
- AHB_SCAN_SLAVE = 1
-};
-
-/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
- * for a certain matching Vendor and Device ID.
- *
- * Return number of devices found.
- *
- * Compact edition...
- */
-static int ambapp_ahb_scan(unsigned int vendor, /* Plug&Play Vendor ID */
- unsigned int driver, /* Plug&Play Device ID */
- ambapp_ahbdev * dev, /* Result(s) is placed here */
- int index, /* Index of device to start copying Plug&Play
- * info into dev
- */
- int max_cnt, /* Maximal count that dev can hold, if dev
- * is NULL function will stop scanning after
- * max_cnt devices are found.
- */
- int type /* Selectes what type of devices to scan.
- * 0=AHB Masters
- * 1=AHB Slaves
- */
- )
-{
- int i, j, cnt = 0, max_pp_devs;
- unsigned int addr;
- ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
- ahbctrl_pp_dev *ahb;
-
- if (max_cnt == 0)
- return 0;
-
- if (type == 0) {
- max_pp_devs = LEON3_AHB_MASTERS;
- ahb = info->masters;
- } else {
- max_pp_devs = LEON3_AHB_SLAVES;
- ahb = info->slaves;
- }
+ found = ambapp_find_apb(abus, devid, index, &apbdev);
+ if (found == 1)
+ ambapp_apb_parse(&apbdev, dev);
- for (i = 0; i < max_pp_devs; i++) {
-#if defined(CONFIG_CMD_AMBAPP)
- if (ambapp_ahb_print && amba_vendor(ahb->conf) &&
- amba_device(ahb->conf)) {
- ambapp_print_ahb(ahb, i);
- }
-#endif
- if ((amba_vendor(ahb->conf) == vendor) &&
- (amba_device(ahb->conf) == driver) &&
- ((index < 0) || (index-- == 0))) {
- /* Convert Plug&Play info info a more readable format */
- cnt++;
- if (dev) {
- dev->irq = amba_irq(ahb->conf);
- dev->ver = amba_ver(ahb->conf);
- dev->userdef[0] = ahb->userdef[0];
- dev->userdef[1] = ahb->userdef[1];
- dev->userdef[2] = ahb->userdef[2];
- for (j = 0; j < 4; j++) {
- addr = amba_membar_start(ahb->bars[j]);
- if (amba_membar_type(ahb->bars[j]) ==
- AMBA_TYPE_AHBIO)
- addr =
- AMBA_TYPE_AHBIO_ADDR(addr);
- dev->address[j] = addr;
- }
- dev++;
- }
- /* found max devices? */
- if (cnt >= max_cnt)
- return cnt;
- }
- /* Get next Plug&Play entry */
- ahb++;
- }
- return cnt;
+ return found;
}
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
+int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device)
{
- register unsigned int ret;
-
- if (!ahb)
- return 0;
-
- switch (info) {
- default:
- info = 0;
- case 0:
- case 1:
- case 2:
- case 3:
- /* Get Address from PnP Info */
- ret = amba_membar_start(ahb->bars[info]);
- if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
- ret = AMBA_TYPE_AHBIO_ADDR(ret);
- return ret;
- }
- return 0;
-
+ unsigned int devid = AMBA_PNP_ID(vendor, device);
+ int found;
+ struct ambapp_find_apb_info apbdev;
+
+ found = ambapp_find_apb(abus, devid, 63, &apbdev);
+ if (found == 1)
+ return 64;
+ else
+ return 63 - apbdev.dec_index;
}
-ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
- register unsigned int driver, /* Plug&Play Device ID */
- register unsigned int opts, /* 1=slave, 0=master */
- register int index)
+int ambapp_ahb_find(struct ambapp_bus *abus, int vendor, int device,
+ int index, ambapp_ahbdev *dev, int type)
{
- register ahbctrl_pp_dev *ahb;
- register ahbctrl_info *info =
- (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
- register int i;
- register int max_pp_devs;
-
- if (opts == 0) {
- max_pp_devs = LEON3_AHB_MASTERS;
- ahb = info->masters;
- } else {
- max_pp_devs = LEON3_AHB_SLAVES;
- ahb = info->slaves;
- }
+ int found;
+ struct ambapp_find_ahb_info ahbdev;
+ unsigned int devid = AMBA_PNP_ID(vendor, device);
- for (i = 0; i < max_pp_devs; i++) {
- if ((amba_vendor(ahb->conf) == vendor) &&
- (amba_device(ahb->conf) == driver) &&
- ((index < 0) || (index-- == 0))) {
- /* Convert Plug&Play info info a more readable format */
- return ahb;
- }
- /* Get next Plug&Play entry */
- ahb++;
- }
- return 0;
+ found = ambapp_find_ahb(abus, devid, index, type, &ahbdev);
+ if (found == 1)
+ ambapp_ahb_parse(&ahbdev, dev);
+
+ return found;
}
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
+int ambapp_ahbmst_find(struct ambapp_bus *abus, int vendor, int device,
+ int index, ambapp_ahbdev *dev)
{
- /* Get number of devices of this vendor&device ID */
- return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
- AHB_SCAN_MASTER);
+ return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST);
}
-int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
- ambapp_ahbdev * dev)
+int ambapp_ahbslv_find(struct ambapp_bus *abus, int vendor, int device,
+ int index, ambapp_ahbdev *dev)
{
- /* find first device of this */
- return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
+ return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV);
}
-int ambapp_ahbmst_next(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int index)
+int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type)
{
- /* find first device of this */
- return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
+ int found;
+ struct ambapp_find_ahb_info ahbdev;
+ unsigned int devid = AMBA_PNP_ID(vendor, device);
+
+ found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev);
+ if (found == 1)
+ return 64;
+ else
+ return 63 - ahbdev.dec_index;
}
-int ambapp_ahbmsts_first(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
+int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device)
{
- /* find first device of this */
- return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
- AHB_SCAN_MASTER);
+ return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST);
}
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
+int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device)
{
- /* Get number of devices of this vendor&device ID */
- return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
- AHB_SCAN_SLAVE);
+ return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV);
}
-int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
- ambapp_ahbdev * dev)
+/* The define CONFIG_SYS_GRLIB_SINGLE_BUS may be defined on GRLIB systems
+ * where only one AHB Bus is available - no bridges are present. This option
+ * is available only to reduce the footprint.
+ *
+ * Defining this on a multi-bus GRLIB system may also work depending on the
+ * design.
+ */
+
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
+
+/* GAISLER AHB2AHB Version 1 Bridge Definitions */
+#define AHB2AHB_V1_FLAG_FFACT 0x0f0 /* Frequency factor against top bus */
+#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100 /* Factor direction, 0=down, 1=up */
+#define AHB2AHB_V1_FLAG_MBUS 0x00c /* Master bus number mask */
+#define AHB2AHB_V1_FLAG_SBUS 0x003 /* Slave bus number mask */
+
+/* Get Parent bus frequency. Note that since we go from a "child" bus
+ * to a parent bus, the frequency factor direction is inverted.
+ */
+unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq)
{
- /* find first device of this */
- return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
+ int dir;
+ unsigned char ffact;
+
+ /* Get division/multiple factor */
+ ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4;
+ if (ffact != 0) {
+ dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR;
+
+ /* Calculate frequency by dividing or
+ * multiplying system frequency
+ */
+ if (dir)
+ freq = freq * ffact;
+ else
+ freq = freq / ffact;
+ }
+
+ return freq;
}
-int ambapp_ahbslv_next(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int index)
+/* AHB2AHB and L2CACHE ver 2 is not supported yet. */
+unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq)
{
- /* find first device of this */
- return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
+ panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n");
+ return -1;
}
+#endif
-int ambapp_ahbslvs_first(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
+/* Return the frequency of a AHB bus identified by index found
+ * note that this is not the AHB Bus number.
+ */
+unsigned int ambapp_bus_freq(struct ambapp_bus *abus, int ahb_bus_index)
{
- /* find first device of this */
- return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
+ unsigned int freq = abus->freq;
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
+ unsigned int ioarea, ioarea_parent, bridge_pnp_ofs;
+ struct ambapp_find_ahb_info ahbinfo;
+ ambapp_ahbdev ahb;
+ int parent;
+
+ debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index);
+
+ while (ahb_bus_index != 0) {
+ debug(" BUS[0]: 0x%08x\n", abus->ioareas[0]);
+ debug(" BUS[1]: 0x%08x\n", abus->ioareas[1]);
+ debug(" BUS[2]: 0x%08x\n", abus->ioareas[2]);
+ debug(" BUS[3]: 0x%08x\n", abus->ioareas[3]);
+ debug(" BUS[4]: 0x%08x\n", abus->ioareas[4]);
+ debug(" BUS[5]: 0x%08x\n", abus->ioareas[5]);
+
+ /* Get I/O area of AHB bus */
+ ioarea = abus->ioareas[ahb_bus_index];
+
+ printf(" IOAREA: 0x%08x\n", ioarea);
+
+ /* Get parent bus */
+ parent = (ioarea & 0x7);
+ if (parent == 0) {
+ panic("%s: parent=0 indicates no parent! Stopping.\n",
+ __func__);
+ return -1;
+ }
+ parent = parent - 1;
+ bridge_pnp_ofs = ioarea & 0x7e0;
+
+ debug(" PARENT: %d\n", parent);
+ debug(" BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs);
+
+ /* Get AHB/AHB bridge PnP address */
+ ioarea_parent = (abus->ioareas[parent] & 0xfff00000) |
+ AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA;
+ ahbinfo.pnp = (struct ambapp_pnp_ahb *)
+ (ioarea_parent | bridge_pnp_ofs);
+
+ debug(" IOAREA PARENT: 0x%08x\n", ioarea_parent);
+ debug(" BRIDGE PNP: 0x%p\n", ahbinfo.pnp);
+
+ /* Parse the AHB information */
+ ahbinfo.ahb_bus_index = parent;
+ ambapp_ahb_parse(&ahbinfo, &ahb);
+
+ debug(" BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n",
+ ahb.vendor, ahb.vendor, ahb.device, ahb.device);
+
+ /* Different bridges may convert frequency differently */
+ if ((ahb.vendor == VENDOR_GAISLER) &&
+ ((ahb.device == GAISLER_AHB2AHB) ||
+ (ahb.device == GAISLER_L2CACHE))) {
+ /* Get new frequency */
+ if (ahb.ver > 1)
+ freq = gaisler_ahb2ahb_v2_freq(&ahb, freq);
+ else
+ freq = gaisler_ahb2ahb_v1_freq(&ahb, freq);
+
+ debug(" NEW FREQ: %dHz\n", freq);
+ } else {
+ panic("%s: unsupported AMBA bridge\n", __func__);
+ return -1;
+ }
+
+ /* Step upwards towards system top bus */
+ ahb_bus_index = parent;
+ }
+#endif
+
+ debug("ambapp_bus_freq: %dHz\n", freq);
+
+ return freq;
}
--- /dev/null
+/* GRLIB AMBA Plug&Play information scanning implemented without
+ * using memory (stack) and one register window. The code scan
+ * the PnP info and inserts the AHB bridges/buses into register
+ * i0-i5.
+ * The code support
+ * - up to 6 AHB buses
+ * - multiple APB buses
+ * - support for AHB2AHB & L2CACHE bridges
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <ambapp.h>
+
+ .seg "text"
+ .globl _nomem_amba_init
+ .globl _nomem_ambapp_find_buses
+ .globl _nomem_find_apb
+ .globl _nomem_find_ahb
+
+/* Overview
+ * ========
+ *
+ * _nomem_amba_init - Init AMBA bus and calls _nomem_ambapp_find_buses
+ * _nomem_ambapp_find_buses - Scan AMBA PnP info for AHB buses/bridges and
+ * place them in i0-i5, see below
+ * _nomem_find_apb - Find one APB device identified by VENDOR:DEVICE
+ * ID and an index.
+ * _nomem_find_ahb - Find one AHB Master or Slave device identified
+ * by VENDOR:DEVICE ID and an index.
+ * init_ahb_bridges - Local function. Clears i0-i5
+ * insert_ahb_bridge - Local function. Insert a new AHB bus into first
+ * free register in i0-i5. It also checks that the
+ * bus has not already been added.
+ * get_ahb_bridge - Local function. Get AHB bus from registers,
+ * return register iN, where N is defined by o0.
+ *
+ * The _nomem_find_apb and _nomem_find_ahb function requires that i0-i5
+ * are populated with the AHB buses of the system. The registers are
+ * initialized by _nomem_ambapp_find_buses.
+ *
+ * AHB Bus result and requirements of i0-i5
+ * ========================================
+ *
+ * i0: AHB BUS0 IOAREA, no parent bus
+ * i1: AHB BUS1 IOAREA, parent bus is always i0 (AHB BUS0) and bridge address
+ * i2: AHB BUS2 IOAREA, 3-bit parent bus number and bridge address
+ * i3: AHB BUS3 IOAREA, 3-bit parent bus number and bridge address
+ * i4: AHB BUS4 IOAREA, 3-bit parent bus number and bridge address
+ * i5: AHB BUS5 IOAREA, 3-bit parent bus number and bridge address
+ *
+ * AHB BUS
+ * -------
+ * Bits 31-20 (0xfff00000) contain the found bus I/O Area (AHB PnP area).
+ *
+ * 3-bit Parent bus
+ * ----------------
+ * Bits 2-0 (0x00000007) contain parent bus number. Zero if no parent
+ * bus, 1 = parent is AHB BUS 0 (i0), 2 = parent is AHB BUS 1 (i1)..
+ *
+ * Bridge Address
+ * --------------
+ * Bits 10-5 (0x000007e0) contain the index of the Bridge's PnP
+ * information on the parent. Since all bridges are found in the
+ * PnP information they all have a PnP entry. Together with the
+ * parent bus number the PnP entry can be found:
+ * PnPEntry = (BRIDGE_ADDRESS + (iN & 0xfff00000)) | 0x000ff800
+ * where N is the parent bus minus one.
+ *
+ */
+
+/* Function initializes the AHB Bridge I/O AREA storage. (Clears i0-i5)
+ *
+ * Arguments
+ * none
+ *
+ * Results
+ * none
+ *
+ * Clobbered
+ * none
+ */
+
+init_ahb_bridges:
+ mov %g0, %i0
+ mov %g0, %i1
+ mov %g0, %i2
+ mov %g0, %i3
+ mov %g0, %i4
+ retl
+ mov %g0, %i5
+
+/* Function returns AHB Bridge I/O AREA for specified bus.
+ *
+ * Arguments
+ * - o0 = bus number
+ *
+ * Results
+ * - o0 = I/O AREA
+ *
+ * Clobbered
+ * none
+ */
+get_ahb_bridge:
+ cmp %o0, 1
+ be,a L1
+ mov %i0, %o0
+
+ cmp %o0, 2
+ be,a L1
+ mov %i1, %o0
+
+ cmp %o0, 3
+ be,a L1
+ mov %i2, %o0
+
+ cmp %o0, 4
+ be,a L1
+ mov %i3, %o0
+
+ cmp %o0, 5
+ be,a L1
+ mov %i4, %o0
+
+ cmp %o0, 6
+ be,a L1
+ mov %i5, %o0
+
+ /* o0 > 6: only 6 buses supported */
+ mov %g0, %o0
+L1:
+ retl
+ nop
+
+/* Function adds a AHB Bridge I/O AREA to the i0-i5 registers if
+ * not already added. It stores the bus PnP start information.
+ *
+ * Arguments
+ * - o0 = AHB Bridge I/O area
+ *
+ * Results
+ * none
+ *
+ * Clobbered
+ * o2, o3
+ */
+insert_ahb_bridge:
+ /* Check that bridge hasn't already been added */
+ andn %o0, 0x7ff, %o2
+ andn %i0, 0x7ff, %o3
+ cmp %o3, %o2
+ be L2
+ andn %i1, 0x7ff, %o3
+ cmp %o3, %o2
+ be L2
+ andn %i2, 0x7ff, %o3
+ cmp %o3, %o2
+ be L2
+ andn %i3, 0x7ff, %o3
+ cmp %o3, %o2
+ be L2
+ andn %i4, 0x7ff, %o3
+ cmp %o3, %o2
+ be L2
+ andn %i5, 0x7ff, %o3
+ cmp %o3, %o2
+ be L2
+
+ /* Insert into first free posistion */
+ cmp %i0, %g0
+ be,a L2
+ mov %o0, %i0
+
+ cmp %i1, %g0
+ be,a L2
+ mov %o0, %i1
+
+ cmp %i2, %g0
+ be,a L2
+ mov %o0, %i2
+
+ cmp %i3, %g0
+ be,a L2
+ mov %o0, %i3
+
+ cmp %i4, %g0
+ be,a L2
+ mov %o0, %i4
+
+ cmp %i5, %g0
+ be,a L2
+ mov %o0, %i5
+L2:
+ retl
+ nop
+
+/* FUNCTION int _nomem_find_ahb_bus(
+ * unsigned int bridge,
+ * int vendor_device,
+ * int index,
+ * void **pconf,
+ * int not_used,
+ * int option
+ * )
+ *
+ * Scans the AHB Master or Slave area for a matching VENDOR:DEVICE, the
+ * index is decremented when a matching device is found but index is
+ * greater than zero. When index is zero and a matching DEVICE:VENDOR
+ * is found the AHB configuration address and AHB I/O area is returned.
+ *
+ * i0-i7,l0,l1,l2,l3,l4,g2,o6 is not available for use.
+ * o1,o5 Must be left untouched
+ *
+ * Results
+ * - o0 Number of found devices (1 or 0)
+ * - o2 is decremented for each matching VENDOR:DEVICE found, zero if found
+ * - o3 Address of the AHB PnP configuration entry (Only valid if o0=1)
+ *
+ * Clobbered
+ * - o3 (Clobbered when no device was found)
+ * - o4 (Number of Devices left to search)
+ * - o0 (Bus ID, PnP ID, Device)
+ */
+_nomem_find_ahb_bus:
+
+ /* Get the number of Slaves/Masters.
+ * Only AHB Bus 0 has 64 AHB Masters/Slaves the
+ * other AHB buses has 16 slaves and 16 masters.
+ */
+ add %g0, 16, %o4 /* Defaulting to 16 */
+ andcc %o0, 0x7, %g0 /* 3-bit bus id */
+ be,a .L_maxloops_detected
+ add %g0, 64, %o4 /* AHB Bus 0 has 64 AHB Masters/Slaves */
+.L_maxloops_detected:
+
+ /* Get start address of AHB Slave or AHB Master area depending on what
+ * we are searching for.
+ */
+ andn %o0, 0x7ff, %o0 /* Remove Bus ID and 5-bit AHB/AHB
+ * Bridge PnP Address to get I/O Area */
+ set AMBA_CONF_AREA, %o3
+ or %o3, %o0, %o3 /* Master area address */
+
+ cmp %o5, DEV_AHB_SLV
+ be,a .L_conf_area_calculated
+ or %o3, AMBA_AHB_SLAVE_CONF_AREA, %o3 /* Add 0x800 to get to slave area */
+.L_conf_area_calculated:
+
+ /* Iterate over all AHB device and try to find matching DEVICE:VENDOR
+ * o1 - VENDOR|DEVICE
+ * o2 - Index
+ * o3 - Current AHB Device Configuration address
+ * o5 - Type (leave untouched)
+ *
+ * o4 - Number of AHB device left to process
+ * o0 - tmp
+ */
+.L_process_one_conf:
+ ld [%o3], %o0
+ andn %o0, 0xfff, %o0
+ cmp %o0, 0 /* No device if zero */
+ beq .L_next_conf
+ cmp %o1, 0 /* If VENDOR:DEVICE==0, consider all matching */
+ beq .L_process_ahb_dev_found
+ cmp %o0, %o1 /* Does VENDOR and DEVICE Match? */
+ bne .L_next_conf
+ nop
+.L_process_ahb_dev_found:
+ /* Found a Matching VENDOR:DEVICE, index must also match */
+ cmp %o2, %g0
+ bne .L_next_conf
+ dec %o2
+ /* Index matches also, return happy with o3 set to AHB Conf Address */
+ mov %g0, %o2
+ retl
+ add %g0, 1, %o0
+
+.L_next_conf:
+ subcc %o4, 1, %o4 /* One device has been processed,
+ * Are there more devices to process? */
+ bne .L_process_one_conf
+ add %o3, AMBA_AHB_CONF_LENGH, %o3 /* Next Configuration entry */
+ /* No Matching device found */
+ retl
+ mov %g0, %o0
+
+/* FUNCTION int _nomem_find_ahb(
+ * int unused,
+ * int vendor_device,
+ * int index,
+ * void **pconf,
+ * int *ahb_bus_index,
+ * int option,
+ * )
+ *
+ * Find a AHB Master or AHB Slave device, it puts the address of the AHB PnP
+ * configuration in o3 (pconf), the I/O Area base address in o4 (pioarea).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus.
+ *
+ * i0-i7, l0, l1, o6, g1, g4-g7 is not available for use.
+ *
+ * Arguments
+ * - o0 Unused
+ *
+ * Results
+ * - o0 Number of found devices (1 or 0)
+ * - o2 Decremented Index (Zero if found)
+ * - o3 Address of the AHB PnP configuration entry
+ * - o4 AHB Bus index the device was found on (if o0=1)
+ * - o5 Left untouched
+ *
+ * Clobbered
+ * - o0 (AHB Bridge and used by _nomem_find_ahb_bus)
+ * - o2 (index is decremented)
+ * - l2 (Current AHB Bus index)
+ * - g2 (return address)
+ */
+_nomem_find_ahb:
+ mov %o7, %g2 /* Save return address */
+ /* Scan all AHB Buses found for the AHB Master/Slave matching VENDOR:DEVICE */
+ clr %l2
+.L_search_next_ahb_bus:
+ add %l2, 1, %l2
+ call get_ahb_bridge /* Get bus %l0 I/O Area */
+ mov %l2, %o0
+ cmp %o0, %g0
+ be .L_no_device_found /* If no more AHB bus is left to be scanned, proceed */
+ nop
+ call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */
+ nop
+ cmp %o0, %g0 /* If VENDOR:DEVICE was not found scan next AHB Bus */
+ be .L_search_next_ahb_bus /* Do next bus is o0=0 (not found) */
+ nop
+ /* The device was found, o0 is 1 */
+ mov %g2, %o7 /* Restore return address */
+ retl
+ mov %l2, %o4 /* The AHB bus index the device was found on */
+
+ /* No device found matching */
+.L_no_device_found:
+ mov %g2, %o7 /* Restore return address */
+ retl
+ mov %g0, %o0
+
+
+/* FUNCTION int _nomem_find_apb_bus(
+ * int apbmst,
+ * int vendor_device,
+ * int index,
+ * void **pconf
+ * )
+ *
+ * Find a APB Slave device, it puts the address of the APB PnP configuration
+ * in o3 (pconf).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges.
+ * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST.
+ *
+ * Results
+ * - o0 Number of found devices (1 or 0)
+ * - o2 Decremented Index
+ * - o3 Address of the found APB device PnP configuration entry
+ *
+ * Clobbered
+ * - o5 PnP VENDOR:DEVICE ID
+ */
+
+_nomem_find_apb_bus:
+ set AMBA_CONF_AREA, %o3
+ or %o0, %o3, %o3 /* Calc start of APB device PnP info */
+ add %g0, 16, %o0 /* o0, number of APB Slaves left to scan */
+.L_process_one_apb_conf:
+ ld [%o3], %o5
+ andn %o5, 0xfff, %o5
+ cmp %o5, 0 /* No device if zero */
+ beq .L_process_apb_dev_not_found
+ cmp %o1, 0 /* If VENDOR:DEVICE == -1, consider all matching */
+ beq .L_process_apb_dev_found
+ cmp %o1, %o5 /* Found VENDOR:DEVICE */
+ bne .L_process_apb_dev_not_found
+ nop
+
+.L_process_apb_dev_found:
+ /* Found matching device, compare index */
+ cmp %o2, %g0
+ bne .L_process_apb_dev_not_found
+ dec %o2
+ /* Matching index and VENDOR:DEVICE */
+ retl
+ add %g0, 1, %o0
+
+.L_process_apb_dev_not_found:
+ subcc %o0, 1, %o0
+ bne .L_process_one_apb_conf
+ add %o3, 8, %o3
+ retl
+ mov %g0, %o0
+
+/* FUNCTION int _nomem_find_apb(
+ * int unused,
+ * int vendor_device,
+ * int index,
+ * void **pconf,
+ * int *ahb_bus_index
+ * )
+ *
+ * Find a APB Slave device, it puts the address of the APB PnP configuration
+ * in o3 (pconf), the APB Master I/O Area base address in o4 (papbarea).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges.
+ * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST.
+ *
+ * i0-i7, l0, l1, o6 is not available for use.
+ *
+ * Arguments
+ * - o0 Unused
+ *
+ * Results
+ * - o0 Number of found devices (1 or 0)
+ * - o2 Decremented Index if not found
+ * - o3 Address of the APB PnP configuration entry
+ * - o4 AHB Bus index of APB Bridge/APB Device
+ *
+ * Clobbered
+ * - o0 (AHB Bridge)
+ * - o2 (index is decremented)
+ * - l2 (APB DEV Index [7..4] : APBMST AHB Index [3..0])
+ * - l3 (Current AHB Bus index)
+ * - l4 (temporary storage for APB VENDOR:DEVICE)
+ * - o5 (AHB Slave ID)
+ * - o0 (clobbered by _nomem_find_ahb_bus)
+ * - g2 (Return address)
+ */
+_nomem_find_apb:
+ /* Scan all AHB Buses found for AHB/APB Bridges */
+ mov %o7, %g2 /* Save return address */
+ mov %o1, %l4 /* Save APB VENDOR:DEVICE */
+ sll %o2, 4, %l2 /* APB MST index = 0 */
+ add %g0, 1, %l3 /* AHB Bus index = 0 */
+.L2_search_next_ahb_bus:
+ call get_ahb_bridge /* Get bus %l3 I/O Area */
+ mov %l3, %o0
+ cmp %o0, %g0
+ be .L2_no_device_found /* If no more AHB bus is left to be scanned, proceed */
+ add %g0, DEV_AHB_SLV, %o5 /* Search for AHB Slave */
+ sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_APBMST)), %o1
+ call _nomem_find_ahb_bus /* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented */
+ and %l2, 0xf, %o2 /* Set APBMST index */
+ cmp %o0, %g0 /* If no AHB/APB Bridge was not found, scan next AHB Bus */
+ be .L_no_apb_bridge_found /* Do next bus */
+ nop
+
+ /* The AHB/APB Bridge was found.
+ * Search for the requested APB Device on the APB bus using
+ * find_apb_bus, it will decrement the index.
+ */
+ ld [%o3 + AMBA_AHB_MBAR0_OFS], %o3
+ sll %o3, 16, %o0
+ and %o0, %o3, %o0 /* Address AND Address Mask */
+ sethi %hi(0xfff00000), %o3
+ and %o0, %o3, %o0 /* AHB/APB Bridge address */
+
+ srl %l2, 4, %o2 /* APB DEV Index */
+ call _nomem_find_apb_bus
+ mov %l4, %o1 /* APB VENDOR:DEVICE */
+ cmp %o0, %g0
+ be .L_apb_dev_not_found
+ mov %g2, %o7 /* Restore return address */
+ /* APB Device found
+ * o0 1
+ * o2 Index is decremented to zero
+ * o3 APB configuration address,
+ * o4 APB Bridge Configuration address.
+ */
+ mov %g0, %o2
+ retl
+ mov %l3, %o4
+
+.L_apb_dev_not_found:
+ /* Update APB DEV Index by saving output from find_apb_bus
+ * (index parameter) into bits [31..4] in L2.
+ */
+ sll %o2, 4, %o2
+ and %l2, 0xf, %l2
+ or %o2, %l2, %l2
+ /* Try finding the next AHB/APB Bridge on the same AHB bus
+ * to find more APB devices
+ */
+ ba .L2_search_next_ahb_bus /* Find next AHB/APB bridge */
+ inc %l2
+
+.L_no_apb_bridge_found:
+ inc %l3 /* Next AHB Bus */
+ ba .L2_search_next_ahb_bus /* Process next AHB bus */
+ andn %l2, 0xf, %l2 /* Start at APB Bridge index 0 at every AHB Bus */
+ /* No device found matching */
+.L2_no_device_found:
+ mov %g2, %o7 /* Restore return address */
+ srl %l2, 4, %o2 /* APB DEV Index */
+ retl
+ mov %g0, %o0
+
+
+
+/* FUNCTION _nomem_amba_scan_gaisler_ahb2ahb_bridge(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ * - o1 may not be used
+ * - o0, o2, o3 may be used.
+ *
+ * Arguments
+ * - o0 PnP Address of Bridge AHB device
+ * - o2 PnP ID of AHB device
+ *
+ * Results
+ * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge
+ *
+ * Clobbered
+ * - o0, o2
+ *
+ */
+_nomem_amba_scan_gaisler_ahb2ahb_bridge:
+ andn %o2, 0xfff, %o2
+ sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_AHB2AHB)), %o3
+ cmp %o2, %o3
+ beq .L_is_ahb2ahb_bridge
+ nop
+
+ retl
+ add %g0, 1, %o0
+
+.L_is_ahb2ahb_bridge:
+ /* Found a GAISLER AHB2AHB bridge */
+ retl
+ ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */
+
+
+/* FUNCTION _nomem_amba_scan_gaisler_l2cache_bridge(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ * - o1 may not be used
+ * - o0, o2, o3 may be used.
+ *
+ * Arguments
+ * - o0 PnP Address of Bridge AHB device
+ * - o2 PnP ID of AHB device
+ *
+ * Results
+ * - o0 Address of new bus PnP area or a 1 if AHB device is no bridge
+ *
+ * Clobbered
+ * - o0, o2
+ *
+ */
+_nomem_amba_scan_gaisler_l2cache_bridge:
+ andn %o2, 0xfff, %o2
+ sethi %hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_L2CACHE)), %o3
+ cmp %o2, %o3
+ beq .L_is_l2cache_bridge
+ nop
+
+ retl
+ add %g0, 1, %o0
+
+.L_is_l2cache_bridge:
+ /* Found a GAISLER l2cache bridge */
+ retl
+ ld [%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */
+
+
+/* FUNCTION _nomem_amba_scan(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ * i0-i7, l0 is used by caller
+ * o5-o7 may not be used.
+ *
+ * Arguments
+ * - o0 Bridge Information: I/O AREA and parent bus
+ * - o1 Bus
+ *
+ * Results
+ * - o0 Number of AHB bridges found
+ *
+ * Clobbered
+ * - o0 (Current AHB slave conf address)
+ * - o2 (Used by insert_bridge)
+ * - o3 (Used by insert_bridge)
+ * - l1 (Number of AHB Slaves left to process)
+ * - l2 (Current AHB slave conf address)
+ * - g2 (Return address)
+ */
+_nomem_amba_scan:
+ mov %o7, %g2 /* Save return address */
+ set 16, %l1
+ cmp %o1, 1
+ be,a .L2_maxloops_detected
+ add %g0, 64, %l1
+.L2_maxloops_detected:
+
+ /* Clear 3-bit parent bus from bridge to get I/O AREA, then or
+ * (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA) to get first AHB slave
+ * conf address.
+ */
+ andn %o0, 0x7ff, %o0
+ set (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA), %l2
+ or %o0, %l2, %l2
+
+ /* Scan AHB Slave area for AHB<->AHB bridges. For each AHB device
+ * all "bridge drivers" are called, the driver function interface:
+ *
+ * Input:
+ * - o0 PnP Address of Bridge AHB device
+ * - o2 PnP ID of AHB device
+ * Return values:
+ * - o0 Address of new bus PnP area, returning a 1 in o2 means not found
+ *
+ * Constraints:
+ * - o1 may not be used
+ * - o0, o2, o3 may be used.
+ *
+ */
+.L_scan_one_ahb_slave:
+ ld [%l2], %o2
+
+ cmp %o2, %g0
+ beq .L_scan_next_ahb_slave
+ nop
+
+ /* Call the GAISLER AHB2AHB bridge driver */
+ call _nomem_amba_scan_gaisler_ahb2ahb_bridge
+ mov %l2, %o0
+ cmp %o0, 1
+ bne .L_found_bridge
+ ld [%l2], %o2
+
+ /* Call the GAISLER L2CACHE bridge driver */
+ call _nomem_amba_scan_gaisler_l2cache_bridge
+ mov %l2, %o0
+ cmp %o0, 1
+ bne .L_found_bridge
+ ld [%l2], %o2
+
+ /* Insert next bridge "driver" function here */
+
+
+ /* The PnP ID did not match a bridge - a new bus was not found ==>
+ * step to next AHB device */
+ ba .L_scan_next_ahb_slave
+ nop
+
+ /* Add Found bus */
+.L_found_bridge:
+ and %l2, 0x7e0, %o2
+ or %o2, %o0, %o0 /* Add AHB/AHB Bridge PnP address */
+ call insert_ahb_bridge /* Insert Bridge into found buses storage */
+ or %o1, %o0, %o0 /* Add parent bus LSB 3-bits */
+
+.L_scan_next_ahb_slave:
+ /* More Slaves to process? */
+ subcc %l1, 1, %l1
+ bne .L_scan_one_ahb_slave
+ add %l2, AMBA_AHB_CONF_LENGH, %l2
+
+ /* No more AHB devices to process */
+ mov %g2, %o7 /* Restore return address */
+ retl
+ nop
+
+/* FUNCTION _nomem_ambapp_find_buses(unsigned int ioarea)
+ *
+ * Find AMBA AHB buses.
+ *
+ * Constraints:
+ * i6-i7, l7 is used by caller
+ *
+ * Arguments
+ * - o0 Bridge Information: I/O AREA and parent bus
+ *
+ * Results
+ * - o0 Number of AHB bridges found
+ * - i0-i5 initialized
+ *
+ * Clobbered
+ * - o0 (Current AHB slave conf address)
+ * - o2 (Used by insert_bridge)
+ * - o3 (Used by insert_bridge)
+ * - l0 (Current AHB Bus)
+ * - l1 (Used by nomem_amba_scan)
+ * - l2 (Used by nomem_amba_scan)
+ * - l3 (Used by nomem_amba_scan)
+ * - l4 (Used by nomem_amba_scan)
+ *
+ * - g1 (level 1 return address)
+ * - g2 (Used by nomem_amba_scan)
+ */
+_nomem_ambapp_find_buses:
+ mov %o7, %g1 /* Save return address */
+
+ /* Initialize AHB Bus storage */
+ call init_ahb_bridges
+ nop
+
+ /* Insert AHB Bus 0 */
+ call insert_ahb_bridge
+ nop /* Argument already prepared by caller */
+
+ /* Scan AHB Bus 0 for AHB Bridges */
+ call _nomem_amba_scan
+ add %g0, 1, %o1
+
+ /* Scan all AHB Buses found for more AHB Bridges */
+ add %g0, 2, %l0
+.L100_search_next_ahb_bus:
+ call get_ahb_bridge /* Get bus %l0 I/O Area */
+ mov %l0, %o0
+ cmp %o0, %g0
+ be .L100_return /* If no more AHB bus is left to be scanned, proceed */
+ nop
+ call _nomem_amba_scan /* Scan bus %l0 for AHB Bridges. i0-i7,l0 is used */
+ mov %l0, %o1 /* I/O AREA untouched in o0 */
+ ba .L100_search_next_ahb_bus /* Do next bus */
+ add %l0, 1, %l0
+
+.L100_return:
+ mov %g1, %o7
+ retl
+ nop
+
+
+/* FUNCTION _nomem_amba_init(unsigned int ioarea)
+ *
+ * Find all AHB buses
+ *
+ * Constraints:
+ * i6, i7, o6, o7, l7, l6, g3, g4, g5, g6, g7 is used by caller
+ *
+ * Arguments
+ * - o0 Bridge Information: I/O AREA and parent bus
+ *
+ * Results
+ * - o0 Number of AHB bridges found
+ *
+ * Clobbered
+ * - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses)
+ * - o0, o1, o2, o3 (Used as arguments)
+ * - o5 (return address)
+ * - g1 (level 1 return address)
+ * - g2 (level 2 return address)
+ */
+_nomem_amba_init:
+ mov %o7, %o5 /* Save return address, o5 not used */
+
+ /* Scan for buses, it will init i0-i5 */
+ call _nomem_ambapp_find_buses
+ nop
+
+ mov %o5, %o7
+ retl
+ nop
+
+/* Call tree and their return address register
+ *
+ *_nomem_amba_scan (g1)
+ * -> init_ahb_bridges (o7)
+ * -> insert_ahb_bridge (o7)
+ * -> _nomem_amba_scan (g2)
+ * -> insert_ahb_bridge (o7)
+ * -> get_ahb_bridge (o7)
+ *
+ *
+ * -> _nomem_find_apb (g2)
+ * -> get_ahb_bridge (o7)
+ * -> _nomem_find_ahb_bus (o7)
+ * -> _nomem_find_apb_bus (o7)
+ * -> _nomem_find_ahb (g2)
+ * -> get_ahb_bridge (o7)
+ * -> _nomem_find_ahb_bus (o7)
+ * -> mem_handler.func() (o7)
+ *
+ */
--- /dev/null
+/* C-interface for AMBA PnP scanning functions implemented in
+ * ambapp_low.S. At the point the memory and stack can be
+ * used.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+
+ .seg "text"
+ .extern _nomem_ambapp_find_buses
+ .extern _nomem_find_apb
+ .extern _nomem_find_ahb
+
+ .globl ambapp_find_buses
+ .globl ambapp_find_apb
+ .globl ambapp_find_ahb
+
+
+/* C-interface for _nomem_ambapp_find_buses used when memory is available.
+ */
+ambapp_find_buses:
+ save %sp, -104, %sp
+ mov %i1, %l7 /* Save second argument */
+ call _nomem_ambapp_find_buses
+ mov %i0, %o0
+
+ /* Store result */
+ st %g0, [%l7+0x00]
+ st %i0, [%l7+0x04]
+ st %i1, [%l7+0x08]
+ st %i2, [%l7+0x0c]
+ st %i3, [%l7+0x10]
+ st %i4, [%l7+0x14]
+ st %i5, [%l7+0x18]
+
+ ret
+ restore
+
+/* C-interface for _nomem_find_apb used when memory is available.
+ *
+ * void ambapp_find_apb(
+ * struct ambapp_bus *abus,
+ * unsigned int dev_vend,
+ * int index,
+ * struct ambapp_find_apb_info *result
+ * );
+ *
+ */
+ambapp_find_apb:
+ save %sp, -104, %sp
+
+ mov %i3, %l7 /* Save second argument */
+ mov %i1, %o1
+ mov %i2, %o2
+
+ /* Initialize buses available in system */
+ ld [%i0+0x08], %i1
+ ld [%i0+0x0c], %i2
+ ld [%i0+0x10], %i3
+ ld [%i0+0x14], %i4
+ ld [%i0+0x18], %i5
+
+ call _nomem_find_apb
+ ld [%i0+0x04], %i0
+
+ st %o2, [%l7+0x08] /* Decremented Index */
+ st %o3, [%l7] /* PnP configuration address of APB Device */
+ st %o4, [%l7+0x04] /* AHB Bus Index of AHB/APB bridge and APB Device */
+ mov %o0, %i0
+ ret
+ restore
+
+/* C-interface for _nomem_find_ahb used when memory is available.
+ *
+ * void ambapp_find_ahb(
+ * struct ambapp_bus *abus,
+ * unsigned int dev_vend,
+ * int index,
+ * int type,
+ * struct ambapp_find_ahb_info *result
+ * );
+ *
+ */
+ambapp_find_ahb:
+ save %sp, -104, %sp
+
+ mov %i4, %l7 /* Save second argument */
+ clr %o0
+ mov %i1, %o1
+ mov %i2, %o2
+ clr %o3
+ clr %o4
+ mov %i3, %o5
+
+ /* Initialize buses available in system */
+ ld [%i0+0x08], %i1
+ ld [%i0+0x0c], %i2
+ ld [%i0+0x10], %i3
+ ld [%i0+0x14], %i4
+ ld [%i0+0x18], %i5
+
+ call _nomem_find_ahb
+ ld [%i0+0x04], %i0
+
+ st %o2, [%l7+0x08] /* Decremented Index */
+ st %o3, [%l7] /* PnP configuration address of AHB Device */
+ st %o4, [%l7+0x04] /* AHB Bus Index of AHB Device */
+ mov %o0, %i0
+ ret
+ restore
/* Initializes CPU and basic hardware such as memory
* controllers, IRQ controller and system timer 0.
*
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
+/* Default Plug&Play I/O area */
+#ifndef CONFIG_AMBAPP_IOAREA
+#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
+#endif
+
#define TIMER_BASE_CLK 1000000
#define US_PER_TICK (1000000 / CONFIG_SYS_HZ)
/*
* Breath some life into the CPU...
*
- * Set up the memory map,
- * initialize a bunch of registers.
- *
* Run from FLASH/PROM:
* - until memory controller is set up, only registers available
+ * - memory controller has already been setup up, stack can be used
* - no global variables available for writing
* - constants available
*/
-
void cpu_init_f(void)
{
- /* these varaiable must not be initialized */
- ambapp_dev_irqmp *irqmp;
- ambapp_apbdev apbdev;
- register unsigned int apbmst;
-
- /* find AMBA APB Master */
- apbmst = (unsigned int)
- ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
- if (!apbmst) {
- /*
- * no AHB/APB bridge, something is wrong
- * ==> jump to start (or hang)
- */
- while (1) ;
- }
- /* Init memory controller */
- if (init_memory_ctrl()) {
- while (1) ;
- }
-
- /****************************************************
- * From here we can use the main memory and the stack.
- */
-
- /* Find AMBA APB IRQMP Controller */
- if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
- /* no IRQ controller, something is wrong
- * ==> jump to start (or hang)
- */
- while (1) ;
- }
- irqmp = (ambapp_dev_irqmp *) apbdev.address;
- /* initialize the IRQMP */
- irqmp->ilevel = 0xf; /* all IRQ off */
- irqmp->iforce = 0;
- irqmp->ipend = 0;
- irqmp->iclear = 0xfffe; /* clear all old pending interrupts */
- irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */
- irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */
-
- /* cache */
}
+/* Routine called from start.S,
+ *
+ * Run from FLASH/PROM:
+ * - memory controller has already been setup up, stack can be used
+ * - global variables available for read/writing
+ * - constants avaiable
+ */
void cpu_init_f2(void)
{
-
+ /* Initialize the AMBA Plug & Play bus structure, the bus
+ * structure represents the AMBA bus that the CPU is located at.
+ */
+ ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb);
}
/*
int cpu_init_r(void)
{
ambapp_apbdev apbdev;
+ int index, cpu;
+ ambapp_dev_gptimer *timer = NULL;
+ unsigned int bus_freq;
/*
* Find AMBA APB IRQMP Controller,
- * When we come so far we know there is a IRQMP available
*/
- ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
- irqmp = (ambapp_dev_irqmp *) apbdev.address;
-
- /* timer */
- if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
- printf("cpu_init_r: gptimer not found!\n");
- return 1;
- }
- gptimer = (ambapp_dev_gptimer *) apbdev.address;
- gptimer_irq = apbdev.irq;
-
- /* initialize prescaler common to all timers to 1MHz */
- gptimer->scalar = gptimer->scalar_reload =
- (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
-
- return (0);
-}
-
-/* find & setup memory controller */
-int init_memory_ctrl()
-{
- register ambapp_dev_mctrl *mctrl;
- register ambapp_dev_sdctrl *sdctrl;
- register ambapp_dev_ddrspa *ddrspa;
- register ambapp_dev_ddr2spa *ddr2spa;
- register ahbctrl_pp_dev *ahb;
- register unsigned int base;
- register int not_found_mctrl = -1;
-
- /* find ESA Memory controller */
- base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0);
- if (base) {
- mctrl = (ambapp_dev_mctrl *) base;
-
- /* config MCTRL memory controller */
- mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300);
- mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2;
- mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3;
- not_found_mctrl = 0;
+ if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER,
+ GAISLER_IRQMP, 0, &apbdev) != 1) {
+ panic("%s: IRQ controller not found\n", __func__);
+ return -1;
}
+ irqmp = (ambapp_dev_irqmp *)apbdev.address;
- /* find Gaisler Fault Tolerant Memory controller */
- base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0);
- if (base) {
- mctrl = (ambapp_dev_mctrl *) base;
-
- /* config MCTRL memory controller */
- mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300);
- mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2;
- mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3;
- not_found_mctrl = 0;
+ /* initialize the IRQMP */
+ irqmp->ilevel = 0xf; /* all IRQ off */
+ irqmp->iforce = 0;
+ irqmp->ipend = 0;
+ irqmp->iclear = 0xfffe; /* clear all old pending interrupts */
+ for (cpu = 0; cpu < 16; cpu++) {
+ /* mask and clear force for all IRQs on CPU[N] */
+ irqmp->cpu_mask[cpu] = 0;
+ irqmp->cpu_force[cpu] = 0;
}
- /* find SDRAM controller */
- base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0);
- if (base) {
- sdctrl = (ambapp_dev_sdctrl *) base;
-
- /* config memory controller */
- sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM;
- not_found_mctrl = 0;
- }
+ /* timer */
+ index = 0;
+ while (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER,
+ index, &apbdev) == 1) {
+ timer = (ambapp_dev_gptimer *)apbdev.address;
+ if (gptimer == NULL) {
+ gptimer = timer;
+ gptimer_irq = apbdev.irq;
+ }
+
+ /* Different buses may have different frequency, the
+ * frequency of the bus tell in which frequency the timer
+ * prescaler operates.
+ */
+ bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index);
- ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
- if (ahb) {
- ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
+ /* initialize prescaler common to all timers to 1MHz */
+ timer->scalar = timer->scalar_reload =
+ (((bus_freq / 1000) + 500) / 1000) - 1;
- /* Config DDR2 memory controller */
- ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1;
- ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3;
- not_found_mctrl = 0;
+ index++;
}
-
- ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
- if (ahb) {
- ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
-
- /* Config DDR memory controller */
- ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG;
- not_found_mctrl = 0;
+ if (!gptimer) {
+ printf("%s: gptimer not found!\n", __func__);
+ return 1;
}
-
- /* failed to find any memory controller */
- return not_found_mctrl;
+ return 0;
}
/* Uses Timer 0 to get accurate
DECLARE_GLOBAL_DATA_PTR;
+/* Select which UART that will become u-boot console */
+#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
+#define CONFIG_SYS_GRLIB_APBUART_INDEX 0
+#endif
+
static int leon3_serial_init(void)
{
ambapp_dev_apbuart *uart;
unsigned int tmp;
/* find UART */
- if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) != 1)
+ if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
+ CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1)
return -1; /* didn't find hardware */
/* found apbuart, let's init .. */
*/
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
{
- unsigned char temp;
ambapp_ahbdev ahbdev;
/* Find GRUSB core using AMBA Plug&Play information */
- if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) {
+ if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI,
+ CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1) {
printf("USB UHCI: Failed to find GRUSB controller\n");
return -1;
}
DECLARE_GLOBAL_DATA_PTR;
-/* We put these variables into .data section so that they are zero
- * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c)
- * the first time. BSS is not garantueed to be zero since BSS
- * hasn't been cleared the first times entering the CPU AMBA functions.
- *
- * The AMBA PnP routines call these functions if ambapp_???_print is set.
- *
- */
-int ambapp_apb_print __attribute__ ((section(".data"))) = 0;
-int ambapp_ahb_print __attribute__ ((section(".data"))) = 0;
-
typedef struct {
int device_id;
char *name;
+ char *desc;
} ambapp_device_name;
-static ambapp_device_name gaisler_devices[] = {
- {GAISLER_LEON3, "GAISLER_LEON3"},
- {GAISLER_LEON3DSU, "GAISLER_LEON3DSU"},
- {GAISLER_ETHAHB, "GAISLER_ETHAHB"},
- {GAISLER_ETHMAC, "GAISLER_ETHMAC"},
- {GAISLER_APBMST, "GAISLER_APBMST"},
- {GAISLER_AHBUART, "GAISLER_AHBUART"},
- {GAISLER_SRCTRL, "GAISLER_SRCTRL"},
- {GAISLER_SDCTRL, "GAISLER_SDCTRL"},
- {GAISLER_APBUART, "GAISLER_APBUART"},
- {GAISLER_IRQMP, "GAISLER_IRQMP"},
- {GAISLER_AHBRAM, "GAISLER_AHBRAM"},
- {GAISLER_GPTIMER, "GAISLER_GPTIMER"},
- {GAISLER_PCITRG, "GAISLER_PCITRG"},
- {GAISLER_PCISBRG, "GAISLER_PCISBRG"},
- {GAISLER_PCIFBRG, "GAISLER_PCIFBRG"},
- {GAISLER_PCITRACE, "GAISLER_PCITRACE"},
- {GAISLER_AHBTRACE, "GAISLER_AHBTRACE"},
- {GAISLER_ETHDSU, "GAISLER_ETHDSU"},
- {GAISLER_PIOPORT, "GAISLER_PIOPORT"},
- {GAISLER_AHBJTAG, "GAISLER_AHBJTAG"},
- {GAISLER_ATACTRL, "GAISLER_ATACTRL"},
- {GAISLER_VGA, "GAISLER_VGA"},
- {GAISLER_KBD, "GAISLER_KBD"},
- {GAISLER_L2TIME, "GAISLER_L2TIME"},
- {GAISLER_L2C, "GAISLER_L2C"},
- {GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"},
- {GAISLER_SPW, "GAISLER_SPW"},
- {GAISLER_SPW2, "GAISLER_SPW2"},
- {GAISLER_EHCI, "GAISLER_EHCI"},
- {GAISLER_UHCI, "GAISLER_UHCI"},
- {GAISLER_AHBSTAT, "GAISLER_AHBSTAT"},
- {GAISLER_DDR2SPA, "GAISLER_DDR2SPA"},
- {GAISLER_DDRSPA, "GAISLER_DDRSPA"},
- {0, NULL}
+typedef struct {
+ unsigned int vendor_id;
+ char *name;
+ char *desc;
+ ambapp_device_name *devices;
+} ambapp_vendor_devnames;
+
+/** Vendor GAISLER devices */
+static ambapp_device_name GAISLER_devices[] = {
+ {GAISLER_LEON2DSU, "LEON2DSU", "Leon2 Debug Support Unit"},
+ {GAISLER_LEON3, "LEON3", "Leon3 SPARC V8 Processor"},
+ {GAISLER_LEON3DSU, "LEON3DSU", "Leon3 Debug Support Unit"},
+ {GAISLER_ETHAHB, "ETHAHB", "OC ethernet AHB interface"},
+ {GAISLER_APBMST, "APBMST", "AHB/APB Bridge"},
+ {GAISLER_AHBUART, "AHBUART", "AHB Debug UART"},
+ {GAISLER_SRCTRL, "SRCTRL", "Simple SRAM Controller"},
+ {GAISLER_SDCTRL, "SDCTRL", "PC133 SDRAM Controller"},
+ {GAISLER_SSRCTRL, "SSRCTRL", "Synchronous SRAM Controller"},
+ {GAISLER_APBUART, "APBUART", "Generic UART"},
+ {GAISLER_IRQMP, "IRQMP", "Multi-processor Interrupt Ctrl."},
+ {GAISLER_AHBRAM, "AHBRAM", "Single-port AHB SRAM module"},
+ {GAISLER_AHBDPRAM, "AHBDPRAM", "Dual-port AHB SRAM module"},
+ {GAISLER_GPTIMER, "GPTIMER", "Modular Timer Unit"},
+ {GAISLER_PCITRG, "PCITRG", "Simple 32-bit PCI Target"},
+ {GAISLER_PCISBRG, "PCISBRG", "Simple 32-bit PCI Bridge"},
+ {GAISLER_PCIFBRG, "PCIFBRG", "Fast 32-bit PCI Bridge"},
+ {GAISLER_PCITRACE, "PCITRACE", "32-bit PCI Trace Buffer"},
+ {GAISLER_DMACTRL, "DMACTRL", "AMBA DMA controller"},
+ {GAISLER_AHBTRACE, "AHBTRACE", "AMBA Trace Buffer"},
+ {GAISLER_DSUCTRL, "DSUCTRL", "DSU/ETH controller"},
+ {GAISLER_CANAHB, "CANAHB", "OC CAN AHB interface"},
+ {GAISLER_GPIO, "GPIO", "General Purpose I/O port"},
+ {GAISLER_AHBROM, "AHBROM", "Generic AHB ROM"},
+ {GAISLER_AHBJTAG, "AHBJTAG", "JTAG Debug Link"},
+ {GAISLER_ETHMAC, "ETHMAC", "GR Ethernet MAC"},
+ {GAISLER_SWNODE, "SWNODE", "SpaceWire Node Interface"},
+ {GAISLER_SPW, "SPW", "SpaceWire Serial Link"},
+ {GAISLER_AHB2AHB, "AHB2AHB", "AHB-to-AHB Bridge"},
+ {GAISLER_USBDC, "USBDC", "GR USB 2.0 Device Controller"},
+ {GAISLER_USB_DCL, "USB_DCL", "USB Debug Communication Link"},
+ {GAISLER_DDRMP, "DDRMP", "Multi-port DDR controller"},
+ {GAISLER_ATACTRL, "ATACTRL", "ATA controller"},
+ {GAISLER_DDRSP, "DDRSP", "Single-port DDR266 controller"},
+ {GAISLER_EHCI, "EHCI", "USB Enhanced Host Controller"},
+ {GAISLER_UHCI, "UHCI", "USB Universal Host Controller"},
+ {GAISLER_I2CMST, "I2CMST", "AMBA Wrapper for OC I2C-master"},
+ {GAISLER_SPW2, "SPW2", "GRSPW2 SpaceWire Serial Link"},
+ {GAISLER_AHBDMA, "AHBDMA", ""},
+ {GAISLER_NUHOSP3, "NUHOSP3", "Nuhorizons Spartan3 IO I/F"},
+ {GAISLER_CLKGATE, "CLKGATE", "Clock gating unit"},
+ {GAISLER_SPICTRL, "SPICTRL", "SPI Controller"},
+ {GAISLER_DDR2SP, "DDR2SP", "Single-port DDR2 controller"},
+ {GAISLER_SLINK, "SLINK", "SLINK Master"},
+ {GAISLER_GRTM, "GRTM", "CCSDS Telemetry Encoder"},
+ {GAISLER_GRTC, "GRTC", "CCSDS Telecommand Decoder"},
+ {GAISLER_GRPW, "GRPW", "PacketWire to AMBA AHB I/F"},
+ {GAISLER_GRCTM, "GRCTM", "CCSDS Time Manager"},
+ {GAISLER_GRHCAN, "GRHCAN", "ESA HurriCANe CAN with DMA"},
+ {GAISLER_GRFIFO, "GRFIFO", "FIFO Controller"},
+ {GAISLER_GRADCDAC, "GRADCDAC", "ADC / DAC Interface"},
+ {GAISLER_GRPULSE, "GRPULSE", "General Purpose I/O with Pulses"},
+ {GAISLER_GRTIMER, "GRTIMER", "Timer Unit with Latches"},
+ {GAISLER_AHB2PP, "AHB2PP", "AMBA AHB to Packet Parallel I/F"},
+ {GAISLER_GRVERSION, "GRVERSION", "Version and Revision Register"},
+ {GAISLER_APB2PW, "APB2PW", "PacketWire Transmit Interface"},
+ {GAISLER_PW2APB, "PW2APB", "PacketWire Receive Interface"},
+ {GAISLER_GRCAN, "GRCAN", "CAN Controller with DMA"},
+ {GAISLER_I2CSLV, "I2CSLV", "I2C Slave"},
+ {GAISLER_U16550, "U16550", "Simple 16550 UART"},
+ {GAISLER_AHBMST_EM, "AHBMST_EM", "AMBA Master Emulator"},
+ {GAISLER_AHBSLV_EM, "AHBSLV_EM", "AMBA Slave Emulator"},
+ {GAISLER_GRTESTMOD, "GRTESTMOD", "Test report module"},
+ {GAISLER_ASCS, "ASCS", "ASCS Master"},
+ {GAISLER_IPMVBCTRL, "IPMVBCTRL", "IPM-bus/MVBC memory controller"},
+ {GAISLER_SPIMCTRL, "SPIMCTRL", "SPI Memory Controller"},
+ {GAISLER_LEON4, "LEON4", "Leon4 SPARC V8 Processor"},
+ {GAISLER_LEON4DSU, "LEON4DSU", "Leon4 Debug Support Unit"},
+ {GAISLER_PWM, "PWM", "PWM generator"},
+ {GAISLER_L2CACHE, "L2CACHE", "L2-Cache Controller"},
+ {GAISLER_SDCTRL64, "SDCTRL64", ""},
+ {GAISLER_FTAHBRAM, "FTAHBRAM", "Generic FT AHB SRAM module"},
+ {GAISLER_FTSRCTRL, "FTSRCTRL", "Simple FT SRAM Controller"},
+ {GAISLER_AHBSTAT, "AHBSTAT", "AHB Status Register"},
+ {GAISLER_LEON3FT, "LEON3FT", "Leon3-FT SPARC V8 Processor"},
+ {GAISLER_FTMCTRL, "FTMCTRL", "Memory controller with EDAC"},
+ {GAISLER_FTSDCTRL, "FTSDCTRL", "FT PC133 SDRAM Controller"},
+ {GAISLER_FTSRCTRL8, "FTSRCTRL8", "FT 8-bit SRAM/16-bit IO Ctrl"},
+ {GAISLER_APBPS2, "APBPS2", "PS2 interface"},
+ {GAISLER_VGACTRL, "VGACTRL", "VGA controller"},
+ {GAISLER_LOGAN, "LOGAN", "On chip Logic Analyzer"},
+ {GAISLER_SVGACTRL, "SVGACTRL", "SVGA frame buffer"},
+ {GAISLER_T1AHB, "T1AHB", "Niagara T1 PCX/AHB bridge"},
+ {GAISLER_MP7WRAP, "MP7WRAP", "CoreMP7 wrapper"},
+ {GAISLER_GRSYSMON, "GRSYSMON", "AMBA wrapper for System Monitor"},
+ {GAISLER_GRACECTRL, "GRACECTRL", "System ACE I/F Controller"},
+ {GAISLER_ATAHBSLV, "ATAHBSLV", "AMBA Test Framework AHB Slave"},
+ {GAISLER_ATAHBMST, "ATAHBMST", "AMBA Test Framework AHB Master"},
+ {GAISLER_ATAPBSLV, "ATAPBSLV", "AMBA Test Framework APB Slave"},
+ {GAISLER_B1553BC, "B1553BC", "AMBA Wrapper for Core1553BBC"},
+ {GAISLER_B1553RT, "B1553RT", "AMBA Wrapper for Core1553BRT"},
+ {GAISLER_B1553BRM, "B1553BRM", "AMBA Wrapper for Core1553BRM"},
+ {GAISLER_AES, "AES", "Advanced Encryption Standard"},
+ {GAISLER_ECC, "ECC", "Elliptic Curve Cryptography"},
+ {GAISLER_PCIF, "PCIF", "AMBA Wrapper for CorePCIF"},
+ {GAISLER_CLKMOD, "CLKMOD", "CPU Clock Switching Ctrl module"},
+ {GAISLER_HAPSTRAK, "HAPSTRAK", "HAPS HapsTrak I/O Port"},
+ {GAISLER_TEST_1X2, "TEST_1X2", "HAPS TEST_1x2 interface"},
+ {GAISLER_WILD2AHB, "WILD2AHB", "WildCard CardBus interface"},
+ {GAISLER_BIO1, "BIO1", "Basic I/O board BIO1"},
+ {GAISLER_SATCAN, "SATCAN", "SatCAN controller"},
+ {GAISLER_CANMUX, "CANMUX", "CAN Bus multiplexer"},
+ {GAISLER_GRTMRX, "GRTMRX", "CCSDS Telemetry Receiver"},
+ {GAISLER_GRTCTX, "GRTCTX", "CCSDS Telecommand Transmitter"},
+ {GAISLER_GRTMDESC, "GRTMDESC", "CCSDS Telemetry Descriptor"},
+ {GAISLER_GRTMVC, "GRTMVC", "CCSDS Telemetry VC Generator"},
+ {GAISLER_GEFFE, "GEFFE", "Geffe Generator"},
+ {GAISLER_GPREG, "GPREG", ""},
+ {GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"},
+ {0, NULL, NULL}
};
-static ambapp_device_name esa_devices[] = {
- {ESA_LEON2, "ESA_LEON2"},
- {ESA_MCTRL, "ESA_MCTRL"},
- {0, NULL}
+
+/** Vendor PENDER devices */
+static ambapp_device_name PENDER_devices[] = {
+ {0, NULL, NULL}
};
-static ambapp_device_name opencores_devices[] = {
- {OPENCORES_PCIBR, "OPENCORES_PCIBR"},
- {OPENCORES_ETHMAC, "OPENCORES_ETHMAC"},
+
+/** Vendor ESA devices */
+static ambapp_device_name ESA_devices[] = {
+ {ESA_LEON2, "LEON2", "Leon2 SPARC V8 Processor"},
+ {ESA_LEON2APB, "LEON2APB", "Leon2 Peripheral Bus"},
+ {ESA_IRQ, "IRQ", "Leon2 Interrupt Controller"},
+ {ESA_TIMER, "TIMER", "Leon2 Timer"},
+ {ESA_UART, "UART", "Leon2 UART"},
+ {ESA_CFG, "CFG", "Leon2 Configuration Register"},
+ {ESA_IO, "IO", "Leon2 Input/Output"},
+ {ESA_MCTRL, "MCTRL", "Leon2 Memory Controller"},
+ {ESA_PCIARB, "PCIARB", "PCI Arbiter"},
+ {ESA_HURRICANE, "HURRICANE", "HurriCANe/HurryAMBA CAN Ctrl"},
+ {ESA_SPW_RMAP, "SPW_RMAP", "UoD/Saab SpaceWire/RMAP link"},
+ {ESA_AHBUART, "AHBUART", "Leon2 AHB Debug UART"},
+ {ESA_SPWA, "SPWA", "ESA/ASTRIUM SpaceWire link"},
+ {ESA_BOSCHCAN, "BOSCHCAN", "SSC/BOSCH CAN Ctrl"},
+ {ESA_IRQ2, "IRQ2", "Leon2 Secondary Irq Controller"},
+ {ESA_AHBSTAT, "AHBSTAT", "Leon2 AHB Status Register"},
+ {ESA_WPROT, "WPROT", "Leon2 Write Protection"},
+ {ESA_WPROT2, "WPROT2", "Leon2 Extended Write Protection"},
+ {ESA_PDEC3AMBA, "PDEC3AMBA", "ESA CCSDS PDEC3AMBA TC Decoder"},
+ {ESA_PTME3AMBA, "PTME3AMBA", "ESA CCSDS PTME3AMBA TM Encoder"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor ASTRIUM devices */
+static ambapp_device_name ASTRIUM_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor OPENCHIP devices */
+static ambapp_device_name OPENCHIP_devices[] = {
+ {OPENCHIP_APBGPIO, "APBGPIO", "APB General Purpose IO"},
+ {OPENCHIP_APBI2C, "APBI2C", "APB I2C Interface"},
+ {OPENCHIP_APBSPI, "APBSPI", "APB SPI Interface"},
+ {OPENCHIP_APBCHARLCD, "APBCHARLCD", "APB Character LCD"},
+ {OPENCHIP_APBPWM, "APBPWM", "APB PWM"},
+ {OPENCHIP_APBPS2, "APBPS2", "APB PS/2 Interface"},
+ {OPENCHIP_APBMMCSD, "APBMMCSD", "APB MMC/SD Card Interface"},
+ {OPENCHIP_APBNAND, "APBNAND", "APB NAND(SmartMedia) Interface"},
+ {OPENCHIP_APBLPC, "APBLPC", "APB LPC Interface"},
+ {OPENCHIP_APBCF, "APBCF", "APB CompactFlash (IDE)"},
+ {OPENCHIP_APBSYSACE, "APBSYSACE", "APB SystemACE Interface"},
+ {OPENCHIP_APB1WIRE, "APB1WIRE", "APB 1-Wire Interface"},
+ {OPENCHIP_APBJTAG, "APBJTAG", "APB JTAG TAP Master"},
+ {OPENCHIP_APBSUI, "APBSUI", "APB Simple User Interface"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor OPENCORES devices */
+static ambapp_device_name OPENCORES_devices[] = {
+ {OPENCORES_PCIBR, "PCIBR", "PCI Bridge"},
+ {OPENCORES_ETHMAC, "ETHMAC", "Ethernet MAC"},
{0, NULL}
};
-typedef struct {
- unsigned int vendor_id;
- char *name;
- ambapp_device_name *devices;
-} ambapp_vendor_devnames;
+/** Vendor CONTRIB devices */
+static ambapp_device_name CONTRIB_devices[] = {
+ {CONTRIB_CORE1, "CORE1", "Contributed core 1"},
+ {CONTRIB_CORE2, "CORE2", "Contributed core 2"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor EONIC devices */
+static ambapp_device_name EONIC_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor RADIONOR devices */
+static ambapp_device_name RADIONOR_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor GLEICHMANN devices */
+static ambapp_device_name GLEICHMANN_devices[] = {
+ {GLEICHMANN_CUSTOM, "CUSTOM", "Custom device"},
+ {GLEICHMANN_GEOLCD01, "GEOLCD01", "GEOLCD01 graphics system"},
+ {GLEICHMANN_DAC, "DAC", "Sigma delta DAC"},
+ {GLEICHMANN_HPI, "HPI", "AHB-to-HPI bridge"},
+ {GLEICHMANN_SPI, "SPI", "SPI master"},
+ {GLEICHMANN_HIFC, "HIFC", "Human interface controller"},
+ {GLEICHMANN_ADCDAC, "ADCDAC", "Sigma delta ADC/DAC"},
+ {GLEICHMANN_SPIOC, "SPIOC", ""},
+ {GLEICHMANN_AC97, "AC97", ""},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor MENTA devices */
+static ambapp_device_name MENTA_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor SUN devices */
+static ambapp_device_name SUN_devices[] = {
+ {SUN_T1, "T1", "Niagara T1 SPARC V9 Processor"},
+ {SUN_S1, "S1", "Niagara S1 SPARC V9 Processor"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor MOVIDIA devices */
+static ambapp_device_name MOVIDIA_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor ORBITA devices */
+static ambapp_device_name ORBITA_devices[] = {
+ {ORBITA_1553B, "1553B", "MIL-STD-1553B Controller"},
+ {ORBITA_429, "429", "429 Interface"},
+ {ORBITA_SPI, "SPI", "SPI Interface"},
+ {ORBITA_I2C, "I2C", "I2C Interface"},
+ {ORBITA_SMARTCARD, "SMARTCARD", "Smart Card Reader"},
+ {ORBITA_SDCARD, "SDCARD", "SD Card Reader"},
+ {ORBITA_UART16550, "UART16550", "16550 UART"},
+ {ORBITA_CRYPTO, "CRYPTO", "Crypto Engine"},
+ {ORBITA_SYSIF, "SYSIF", "System Interface"},
+ {ORBITA_PIO, "PIO", "Programmable IO module"},
+ {ORBITA_RTC, "RTC", "Real-Time Clock"},
+ {ORBITA_COLORLCD, "COLORLCD", "Color LCD Controller"},
+ {ORBITA_PCI, "PCI", "PCI Module"},
+ {ORBITA_DSP, "DSP", "DPS Co-Processor"},
+ {ORBITA_USBHOST, "USBHOST", "USB Host"},
+ {ORBITA_USBDEV, "USBDEV", "USB Device"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor SYNOPSYS devices */
+static ambapp_device_name SYNOPSYS_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor NASA devices */
+static ambapp_device_name NASA_devices[] = {
+ {NASA_EP32, "EP32", "EP32 Forth processor"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor CAL devices */
+static ambapp_device_name CAL_devices[] = {
+ {CAL_DDRCTRL, "DDRCTRL", ""},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor EMBEDDIT devices */
+static ambapp_device_name EMBEDDIT_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor CETON devices */
+static ambapp_device_name CETON_devices[] = {
+ {0, NULL, NULL}
+};
+
+
+/** Vendor ACTEL devices */
+static ambapp_device_name ACTEL_devices[] = {
+ {ACTEL_COREMP7, "COREMP7", "CoreMP7 Processor"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendor APPLECORE devices */
+static ambapp_device_name APPLECORE_devices[] = {
+ {APPLECORE_UTLEON3, "UTLEON3", "AppleCore uT-LEON3 Processor"},
+ {APPLECORE_UTLEON3DSU, "UTLEON3DSU", "AppleCore uT-LEON3 DSU"},
+ {0, NULL, NULL}
+};
+
+
+/** Vendors and their devices */
static ambapp_vendor_devnames vendors[] = {
- {VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices},
- {VENDOR_ESA, "VENDOR_ESA", esa_devices},
- {VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices},
- {0, NULL, 0}
+ {VENDOR_GAISLER, "GAISLER", "Gaisler Research", GAISLER_devices},
+ {VENDOR_PENDER, "PENDER", "", PENDER_devices},
+ {VENDOR_ESA, "ESA", "European Space Agency", ESA_devices},
+ {VENDOR_ASTRIUM, "ASTRIUM", "", ASTRIUM_devices},
+ {VENDOR_OPENCHIP, "OPENCHIP", "OpenChip", OPENCHIP_devices},
+ {VENDOR_OPENCORES, "OPENCORES", "OpenCores", OPENCORES_devices},
+ {VENDOR_CONTRIB, "CONTRIB", "Various contributions", CONTRIB_devices},
+ {VENDOR_EONIC, "EONIC", "Eonic BV", EONIC_devices},
+ {VENDOR_RADIONOR, "RADIONOR", "Radionor Communications", RADIONOR_devices},
+ {VENDOR_GLEICHMANN, "GLEICHMANN", "Gleichmann Electronics", GLEICHMANN_devices},
+ {VENDOR_MENTA, "MENTA", "Menta", MENTA_devices},
+ {VENDOR_SUN, "SUN", "Sun Microsystems", SUN_devices},
+ {VENDOR_MOVIDIA, "MOVIDIA", "", MOVIDIA_devices},
+ {VENDOR_ORBITA, "ORBITA", "Orbita", ORBITA_devices},
+ {VENDOR_SYNOPSYS, "SYNOPSYS", "Synopsys Inc.", SYNOPSYS_devices},
+ {VENDOR_NASA, "NASA", "NASA", NASA_devices},
+ {VENDOR_CAL, "CAL", "", CAL_devices},
+ {VENDOR_EMBEDDIT, "EMBEDDIT", "Embedd.it", EMBEDDIT_devices},
+ {VENDOR_CETON, "CETON", "Ceton Corporation", CETON_devices},
+ {VENDOR_ACTEL, "ACTEL", "Actel Corporation", ACTEL_devices},
+ {VENDOR_APPLECORE, "APPLECORE", "AppleCore", APPLECORE_devices},
+ {0, NULL, NULL, NULL}
};
-static char *ambapp_get_devname(ambapp_device_name * devs, int id)
+static ambapp_device_name *ambapp_get_dev(ambapp_device_name *devs, int id)
{
if (!devs)
return NULL;
while (devs->device_id > 0) {
if (devs->device_id == id)
- return devs->name;
+ return devs;
devs++;
}
return NULL;
char *ambapp_device_id2str(int vendor, int id)
{
ambapp_vendor_devnames *ven = &vendors[0];
+ ambapp_device_name *dev;
while (ven->vendor_id > 0) {
if (ven->vendor_id == vendor) {
- return ambapp_get_devname(ven->devices, id);
+ dev = ambapp_get_dev(ven->devices, id);
+ if (!dev)
+ return NULL;
+ return dev->name;
+ }
+ ven++;
+ }
+ return NULL;
+}
+
+char *ambapp_device_id2desc(int vendor, int id)
+{
+ ambapp_vendor_devnames *ven = &vendors[0];
+ ambapp_device_name *dev;
+
+ while (ven->vendor_id > 0) {
+ if (ven->vendor_id == vendor) {
+ dev = ambapp_get_dev(ven->devices, id);
+ if (!dev)
+ return NULL;
+ return dev->desc;
}
ven++;
}
static char *unknown = "unknown";
+char *ambapp_type_names[4] = {
+ /* 0 */ "UNUSED",
+ /* 1 */ "apb",
+ /* 2 */ "ahbmem",
+ /* 3 */ "ahbio"
+};
+
/* Print one APB device */
-void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index)
+void ambapp_print_apb(ambapp_apbdev *dev, int index)
{
char *dev_str, *ven_str;
- int irq, ver, vendor, deviceid;
- unsigned int address, apbmst_base, mask;
-
- vendor = amba_vendor(apb->conf);
- deviceid = amba_device(apb->conf);
- irq = amba_irq(apb->conf);
- ver = amba_ver(apb->conf);
- apbmst_base = apbmst->address[0] & LEON3_IO_AREA;
- address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) &
- (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
+ unsigned int freq;
- mask = amba_membar_mask(apb->bar) << 8;
- mask = ((~mask) & 0x000fffff) + 1;
-
- ven_str = ambapp_vendor_id2str(vendor);
+ ven_str = ambapp_vendor_id2str(dev->vendor);
if (!ven_str) {
ven_str = unknown;
dev_str = unknown;
} else {
- dev_str = ambapp_device_id2str(vendor, deviceid);
+ dev_str = ambapp_device_id2str(dev->vendor, dev->device);
if (!dev_str)
dev_str = unknown;
}
- printf("0x%02x:0x%02x:0x%02x: %s %s\n"
+ /* Get Frequency of Core */
+ freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
+
+ printf("0x%02x:0x%02x:0x%02x: %s %s (%dkHz)\n"
" apb: 0x%08x - 0x%08x\n"
" irq: %-2d (ver: %-2d)\n",
- index, vendor, deviceid, ven_str, dev_str, address,
- address + mask, irq, ver);
+ index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000,
+ dev->address, dev->address + (dev->mask-1),
+ dev->irq, dev->ver);
}
-void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index)
+void ambapp_print_ahb(ambapp_ahbdev *dev, int index)
{
- char *dev_str, *ven_str;
- int irq, ver, vendor, deviceid;
- unsigned int addr, mask;
- int j;
+ char *dev_str, *ven_str, *type_str;
+ int i;
+ unsigned int freq;
- vendor = amba_vendor(ahb->conf);
- deviceid = amba_device(ahb->conf);
- irq = amba_irq(ahb->conf);
- ver = amba_ver(ahb->conf);
-
- ven_str = ambapp_vendor_id2str(vendor);
+ ven_str = ambapp_vendor_id2str(dev->vendor);
if (!ven_str) {
ven_str = unknown;
dev_str = unknown;
} else {
- dev_str = ambapp_device_id2str(vendor, deviceid);
+ dev_str = ambapp_device_id2str(dev->vendor, dev->device);
if (!dev_str)
dev_str = unknown;
}
- printf("0x%02x:0x%02x:0x%02x: %s %s\n",
- index, vendor, deviceid, ven_str, dev_str);
+ /* Get Frequency of Core */
+ freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
+
+ printf("0x%02x:0x%02x:0x%02x: %s %s (%dkHz)\n",
+ index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000);
- for (j = 0; j < 4; j++) {
- addr = amba_membar_start(ahb->bars[j]);
- if (amba_membar_type(ahb->bars[j]) == 0)
+ for (i = 0; i < 4; i++) {
+ if (dev->type[i] == 0)
continue;
- if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO)
- addr = AMBA_TYPE_AHBIO_ADDR(addr);
- mask = amba_membar_mask(ahb->bars[j]) << 20;
- printf(" mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1));
+ type_str = ambapp_type_names[dev->type[i]];
+ printf(" %-7s: 0x%08x - 0x%08x\n", type_str, dev->address[i],
+ dev->address[i] + (dev->mask[i]-1));
}
- printf(" irq: %-2d (ver: %d)\n", irq, ver);
+ printf(" irq: %-2d (ver: %d)\n", dev->irq, dev->ver);
}
int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
+ int index;
+ ambapp_apbdev apbdev;
+ ambapp_ahbdev ahbdev;
/* Print AHB Masters */
- puts("--------- AHB Masters ---------\n");
- ambapp_apb_print = 0;
- ambapp_ahb_print = 1;
- ambapp_ahbmst_count(99, 99); /* Get vendor&device 99 = nonexistent... */
+ puts("\n--------- AHB Masters ---------\n");
+ index = 0;
+ while (ambapp_ahbmst_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) {
+ /* Found a AHB Master Device */
+ ambapp_print_ahb(&ahbdev, index);
+ index++;
+ }
/* Print AHB Slaves */
- puts("--------- AHB Slaves ---------\n");
- ambapp_ahbslv_count(99, 99); /* Get vendor&device 99 = nonexistent... */
+ puts("\n--------- AHB Slaves ---------\n");
+ index = 0;
+ while (ambapp_ahbslv_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1) {
+ /* Found a AHB Slave Device */
+ ambapp_print_ahb(&ahbdev, index);
+ index++;
+ }
/* Print APB Slaves */
- puts("--------- APB Slaves ---------\n");
- ambapp_apb_print = 1;
- ambapp_ahb_print = 0;
- ambapp_apb_count(99, 99); /* Get vendor&device 99 = nonexistent... */
-
- /* Reset, no futher printing */
- ambapp_apb_print = 0;
- ambapp_ahb_print = 0;
+ puts("\n--------- APB Slaves ---------\n");
+ index = 0;
+ while (ambapp_apb_find(&ambapp_plb, 0, 0, index, &apbdev) == 1) {
+ /* Found a APB Slave Device */
+ ambapp_print_apb(&apbdev, index);
+ index++;
+ }
+
puts("\n");
return 0;
}
while (vend->vendor_id && vend->name) {
vend->name = (char *)((unsigned int)vend->name + gd->reloc_off);
- vend->devices =
- (ambapp_device_name *) ((unsigned int)vend->devices +
- gd->reloc_off);;
+ vend->desc = (char *)((unsigned int)vend->desc + gd->reloc_off);
+ vend->devices = (ambapp_device_name *)
+ ((unsigned int)vend->devices + gd->reloc_off);
dev = vend->devices;
vend++;
if (!dev)
continue;
while (dev->device_id && dev->name) {
dev->name =
- (char *)((unsigned int)dev->name + gd->reloc_off);;
+ (char *)((unsigned int)dev->name + gd->reloc_off);
+ dev->desc =
+ (char *)((unsigned int)dev->desc + gd->reloc_off);
dev++;
}
}
#define GRETH_PHY_ADR_DEFAULT 0
#endif
+/* Let board select which GRETH to use as network interface, set
+ * this to zero if only one GRETH is available.
+ */
+#ifndef CONFIG_SYS_GRLIB_GRETH_INDEX
+#define CONFIG_SYS_GRLIB_GRETH_INDEX 0
+#endif
+
/* ByPass Cache when reading regs */
#define GRETH_REGLOAD(addr) SPARC_NOCACHE_READ(addr)
/* Write-through cache ==> no bypassing needed on writes */
debug("Scanning for GRETH\n");
- /* Find Device & IRQ via AMBA Plug&Play information */
- if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {
+ /* Find Device & IRQ via AMBA Plug&Play information,
+ * CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple
+ * GRETHs in system.
+ */
+ if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC,
+ CONFIG_SYS_GRLIB_GRETH_INDEX, &apbdev) != 1) {
return -1; /* GRETH not found */
}
* the APB bus, also freely available in GRLIB at
* www.gaisler.com.
*
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2009, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __AMBAPP_H__
#define __AMBAPP_H__
-/* Default location of Plug&Play info
- * normally 0xfffff000 for AHB masters
- * and 0xfffff800 for AHB slaves.
- * Normally no need to change this.
- */
-#define LEON3_IO_AREA 0xfff00000
-#define LEON3_CONF_AREA 0xff000
-#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
-
-/* Max devices this software will support */
-#define LEON3_AHB_MASTERS 16
-#define LEON3_AHB_SLAVES 16
-/*#define LEON3_APB_MASTERS 1*/ /* Number of APB buses that has Plug&Play */
-#define LEON3_APB_SLAVES 16 /* Total number of APB slaves per APB bus */
-
-/* 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_EMBEDDIT 234
-#define VENDOR_CAL 202
-
-/* Gaisler Research device id's */
-#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_APBUART 0x00C
-#define GAISLER_IRQMP 0x00D
-#define GAISLER_AHBRAM 0x00E
-#define GAISLER_GPTIMER 0x011
-#define GAISLER_PCITRG 0x012
-#define GAISLER_PCISBRG 0x013
-#define GAISLER_PCIFBRG 0x014
-#define GAISLER_PCITRACE 0x015
-#define GAISLER_PCIDMA 0x016
-#define GAISLER_AHBTRACE 0x017
-#define GAISLER_ETHDSU 0x018
-#define GAISLER_PIOPORT 0x01A
-#define GAISLER_AHBJTAG 0x01c
-#define GAISLER_SPW 0x01f
-#define GAISLER_ATACTRL 0x024
-#define GAISLER_VGA 0x061
-#define GAISLER_KBD 0X060
-#define GAISLER_ETHMAC 0x01D
-#define GAISLER_DDRSPA 0x025
-#define GAISLER_EHCI 0x026
-#define GAISLER_UHCI 0x027
-#define GAISLER_SPW2 0x029
-#define GAISLER_DDR2SPA 0x02E
-#define GAISLER_AHBSTAT 0x052
-#define GAISLER_FTMCTRL 0x054
-
-#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 0x2
-#define ESA_MCTRL 0xF
-
-/* Opencores device id's */
-#define OPENCORES_PCIBR 0x4
-#define OPENCORES_ETHMAC 0x5
-
-/* Vendor codes */
-
-/*
- *
- * Macros for manipulating Configuration registers
- *
- */
+#include <ambapp_ids.h>
-#define amba_vendor(x) (((x) >> 24) & 0xff)
-
-#define amba_device(x) (((x) >> 12) & 0xfff)
-
-#define amba_membar_start(mbar) \
- (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
-
-#define amba_iobar_start(base, iobar) \
- ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
-
-#define amba_irq(conf) ((conf) & 0xf)
+#ifndef __ASSEMBLER__
+/* 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)
+/* AMBA Plug&Play AHB Masters & Slaves information locations
+ * Max devices is 64 supported by HW, however often only 16
+ * are used.
+ */
+struct ambapp_pnp_info {
+ struct ambapp_pnp_ahb masters[64];
+ struct ambapp_pnp_ahb slaves[63];
+ const unsigned int unused[4];
+ const unsigned int systemid[4];
+};
+
+/* Describes a AMBA PnP bus */
+struct ambapp_bus {
+ int buses; /* Number of buses */
+ unsigned int ioareas[6]; /* PnP I/O AREAs of AHB buses */
+ unsigned int freq; /* Frequency of bus0 [Hz] */
+};
+
+/* Processor Local AMBA bus */
+extern struct ambapp_bus ambapp_plb;
+
+/* Get Bus frequency of a certain AMBA bus */
+extern unsigned int ambapp_bus_freq(
+ struct ambapp_bus *abus,
+ int ahb_bus_index
+ );
+
+/* AMBA PnP information of a APB Device */
+typedef struct {
+ unsigned int vendor;
+ unsigned int device;
+ unsigned char irq;
+ unsigned char ver;
+ unsigned int address;
+ unsigned int mask;
+ int ahb_bus_index;
+} ambapp_apbdev;
-#define amba_membar_type(mbar) ((mbar) & 0xf)
+/* AMBA PnP information of a AHB Device */
+typedef struct {
+ unsigned int vendor;
+ unsigned int device;
+ unsigned char irq;
+ unsigned char ver;
+ unsigned int userdef[3];
+ unsigned int address[4];
+ unsigned int mask[4];
+ int type[4];
+ int ahb_bus_index;
+} ambapp_ahbdev;
-#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
+/* Scan AMBA Bus for AHB Bridges */
+extern void ambapp_bus_init(
+ unsigned int ioarea,
+ unsigned int freq,
+ struct ambapp_bus *abus);
-#define AMBA_TYPE_APBIO 0x1
-#define AMBA_TYPE_MEM 0x2
-#define AMBA_TYPE_AHBIO 0x3
+/* Find APB Slave device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_apb_find(
+ struct ambapp_bus *abus,
+ int vendor,
+ int device,
+ int index,
+ ambapp_apbdev *dev
+ );
+
+/* Find AHB Master device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_ahbmst_find(
+ struct ambapp_bus *abus,
+ int vendor,
+ int device,
+ int index,
+ ambapp_ahbdev *dev
+ );
+
+/* Find AHB Slave device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_ahbslv_find(
+ struct ambapp_bus *abus,
+ int vendor,
+ int device,
+ int index,
+ ambapp_ahbdev *dev
+ );
+
+/* Return number of APB Slave devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device);
-#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
+/* Return number of AHB Master devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device);
-#ifndef __ASSEMBLER__
+/* Return number of AHB Slave devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device);
#ifdef CONFIG_CMD_AMBAPP
/* Return name of vendor */
char *ambapp_vendor_id2str(int vendor);
-#endif
-/*
- * Types and structure used for AMBA Plug & Play bus scanning
- */
+/* Return description of a device */
+char *ambapp_device_id2desc(int vendor, int id);
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
- unsigned int conf;
- unsigned int userdef[3];
- unsigned int bars[4];
-} ahbctrl_pp_dev;
+#endif
-/* Prototypes for scanning AMBA Plug&Play bus for AMBA
- * i) AHB Masters
- * ii) AHB Slaves
- * iii) APB Slaves (APB MST is a AHB Slave)
- */
+#endif /* defined(__ASSEMBLER__) */
-typedef struct {
- unsigned char irq;
- unsigned char ver;
- unsigned int address;
-} ambapp_apbdev;
-
-typedef struct {
- unsigned char irq;
- unsigned char ver;
- unsigned int userdef[3];
- unsigned int address[4];
-} ambapp_ahbdev;
+#define AMBA_DEFAULT_IOAREA 0xfff00000
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA 0x800
-/* AMBA Plug&Play AHB Masters & Slaves information locations
- * Max devices is 64 supported by HW, however often only 8
- * are used.
- */
-typedef struct {
- ahbctrl_pp_dev masters[64];
- ahbctrl_pp_dev slaves[64];
-} ahbctrl_info;
+#define DEV_NONE 0
+#define DEV_AHB_MST 1
+#define DEV_AHB_SLV 2
+#define DEV_APB_SLV 3
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
- unsigned int conf;
- unsigned int bar;
-} apbctrl_pp_dev;
+#define AMBA_TYPE_APBIO 0x1
+#define AMBA_TYPE_MEM 0x2
+#define AMBA_TYPE_AHBIO 0x3
-/* All functions return the number of found devices
- * 0 = no devices found
+/* ID layout for APB and AHB devices */
+#define AMBA_PNP_ID(vendor, device) (((vendor)<<24) | ((device)<<12))
+
+/* APB Slave PnP layout definitions */
+#define AMBA_APB_ID_OFS (0*4)
+#define AMBA_APB_IOBAR_OFS (1*4)
+#define AMBA_APB_CONF_LENGH (2*4)
+
+/* AHB Master/Slave layout PnP definitions */
+#define AMBA_AHB_ID_OFS (0*4)
+#define AMBA_AHB_CUSTOM0_OFS (1*4)
+#define AMBA_AHB_CUSTOM1_OFS (2*4)
+#define AMBA_AHB_CUSTOM2_OFS (3*4)
+#define AMBA_AHB_MBAR0_OFS (4*4)
+#define AMBA_AHB_MBAR1_OFS (5*4)
+#define AMBA_AHB_MBAR2_OFS (6*4)
+#define AMBA_AHB_MBAR3_OFS (7*4)
+#define AMBA_AHB_CONF_LENGH (8*4)
+
+/* Macros for extracting information from AMBA PnP information
+ * registers.
*/
-/****************************** APB SLAVES ******************************/
-int ambapp_apb_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_apb_first(unsigned int vendor,
- unsigned int driver, ambapp_apbdev * dev);
-
-int ambapp_apb_next(unsigned int vendor,
- unsigned int driver, ambapp_apbdev * dev, int index);
-
-int ambapp_apbs_first(unsigned int vendor,
- unsigned int driver, ambapp_apbdev * dev, int max_cnt);
-
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_ahbmst_first(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev);
+#define amba_vendor(x) (((x) >> 24) & 0xff)
-int ambapp_ahbmst_next(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int index);
+#define amba_device(x) (((x) >> 12) & 0xfff)
-int ambapp_ahbmsts_first(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+#define amba_irq(conf) ((conf) & 0x1f)
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
+#define amba_ver(conf) (((conf)>>5) & 0x1f)
-int ambapp_ahbslv_first(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev);
+#define amba_iobar_start(base, iobar) \
+ ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)))
-int ambapp_ahbslv_next(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int index);
+#define amba_membar_start(mbar) \
+ (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
-int ambapp_ahbslvs_first(unsigned int vendor,
- unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+#define amba_membar_type(mbar) ((mbar) & 0xf)
-/*************************** AHB/APB only regs functions *************************
- * During start up, no memory is available we can use the simplified functions
- * to get to the memory controller.
- *
- * Functions uses no stack/memory, only registers.
- */
-unsigned int ambapp_apb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
- register unsigned int driver, /* Plug&Play Device ID */
- register int index);
+#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff)
-ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor, /* Plug&Play Vendor ID */
- register unsigned int driver, /* Plug&Play Device ID */
- register unsigned int opts, /* scan for AHB 1=slave, 0=masters */
- register int index);
+#define amba_ahbio_adr(addr, base_ioarea) \
+ ((unsigned int)(base_ioarea) | ((addr) >> 12))
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
+#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1)
/*************************** AMBA Plug&Play device register MAPS *****************/
#define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive interrupt */
#define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit interrupt */
+#ifndef __ASSEMBLER__
+
typedef struct {
volatile unsigned int ilevel;
volatile unsigned int ipend;
--- /dev/null
+/* AMBA Plug & Play Bus Vendor and Device IDs.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+
+#ifndef __AMBAPP_IDS_H__
+#define __AMBAPP_IDS_H__
+
+/* Vendor ID defines */
+#define VENDOR_GAISLER 0x01
+#define VENDOR_PENDER 0x02
+#define VENDOR_ESA 0x04
+#define VENDOR_ASTRIUM 0x06
+#define VENDOR_OPENCHIP 0x07
+#define VENDOR_OPENCORES 0x08
+#define VENDOR_CONTRIB 0x09
+#define VENDOR_EONIC 0x0b
+#define VENDOR_RADIONOR 0x0f
+#define VENDOR_GLEICHMANN 0x10
+#define VENDOR_MENTA 0x11
+#define VENDOR_SUN 0x13
+#define VENDOR_MOVIDIA 0x14
+#define VENDOR_ORBITA 0x17
+#define VENDOR_SYNOPSYS 0x21
+#define VENDOR_NASA 0x22
+#define VENDOR_CAL 0xca
+#define VENDOR_EMBEDDIT 0xea
+#define VENDOR_CETON 0xcb
+#define VENDOR_ACTEL 0xac
+#define VENDOR_APPLECORE 0xae
+
+/* Aeroflex Gaisler device ID defines */
+#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_LEON4 0x048
+#define GAISLER_LEON4DSU 0x049
+#define GAISLER_PWM 0x04a
+#define GAISLER_L2CACHE 0x04b
+#define GAISLER_SDCTRL64 0x04c
+#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_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_ATAHBSLV 0x068
+#define GAISLER_ATAHBMST 0x069
+#define GAISLER_ATAPBSLV 0x06a
+#define GAISLER_B1553BC 0x070
+#define GAISLER_B1553RT 0x071
+#define GAISLER_B1553BRM 0x072
+#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_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_GPREG 0x087
+#define GAISLER_GRTMPAHB 0x088
+
+/* European Space Agency device ID defines */
+#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_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
+
+/* OpenChip device ID defines */
+#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
+
+/* Various contributions device ID defines */
+#define CONTRIB_CORE1 0x001
+#define CONTRIB_CORE2 0x002
+
+/* Gleichmann Electronics device ID defines */
+#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
+
+/* Sun Microsystems device ID defines */
+#define SUN_T1 0x001
+#define SUN_S1 0x011
+
+/* Orbita device ID defines */
+#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
+
+/* NASA device ID defines */
+#define NASA_EP32 0x001
+
+/* CAL device ID defines */
+#define CAL_DDRCTRL 0x188
+
+/* Actel Corporation device ID defines */
+#define ACTEL_COREMP7 0x001
+
+/* AppleCore device ID defines */
+#define APPLECORE_UTLEON3 0x001
+#define APPLECORE_UTLEON3DSU 0x002
+
+/* Opencores device id's */
+#define OPENCORES_PCIBR 0x4
+#define OPENCORES_ETHMAC 0x5
+
+#endif