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_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); } }
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)); } }
/* Parse AHB PnP information */ void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev) { 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; } }
/* 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; }
int rtems_leon_open_eth_driver_attach( struct rtems_bsdnet_ifconfig *config, int attach ) { int device_found = 0; int i; unsigned int conf, iobar; unsigned int base_addr = 0; /* avoid warnings */ unsigned int eth_irq = 0; /* avoid warnings */ /* Scan for MAC AHB slave interface */ for (i = 0; i < amba_conf.ahbslv.devnr; i++) { conf = amba_get_confword(amba_conf.ahbslv, i, 0); if (((amba_vendor(conf) == VENDOR_OPENCORES) && (amba_device(conf) == OPENCORES_ETHMAC)) || ((amba_vendor(conf) == VENDOR_GAISLER) && (amba_device(conf) == GAISLER_ETHAHB))) { iobar = amba_ahb_get_membar(amba_conf.ahbslv, i, 0); base_addr = amba_iobar_start(LEON3_IO_AREA, iobar); eth_irq = amba_irq(conf) + 0x10; device_found = 1; break; } } if (device_found) { /* clear control register and reset NIC */ *(volatile int *) base_addr = 0; *(volatile int *) base_addr = 0x800; *(volatile int *) base_addr = 0; leon_open_eth_configuration.base_address = base_addr; leon_open_eth_configuration.vector = eth_irq; leon_open_eth_configuration.txd_count = TDA_COUNT; leon_open_eth_configuration.rxd_count = RDA_COUNT; /* enable 100 MHz operation only if cpu frequency >= 50 MHz */ if (LEON3_Timer_Regs->scaler_reload >= 49) leon_open_eth_configuration.en100MHz = 1; if (rtems_open_eth_driver_attach( config, &leon_open_eth_configuration )) { LEON_Clear_interrupt(leon_open_eth_configuration.vector); LEON_Unmask_interrupt(leon_open_eth_configuration.vector); } } return 0; }
void reportahbdevice() { unsigned int pahb, ahb; unsigned int vendor, device; unsigned int membase = 0; int i = 0; int j = 0; unsigned int tmp = 0; int ahb_addr = ( int )(LEON3_IO_AREA | LEON3_CONF_AREA | LEON3_AHB_SLAVE_CONF_AREA ); for (i = 0; i < LEON3_AHB_SLAVES ; i++ ) { pahb = (ahb_addr + (i * LEON3_AHB_CONF_WORDS * 4)); ahb = ramread(pahb); vendor = amba_vendor(ahb); device = amba_device(ahb); if (vendor != 0 && device !=0 ) { printf("%02x.%02x:%03x ", i, vendor, device); printdevice(device, vendor); printf("(ver %d)", amba_ver(ahb)); printf("\n"); if (amba_irq(ahb) != 0) { printf("%16s %d \n", "irq", amba_irq(ahb)); } for (j = 0; j < 4; j++) { tmp = ramread(pahb + 0x10 + j * 4); if (tmp != 0x00000000) { membase = getmembase(tmp); printf(" %16s %8.8x - %8.8x \n", "ahb:", membase, membase + (0xffffffff - ((tmp & 0xfff0) << 16) + 1)); } } if ((vendor == 0x41) && (device == 0x021)) { tmp = ramread(0x08000000); printf("%12s %d-bit prom @ 0x%8.8x \n", "", ((((tmp >> 8) & 0x3) == 1)? 16 : 8), 0x00000000); tmp = ramread(0x08000000 + 4); printf("%12s %d-bit sram @ 0x%8.8x \n", "", ((((tmp >> 4) & 0x3) == 1)? 32 : 16), 0x04000000); } if ((vendor == 0x01) && (device == 0x004)) { printf("%12s AHB trace 128 lines \n", ""); printf("%12s CPU#0 win 8, whbp 4, itrace 128, V8 mul/div, lddel 1, GRFPU-lite \n", ""); ramwrite(0x90400024, 2); tmp =ramread(0x90700000 + 0x8); printf("%12s icache 1 * %d kbyte, %d byte/line\n", "", (((tmp >> 20)&0xf)==2)?4:2, (((tmp >> 16)&0x7)==3)?32:16); tmp =ramread(0x90700000 + 0xc); printf("%12s dcache 1 * %d kbyte, %d byte/line\n", "", (((tmp >> 20)&0xf)==2)?4:2, (((tmp >> 16)&0x7)==3)?32:16); }
/* Parse APB PnP Information */ void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev) { 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; }
/* 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; }
static void vendor_dev_string(unsigned long conf, char *vendorbuf, char *devbuf) { int vendor = amba_vendor(conf); int dev = amba_device(conf); char *devstr; char *vendorstr; sprintf(vendorbuf, "Unknown vendor %2x", vendor); sprintf(devbuf, "Unknown device %2x", dev); vendorstr = vendor_id2str(vendor); if(vendorstr) { sprintf(vendorbuf, "%s", vendorstr); } devstr = device_id2str(vendor, dev); if(devstr) { sprintf(devbuf, "%s", devstr); } vendorbuf[0] = 0; devbuf[0] = 0; }
/* 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 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; }
// amba scan operation void reportahbmasterdevice() { unsigned int pahb, ahb; unsigned int vendor, device; int i = 0; int ahb_addr = ( int )(LEON3_IO_AREA | LEON3_CONF_AREA ); for (i = 0; i < LEON3_AHB_MASTERS ; i++ ) { pahb = (ahb_addr + (i * LEON3_AHB_CONF_WORDS * 4)); ahb = ramread(pahb); vendor = amba_vendor(ahb); device = amba_device(ahb); if (vendor != 0 && device !=0 ) { printf("%02x.%02x:%03x ", i, vendor, device); printdevice(device, vendor); printf("(ver %d)", amba_ver(ahb)); printf("\n"); printf("%23s %d \n", "ahb master", i); } } return ; }
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; } /* Get APB CTRL Plug&Play info area */ apbmst_base = apbmst.address[0] & LEON3_IO_AREA; apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA); 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++; }
void amba_prinf_config(void) { char devbuf[128]; char vendorbuf[128]; unsigned int conf; int i = 0; int j = 0; unsigned int addr; unsigned int m; printf(" Vendors Slaves\n"); printf("Ahb masters:\n"); i = 0; while (i < amba_conf.ahbmst.devnr) { conf = amba_get_confword(amba_conf.ahbmst, i, 0); vendor_dev_string(conf, vendorbuf, devbuf); printf("%2i(%2x:%3x|%2i): %16s %16s \n", i, amba_vendor(conf), amba_device(conf), amba_irq(conf), vendorbuf, devbuf); for (j = 0; j < 4; j++) { m = amba_ahb_get_membar(amba_conf.ahbmst, i, j); if (m) { addr = amba_membar_start(m); printf(" +%i: 0x%x \n", j, addr); } } i++; } printf("Ahb slaves:\n"); i = 0; while (i < amba_conf.ahbslv.devnr) { conf = amba_get_confword(amba_conf.ahbslv, i, 0); vendor_dev_string(conf, vendorbuf, devbuf); printf("%2i(%2x:%3x|%2i): %16s %16s \n", i, amba_vendor(conf), amba_device(conf), amba_irq(conf), vendorbuf, devbuf); for (j = 0; j < 4; j++) { m = amba_ahb_get_membar(amba_conf.ahbslv, i, j); if (m) { addr = amba_membar_start(m); if (amba_membar_type(m) == AMBA_TYPE_AHBIO) { addr = AMBA_TYPE_AHBIO_ADDR(addr); } else if (amba_membar_type(m) == AMBA_TYPE_APBIO) { printf("Warning: apbio membar\n"); } printf(" +%i: 0x%x (raw:0x%x)\n", j, addr, m); } } i++; } printf("Apb slaves:\n"); i = 0; while (i < amba_conf.apbslv.devnr) { conf = amba_get_confword(amba_conf.apbslv, i, 0); vendor_dev_string(conf, vendorbuf, devbuf); printf("%2i(%2x:%3x|%2i): %16s %16s \n", i, amba_vendor(conf), amba_device(conf), amba_irq(conf), vendorbuf, devbuf); m = amba_apb_get_membar(amba_conf.apbslv, i); addr = amba_iobar_start(amba_conf.apbslv.apbmst[i], m); printf(" +%2i: 0x%x (raw:0x%x) \n", 0, addr, m); i++; } }