コード例 #1
0
/**
 * Read a VGA ROM
 *
 */
static int
pci_device_openbsd_read_rom(struct pci_device *device, void *buffer)
{
	struct pci_device_private *priv = (struct pci_device_private *)device;
	unsigned char *bios;
	pciaddr_t rom_base;
	pciaddr_t rom_size;
	u_int32_t csr, rom;
	int pci_rom, domain, bus, dev, func;

	domain = device->domain;
	if (domain < 0 || domain >= ndomains)
		return ENXIO;

	bus = device->bus;
	dev = device->dev;
	func = device->func;

	if (aperturefd == -1)
		return ENOSYS;

	if (priv->base.rom_size == 0) {
#if defined(__alpha__) || defined(__amd64__) || defined(__i386__)
		if ((device->device_class & 0x00ffff00) ==
		    ((PCI_CLASS_DISPLAY << 16) |
			(PCI_SUBCLASS_DISPLAY_VGA << 8))) {
			rom_base = 0xc0000;
			rom_size = 0x10000;
			pci_rom = 0;
		} else
#endif
			return ENOSYS;
	} else {
		rom_base = priv->rom_base;
		rom_size = priv->base.rom_size;
		pci_rom = 1;

		pci_read(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, &csr);
		pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG,
		    csr | PCI_COMMAND_MEM_ENABLE);
		pci_read(domain, bus, dev, func, PCI_ROM_REG, &rom);
		pci_write(domain, bus, dev, func, PCI_ROM_REG,
		    rom | PCI_ROM_ENABLE);
	}

	bios = mmap(NULL, rom_size, PROT_READ, MAP_SHARED,
	    aperturefd, (off_t)rom_base);
	if (bios == MAP_FAILED)
		return errno;

	memcpy(buffer, bios, rom_size);
	munmap(bios, rom_size);

	if (pci_rom) {
		/* Restore PCI config space */
		pci_write(domain, bus, dev, func, PCI_ROM_REG, rom);
		pci_write(domain, bus, dev, func, PCI_COMMAND_STATUS_REG, csr);
	}
	return 0;
}
コード例 #2
0
ファイル: pci.c プロジェクト: danilaslau/frotznet
int pci_probe(int bus, int dev, int func, pci_cfg *cfg)
{
	uint32 *word = (uint32 *) cfg;
	uint32 v;	
	int i;
	for(i=0;i<4;i++){
		word[i] = pci_read(bus,dev,func,4*i,4);
	}
	if(cfg->vendor_id == 0xffff) return 1;

	cfg->bus = bus;
	cfg->dev = dev;
	cfg->func = func;
#if 0	
	printf("Device Info: /bus/pci/%d/%d/%d\n",bus,dev,func);
	printf("  * Vendor: %S   Device: %S  Class/SubClass/Interface %X/%X/%X\n",
		   cfg->vendor_id,cfg->device_id,cfg->base_class,cfg->sub_class,cfg->interface);
	printf("  * Status: %S  Command: %S  BIST/Type/Lat/CLS: %X/%X/%X/%X\n",
		   cfg->status, cfg->command, cfg->bist, cfg->header_type, 
		   cfg->latency_timer, cfg->cache_line_size);
#endif
			
	switch(cfg->header_type & 0x7F){
	case 0: /* normal device */
		for(i=0;i<6;i++){
			v = pci_read(bus,dev,func,i*4 + 0x10, 4);
			if(v) {
				int v2;
				pci_write(bus,dev,func,i*4 + 0x10, 0xffffffff, 4);
				v2 = pci_read(bus,dev,func,i*4+0x10, 4) & 0xfffffff0;
				pci_write(bus,dev,func,i*4 + 0x10, v, 4);
				v2 = 1 + ~v2;
				if(v & 1) {
//					printf("  * Base Register %d IO: %x (%x)\n",i,v&0xfff0,v2&0xffff);
					cfg->base[i] = v & 0xffff;
					cfg->size[i] = v2 & 0xffff;
				} else {
//					printf("  * Base Register %d MM: %x (%x)\n",i,v&0xfffffff0,v2);
					cfg->base[i] = v;
					cfg->size[i] = v2;
				}
			} else {
				cfg->base[i] = 0;
				cfg->size[i] = 0;
			}
			
		}
		v = pci_read(bus,dev,func,0x3c,1);
		cfg->irq = (v == 0xff ? 0 : v);
			
//		printf("  * Interrupt Line: %X\n",cfg->irq);
		break;
	case 1:
//		printf("  * PCI <-> PCI Bridge\n");
		break;
	default:
//		printf("  * Unknown Header Type\n");
	}
	return 0;	
}
コード例 #3
0
ファイル: msix.c プロジェクト: naredula-jana/Jiny-Kernel
int pci_read_msi(pci_addr_t *addr, pci_dev_header_t *pci_hdr,pci_bar_t *bars, uint32_t bars_total,  struct pcicfg_msix *msix) {
	uint32_t ret;
	uint16_t buf;
	uint32_t val;
	uint32_t bar_offset;

	uint8_t pos=pci_hdr->capabilities_pointer;

	ret = pci_read(addr, pos, 2, &buf);
	ret = pci_read(addr, pos + PCIR_MSIX_CTRL, 2, &msix->msix_ctrl);

	msix->msix_msgnum = (msix->msix_ctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1;
	if (msix->msix_msgnum > 0) {
		msix->isr_vector = msi_start_vector;
		msi_start_vector = msi_start_vector + msix->msix_msgnum;
		ut_log(" msi vector start :%d num:%d \n",msix->isr_vector,msix->msix_msgnum);
	} else {
		msix->isr_vector = 0;
	}
	ret = pci_read(addr, pos + PCIR_MSIX_TABLE, 4, &bar_offset);
	msix->msix_table_bar = PCIR_BAR(bar_offset & PCIM_MSIX_BIR_MASK);
	if (bar_offset >= bars_total) return 0;
	msix->msix_table_res = bars[bar_offset].addr;

	msix->msix_table  = vm_create_kmap("msix",0x1000,PROT_WRITE,MAP_FIXED,msix->msix_table_res);
	ut_log(" msix table :%x  bar addr:%x  baroffset:%d msix tableres:%x\n",msix->msix_table,bars[bar_offset].addr,bar_offset,msix->msix_table_res);

	ret = pci_read(addr, pos + PCIR_MSIX_PBA, 4, &val);
	msix->msix_pba_bar = PCIR_BAR(val & PCIM_MSIX_BIR_MASK);
	return msix->isr_vector;
}
コード例 #4
0
/*
 ****************************************************************
 *	Inicialização						*
 ****************************************************************
 */
int
ata_sis_chipinit (PCIDATA *pci)
{
 	ATA_PCI_CTLR		*ctlrp = pci->pci_dev_info_ptr;
	const ATA_CHIP_ID	*idp = ctlrp->ac_idp;

	switch (idp->ch_cfg1)
	{
	    case SIS33:
		break;

	    case SIS66:
	    case SIS100OLD:
		pci_write (pci, 0x52, pci_read (pci, 0x52, 1) & ~0x04, 1);
		break;

	    case SIS100NEW:
	    case SIS133OLD:
		pci_write (pci, 0x49, pci_read (pci, 0x49, 1) & ~0x01, 1);
		break;

	    case SIS133NEW:
		pci_write (pci, 0x50, pci_read (pci, 0x50, 2) | 0x0008, 2);
		pci_write (pci, 0x52, pci_read (pci, 0x52, 2) | 0x0008, 2);
		break;

	    case SISSATA:
#if (0)	/*******************************************************/
		ctlr->r_type2 = SYS_RES_IOPORT;
		ctlr->r_rid2 = PCIR_BAR(5);
		if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, &ctlr->r_rid2, RF_ACTIVE)))
		{
			ctlrp->ac_allocate = ata_sis_allocate;
			ctlrp->ac_reset = ata_sis_reset;

			/* enable PCI interrupt */
			pci_write (pci, PCIR_COMMAND, pci_read (pci, PCIR_COMMAND, 2) & ~0x0400,2);
		}

		ctlrp->ac_setmode = ata_sata_setmode;

		return (0);
#endif	/*******************************************************/

	    default:
		return (-1);
	}

#ifndef	BOOT
	ctlrp->ac_setmode = ata_sis_pata_setmode;
#endif

	return (0);

}	/* end ata_sis_chipinit */
コード例 #5
0
ファイル: pci.c プロジェクト: wayling/Jiny-Kernel
int pci_generic_read(pci_addr_t *d, uint16_t pos, uint16_t len, void *buf)
{ 
	int c;
	int step;

	while(len > 0) {
		if((pos & 1) && len >= 1) {
			step = 1;
		} else if((pos & 3) && len >= 2) {
			step = 2;
		} else if(len < 2) {
			step = 1;
		} else if(len < 4) {
			step = 2;
		} else {
			step = 4;
		}

		c = pci_read(d, pos, step, buf);

		if( c != 0) {
			return c;
		}
		buf += step;
		pos += step;
		len -= step;
	}

	return 0;
}
コード例 #6
0
ファイル: pci.c プロジェクト: phase/cakeos
static PCI_Device_t* pci_readdevice(int bus, int dev, int func)
{ 
  int place, total = sizeof(PCI_Device_t) / sizeof(unsigned long);

  for (place = 0; place < total; place++)
    ((u32int*)ret)[place] =  pci_read(bus, dev, func, (place * sizeof (unsigned long)));
  
  return ret;
}
コード例 #7
0
static int
pci_nfuncs(int domain, int bus, int dev)
{
	uint32_t hdr;

	if (domain < 0 || domain >= ndomains)
		return ENXIO;

	if (pci_read(domain, bus, dev, 0, PCI_BHLC_REG, &hdr) != 0)
		return -1;

	return (PCI_HDRTYPE_MULTIFN(hdr) ? 8 : 1);
}
コード例 #8
0
static int pci_rcba_mask_get(union pci_addr_reg pci_ctrl_addr,
			     u32_t *mask)
{
	u32_t old_value;

	/* save the current setting */
	pci_read(DEFAULT_PCI_CONTROLLER,
			pci_ctrl_addr,
			sizeof(old_value),
			&old_value);

	/* write to the RCBA to see how large it is */
	pci_write(DEFAULT_PCI_CONTROLLER,
			pci_ctrl_addr,
			sizeof(u32_t),
			0xffffffff);

	pci_read(DEFAULT_PCI_CONTROLLER,
			pci_ctrl_addr,
			sizeof(*mask),
			mask);

	/* put back the old configuration */
	pci_write(DEFAULT_PCI_CONTROLLER,
			pci_ctrl_addr,
			sizeof(old_value),
			old_value);

	/* check if this RCBA is implemented */
	if (*mask != 0xffffffff && *mask != 0) {
		/* clear the least address unrelated bit */
		*mask &= ~0x01;
		return 0;
	}

	/* RCBA not supported */

	return -1;
}
コード例 #9
0
ファイル: pci.c プロジェクト: wayling/Jiny-Kernel
static int get_bar(pci_addr_t *addr, int barno, uint32_t *start, uint32_t *len)
{
	int res;
	uint16_t offset;
	uint32_t mask = ~0U;

	// We write all ones to the register and read it.

	offset = PCI_BAR_0 + 4 * barno;

	res = pci_read(addr, offset, 4, start);

	if(res != 0) {
		return -1;
	}

	res = pci_write(addr, offset, 4, &mask);

	if(res != 0) {
		return -1;
	}

	res = pci_read(addr, offset, 4, len);

	if(res != 0) {
		return -1;
	}

	res = pci_write(addr, offset, 4, start);

	if(res != 0) {
		return -1;
	}
	if (*start == 0 ) return 0;
	DEBUG("   barno:%d start :%i len:%i \n",barno,*start,*len);
	return 0;
}
コード例 #10
0
ファイル: pci.c プロジェクト: JoshuaKissoon/NoNameOS
struct PCI_DEVICEINFO * pci_probeDevice( int bus, int dev, int func )
{
    struct PCI_DEVICEINFO * info;
    DWORD data;
    int index;
    // read in the vendor id
    data = pci_read( bus, dev, func, PCI_VENDORID, SIZE_WORD );
    // if we dont have one we return fail
    if( data == 0xFFFF || data == VENDOR_UNKNOWN )
    	return NULL;
    // if we have a vendor then we have a device. create a device info structure and fill it in
    info = (struct PCI_DEVICEINFO *)mm_kmalloc( sizeof(struct PCI_DEVICEINFO) );
    // fill in the vendor id    
    info->vendor_id = data;
    // fill in the device id   
    info->device_id = pci_read( bus, dev, func, PCI_DEVICEID, SIZE_WORD );
	// linear search for the vendor and device name based on the id's we just read in
	for( index=0 ; pci_devices[index].vendor_id != VENDOR_UNKNOWN ; index++ )
	{
		// if we have a match we break out of the loop
		if( pci_devices[index].vendor_id == info->vendor_id && pci_devices[index].device_id == info->device_id )
			break;
	}
	// fill in the vendor/device name into our device info structure
    info->vendor_name = pci_devices[index].vendor_name;
    info->device_name = pci_devices[index].device_name;
    // fill in the header type
    info->header_type = pci_read( bus, dev, func, PCI_HEADERTYPE, SIZE_BYTE );
    // fill in the sub sys info
    info->subsys_vendor = pci_read( bus, dev, func, PCI_SUBSYSVENDOR, SIZE_WORD );
    info->subsys = pci_read( bus, dev, func, PCI_SUBSYS, SIZE_WORD );
	// fill in the device class
	info->sub_class = pci_read( bus, dev, func, PCI_SUBCLASS, SIZE_BYTE );
	info->base_class = pci_read( bus, dev, func, PCI_BASECLASS, SIZE_BYTE );
	// linear search for the base class name
	for( index=0 ; pci_baseclassnames[index].base_class != 0xFF ; index++ )
	{
		if( pci_baseclassnames[index].base_class == info->base_class )
			break;
	}
	info->class_name = pci_baseclassnames[index].name;
	// fill in an irq value if their is one
	data = pci_read( bus, dev, func, PCI_IRQ, SIZE_BYTE );
	info->irq = ( data == 0xFF ? 0 : data );
	// return our new info structure
    return info;
}
コード例 #11
0
ファイル: pci.c プロジェクト: SimonGustavsson/nox
uint8_t pci_read_byte(struct pci_address* addr, uint8_t reg_offset)
{
    return (uint8_t)pci_read(addr->bus, addr->device, addr->func, reg_offset, sizeof(uint8_t)); 
}
コード例 #12
0
/*
 ****************************************************************
 *	Reconhecimento						*
 ****************************************************************
 */
const ATA_CHIP_ID *
ata_sis_ident (PCIDATA *pci, ulong chipset_id)
{
	ATA_CHIP_ID		*idp;
	int			found = 0;
	uchar			rev  = pci->pci_revid;
	ATA_PCI_CTLR		*ctlrp = pci->pci_dev_info_ptr;

	ctlrp->ac_chip_nm  = "SiS";
	ctlrp->ac_chipinit = ata_sis_chipinit;

#if (0)	/*******************************************************/
	PCIDATA			*parent = pci->pci_parent;
	chipset_id = (parent->pci_device << 16) | parent->pci_vendor;
#endif	/*******************************************************/

	for (idp = sis_ids; /* abaixo */; idp++)
	{
		if (idp->ch_id == 0)
			return (ctlrp->ac_idp = NULL);

		if (chipset_id == idp->ch_id && rev >= idp->ch_rev)
			break;
	}

	if (idp->ch_cfg2 /*** && !found ***/)
	{
		uchar		reg57 = pci_read (pci, 0x57, 1);

		pci_write (pci, 0x57, (reg57 & 0x7F), 1);

		if (pci_read (pci, PCIR_DEVVENDOR, 4) == ATA_SIS5518)
			{ found = 1; idp = &sis_quirk1; }

		pci_write (pci, 0x57, reg57, 1);
	}

	if (idp->ch_cfg2 && !found)
	{
		uchar	reg4a = pci_read (pci, 0x4A, 1);

		pci_write (pci, 0x4A, (reg4a | 0x10), 1);

		if (pci_read (pci, PCIR_DEVVENDOR, 4) == ATA_SIS5517)
		{
			memmove (&sis_quirk2, idp, sizeof (ATA_CHIP_ID));

			found = 1;

			idp = &sis_quirk2;	idp->ch_nm = "961";

			if (chipset_id == ATA_SISSOUTH)
			{
				idp->ch_cfg1	= SIS133OLD;
				idp->ch_max_dma = ATA_UDMA6;
			}
			else
			{
				idp->ch_cfg1	= SIS100NEW;
				idp->ch_max_dma = ATA_UDMA5;
			}
		}

		pci_write (pci, 0x4A, reg4a, 1);
	}

	return (ctlrp->ac_idp = idp);

}	/* end ata_sis_ident */
コード例 #13
0
/*
 ****************************************************************
 *	Inicializa o DMA para os Controladores PATA		*
 ****************************************************************
 */
void
ata_sis_pata_setmode (PCIDATA *pci, ATA_DEVICE *adp, int mode)
{
 	ATA_PCI_CTLR		*ctlrp = pci->pci_dev_info_ptr;
	const ATA_CHIP_ID	*idp = ctlrp->ac_idp;
	int			devno;

	devno = (adp->ad_channel->ch_unit << 1) + adp->ad_devno;

	mode  = ata_limit_mode (adp, mode, idp->ch_max_dma);

	if (idp->ch_cfg1 == SIS133NEW)
	{
		if (mode > ATA_UDMA2 && pci_read (pci, adp->ad_channel->ch_unit ? 0x52 : 0x50, 2) & 0x8000)
		{
			mode = ATA_UDMA2;
			printf ("ata[%d,%d]: DMA limitado a %s\n", ATA_DEVNO, ata_dmamode_to_str (mode));
		}
	}
	else
	{
		if (mode > ATA_UDMA2 &&	pci_read (pci, 0x48, 1) & (adp->ad_channel->ch_unit ? 0x20 : 0x10))
		{
			mode = ATA_UDMA2;
			printf ("ata[%d,%d]: DMA limitado a %s\n", ATA_DEVNO, ata_dmamode_to_str (mode));
		}
	}

	if (ata_command (adp, ATA_C_SETFEATURES, 0, mode, ATA_C_F_SETXFER, 0))
		return;

	switch (idp->ch_cfg1)
	{
	    case SIS133NEW:
	    {
		ulong timings[] = 
		{
			0x28269008, 0x0c266008, 0x04263008, 0x0c0a3008, 0x05093008,
			0x22196008, 0x0c0a3008, 0x05093008, 0x050939fc, 0x050936ac,
			0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c
		};
		ulong reg;

		reg = (pci_read (pci, 0x57, 1) & 0x40?0x70 : 0x40) + (devno << 2);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 4);
		break;
	    }

	    case SIS133OLD:
	    {
		ushort timings[] =
		{
			0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033, 0x0031,
		 	0x8f31, 0x8a31, 0x8731, 0x8531, 0x8331, 0x8231, 0x8131
		};
		ushort reg = 0x40 + (devno << 1);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 2);
		break;
	    }

	    case SIS100NEW:
	    {
		ushort timings[] =
		{
			0x00cb, 0x0067, 0x0044, 0x0033, 0x0031, 0x0044, 0x0033,
			0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131
		};
		ushort reg = 0x40 + (devno << 1);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 2);
		break;
	    }

	    case SIS100OLD:
	    case SIS66:
	    case SIS33:
	    {
		ushort timings[] =
		{
			0x0c0b, 0x0607, 0x0404, 0x0303, 0x0301, 0x0404, 0x0303,
			0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301
		};
		ushort reg = 0x40 + (devno << 1);

		pci_write (pci, reg, timings[ata_mode2idx (mode)], 2);
		break;
	    }
	}

	adp->ad_transfer_mode = mode;

}	/* end ata_sis_pata_setmode */
コード例 #14
0
int pci_legacy_bridge_detect(struct pci_dev_info *dev_info)
{
	union pci_addr_reg pci_ctrl_addr;
	static union pci_dev pci_dev_header;
	u32_t pci_data; /* temporary data to read */
	u32_t rcba; /* root complex base address */
	u32_t rcba_mask; /* bits set for RCBA */

	/* initialise the PCI controller address register value */
	pci_ctrl_addr.value = 0;

	pci_ctrl_addr.field.bus = CONFIG_PCI_LEGACY_BRIDGE_BUS;
	pci_ctrl_addr.field.device = CONFIG_PCI_LEGACY_BRIDGE_DEV;

	/* verify first if there is a valid device at this point */
	pci_ctrl_addr.field.func = 0;

	pci_read(DEFAULT_PCI_CONTROLLER,
			pci_ctrl_addr,
			sizeof(pci_data),
			&pci_data);

	if (pci_data == 0xffffffff) {
		return -1;
	}

	/* get the PCI header from the device */
	pci_header_get(DEFAULT_PCI_CONTROLLER,
		       pci_ctrl_addr,
		       &pci_dev_header);

	if (pci_dev_header.field.vendor_id != CONFIG_PCI_LEGACY_BRIDGE_VENDOR_ID ||
	    pci_dev_header.field.device_id != CONFIG_PCI_LEGACY_BRIDGE_DEVICE_ID) {
		return -1;
	}

	pci_ctrl_addr.field.reg = PCI_LEGACY_BRIDGE_REG;

	/* read RCBA PCI register */
	pci_read(DEFAULT_PCI_CONTROLLER,
			pci_ctrl_addr,
			sizeof(rcba),
			&rcba);

	if (pci_rcba_mask_get(pci_ctrl_addr, &rcba_mask) != 0) {
		return -1;
	}

	dev_info->addr = rcba & rcba_mask;
	if (dev_info->addr != 0) {
		/* calculate the size of the root complex memory required */
		dev_info->size = 1 << (find_lsb_set(rcba_mask) - 1);
	}

	dev_info->irq = -1;
	dev_info->bus = CONFIG_PCI_LEGACY_BRIDGE_BUS;
	dev_info->dev = CONFIG_PCI_LEGACY_BRIDGE_DEV;
	dev_info->function = 0;
	dev_info->mem_type = BAR_SPACE_MEM;
	dev_info->class_type = pci_dev_header.field.class;
	dev_info->bar = 0;
	dev_info->vendor_id = pci_dev_header.field.vendor_id;
	dev_info->device_id = pci_dev_header.field.device_id;

	return 0;
}
コード例 #15
0
static int
pci_device_openbsd_probe(struct pci_device *device)
{
	struct pci_device_private *priv = (struct pci_device_private *)device;
	struct pci_mem_region *region;
	uint64_t reg64, size64;
	uint32_t bar, reg, size;
	int domain, bus, dev, func, err;

	domain = device->domain;
	bus = device->bus;
	dev = device->dev;
	func = device->func;

	err = pci_read(domain, bus, dev, func, PCI_BHLC_REG, &reg);
	if (err)
		return err;

	priv->header_type = PCI_HDRTYPE_TYPE(reg);
	if (priv->header_type != 0)
		return 0;

	region = device->regions;
	for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
	     bar += sizeof(uint32_t), region++) {
		err = pci_read(domain, bus, dev, func, bar, &reg);
		if (err)
			return err;

		/* Probe the size of the region. */
		err = pci_readmask(domain, bus, dev, func, bar, &size);
		if (err)
			return err;

		if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) {
			region->is_IO = 1;
			region->base_addr = PCI_MAPREG_IO_ADDR(reg);
			region->size = PCI_MAPREG_IO_SIZE(size);
		} else {
			if (PCI_MAPREG_MEM_PREFETCHABLE(reg))
				region->is_prefetchable = 1;
			switch(PCI_MAPREG_MEM_TYPE(reg)) {
			case PCI_MAPREG_MEM_TYPE_32BIT:
			case PCI_MAPREG_MEM_TYPE_32BIT_1M:
				region->base_addr = PCI_MAPREG_MEM_ADDR(reg);
				region->size = PCI_MAPREG_MEM_SIZE(size);
				break;
			case PCI_MAPREG_MEM_TYPE_64BIT:
				region->is_64 = 1;

				reg64 = reg;
				size64 = size;

				bar += sizeof(uint32_t);

				err = pci_read(domain, bus, dev, func, bar, &reg);
				if (err)
					return err;
				reg64 |= (uint64_t)reg << 32;

				err = pci_readmask(domain, bus, dev, func, bar, &size);
				if (err)
					return err;
				size64 |= (uint64_t)size << 32;

				region->base_addr = PCI_MAPREG_MEM64_ADDR(reg64);
				region->size = PCI_MAPREG_MEM64_SIZE(size64);
				region++;
				break;
			}
		}
	}

	/* Probe expansion ROM if present */
	err = pci_read(domain, bus, dev, func, PCI_ROM_REG, &reg);
	if (err)
		return err;
	if (reg != 0) {
		err = pci_write(domain, bus, dev, func, PCI_ROM_REG, ~PCI_ROM_ENABLE);
		if (err)
			return err;
		pci_read(domain, bus, dev, func, PCI_ROM_REG, &size);
		pci_write(domain, bus, dev, func, PCI_ROM_REG, reg);

		if (PCI_ROM_ADDR(reg) != 0) {
			priv->rom_base = PCI_ROM_ADDR(reg);
			device->rom_size = PCI_ROM_SIZE(size);
		}
	}
	return 0;
}
コード例 #16
0
int
pci_system_openbsd_create(void)
{
	struct pci_device_private *device;
	int domain, bus, dev, func, ndevs, nfuncs;
	char path[MAXPATHLEN];
	uint32_t reg;

	if (ndomains > 0)
		return 0;

	pci_sys = calloc(1, sizeof(struct pci_system));
	if (pci_sys == NULL)
		return ENOMEM;

	pci_sys->methods = &openbsd_pci_methods;

	for (domain = 0; domain < sizeof(pcifd) / sizeof(pcifd[0]); domain++) {
		snprintf(path, sizeof(path), "/dev/pci%d", domain);
	        pcifd[domain] = open(path, O_RDWR | O_CLOEXEC);
		if (pcifd[domain] == -1) {
			pcifd[domain] = open(path, O_RDONLY | O_CLOEXEC);
			if (pcifd[domain] == -1)
				break;
		}
		ndomains++;
	}

	if (ndomains == 0)
		return ENXIO;

	ndevs = 0;
	for (domain = 0; domain < ndomains; domain++) {
		for (bus = 0; bus < 256; bus++) {
			for (dev = 0; dev < 32; dev++) {
				nfuncs = pci_nfuncs(domain, bus, dev);
				for (func = 0; func < nfuncs; func++) {
					if (pci_read(domain, bus, dev, func,
					    PCI_ID_REG, &reg) != 0)
						continue;
					if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
					    PCI_VENDOR(reg) == 0)
						continue;

					ndevs++;
				}
			}
		}
	}

	pci_sys->num_devices = ndevs;
	pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
	if (pci_sys->devices == NULL) {
		free(pci_sys);
		pci_sys = NULL;
		for (domain = 0; domain < ndomains; domain++)
			close(pcifd[domain]);
		ndomains = 0;
		return ENOMEM;
	}

	device = pci_sys->devices;
	for (domain = 0; domain < ndomains; domain++) {
		for (bus = 0; bus < 256; bus++) {
			for (dev = 0; dev < 32; dev++) {
				nfuncs = pci_nfuncs(domain, bus, dev);
				for (func = 0; func < nfuncs; func++) {
					if (pci_read(domain, bus, dev, func,
					    PCI_ID_REG, &reg) != 0)
						continue;
					if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID ||
					    PCI_VENDOR(reg) == 0)
						continue;

					device->base.domain = domain;
					device->base.bus = bus;
					device->base.dev = dev;
					device->base.func = func;
					device->base.vendor_id = PCI_VENDOR(reg);
					device->base.device_id = PCI_PRODUCT(reg);

					if (pci_read(domain, bus, dev, func,
					    PCI_CLASS_REG, &reg) != 0)
						continue;

					device->base.device_class =
					    PCI_INTERFACE(reg) |
					    PCI_CLASS(reg) << 16 |
					    PCI_SUBCLASS(reg) << 8;
					device->base.revision = PCI_REVISION(reg);

					if (pci_read(domain, bus, dev, func,
					    PCI_SUBVEND_0, &reg) != 0)
						continue;

					device->base.subvendor_id = PCI_VENDOR(reg);
					device->base.subdevice_id = PCI_PRODUCT(reg);

					device++;
				}
			}
		}
	}

	return 0;
}
コード例 #17
0
ファイル: pci.c プロジェクト: SimonGustavsson/nox
uint32_t pci_read_dword(struct pci_address* addr, uint8_t reg_offset)
{
    return pci_read(addr->bus, addr->device, addr->func, reg_offset, sizeof(uint32_t));
}