예제 #1
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;	
}
예제 #2
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;
}
예제 #3
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 */
예제 #4
0
int pci_enable_msix(pci_addr_t *addr ,struct pcicfg_msix *msix,uint8_t capabilities_pointer){
	update_msix_table(msix, 0);
	msix->msix_ctrl = msix->msix_ctrl | 0x8000; // enable msix
	pci_write(addr, capabilities_pointer + PCIR_MSIX_CTRL, 2, &msix->msix_ctrl);

	ut_log("MSIX... Configured ISR vector:%d  numvector:%d ctrl:%x\n", msix->isr_vector, msix->msix_msgnum, msix->msix_ctrl);
	return 1;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
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;
}
예제 #8
0
파일: pci.c 프로젝트: SimonGustavsson/nox
void pci_write_byte(struct pci_address* addr, uint8_t reg_offset, uint8_t value)
{
    pci_write(addr->bus, addr->device, addr->func, reg_offset, sizeof(uint8_t), value);
}
예제 #9
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 */
예제 #10
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 */