Ejemplo n.º 1
0
void pci_get_bar(pci_bar_t *bar, uint32_t id, uint32_t index)
{
	// Read PCI bar register
	uint32_t addressLow;
	uint32_t maskLow;
	pci_read_bar(id, index, &addressLow, &maskLow);

	if (addressLow & PCI_BAR_64) {
		// 64-bit MMIO
		uint32_t addressHigh;
		uint32_t maskHigh;
		pci_read_bar(id, index + 1, &addressHigh, &maskHigh);

		bar->u.address = (void *)(((uint32_t)addressHigh << 16) | (addressLow & ~0xf));
		bar->size = ~(((uint32_t)maskHigh << 16) | (maskLow & ~0xf)) + 1;
		bar->flags = addressLow & 0xf;
	} else if (addressLow & PCI_BAR_IO) {
		// I/O register
		bar->u.port = (uint16_t)(addressLow & ~0x3);
		bar->size = (uint16_t)(~(maskLow & ~0x3) + 1);
		bar->flags = addressLow & 0x3;
	} else {
		// 32-bit MMIO
		bar->u.address = (void *)(uint32_t)(addressLow & ~0xf);
		bar->size = ~(maskLow & ~0xf) + 1;
		bar->flags = addressLow & 0xf;
	}
}
Ejemplo n.º 2
0
void vga_setup( PCONFIGURATION_COMPONENT_DATA pcibus, 
                struct _pci_desc *desc, struct _vga_desc *vga_desc,
        int bus, int dev, int fn ) {
    struct _pci_bar bar_data;
    int i;

    for( i = 0; i < 6; i++ ) {
        pci_read_bar( desc, bus, dev, fn, i, &bar_data );
        print_bar( &bar_data );
        if( (bar_data.data > 0x10000) || ((bar_data.data&1) == 1) ) {
            vga_desc->addr = (char *)(0xc0000000 + (bar_data.data & ~0x7ff));
//        BootInfo.dispDeviceBase = vga_desc->addr;
            break;
        }
    }
}
Ejemplo n.º 3
0
static int
pci_iov_setup_bars(struct pci_devinfo *dinfo)
{
	device_t dev;
	struct pcicfg_iov *iov;
	pci_addr_t bar_value, testval;
	int i, last_64, error;

	iov = dinfo->cfg.iov;
	dev = dinfo->cfg.dev;
	last_64 = 0;

	pci_add_resources_ea(device_get_parent(dev), dev, 1);

	for (i = 0; i <= PCIR_MAX_BAR_0; i++) {
		/* First, try to use BARs allocated with EA */
		error = pci_iov_alloc_bar_ea(dinfo, i);
		if (error == 0)
			continue;

		/* Allocate legacy-BAR only if EA is not enabled */
		if (pci_ea_is_enabled(dev, iov->iov_pos + PCIR_SRIOV_BAR(i)))
			continue;

		/*
		 * If a PCI BAR is a 64-bit wide BAR, then it spans two
		 * consecutive registers.  Therefore if the last BAR that
		 * we looked at was a 64-bit BAR, we need to skip this
		 * register as it's the second half of the last BAR.
		 */
		if (!last_64) {
			pci_read_bar(dev,
			    iov->iov_pos + PCIR_SRIOV_BAR(i),
			    &bar_value, &testval, &last_64);

			if (testval != 0) {
				error = pci_iov_alloc_bar(dinfo, i,
				   pci_mapsize(testval));
				if (error != 0)
					return (error);
			}
		} else
			last_64 = 0;
	}

	return (0);
}
Ejemplo n.º 4
0
static int
pci_iov_setup_bars(struct pci_devinfo *dinfo)
{
	device_t dev;
	struct pcicfg_iov *iov;
	pci_addr_t bar_value, testval;
	int i, last_64, error;

	iov = dinfo->cfg.iov;
	dev = dinfo->cfg.dev;
	last_64 = 0;

	for (i = 0; i <= PCIR_MAX_BAR_0; i++) {
		/*
		 * If a PCI BAR is a 64-bit wide BAR, then it spans two
		 * consecutive registers.  Therefore if the last BAR that
		 * we looked at was a 64-bit BAR, we need to skip this
		 * register as it's the second half of the last BAR.
		 */
		if (!last_64) {
			pci_read_bar(dev,
			    iov->iov_pos + PCIR_SRIOV_BAR(i),
			    &bar_value, &testval, &last_64);

			if (testval != 0) {
				error = pci_iov_alloc_bar(dinfo, i,
				   pci_mapsize(testval));
				if (error != 0)
					return (error);
			}
		} else
			last_64 = 0;
	}

	return (0);
}
Ejemplo n.º 5
0
struct resource *
thunder_pcie_alloc_resource(device_t dev, device_t child, int type, int *rid,
    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
	struct thunder_pcie_softc *sc = device_get_softc(dev);
	struct rman *rm = NULL;
	struct resource *res;
	pci_addr_t map, testval;

	switch (type) {
	case SYS_RES_IOPORT:
		goto fail;
		break;
	case SYS_RES_MEMORY:
		rm = &sc->mem_rman;
		break;
	default:
		return (bus_generic_alloc_resource(dev, child,
		    type, rid, start, end, count, flags));
	};

	if ((start == 0UL) && (end == ~0UL)) {

		/* Read BAR manually to get resource address and size */
		pci_read_bar(child, *rid, &map, &testval, NULL);

		/* Mask the information bits */
		if (PCI_BAR_MEM(map))
			map &= PCIM_BAR_MEM_BASE;
		else
			map &= PCIM_BAR_IO_BASE;

		if (PCI_BAR_MEM(testval))
			testval &= PCIM_BAR_MEM_BASE;
		else
			testval &= PCIM_BAR_IO_BASE;

		start = map;
		count = (~testval) + 1;
		/*
		 * Internal ThunderX devices supports up to 3 64-bit BARs.
		 * If we're allocating anything above, that means upper layer
		 * wants us to allocate VF-BAR. In that case reserve bigger
		 * slice to make a room for other VFs adjacent to this one.
		 */
		if (*rid > PCIR_BAR(5))
			count = count * thunder_pcie_max_vfs;
		end = start + count - 1;
	}

	/* Convert input BUS address to required PHYS */
	if (range_addr_is_pci(sc->ranges, start, count) == 0)
		goto fail;
	start = range_addr_pci_to_phys(sc->ranges, start);
	end = start + count - 1;

	if (bootverbose) {
		device_printf(dev,
		    "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n",
		    start, end, count);
	}

	res = rman_reserve_resource(rm, start, end, count, flags, child);
	if (res == NULL)
		goto fail;

	rman_set_rid(res, *rid);

	if ((flags & RF_ACTIVE) != 0)
		if (bus_activate_resource(child, type, *rid, res)) {
			rman_release_resource(res);
			goto fail;
		}

	return (res);

fail:
	if (bootverbose) {
		device_printf(dev, "%s FAIL: type=%d, rid=%d, "
		    "start=%016lx, end=%016lx, count=%016lx, flags=%x\n",
		    __func__, type, *rid, start, end, count, flags);
	}

	return (NULL);
}
Ejemplo n.º 6
0
void pci_cfg_e1k(net_info_t *net)
{
   pci_cfg_dev_vdr_t dvd;
   e1k_info_t        *e1k = &net->arch;
   pci_cfg_val_t     *pci = &net->pci;

   /* search dev */
   dvd.vendor = PCI_CFG_VENDOR_INTEL;
   dvd.device = PCI_CFG_DEVICE_i82545EM_C;
   if(!pci_search(pci_check_dvd, dvd.raw, 1, pci))
   {
      dvd.device = PCI_CFG_DEVICE_i82540EM;
      if(!pci_search(pci_check_dvd, dvd.raw, 1, pci))
	 goto __not_found;
   }

   pci->addr.reg = PCI_CFG_CLASS_REV_OFFSET;
   pci_cfg_read(pci);
   if(pci->cr.class != PCI_CFG_CLASS_i8254x)
      goto __not_found;

   pci->addr.reg = PCI_CFG_CMD_STS_OFFSET;
   pci_cfg_read(pci);

   /* dma enable */
   if(!pci->cs.cmd.mm || !pci->cs.cmd.bus_master)
   {
      pci->cs.cmd.mm = 1;
      pci->cs.cmd.bus_master = 1;
      pci_cfg_write(pci);
   }

   pci_cfg_read(pci);
   debug(PCI_E1000, "e1k CMD/STS 0x%x 0x%x | CMD io %d mm %d dma %d\n"
	 ,pci->cs.cmd.raw, pci->cs.sts.raw
	 ,pci->cs.cmd.io, pci->cs.cmd.mm, pci->cs.cmd.bus_master);

   /* BAR regs */
   if(!pci_read_bar(pci, 0) && pci->br.io)
      panic("could not read i8254x registers (bar0 0x%x)", pci->br.raw);

   e1k->base.linear = pci->br.raw & 0xfffffff0;

   if(pci->br.type == PCI_CFG_MEM_BAR_64)
   {
      raw64_t addr = { .low = 0 };

      pci_read_bar(pci, 1);
      addr.high = pci->data.raw;
      e1k->base.linear += addr.raw;
   }

   debug(PCI_E1000, "e1k BAR 0x%X\n", e1k->base.linear);

   setptr(e1k->ctl,    e1k->base.linear + 0);
   setptr(e1k->sts,    e1k->base.linear + 8);
   setptr(e1k->eerd,   e1k->base.linear + 0x14);
   setptr(e1k->fcal,   e1k->base.linear + 0x28);
   setptr(e1k->fcah,   e1k->base.linear + 0x2c);
   setptr(e1k->fct,    e1k->base.linear + 0x30);
   setptr(e1k->fcttv,  e1k->base.linear + 0x170);

   setptr(e1k->icr,    e1k->base.linear + 0xc0);
   setptr(e1k->ics,    e1k->base.linear + 0xc8);
   setptr(e1k->ims,    e1k->base.linear + 0xd0);
   setptr(e1k->imc,    e1k->base.linear + 0xd8);

   setptr(e1k->rx.ctl, e1k->base.linear + 0x100);
   setptr(e1k->rx.bal, e1k->base.linear + 0x2800);
   setptr(e1k->rx.bah, e1k->base.linear + 0x2804);
   setptr(e1k->rx.dl,  e1k->base.linear + 0x2808);
   setptr(e1k->rx.dh,  e1k->base.linear + 0x2810);
   setptr(e1k->rx.dt,  e1k->base.linear + 0x2818);

   setptr(e1k->tx.ctl, e1k->base.linear + 0x400);
   setptr(e1k->tx.ipg, e1k->base.linear + 0x410);
   setptr(e1k->tx.bal, e1k->base.linear + 0x3800);
   setptr(e1k->tx.bah, e1k->base.linear + 0x3804);
   setptr(e1k->tx.dl,  e1k->base.linear + 0x3808);
   setptr(e1k->tx.dh,  e1k->base.linear + 0x3810);
   setptr(e1k->tx.dt,  e1k->base.linear + 0x3818);

   setptr(e1k->mta,    e1k->base.linear + 0x5200);
   setptr(e1k->ra,     e1k->base.linear + 0x5400);

   /* Interrupt line */
   pci->addr.reg = PCI_CFG_INT_OFFSET;
   pci_cfg_read(pci);

   net->irq = pci->data.blow;

   debug(PCI_E1000, "e1k irq line %d\n", net->irq);

   return;

__not_found:
   panic("no i8254x ethernet controller found");
}