void pcidiagset(int b, int d, int f, int bar, int vendor, int device, int exact) { epicsUInt32 len=0; struct bdf loc; epicsPCIID ids[] = { DEVPCI_DEVICE_VENDOR(device,vendor), DEVPCI_END }; diagbase = NULL; diagdev = NULL; diaglen = 0; printf("Looking for %u:%u.%u\n", b, d, f); if(vendor==0 && !exact) ids[0].vendor=DEVPCI_ANY_VENDOR; if(device==0 && !exact) ids[0].device=DEVPCI_ANY_DEVICE; loc.b=b; loc.d=d; loc.f=f; loc.dev=0; if(devPCIFindCB(ids, &matchbdf, (void*)&loc, 0)) { printf("Error searching\n"); return; } if(!loc.dev) { printf("No such device\n"); return; } printf("Mapping %u:%u.%u\n", loc.dev->bus, loc.dev->device, loc.dev->function); #if defined(linux) if(devPCIBarLen(loc.dev, bar, &len)) { printf("Failed to get BAR length\n"); len=0; } #endif if(devPCIToLocalAddr(loc.dev, bar, &diagbase, 0)) { printf("Failed to map BAR\n"); return; } diagdev = loc.dev; diaglen=len; #if defined(linux) printf("BAR %u from 0x%08lx for %u bytes\n",bar, (unsigned long)diagbase, diaglen); #else printf("BAR %u from 0x%08lx\n",bar, (unsigned long)diagbase); #endif }
void fribEvrSetupPCI(const char *name, const char *pcispec) { try { const epicsPCIDevice *dev = NULL; if(devPCIFindSpec(evr_frib_ids, pcispec, &dev, 0)) { fprintf(stderr, "No such device: %s\n", pcispec); return; } fprintf(stderr, "Found device\n"); volatile unsigned char *base = NULL; if(devPCIToLocalAddr(dev, 0, (volatile void**)&base, 0)) { fprintf(stderr, "Can't map BAR 0 of %s\n", pcispec); return; } epicsUInt32 blen = 0; if(devPCIBarLen(dev, 0, &blen)) { fprintf(stderr, "Can't determine BAR 0 len of %s\n", pcispec); return; } if(!base || blen<REGLEN) { fprintf(stderr, "Invalid base %p or length %u of %s\n", base, (unsigned)blen, pcispec); return; } bus_configuration bconf; bconf.busType = busType_pci; bconf.pci.dev = dev; mrf::auto_ptr<EVRFRIB> evr(new EVRFRIB(name, bconf, base)); // lose our pointer // a pointer is retained in the global Objects list evr.release(); fprintf(stderr, "Ready\n"); }catch(std::exception &e){ fprintf(stderr, "Error: %s\n", e.what()); } }
epicsStatus mrmEvgSetupPCI ( const char* id, // Card Identifier int b, // Bus number int d, // Device number int f, // Function number bool ignoreVersion) // Ignore errors due to kernel module and firmware version checks { deviceInfoT deviceInfo; deviceInfo.bus.busType = busType_pci; deviceInfo.bus.pci.bus = b; deviceInfo.bus.pci.device = d; deviceInfo.bus.pci.function = f; deviceInfo.series = series_unknown; try { if (mrf::Object::getObject(id)) { errlogPrintf("ID %s already in use\n", id); return -1; } if(checkUIOVersion(1) > 0) { // check if kernel version is successfully read and is as expected or higher, and if it can be read at all. if(ignoreVersion){ epicsPrintf("Ignoring kernel module error.\n"); } else{ return -1; } } /* Find PCI device from devLib2 */ const epicsPCIDevice *cur = 0; if (devPCIFindBDF(mrmevgs, b, d, f, &cur, 0)) { errlogPrintf("PCI Device not found on %x:%x.%x\n", b, d, f); return -1; } epicsPrintf("Device %s %x:%x.%x\n", id, cur->bus, cur->device, cur->function); epicsPrintf("Using IRQ %u\n", cur->irq); /* MMap BAR0(plx) and BAR2(EVG)*/ volatile epicsUInt8 *BAR_plx, *BAR_evg; // base addressed for plx/evg bars if (devPCIToLocalAddr(cur, 0, (volatile void**) (void *) &BAR_plx, 0) || devPCIToLocalAddr(cur, 2, (volatile void**) (void *) &BAR_evg, 0)) { errlogPrintf("Failed to map BARs 0 and 2\n"); return -1; } if (!BAR_plx || !BAR_evg) { errlogPrintf("BARs mapped to zero? (%08lx,%08lx)\n", (unsigned long) BAR_plx, (unsigned long) BAR_evg); return -1; } //Set LE mode on PLX bridge //TODO: this limits cPCI EVG device support to LE architectures // At this point in time we do not have any BE PCI systems at hand so this is left as // unsported until we HW to test it on... epicsUInt32 plxCtrl = LE_READ32(BAR_plx,LAS0BRD); plxCtrl = plxCtrl & ~LAS0BRD_ENDIAN; LE_WRITE32(BAR_plx,LAS0BRD,plxCtrl); epicsUInt32 version = checkVersion(BAR_evg, 0x3); epicsPrintf("Firmware version: %08x\n", version); if(version == 0) { if(ignoreVersion) { epicsPrintf("Ignoring version error.\n"); } else { return -1; } } evgMrm* evg = new evgMrm(id, deviceInfo, BAR_evg, 0, cur); evg->getSeqRamMgr()->getSeqRam(0)->disable(); evg->getSeqRamMgr()->getSeqRam(1)->disable(); /*Disable the interrupts and enable them at the end of iocInit via initHooks*/ WRITE32(BAR_evg, IrqFlag, READ32(BAR_evg, IrqFlag)); WRITE32(BAR_evg, IrqEnable, 0); /* * Enable active high interrupt1 through the PLX to the PCI bus. */ // LE_WRITE16(BAR_plx, INTCSR, INTCSR_INT1_Enable| INTCSR_INT1_Polarity| INTCSR_PCI_Enable); if(ignoreVersion){ epicsPrintf("Not enabling interrupts.\n"); } else { if(devPCIEnableInterrupt(cur)) { errlogPrintf("Failed to enable interrupt\n"); return -1; } } #ifdef __linux__ evg->isrLinuxPvt = (void*) cur; #endif /*Connect Interrupt handler to isr thread*/ if(ignoreVersion){ epicsPrintf("Not connecting interrupts.\n"); } else { if (devPCIConnectInterrupt(cur, &evgMrm::isr_pci, (void*) evg, 0)) {//devConnectInterruptVME(irqVector & 0xff, &evgMrm::isr, evg)){ errlogPrintf("ERROR:Failed to connect PCI interrupt\n"); delete evg; return -1; } else { epicsPrintf("PCI interrupt connected!\n"); } } } catch (std::exception& e) { errlogPrintf("Error: %s\n", e.what()); errlogFlush(); return -1; } return 0; } //mrmEvgSetupPCI