forked from Imagelibrary/rtems
2007-09-05 Daniel Hellstrom <daniel@gaisler.com>
* shared/amba/ambapp.c, shared/include/ambapp.h: New files.
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
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
|
||||
|
||||
499
c/src/lib/libbsp/sparc/shared/amba/ambapp.c
Normal file
499
c/src/lib/libbsp/sparc/shared/amba/ambapp.c
Normal file
@@ -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;
|
||||
}
|
||||
279
c/src/lib/libbsp/sparc/shared/include/ambapp.h
Normal file
279
c/src/lib/libbsp/sparc/shared/include/ambapp.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user