summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-09-06 00:01:53 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-09-06 00:01:53 +0000
commit2eb4aba98f423088e0ed8f53ac1f93d47e7447bc (patch)
tree2908f95c1fd3c52dcb81ef634f0e1f895d98ca14 /c
parent2007-09-05 Daniel Hellstrom <daniel@gaisler.com> (diff)
downloadrtems-2eb4aba98f423088e0ed8f53ac1f93d47e7447bc.tar.bz2
2007-09-05 Daniel Hellstrom <daniel@gaisler.com>
* shared/amba/ambapp.c, shared/include/ambapp.h: New files.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/sparc/ChangeLog4
-rw-r--r--c/src/lib/libbsp/sparc/shared/amba/ambapp.c499
-rw-r--r--c/src/lib/libbsp/sparc/shared/include/ambapp.h279
3 files changed, 782 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/ChangeLog b/c/src/lib/libbsp/sparc/ChangeLog
index 8e8ab5989e..32348679c5 100644
--- a/c/src/lib/libbsp/sparc/ChangeLog
+++ b/c/src/lib/libbsp/sparc/ChangeLog
@@ -1,5 +1,9 @@
2007-09-05 Daniel Hellstrom <daniel@gaisler.com>
+ * shared/amba/ambapp.c, shared/include/ambapp.h: New files.
+
+2007-09-05 Daniel Hellstrom <daniel@gaisler.com>
+
* Makefile.am: LEON3 AMBA PnP bus scanning moved to shared/amba/amba.c
and shared/include/ambapp.h. The AMBA scanning was improved to take
account for PnP info address translation. This is useful when
diff --git a/c/src/lib/libbsp/sparc/shared/amba/ambapp.c b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
new file mode 100644
index 0000000000..d030fcef1b
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/amba/ambapp.c
@@ -0,0 +1,499 @@
+/*
+ * AMBA Plag & Play Bus Driver
+ *
+ * This driver hook performs bus scanning.
+ *
+ * COPYRIGHT (c) 2004.
+ * Gaisler Research
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/bspIo.h>
+#include <ambapp.h>
+
+#define amba_insert_device(tab, address) \
+{ \
+ if (*(address)) \
+ { \
+ (tab)->addr[(tab)->devnr] = (address); \
+ (tab)->devnr ++; \
+ } \
+} while(0)
+
+#define amba_insert_apb_device(tab, address, apbmst) \
+{ \
+ if (*(address)) \
+ { \
+ (tab)->addr[(tab)->devnr] = (address); \
+ (tab)->apbmst[(tab)->devnr] = (apbmst); \
+ (tab)->devnr ++; \
+ } \
+} while(0)
+
+static unsigned int
+addr_from (struct amba_mmap *mmaps, unsigned int address)
+{
+ /* no translation? */
+ if (!mmaps)
+ return address;
+
+ while (mmaps->size) {
+ if ((address >= mmaps->remote_amba_adr)
+ && (address <= (mmaps->remote_amba_adr + (mmaps->size - 1)))) {
+ return (address - mmaps->remote_amba_adr) + mmaps->cpu_adr;
+ }
+ mmaps++;
+ }
+ return 1;
+}
+
+
+void
+amba_scan (amba_confarea_type * amba_conf, unsigned int ioarea,
+ struct amba_mmap *mmaps)
+{
+ unsigned int *cfg_area; /* address to configuration area */
+ unsigned int mbar, conf, custom;
+ int i, j;
+ unsigned int apbmst;
+ int maxloops = amba_conf->notroot ? 16 : 64; /* scan first bus for 64 devices, rest for 16 devices */
+
+ amba_conf->ahbmst.devnr = 0;
+ amba_conf->ahbslv.devnr = 0;
+ amba_conf->apbslv.devnr = 0;
+ cfg_area = (unsigned int *) (ioarea | AMBA_CONF_AREA);
+ amba_conf->ioarea = ioarea;
+ amba_conf->mmaps = mmaps;
+
+ for (i = 0; i < maxloops; i++) {
+ amba_insert_device (&amba_conf->ahbmst, cfg_area);
+ cfg_area += AMBA_AHB_CONF_WORDS;
+ }
+
+ cfg_area =
+ (unsigned int *) (ioarea | AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA);
+ for (i = 0; i < maxloops; i++) {
+ amba_insert_device (&amba_conf->ahbslv, cfg_area);
+ cfg_area += AMBA_AHB_CONF_WORDS;
+ }
+
+ for (i = 0; i < amba_conf->ahbslv.devnr; i++){
+ conf = amba_get_confword(amba_conf->ahbslv, i, 0);
+ mbar = amba_ahb_get_membar(amba_conf->ahbslv, i, 0);
+ if ( (amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_AHB2AHB) ){
+ /* Found AHB->AHB bus bridge, scan it if more free amba_confarea_type:s available
+ * Custom config 1 contain ioarea.
+ */
+ custom = amba_ahb_get_custom(amba_conf->ahbslv,i,1);
+
+ if ( amba_ver(conf) && amba_conf->next ){
+ amba_conf->next->notroot = 1;
+ amba_scan(amba_conf->next,custom,mmaps);
+ }
+ }else if ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_APBMST))
+ {
+ apbmst = amba_membar_start(mbar);
+ if ( (apbmst=addr_from(mmaps,apbmst)) == 1 )
+ continue; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB/APB bridge. Skip it.
+ */
+ cfg_area = (unsigned int *)( apbmst | AMBA_CONF_AREA);
+ for (j=0; (amba_conf->apbslv.devnr<AMBA_APB_SLAVES) && (j<AMBA_APB_SLAVES); j++){
+ amba_insert_apb_device(&amba_conf->apbslv, cfg_area, apbmst);
+ cfg_area += AMBA_APB_CONF_WORDS;
+ }
+ }
+ }
+}
+
+void
+amba_print_dev(int devno, unsigned int conf){
+ int irq = amba_irq(conf);
+ if ( irq > 0 ){
+ printk("%x.%x.%x: irq %d\n",devno,amba_vendor(conf),amba_device(conf),irq);
+ }else{
+ printk("%x.%x.%x: no irq\n",devno,amba_vendor(conf),amba_device(conf));
+ }
+}
+
+void
+amba_apb_print_dev(int devno, unsigned int conf, unsigned int address){
+ int irq = amba_irq(conf);
+ if ( irq > 0 ){
+ printk("%x.%x.%x: irq %d, apb: 0x%lx\n",devno,amba_vendor(conf),amba_device(conf),irq,address);
+ }else{
+ printk("%x.%x.%x: no irq, apb: 0x%lx\n",devno,amba_vendor(conf),amba_device(conf),address);
+ }
+}
+
+/* Print AMBA Plug&Play info on terminal */
+void
+amba_print_conf (amba_confarea_type * amba_conf)
+{
+ int i,base=0;
+ unsigned int conf, iobar, address;
+ unsigned int apbmst;
+
+ /* print all ahb masters */
+ printk("--- AMBA AHB Masters ---\n");
+ for(i=0; i<amba_conf->ahbmst.devnr; i++){
+ conf = amba_get_confword(amba_conf->ahbmst, i, 0);
+ amba_print_dev(i,conf);
+ }
+
+ /* print all ahb slaves */
+ printk("--- AMBA AHB Slaves ---\n");
+ for(i=0; i<amba_conf->ahbslv.devnr; i++){
+ conf = amba_get_confword(amba_conf->ahbslv, i, 0);
+ amba_print_dev(i,conf);
+ }
+
+ /* print all apb slaves */
+ apbmst = 0;
+ for(i=0; i<amba_conf->apbslv.devnr; i++){
+ if ( apbmst != amba_conf->apbslv.apbmst[i] ){
+ apbmst = amba_conf->apbslv.apbmst[i];
+ printk("--- AMBA APB Slaves on 0x%x ---\n",apbmst);
+ base=i;
+ }
+ conf = amba_get_confword(amba_conf->apbslv, i, 0);
+ iobar = amba_apb_get_membar(amba_conf->apbslv, i);
+ address = amba_iobar_start(amba_conf->apbslv.apbmst[i], iobar);
+ amba_apb_print_dev(i-base,conf,address);
+ }
+
+}
+/**** APB Slaves ****/
+
+/* Return number of APB Slave devices which has given vendor and device */
+int
+amba_get_number_apbslv_devices (amba_confarea_type * amba_conf, int vendor,
+ int device)
+{
+ unsigned int conf;
+ int cnt, i;
+
+ for (cnt = i = 0; i < amba_conf->apbslv.devnr; i++) {
+ conf = amba_get_confword (amba_conf->apbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
+ cnt++;
+ }
+ return cnt;
+}
+
+/* Get First APB Slave device of this vendor&device id */
+int
+amba_find_apbslv (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_apb_device * dev)
+{
+ unsigned int conf, iobar;
+ int i;
+
+ for (i = 0; i < amba_conf->apbslv.devnr; i++) {
+ conf = amba_get_confword (amba_conf->apbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ iobar = amba_apb_get_membar (amba_conf->apbslv, i);
+ dev->start = amba_iobar_start (amba_conf->apbslv.apbmst[i], iobar);
+ dev->irq = amba_irq (conf);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Get APB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_apbslv() ) */
+int
+amba_find_next_apbslv (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_apb_device * dev, int index)
+{
+ unsigned int conf, iobar;
+ int cnt, i;
+
+ for (cnt = i = 0; i < amba_conf->apbslv.devnr; i++) {
+ conf = amba_get_confword (amba_conf->apbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ if (cnt == index) {
+ /* found device */
+ iobar = amba_apb_get_membar (amba_conf->apbslv, i);
+ dev->start = amba_iobar_start (amba_conf->apbslv.apbmst[i], iobar);
+ dev->irq = amba_irq (conf);
+ return 1;
+ }
+ cnt++;
+ }
+ }
+ return 0;
+}
+
+/* Get first nr APB Slave devices, put them into dev (which is an array of nr length) */
+int
+amba_find_apbslvs (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_apb_device * devs, int maxno)
+{
+ unsigned int conf, iobar;
+ int cnt, i;
+
+ for (cnt = i = 0; (i < amba_conf->apbslv.devnr) && (cnt < maxno); i++) {
+ conf = amba_get_confword (amba_conf->apbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ /* found device */
+ iobar = amba_apb_get_membar (amba_conf->apbslv, i);
+ devs[cnt].start = amba_iobar_start (amba_conf->apbslv.apbmst[i], iobar);
+ devs[cnt].irq = amba_irq (conf);
+ cnt++;
+ }
+ }
+ return cnt;
+}
+
+/***** AHB SLAVES *****/
+
+/* Return number of AHB Slave devices which has given vendor and device */
+int
+amba_get_number_ahbslv_devices (amba_confarea_type * amba_conf, int vendor,
+ int device)
+{
+ unsigned int conf;
+ int cnt, i;
+
+ for (cnt = i = 0; i < amba_conf->ahbslv.devnr; i++) {
+ conf = amba_get_confword (amba_conf->ahbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
+ cnt++;
+ }
+ return cnt;
+}
+
+/* Get First AHB Slave device of this vendor&device id */
+int
+amba_find_ahbslv (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * dev)
+{
+ unsigned int conf, mbar, addr;
+ int j, i;
+
+ for (i = 0; i < amba_conf->ahbslv.devnr; i++) {
+ conf = amba_get_confword (amba_conf->ahbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ for (j = 0; j < 4; j++) {
+ mbar = amba_ahb_get_membar (amba_conf->ahbslv, i, j);
+ addr = amba_membar_start (mbar);
+ if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
+ addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
+ } else { /* convert address if needed */
+ if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
+ addr = 0; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB address. Skip it.
+ */
+ }
+ }
+ dev->start[j] = addr;
+ }
+ dev->irq = amba_irq (conf);
+ dev->ver = amba_ver (conf);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Get AHB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbslv() ) */
+int
+amba_find_next_ahbslv (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * dev, int index)
+{
+ unsigned int conf, mbar, addr;
+ int i, j, cnt;
+
+ for (cnt = i = 0; i < amba_conf->ahbslv.devnr; i++) {
+ conf = amba_get_confword (amba_conf->ahbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ if (cnt == index) {
+ for (j = 0; j < 4; j++) {
+ mbar = amba_ahb_get_membar (amba_conf->ahbslv, i, j);
+ addr = amba_membar_start (mbar);
+ if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
+ addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
+ } else {
+ /* convert address if needed */
+ if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
+ addr = 0; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB address. Skip it.
+ */
+ }
+ }
+ dev->start[j] = addr;
+ }
+ dev->irq = amba_irq (conf);
+ dev->ver = amba_ver (conf);
+ return 1;
+ }
+ cnt++;
+ }
+ }
+ return 0;
+}
+
+/* Get first nr AHB Slave devices, put them into dev (which is an array of nr length) */
+int
+amba_find_ahbslvs (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * devs, int maxno)
+{
+ unsigned int conf, mbar, addr;
+ int i, j, cnt;
+
+ for (cnt = i = 0; (i < amba_conf->ahbslv.devnr) && (maxno < cnt); i++) {
+ conf = amba_get_confword (amba_conf->ahbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ for (j = 0; j < 4; j++) {
+ mbar = amba_ahb_get_membar (amba_conf->ahbslv, i, j);
+ addr = amba_membar_start (mbar);
+ if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
+ addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
+ } else {
+ /* convert address if needed */
+ if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
+ addr = 0; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB address. Skip it.
+ */
+ }
+ }
+ devs[cnt].start[j] = addr;
+ }
+ devs[cnt].irq = amba_irq (conf);
+ devs[cnt].ver = amba_ver (conf);
+ cnt++;
+ }
+ }
+ return cnt;
+}
+
+
+/***** AHB Masters *****/
+
+/* Return number of AHB Slave devices which has given vendor and device */
+int
+amba_get_number_ahbmst_devices (amba_confarea_type * amba_conf, int vendor,
+ int device)
+{
+ unsigned int conf;
+ int cnt, i;
+
+ for (cnt = i = 0; i < amba_conf->ahbmst.devnr; i++) {
+ conf = amba_get_confword (amba_conf->ahbmst, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device))
+ cnt++;
+ }
+ return cnt;
+}
+
+/* Get First AHB Slave device of this vendor&device id */
+int
+amba_find_ahbmst (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * dev)
+{
+ unsigned int conf, mbar, addr;
+ int j, i;
+
+ for (i = 0; i < amba_conf->ahbmst.devnr; i++) {
+ conf = amba_get_confword (amba_conf->ahbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ for (j = 0; j < 4; j++) {
+ mbar = amba_ahb_get_membar (amba_conf->ahbmst, i, j);
+ addr = amba_membar_start (mbar);
+ if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
+ addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
+ } else {
+ /* convert address if needed */
+ if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
+ addr = 0; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB address. Skip it.
+ */
+ }
+ }
+ dev->start[j] = addr;
+ }
+ dev->irq = amba_irq (conf);
+ dev->ver = amba_ver (conf);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Get AHB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbslv() ) */
+int
+amba_find_next_ahbmst (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * dev, int index)
+{
+ unsigned int conf, mbar, addr;
+ int i, j, cnt;
+
+ for (cnt = i = 0; i < amba_conf->ahbmst.devnr; i++) {
+ conf = amba_get_confword (amba_conf->ahbmst, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ if (cnt == index) {
+ for (j = 0; j < 4; j++) {
+ mbar = amba_ahb_get_membar (amba_conf->ahbmst, i, j);
+ addr = amba_membar_start (mbar);
+ if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
+ addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
+ } else {
+ /* convert address if needed */
+ if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
+ addr = 0; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB address. Skip it.
+ */
+ }
+ }
+ dev->start[j] = addr;
+ }
+ dev->irq = amba_irq (conf);
+ dev->ver = amba_ver (conf);
+ return 1;
+ }
+ cnt++;
+ }
+ }
+ return 0;
+}
+
+/* Get first nr AHB Slave devices, put them into dev (which is an array of nr length) */
+int
+amba_find_ahbmsts (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * devs, int maxno)
+{
+ unsigned int conf, mbar, addr;
+ int i, j, cnt;
+
+ for (cnt = i = 0; (i < amba_conf->ahbmst.devnr) && (maxno < cnt); i++) {
+ conf = amba_get_confword (amba_conf->ahbslv, i, 0);
+ if ((amba_vendor (conf) == vendor) && (amba_device (conf) == device)) {
+ for (j = 0; j < 4; j++) {
+ mbar = amba_ahb_get_membar (amba_conf->ahbmst, i, j);
+ addr = amba_membar_start (mbar);
+ if (amba_membar_type (mbar) == AMBA_TYPE_AHBIO) {
+ addr = AMBA_TYPE_AHBIO_ADDR (addr, amba_conf->ioarea);
+ } else {
+ /* convert address if needed */
+ if ((addr = addr_from (amba_conf->mmaps, addr)) == 1) {
+ addr = 0; /* no available memory translation available, will not be able to access
+ * Plug&Play information for this AHB address. Skip it.
+ */
+ }
+ }
+ devs[cnt].start[j] = addr;
+ }
+ devs[cnt].irq = amba_irq (conf);
+ devs[cnt].ver = amba_ver (conf);
+ cnt++;
+ }
+ }
+ return cnt;
+}
diff --git a/c/src/lib/libbsp/sparc/shared/include/ambapp.h b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
new file mode 100644
index 0000000000..e63648d13c
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
@@ -0,0 +1,279 @@
+/*
+ * AMBA Plag & Play Bus Driver Macros for LEON2
+ *
+ * Macros used for AMBA Plug & Play bus scanning
+ *
+ * COPYRIGHT (c) 2007.
+ * Gaisler Research
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef __AMBAPP_H__
+#define __AMBAPP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA (1 << 11)
+
+#define AMBA_AHB_CONF_WORDS 8
+#define AMBA_APB_CONF_WORDS 2
+#define AMBA_AHB_MASTERS 16
+#define AMBA_AHB_SLAVES 16
+#define AMBA_APB_SLAVES 16
+#define AMBA_APBUARTS 8
+
+/* Vendor codes */
+#define VENDOR_GAISLER 1
+#define VENDOR_PENDER 2
+#define VENDOR_ESA 4
+#define VENDOR_OPENCORES 8
+
+/* Gaisler Research device id's */
+#define GAISLER_LEON3 0x03
+#define GAISLER_LEON3DSU 0x04
+#define GAISLER_ETHAHB 0x05
+#define GAISLER_APBMST 0x06
+#define GAISLER_AHBUART 0x07
+#define GAISLER_SRCTRL 0x08
+#define GAISLER_SDCTRL 0x09
+#define GAISLER_APBUART 0x0C
+#define GAISLER_IRQMP 0x0D
+#define GAISLER_AHBRAM 0x0E
+#define GAISLER_GPTIMER 0x11
+#define GAISLER_PCITRG 0x12
+#define GAISLER_PCISBRG 0x13
+#define GAISLER_PCIFBRG 0x14
+#define GAISLER_PCITRACE 0x15
+#define GAISLER_DMACTRL 0x16
+#define GAISLER_OCCAN 0x19
+#define GAISLER_PIOPORT 0x1A
+#define GAISLER_ETHMAC 0x1D
+#define GAISLER_SPACEWIRE 0x1f
+#define GAISLER_AHB2AHB 0x20
+#define GAISLER_GRHCAN 0x34
+#define GAISLER_GRFIFO 0x35
+#define GAISLER_GRPULSE 0x37
+#define GAISLER_GRTIMER 0x38
+#define GAISLER_FTAHBRAM 0x50
+#define GAISLER_FTMCTRL 0x54
+#define GAISLER_BRM 0x72
+
+
+/* European Space Agency device id's */
+#define ESA_LEON2 0x2
+#define ESA_MCTRL 0xF
+#define ESA_SPW2 0x12
+
+/* Opencores device id's */
+#define OPENCORES_PCIBR 0x4
+#define OPENCORES_ETHMAC 0x5
+
+/*
+ *
+ * Macros for manipulating Configuration registers
+ *
+ */
+#define amba_get_confword(tab, index, word) (*((tab).addr[(index)]+(word)))
+
+#define amba_vendor(x) (((x) >> 24) & 0xff)
+
+#define amba_device(x) (((x) >> 12) & 0xfff)
+
+#define amba_ahb_get_membar(tab, index, nr) (*((tab).addr[(index)]+4+(nr)))
+
+#define amba_ahb_get_custom(tab, index, nr) (*((tab).addr[(index)]+1+(nr)))
+
+#define amba_apb_get_membar(tab, index) (*((tab).addr[(index)]+1))
+
+#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) & 0x1f)
+
+#define amba_ver(conf) (((conf)>>5) & 0x1f)
+
+#define amba_membar_type(mbar) ((mbar) & 0xf)
+
+#define AMBA_TYPE_APBIO 0x1
+#define AMBA_TYPE_MEM 0x2
+#define AMBA_TYPE_AHBIO 0x3
+
+#define AMBA_TYPE_AHBIO_ADDR(addr,base_ioarea) ((unsigned int)(base_ioarea) | ((addr) >> 12))
+
+/*
+ * Types and structure used for AMBA Plug & Play bus scanning
+ *
+ */
+typedef struct amba_device_table {
+ int devnr; /* numbrer of devices on AHB or APB bus */
+ unsigned int *addr[16]; /* addresses to the devices configuration tables */
+} amba_device_table;
+
+typedef struct {
+ int devnr;
+ unsigned int *addr[AMBA_APB_SLAVES]; /* addresses to the devices configuration tables */
+ unsigned int apbmst[AMBA_APB_SLAVES]; /* pointer to AHB slave (which is a APB master) */
+} amba_apb_dev;
+
+struct amba_mmap {
+ unsigned int cpu_adr;
+ unsigned int size;
+ unsigned int remote_amba_adr;
+};
+
+typedef struct _amba_confarea_type amba_confarea_type;
+
+struct _amba_confarea_type {
+ amba_confarea_type *next; /* next bus in chain */
+ int notroot; /* is root of a bus (mother AHB has 64 masters/slaves rest 16) */
+ unsigned int ioarea;
+ struct amba_mmap *mmaps;
+ amba_device_table ahbmst;
+ amba_device_table ahbslv;
+ amba_apb_dev apbslv;
+};
+
+typedef struct {
+ unsigned int start, irq, bus_id;
+} amba_apb_device;
+
+typedef struct {
+ unsigned int start[4], irq, ver;
+} amba_ahb_device;
+
+/* Scans AMBA Plug&Play Information and convers that information
+ * to a more readable format in RAM.
+ *
+ * Will scan for - AHB Masters
+ * - AHB Slaves
+ * - APB Slaves (if a AHB/APB bridge is found)
+ *
+ * \param amba_conf AMBA P&P device info is placed here.
+ * \param ioarea address of AMBA Plug&Play information,
+ * on LEON3 systems default is 0xfff00000
+ * \param mmaps Memory mmap specific to this amba bus,
+ * if NULL no translation will be made (default).
+ * A array of maps, ending with a entry with size=0.
+ */
+void amba_scan (amba_confarea_type * amba_conf, unsigned int ioarea,
+ struct amba_mmap *mmaps);
+
+/* Print AMBA Plug&Play info on terminal */
+void amba_print_conf (amba_confarea_type * amba_conf);
+
+
+
+
+/***** APB SLAVES *****/
+
+/* Return number of APB Slave devices which has given vendor and device */
+int amba_get_number_apbslv_devices (amba_confarea_type * amba_conf, int vendor,
+ int device);
+
+/* Get First APB Slave device of this vendor&device id */
+int amba_find_apbslv (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_apb_device * dev);
+
+/* Get APB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_apbslv() ) */
+int amba_find_next_apbslv (amba_confarea_type * amba_conf, int vendor,
+ int device, amba_apb_device * dev, int index);
+
+/* Get first nr APB Slave devices, put them into dev (which is an array of nr length) */
+int amba_find_apbslvs (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_apb_device * devs, int maxno);
+
+
+
+/***** AHB SLAVES *****/
+
+/* Return number of AHB Slave devices which has given vendor and device */
+int amba_get_number_ahbslv_devices (amba_confarea_type * amba_conf, int vendor,
+ int device);
+
+/* Get First AHB Slave device of this vendor&device id */
+int amba_find_ahbslv (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * dev);
+
+/* Get AHB Slave device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbslv() ) */
+int amba_find_next_ahbslv (amba_confarea_type * amba_conf, int vendor,
+ int device, amba_ahb_device * dev, int index);
+
+/* Get first nr AHB Slave devices, put them into dev (which is an array of nr length) */
+int amba_find_ahbslvs (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * devs, int maxno);
+
+
+
+/***** AHB MASTERS *****/
+
+/* Return number of AHB Master devices which has given vendor and device */
+int amba_get_number_ahbmst_devices (amba_confarea_type * amba_conf, int vendor,
+ int device);
+
+/* Get First AHB Master device of this vendor&device id */
+int amba_find_ahbmst (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * dev);
+
+/* Get AHB Master device of this vendor&device id. (setting nr to 0 is eqivalent to calling amba_find_ahbmst() ) */
+int amba_find_next_ahbmst (amba_confarea_type * amba_conf, int vendor,
+ int device, amba_ahb_device * dev, int index);
+
+/* Get first nr AHB Master devices, put them into dev (which is an array of nr length) */
+int amba_find_ahbmsts (amba_confarea_type * amba_conf, int vendor, int device,
+ amba_ahb_device * devs, int maxno);
+
+
+/******** AMBA DEVICES *******/
+
+/* ESA MEMORY CONTROLLER */
+typedef struct {
+ unsigned int mcfg1;
+ unsigned int mcfg2;
+ unsigned int mcfg3;
+} ambapp_regmap_mctrl;
+
+/* APB UART */
+typedef struct {
+ volatile unsigned int data;
+ volatile unsigned int status;
+ volatile unsigned int ctrl;
+ volatile unsigned int scaler;
+} ambapp_apb_uart;
+
+typedef struct {
+ volatile unsigned int ilevel;
+ volatile unsigned int ipend;
+ volatile unsigned int iforce;
+ volatile unsigned int iclear;
+ volatile unsigned int mpstat;
+ volatile unsigned int notused01;
+ volatile unsigned int notused02;
+ volatile unsigned int notused03;
+ volatile unsigned int notused10;
+ volatile unsigned int notused11;
+ volatile unsigned int notused12;
+ volatile unsigned int notused13;
+ volatile unsigned int notused20;
+ volatile unsigned int notused21;
+ volatile unsigned int notused22;
+ volatile unsigned int notused23;
+ volatile unsigned int mask[16];
+ volatile unsigned int force[16];
+} LEON3_IrqCtrl_Regs_Map;
+
+/*****************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif