Ejemplo n.º 1
0
static void probe_function(uint8_t bus, uint8_t device, uint8_t function) {
    uint32_t class = pci_readconfig(bus, device, function, 0x08);
    uint8_t baseclass = class >> 24;
    uint8_t subclass = class >> 16;
    uint8_t prog_interface = class >> 8;
    //uint8_t revision = class;

    d_printf("Found PCI device! bus %x device %x function %x\n",
        bus, device, function);

    d_printf("    base class: %x subclass: %x prog_interface: %x\n", baseclass, subclass, prog_interface);

    // is this a PCI bridge?
    if(baseclass == 0x04 && subclass == 0x06) {
        uint32_t secondary_bus = pci_readconfig(bus, device, function, 0x18);
        secondary_bus >>= 8;
        secondary_bus &= 0xff;

        probe_bus(secondary_bus);
    }
Ejemplo n.º 2
0
static pciconf_bus_t *
query_bus(pciconf_bus_t *parent, pciconf_dev_t *pd, int dev)
{
	pciconf_bus_t	*pb;
	pcireg_t	busreg, io, pmem;
	pciconf_win_t	*pi, *pm;

	pb = malloc (sizeof (pciconf_bus_t), M_DEVBUF, M_NOWAIT);
	if (!pb)
		panic("Unable to allocate memory for PCI configuration.");

	pb->cacheline_size = parent->cacheline_size;
	pb->parent_bus = parent;
	alloc_busno(parent, pb);
	if (pci_conf_debug)
		printf("PCI bus bridge covers busses %d-%d\n",
			pb->busno, pb->last_busno);

	busreg  =  parent->busno << PCI_BRIDGE_BUS_PRIMARY_SHIFT;
	busreg |=      pb->busno << PCI_BRIDGE_BUS_SECONDARY_SHIFT;
	busreg |= pb->last_busno << PCI_BRIDGE_BUS_SUBORDINATE_SHIFT;
	pci_conf_write(parent->pc, pd->tag, PCI_BRIDGE_BUS_REG, busreg);

	pb->swiz = parent->swiz + dev;

	pb->ioext = NULL;
	pb->memext = NULL;
	pb->pmemext = NULL;
	pb->pc = parent->pc;
	pb->io_total = pb->mem_total = pb->pmem_total = 0;

	pb->io_32bit = 0;
	if (parent->io_32bit) {
		io = pci_conf_read(parent->pc, pd->tag, PCI_BRIDGE_STATIO_REG);
		if (PCI_BRIDGE_IO_32BITS(io)) {
			pb->io_32bit = 1;
		}
	}

	pb->pmem_64bit = 0;
	if (parent->pmem_64bit) {
		pmem = pci_conf_read(parent->pc, pd->tag,
		    PCI_BRIDGE_PREFETCHMEM_REG);
		if (PCI_BRIDGE_PREFETCHMEM_64BITS(pmem)) {
			pb->pmem_64bit = 1;
		}
	}

	if (probe_bus(pb)) {
		printf("Failed to probe bus %d\n", pb->busno);
		goto err;
	}

	if (pb->io_total > 0) {
		if (parent->niowin >= MAX_CONF_IO) {
			printf("pciconf: too many I/O windows\n");
			goto err;
		}
		pb->io_total |= 0xfff;	/* Round up */
		pi = get_io_desc(parent, pb->io_total);
		pi->dev = pd;
		pi->reg = 0;
		pi->size = pb->io_total;
		pi->align = 0x1000;	/* 4K alignment */
		pi->prefetch = 0;
		parent->niowin++;
		parent->io_total += pb->io_total;
	}

	if (pb->mem_total > 0) {
		if (parent->nmemwin >= MAX_CONF_MEM) {
			printf("pciconf: too many MEM windows\n");
			goto err;
		}
		pb->mem_total |= 0xfffff;	/* Round up */
		pm = get_mem_desc(parent, pb->mem_total);
		pm->dev = pd;
		pm->reg = 0;
		pm->size = pb->mem_total;
		pm->align = 0x100000;	/* 1M alignment */
		pm->prefetch = 0;
		parent->nmemwin++;
		parent->mem_total += pb->mem_total;
	}

	if (pb->pmem_total > 0) {
		if (parent->nmemwin >= MAX_CONF_MEM) {
			printf("pciconf: too many MEM windows\n");
			goto err;
		}
		pb->pmem_total |= 0xfffff;	/* Round up */
		pm = get_mem_desc(parent, pb->pmem_total);
		pm->dev = pd;
		pm->reg = 0;
		pm->size = pb->pmem_total;
		pm->align = 0x100000;		/* 1M alignment */
		pm->prefetch = 1;
		parent->nmemwin++;
		parent->pmem_total += pb->pmem_total;
	}

	return pb;
err:
	free(pb, M_DEVBUF);
	return NULL;
}