Exemple #1
0
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;
}
Exemple #2
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;
}
Exemple #3
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 ) );
}
Exemple #4
0
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;
}
Exemple #5
0
/**
 * 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, &reg16);
	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;
}
Exemple #6
0
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.  */
}
Exemple #7
0
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;

}
Exemple #8
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);
}
Exemple #9
0
/**
 * 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);
	}
}
Exemple #11
0
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);
}
Exemple #12
0
/**
 * 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);
}
Exemple #13
0
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;
}
Exemple #15
0
/********************************************************************
* 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;
	}
Exemple #16
0
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;
}
Exemple #18
0
/**
 * 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;
}
Exemple #20
0
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);
}
Exemple #21
0
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
Exemple #22
0
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;
}
Exemple #23
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(&regs, 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, &regs, &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;
}
Exemple #26
0
Fichier : pci.c Projet : Fantu/Xen
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;
}
Exemple #28
0
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 {
Exemple #29
0
/* 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;
}
Exemple #30
0
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");
}