diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-09-06 00:01:53 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2007-09-06 00:01:53 +0000 |
commit | 2eb4aba98f423088e0ed8f53ac1f93d47e7447bc (patch) | |
tree | 2908f95c1fd3c52dcb81ef634f0e1f895d98ca14 /c | |
parent | 2007-09-05 Daniel Hellstrom <daniel@gaisler.com> (diff) | |
download | rtems-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/ChangeLog | 4 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/amba/ambapp.c | 499 | ||||
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/include/ambapp.h | 279 |
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 |