int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value) { dde_kit_pci_readb(PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC(pci->busdevfn), where, value); return 0; }
static int octeon_pcie_read_config_byte(struct pci_controller *hose, pci_dev_t dev, int reg, u8 * val) { //printf("read_config_byte: first_busno = %d, pci_bus = %d, pci_dev = %d, pcie_port = %d\n", hose->first_busno, PCI_BUS(dev), PCI_DEV(dev), octeon_get_pcie_port(hose)); if (((PCI_BUS(dev) - hose->first_busno) == 0) && (PCI_DEV(dev) != 0)) *val = 0xff; else *val = (u8) cvmx_pcie_config_read8(octeon_get_pcie_port(hose), PCI_BUS(dev) - hose->first_busno + 1, PCI_DEV(dev), PCI_FUNC(dev), reg); return 0; }
static unsigned long efipci_address ( struct pci_device *pci, unsigned long location ) { return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ), PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ), EFIPCI_OFFSET ( location ) ); }
int pci_conf_write_intercept(unsigned int seg, unsigned int bdf, unsigned int reg, unsigned int size, uint32_t *data) { struct pci_dev *pdev; int rc = xsm_pci_config_permission(XSM_HOOK, current->domain, bdf, reg, reg + size - 1, 1); if ( rc < 0 ) return rc; ASSERT(!rc); /* * Avoid expensive operations when no hook is going to do anything * for the access anyway. */ if ( reg < 64 || reg >= 256 ) return 0; pcidevs_lock(); pdev = pci_get_pdev(seg, PCI_BUS(bdf), PCI_DEVFN2(bdf)); if ( pdev ) rc = pci_msi_conf_write_intercept(pdev, reg, size, data); pcidevs_unlock(); return rc; }
/** * is_error_source - check whether the device is source of reported error * @dev: pointer to pci_dev to be checked * @e_info: pointer to reported error info */ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) { int pos; u32 status, mask; u16 reg16; /* * When bus id is equal to 0, it might be a bad id * reported by root port. */ if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { /* Device ID match? */ if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) return true; /* Continue id comparing if there is no multiple error */ if (!e_info->multi_error_valid) return false; } /* * When either * 1) nosourceid==y; * 2) bus id is equal to 0. Some ports might lose the bus * id of error source id; * 3) There are multiple errors and prior id comparing fails; * We check AER status registers to find possible reporter. */ if (atomic_read(&dev->enable_cnt) == 0) return false; pos = pci_pcie_cap(dev); if (!pos) return false; /* Check if AER is enabled */ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); if (!(reg16 & ( PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE))) return false; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return false; /* Check if error is recorded */ if (e_info->severity == AER_CORRECTABLE) { pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask); } else { pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask); } if (status & ~mask) return true; return false; }
static void pci_setup_device(int bdf, uint32_t *p_io_base, uint32_t *p_mem_base) { int vendor_id, device_id, class_id, region; vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID); device_id = pci_config_readw(bdf, PCI_DEVICE_ID); class_id = pci_config_readw(bdf, PCI_CLASS_DEVICE); printf("PCI: %02x:%02x:%x class %04x id %04x:%04x\r\n", PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf), class_id, vendor_id, device_id); for (region = 0; region < PCI_REGION_ROM; region++) { int ofs = PCI_BASE_ADDRESS_0 + region * 4; uint32_t old, mask, val, size, align; uint32_t *p_base; old = pci_config_readl(bdf, ofs); if (old & PCI_BASE_ADDRESS_SPACE_IO) { mask = PCI_BASE_ADDRESS_IO_MASK; p_base = p_io_base; } else { mask = PCI_BASE_ADDRESS_MEM_MASK; p_base = p_mem_base; } pci_config_writel(bdf, ofs, -1); val = pci_config_readl(bdf, ofs); pci_config_writel(bdf, ofs, old); align = size = ~(val & mask) + 1; if (val != 0) { uint32_t addr = *p_base; addr = (addr + align - 1) & ~(align - 1); *p_base = addr + size; pci_config_writel(bdf, ofs, addr); printf("PCI: region %d: %08x\r\n", region, addr); if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { pci_config_writel(bdf, ofs + 4, 0); region++; } } } pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); /* Map the interrupt. */ }
static int octeon_pcie_write_config_dword(struct pci_controller *hose, pci_dev_t dev, int reg, u32 val) { cvmx_pcie_config_write32(octeon_get_pcie_port(hose), PCI_BUS(dev) - hose->first_busno + 1, PCI_DEV(dev), PCI_FUNC(dev), reg, val); return 0; }
static void mch_init_dmar(MCHPCIState *mch) { PCIBus *pci_bus = PCI_BUS(qdev_get_parent_bus(DEVICE(mch))); mch->iommu = INTEL_IOMMU_DEVICE(qdev_create(NULL, TYPE_INTEL_IOMMU_DEVICE)); object_property_add_child(OBJECT(mch), "intel-iommu", OBJECT(mch->iommu), NULL); qdev_init_nofail(DEVICE(mch->iommu)); sysbus_mmio_map(SYS_BUS_DEVICE(mch->iommu), 0, Q35_HOST_BRIDGE_IOMMU_ADDR); pci_setup_iommu(pci_bus, q35_host_dma_iommu, mch->iommu); }
/** * Read from PCI config space. * @param bdf 16-bit bus/device/function ID of target. * @param address Config space access address. * @param size Access size (1, 2 or 4 bytes). * * @return Read value. * * @see pci_write_config */ u32 pci_read_config(u16 bdf, u16 address, unsigned int size) { void *mmcfg_addr = pci_get_device_mmcfg_base(bdf) + address; if (!pci_space || PCI_BUS(bdf) > end_bus) return arch_pci_read_config(bdf, address, size); if (size == 1) return mmio_read8(mmcfg_addr); else if (size == 2) return mmio_read16(mmcfg_addr); else return mmio_read32(mmcfg_addr); }
void adjust_pci_device ( struct pci_device *pci ) { unsigned short new_command, pci_command = 0; pci_read_config_word(pci, PCI_COMMAND, &pci_command); new_command = pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_MEM | PCI_COMMAND_IO; if (pci_command != new_command) { LOG("PCI BIOS has not enabled device " FMT_BUSDEVFN "! " "Updating PCI command %04x->%04x\n", PCI_BUS(pci->busdevfn), PCI_SLOT(pci->busdevfn), PCI_FUNC (pci->busdevfn), pci_command, new_command); pci_write_config_word(pci, PCI_COMMAND, new_command); } unsigned char pci_latency; pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency); if ( pci_latency < 32 ) { LOG("PCI device " FMT_BUSDEVFN " latency timer is unreasonably " "low at %d. Setting to 32.\n", PCI_BUS(pci->busdevfn), PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ), pci_latency ); pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32); } }
static int tlp_cfg_dword_write(struct intel_fpga_pcie *pcie, pci_dev_t bdf, int offset, u8 byte_en, u32 value) { u32 headers[TLP_HDR_SIZE]; u8 busno = PCI_BUS(bdf); headers[0] = TLP_CFGWR_DW0(pcie, busno); headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en); headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset); tlp_write_packet(pcie, headers, value); return tlp_read_packet(pcie, NULL); }
/** * Write to PCI config space. * @param bdf 16-bit bus/device/function ID of target. * @param address Config space access address. * @param value Value to be written. * @param size Access size (1, 2 or 4 bytes). * * @see pci_read_config */ void pci_write_config(u16 bdf, u16 address, u32 value, unsigned int size) { void *mmcfg_addr = pci_get_device_mmcfg_base(bdf) + address; if (!pci_space || PCI_BUS(bdf) > end_bus) return arch_pci_write_config(bdf, address, value, size); if (size == 1) mmio_write8(mmcfg_addr, value); else if (size == 2) mmio_write16(mmcfg_addr, value); else mmio_write32(mmcfg_addr, value); }
static bool intel_fpga_pcie_addr_valid(struct intel_fpga_pcie *pcie, pci_dev_t bdf) { /* If there is no link, then there is no device */ if (!IS_ROOT_PORT(pcie, bdf) && !intel_fpga_pcie_link_up(pcie)) return false; /* access only one slot on each root port */ if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) > 0) return false; if ((PCI_BUS(bdf) == pcie->first_busno + 1) && PCI_DEV(bdf) > 0) return false; return true; }
osal_result os_pci_read_config_32( os_pci_dev_t pci_dev, unsigned int offset, unsigned int* val) { unsigned long hosemonky; int fDev; char szDevAddr[64]; if(NULL == pci_dev) { return OSAL_INVALID_HANDLE; } if(NULL == val) { return OSAL_INVALID_PARAM; } if(21 != snprintf(szDevAddr, sizeof(szDevAddr), "/proc/bus/pci/%2.2x/%2.2x.%1.1x", (unsigned int)PCI_BUS(((pci_dev_t*)pci_dev)->slot_address), (unsigned int)PCI_DEV(((pci_dev_t*)pci_dev)->slot_address), (unsigned int)PCI_FUNC(((pci_dev_t*)pci_dev)->slot_address))) { return OSAL_ERROR; } if(-1 == (fDev = open(szDevAddr, O_RDONLY))) { return OSAL_NOT_FOUND; } if(-1 == lseek(fDev, offset, SEEK_SET)) { close(fDev); return OSAL_ERROR; } if(4 != read(fDev, &hosemonky, 4)) { close(fDev); return OSAL_ERROR; } close(fDev); OS_DEBUG("OSAL_PCI ReadConfig32 dev: %s, offset 0x%x, data 0x%X\n", szDevAddr, offset, hosemonky); *val= (unsigned int) hosemonky; return OSAL_SUCCESS; }
/******************************************************************** * pciWriteConfigReg - Write to a PCI configuration register * - Make sure the GT is configured as a master before writing * to another device on the PCI. * - The function takes care of Big/Little endian conversion. * * * Inputs: unsigned int regOffset: The register offset as it apears in the GT spec * (or any other PCI device spec) * pciDevNum: The device number needs to be addressed. * * Configuration Address 0xCF8: * * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number * |congif|Reserved| Bus |Device|Function|Register|00| * |Enable| |Number|Number| Number | Number | | <=field Name * *********************************************************************/ void pciWriteConfigReg (PCI_HOST host, unsigned int regOffset, unsigned int pciDevNum, unsigned int data) { volatile unsigned int DataForAddrReg; unsigned int functionNum; unsigned int busNum = PCI_BUS (pciDevNum); unsigned int addr; if (pciDevNum > 32) /* illegal device Number */ return; if (pciDevNum == SELF) { /* configure our configuration space. */ pciDevNum = (GTREGREAD (pci_p2p_configuration_reg[host]) >> 24) & 0x1f; busNum = GTREGREAD (pci_p2p_configuration_reg[host]) & 0xff0000; }
static void pciauto_prescan_setup_bridge(struct pci_controller *hose, pci_dev_t dev, int sub_bus) { struct pci_region *pci_mem = hose->pci_mem; struct pci_region *pci_io = hose->pci_io; unsigned int cmdstat; pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); /* Configure bus number registers */ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev)); pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus); pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff); if (pci_mem) { /* Round memory allocator to 1MB boundary */ pciauto_region_align(pci_mem, 0x100000); /* Set up memory and I/O filter limits, assume 32-bit I/O space */ pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE, (pci_mem->bus_lower & 0xfff00000) >> 16); cmdstat |= PCI_COMMAND_MEMORY; } if (pci_io) { /* Round I/O allocator to 4KB boundary */ pciauto_region_align(pci_io, 0x1000); pci_hose_write_config_byte(hose, dev, PCI_IO_BASE, (pci_io->bus_lower & 0x0000f000) >> 8); pci_hose_write_config_word(hose, dev, PCI_IO_BASE_UPPER16, (pci_io->bus_lower & 0xffff0000) >> 16); cmdstat |= PCI_COMMAND_IO; } /* We don't support prefetchable memory for now, so disable */ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000); /* Enable memory and I/O accesses, enable bus master */ pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER); }
/**************************************************************************** PARAMETERS: pcidev - PCI device info for the video card on the bus to boot VGAInfo - BIOS emulator VGA info structure RETURNS: True if successfully initialised, false if not. REMARKS: Loads and POST's the display controllers BIOS, directly from the BIOS image we can extract over the PCI bus. ****************************************************************************/ static int PCI_postController(pci_dev_t pcidev, BE_VGAInfo * VGAInfo) { u32 BIOSImageLen; uchar *mappedBIOS; uchar *copyOfBIOS; /*Allocate memory to store copy of BIOS from display controller*/ if ((mappedBIOS = PCI_mapBIOSImage(pcidev)) == NULL) { printf("videoboot: Video ROM failed to map!\n"); return false; } BIOSImageLen = mappedBIOS[2] * 512; if ((copyOfBIOS = malloc(BIOSImageLen)) == NULL) { printf("videoboot: Out of memory!\n"); return false; } memcpy(copyOfBIOS, mappedBIOS, BIOSImageLen); PCI_unmapBIOSImage(pcidev, mappedBIOS); /*Save information in VGAInfo structure*/ VGAInfo->function = PCI_FUNC(pcidev); VGAInfo->device = PCI_DEV(pcidev); VGAInfo->bus = PCI_BUS(pcidev); VGAInfo->pcidev = pcidev; VGAInfo->BIOSImage = copyOfBIOS; VGAInfo->BIOSImageLen = BIOSImageLen; /*Now execute the BIOS POST for the device*/ if (copyOfBIOS[0] != 0x55 || copyOfBIOS[1] != 0xAA) { printf("videoboot: Video ROM image is invalid!\n"); return false; } PCI_doBIOSPOST(pcidev, VGAInfo); /*Reset the size of the BIOS image to the final size*/ VGAInfo->BIOSImageLen = copyOfBIOS[2] * 512; return true; }
/** * Probe UNDI root bus * * @v rootdev UNDI bus root device * * Scans the UNDI bus for devices and registers all devices it can * find. */ static int undibus_probe ( struct root_device *rootdev ) { struct undi_device *undi = &preloaded_undi; int rc; /* Check for a valie preloaded UNDI device */ if ( ! undi->entry.segment ) { DBG ( "No preloaded UNDI device found!\n" ); return -ENODEV; } /* Add to device hierarchy */ undi->dev.driver_name = "undionly"; if ( undi->pci_busdevfn != UNDI_NO_PCI_BUSDEVFN ) { undi->dev.desc.bus_type = BUS_TYPE_PCI; undi->dev.desc.location = undi->pci_busdevfn; undi->dev.desc.vendor = undi->pci_vendor; undi->dev.desc.device = undi->pci_device; snprintf ( undi->dev.name, sizeof ( undi->dev.name ), "UNDI-PCI%02x:%02x.%x", PCI_BUS ( undi->pci_busdevfn ), PCI_SLOT ( undi->pci_busdevfn ), PCI_FUNC ( undi->pci_busdevfn ) ); } else if ( undi->isapnp_csn != UNDI_NO_ISAPNP_CSN ) { undi->dev.desc.bus_type = BUS_TYPE_ISAPNP; snprintf ( undi->dev.name, sizeof ( undi->dev.name ), "UNDI-ISAPNP" ); } undi->dev.parent = &rootdev->dev; list_add ( &undi->dev.siblings, &rootdev->dev.children); INIT_LIST_HEAD ( &undi->dev.children ); /* Create network device */ if ( ( rc = undinet_probe ( undi ) ) != 0 ) goto err; return 0; err: list_del ( &undi->dev.siblings ); return rc; }
osal_result os_pci_get_device_address( os_pci_dev_t pci_dev, unsigned int *bus, unsigned int *dev, unsigned int *func) { pci_dev_t *pdev = (pci_dev_t *) pci_dev; if(bus) { *bus = PCI_BUS(pdev->slot_address); } if(dev) { *dev = PCI_DEV(pdev->slot_address); } if(func) { *func = PCI_FUNC(pdev->slot_address); } return OSAL_SUCCESS; }
static int pcie_intel_fpga_read_config(struct udevice *bus, pci_dev_t bdf, uint offset, ulong *valuep, enum pci_size_t size) { struct intel_fpga_pcie *pcie = dev_get_priv(bus); dev_dbg(pcie->dev, "PCIE CFG read: (b.d.f)=(%02d.%02d.%02d)\n", PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset)) { *valuep = (u32)pci_get_ff(size); return 0; } if (!intel_fpga_pcie_addr_valid(pcie, bdf)) { *valuep = (u32)pci_get_ff(size); return 0; } return _pcie_intel_fpga_read_config(pcie, bdf, offset, valuep, size); }
static u32 pci_conf_read(pci_reg pcitag, u32 reg, size_t size) { u32 bus, dev, fun; u32 addr, type, val = 0xff; // 0xff means invalid sometimes bus = PCI_BUS(pcitag); dev = PCI_SLOT(pcitag); fun = PCI_FUNC(pcitag); /*range check is valueless*/ #ifdef CONFIG_CS5536 extern u32 cs5536_pci_conf_read(pci_reg, u32, size_t); if(dev == CS5536_IDSEL){ if(size != 4){ printf("must be 4 bytes to read!\n"); return 0xffffffff; } return cs5536_pci_conf_read(pcitag, reg, size); } #endif if(bus == 0) { addr = ((1 << (dev + 11)) | (fun << 8) | reg); type = 0; } else { addr = ((bus << 16) | (dev << 11) | (fun << 8) | reg); type = 0x10000; } printf("addr is %x\n", addr); *(volatile u32 *)(PHY_TO_UNCACHED(NB_PCICMD)) |= 0x28000000; *(volatile u32 *)(PHY_TO_UNCACHED(PCIMAP_CFG)) = (addr >> 16) | type; val = *(volatile u32 *)(PHY_TO_UNCACHED(PCICFG_SPACE) | (addr & 0xfffc)); if(size == 4) { return val; } else if (size == 1){ val = (val >> ((reg & 3) * 8)) & 0xff; } else if (size == 2){ //caller will ensure reg align is ok
int fdtdec_get_pci_bar32(const void *blob, int node, struct fdt_pci_addr *addr, u32 *bar) { pci_dev_t bdf; int barnum; int ret; /* get pci devices's bdf */ ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf); if (ret) return ret; /* extract the bar number from fdt_pci_addr */ barnum = addr->phys_hi & 0xff; if ((barnum < PCI_BASE_ADDRESS_0) || (barnum > PCI_CARDBUS_CIS)) return -EINVAL; barnum = (barnum - PCI_BASE_ADDRESS_0) / 4; *bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum); return 0; }
static int _pcie_intel_fpga_write_config(struct intel_fpga_pcie *pcie, pci_dev_t bdf, uint offset, ulong value, enum pci_size_t size) { u32 data; u8 byte_en; dev_dbg(pcie->dev, "PCIE CFG write: (b.d.f)=(%02d.%02d.%02d)\n", PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n", offset, size, value); /* Uses memory mapped method to read rootport config registers */ if (IS_ROOT_PORT(pcie, bdf)) return intel_fpga_pcie_rp_wr_conf(pcie->bus, bdf, offset, value, size); byte_en = pcie_get_byte_en(offset, size); data = pci_conv_size_to_32(0, value, offset, size); return tlp_cfg_dword_write(pcie, bdf, offset & ~DWORD_MASK, byte_en, data); }
/**************************************************************************** PARAMETERS: pcidev - PCI device info for the video card on the bus to boot VGAInfo - BIOS emulator VGA info structure REMARKS: This function executes the BIOS POST code on the controller. We assume that at this stage the controller has its I/O and memory space enabled and that all other controllers are in a disabled state. ****************************************************************************/ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo) { RMREGS regs; RMSREGS sregs; /* Determine the value to store in AX for BIOS POST. Per the PCI specs, AH must contain the bus and AL must contain the devfn, encoded as (dev << 3) | fn */ memset(®s, 0, sizeof(regs)); memset(&sregs, 0, sizeof(sregs)); regs.x.ax = ((int)PCI_BUS(pcidev) << 8) | ((int)PCI_DEV(pcidev) << 3) | (int)PCI_FUNC(pcidev); /*Setup the X86 emulator for the VGA BIOS*/ BE_setVGA(VGAInfo); /*Execute the BIOS POST code*/ BE_callRealMode(0xC000, 0x0003, ®s, &sregs); /*Cleanup and exit*/ BE_getVGA(VGAInfo); }
osal_result os_pci_write_config_32( os_pci_dev_t pci_dev, unsigned int offset, unsigned int val) { int fDev; char szDevAddr[64]; if(NULL == pci_dev) { return OSAL_INVALID_HANDLE; } if(21 != snprintf(szDevAddr, sizeof(szDevAddr), "/proc/bus/pci/%2.2x/%2.2x.%1.1x", (unsigned int)PCI_BUS(((pci_dev_t*)pci_dev)->slot_address), (unsigned int)PCI_DEV(((pci_dev_t*)pci_dev)->slot_address), (unsigned int)PCI_FUNC(((pci_dev_t*)pci_dev)->slot_address))) { return OSAL_ERROR; } if(-1 == (fDev = open(szDevAddr, O_WRONLY))) { return OSAL_NOT_FOUND; } if(-1 == lseek(fDev, offset, SEEK_SET)) { close(fDev); return OSAL_ERROR; } if(4 != write(fDev, &val, 4)) { close(fDev); return OSAL_ERROR; } close(fDev); return OSAL_SUCCESS; }
int pci_conf_write_intercept(unsigned int seg, unsigned int bdf, unsigned int reg, unsigned int size, uint32_t *data) { struct pci_dev *pdev; int rc = 0; /* * Avoid expensive operations when no hook is going to do anything * for the access anyway. */ if ( reg < 64 || reg >= 256 ) return 0; spin_lock(&pcidevs_lock); pdev = pci_get_pdev(seg, PCI_BUS(bdf), PCI_DEVFN2(bdf)); if ( pdev ) rc = pci_msi_conf_write_intercept(pdev, reg, size, data); spin_unlock(&pcidevs_lock); return rc; }
osal_result os_pci_device_from_slot(os_pci_dev_t *pci_dev, unsigned int slot) { pci_dev_t *device; FILE* fDev; char szDevAddr[64]; *pci_dev = NULL; if(21 != snprintf(szDevAddr, sizeof(szDevAddr), "/proc/bus/pci/%2.2x/%2.2x.%1.1x", (unsigned int)PCI_BUS(slot), (unsigned int)PCI_DEV(slot), (unsigned int)PCI_FUNC(slot))) { return OSAL_ERROR; } if(NULL == (fDev = fopen(szDevAddr, "r"))) { return OSAL_NOT_FOUND; } device = (pci_dev_t*) OS_ALLOC(sizeof(pci_dev_t)); if(device == NULL) { fclose(fDev); return OSAL_INSUFFICIENT_MEMORY; } device->slot_address = slot; *pci_dev = ((os_pci_dev_t*) device); fclose(fDev); OS_DEBUG("OSAL_PCI Found Dev: %s\n", szDevAddr); return OSAL_SUCCESS; }
static void pciauto_prescan_setup_bridge(struct pci_controller *hose, pci_dev_t dev, int sub_bus) { struct pci_region *pci_mem = hose->pci_mem; struct pci_region *pci_prefetch = hose->pci_prefetch; struct pci_region *pci_io = hose->pci_io; unsigned int cmdstat; pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); /* Configure bus number registers */ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev)); pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus); pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff); if (pci_mem) { /* Round memory allocator to 1MB boundary */ pciauto_region_align(pci_mem, 0x100000); /* Set up memory and I/O filter limits, assume 32-bit I/O space */ pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE, (pci_mem->bus_lower & 0xfff00000) >> 16); cmdstat |= PCI_COMMAND_MEMORY; } if (pci_prefetch) { /* Round memory allocator to 1MB boundary */ pciauto_region_align(pci_prefetch, 0x100000); /* Set up memory and I/O filter limits, assume 32-bit I/O space */ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, (pci_prefetch->bus_lower & 0xfff00000) >> 16); cmdstat |= PCI_COMMAND_MEMORY; } else {
/* HJF: Changed this to return int. I think this is required * to get the correct result when scanning bridges */ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) { unsigned int sub_bus = PCI_BUS(dev); unsigned short class; unsigned char prg_iface; int n; pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); switch(class) { case PCI_CLASS_BRIDGE_PCI: hose->current_busno++; pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io); DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev)); /* Passing in current_busno allows for sibling P2P bridges */ pciauto_prescan_setup_bridge(hose, dev, hose->current_busno); /* * need to figure out if this is a subordinate bridge on the bus * to be able to properly set the pri/sec/sub bridge registers. */ n = pci_hose_scan_bus(hose, hose->current_busno); /* figure out the deepest we've gone for this leg */ sub_bus = max(n, sub_bus); pciauto_postscan_setup_bridge(hose, dev, sub_bus); sub_bus = hose->current_busno; break; case PCI_CLASS_STORAGE_IDE: pci_hose_read_config_byte(hose, dev, PCI_CLASS_PROG, &prg_iface); if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { DEBUGF("PCI Autoconfig: Skipping legacy mode IDE controller\n"); return sub_bus; } pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io); break; case PCI_CLASS_BRIDGE_CARDBUS: /* just do a minimal setup of the bridge, let the OS take care of the rest */ pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io); DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev)); hose->current_busno++; break; #ifdef CONFIG_MPC5200 case PCI_CLASS_BRIDGE_OTHER: DEBUGF("PCI Autoconfig: Skipping bridge device %d\n", PCI_DEV(dev)); break; #endif default: pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io); break; } return sub_bus; }
void bebox_state::bebox_peripherals(machine_config &config) { config.m_minimum_quantum = attotime::from_hz(60); PIT8254(config, m_pit8254, 0); m_pit8254->set_clk<0>(4772720/4); /* heartbeat IRQ */ m_pit8254->set_clk<1>(4772720/4); /* dram refresh */ m_pit8254->set_clk<2>(4772720/4); /* pio port c pin 4, and speaker polling */ m_pit8254->out_handler<0>().set(FUNC(bebox_state::bebox_timer0_w)); m_pit8254->out_handler<2>().set("kbdc", FUNC(kbdc8042_device::write_out2)); AM9517A(config, m_dma8237[0], XTAL(14'318'181)/3); m_dma8237[0]->out_hreq_callback().set(FUNC(bebox_state::bebox_dma_hrq_changed)); m_dma8237[0]->out_eop_callback().set(FUNC(bebox_state::bebox_dma8237_out_eop)); m_dma8237[0]->in_memr_callback().set(FUNC(bebox_state::bebox_dma_read_byte)); m_dma8237[0]->out_memw_callback().set(FUNC(bebox_state::bebox_dma_write_byte)); m_dma8237[0]->in_ior_callback<2>().set(FUNC(bebox_state::bebox_dma8237_fdc_dack_r)); m_dma8237[0]->out_iow_callback<2>().set(FUNC(bebox_state::bebox_dma8237_fdc_dack_w)); m_dma8237[0]->out_dack_callback<0>().set(FUNC(bebox_state::pc_dack0_w)); m_dma8237[0]->out_dack_callback<1>().set(FUNC(bebox_state::pc_dack1_w)); m_dma8237[0]->out_dack_callback<2>().set(FUNC(bebox_state::pc_dack2_w)); m_dma8237[0]->out_dack_callback<3>().set(FUNC(bebox_state::pc_dack3_w)); AM9517A(config, m_dma8237[1], XTAL(14'318'181)/3); PIC8259(config, m_pic8259[0], 0); m_pic8259[0]->out_int_callback().set(FUNC(bebox_state::bebox_pic8259_master_set_int_line)); m_pic8259[0]->in_sp_callback().set_constant(1); m_pic8259[0]->read_slave_ack_callback().set(FUNC(bebox_state::get_slave_ack)); PIC8259(config, m_pic8259[1], 0); m_pic8259[1]->out_int_callback().set(FUNC(bebox_state::bebox_pic8259_slave_set_int_line)); m_pic8259[1]->in_sp_callback().set_constant(0); NS16550(config, "ns16550_0", 0); /* TODO: Verify model */ NS16550(config, "ns16550_1", 0); /* TODO: Verify model */ NS16550(config, "ns16550_2", 0); /* TODO: Verify model */ NS16550(config, "ns16550_3", 0); /* TODO: Verify model */ /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(XTAL(25'174'800), 900, 0, 640, 526, 0, 480); screen.set_screen_update("vga", FUNC(cirrus_gd5428_device::screen_update)); cirrus_gd5428_device &vga(CIRRUS_GD5428(config, "vga", 0)); vga.set_screen("screen"); speaker_device &speaker(SPEAKER(config, "mono")); speaker.front_center(); ym3812_device &ym3812(YM3812(config, "ym3812", 3579545)); ym3812.add_route(ALL_OUTPUTS, speaker, 1.0); FUJITSU_29F016A(config, "flash"); scsi_port_device &scsibus(SCSI_PORT(config, "scsi")); scsibus.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_0)); scsibus.set_slot_device(2, "cdrom", SCSICD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_3)); lsi53c810_device &scsictrl(LSI53C810(config, "lsi53c810")); scsictrl.set_irq_callback(FUNC(bebox_state::scsi_irq_callback)); scsictrl.set_dma_callback(FUNC(bebox_state::scsi_dma_callback)); scsictrl.set_fetch_callback(FUNC(bebox_state::scsi_fetch)); scsictrl.set_scsi_port("scsi"); ide_controller_device &idectrl(IDE_CONTROLLER(config, "ide")); idectrl.set_default_ata_devices("hdd", nullptr); idectrl.irq_handler().set(FUNC(bebox_state::bebox_ide_interrupt)); /* pci */ PCI_BUS(config, m_pcibus, 0); m_pcibus->set_busnum(0); pci_connector_device &pcislot0 = add_pci_slot(config, "pcibus:0", 0, "mpc105"); pcislot0.set_option_machine_config("mpc105", mpc105_config); add_pci_slot(config, "pcibus:1", 1, "cirrus"); /*MCFG_PCI_BUS_DEVICE(12, nullptr, scsi53c810_pci_read, scsi53c810_pci_write)*/ SMC37C78(config, m_smc37c78, 24'000'000); m_smc37c78->intrq_wr_callback().set(FUNC(bebox_state::fdc_interrupt)); m_smc37c78->drq_wr_callback().set(m_dma8237[0], FUNC(am9517a_device::dreq2_w)); floppy_connector &fdc(FLOPPY_CONNECTOR(config, "smc37c78:0")); fdc.option_add("35hd", FLOPPY_35_HD); fdc.set_default_option("35hd"); fdc.set_formats(bebox_state::floppy_formats); MC146818(config, "rtc", 32.768_kHz_XTAL); kbdc8042_device &kbdc(KBDC8042(config, "kbdc")); kbdc.set_keyboard_type(kbdc8042_device::KBDC8042_STANDARD); kbdc.system_reset_callback().set_inputline(m_ppc[0], INPUT_LINE_RESET); kbdc.input_buffer_full_callback().set(FUNC(bebox_state::bebox_keyboard_interrupt)); /* internal ram */ RAM(config, m_ram); m_ram->set_default_size("32M"); m_ram->set_extra_options("8M,16M"); }