예제 #1
0
static void
amdsbwd_identify(driver_t *driver, device_t parent)
{
	device_t		child;
	device_t		smb_dev;

	if (resource_disabled("amdsbwd", 0))
		return;
	if (device_find_child(parent, "amdsbwd", -1) != NULL)
		return;

	/*
	 * Try to identify SB600/SB7xx by PCI Device ID of SMBus device
	 * that should be present at bus 0, device 20, function 0.
	 */
	smb_dev = pci_find_bsf(0, 20, 0);
	if (smb_dev == NULL)
		return;
	if (pci_get_devid(smb_dev) != AMDSB_SMBUS_DEVID)
		return;

	child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "amdsbwd", -1);
	if (child == NULL)
		device_printf(parent, "add amdsbwd child failed\n");
}
예제 #2
0
static int
amdsbwd_attach_sb(device_t dev, struct amdsbwd_softc *sc)
{
	device_t	smb_dev;

	sc->max_ticks = UINT16_MAX;
	sc->rid_ctrl = 0;
	sc->rid_count = 1;

	smb_dev = pci_find_bsf(0, 20, 0);
	KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
	if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID)
		sc->ms_per_tick = 10;
	else
		sc->ms_per_tick = 1000;

	sc->res_ctrl = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->rid_ctrl, RF_ACTIVE);
	if (sc->res_ctrl == NULL) {
		device_printf(dev, "bus_alloc_resource for ctrl failed\n");
		return (ENXIO);
	}
	sc->res_count = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->rid_count, RF_ACTIVE);
	if (sc->res_count == NULL) {
		device_printf(dev, "bus_alloc_resource for count failed\n");
		return (ENXIO);
	}
	return (0);
}
예제 #3
0
static int
amdsbwd_probe(device_t dev)
{
	struct resource		*res;
	device_t		smb_dev;
	uint32_t		addr;
	int			rid;
	int			rc;

	/* Do not claim some ISA PnP device by accident. */
	if (isa_get_logicalid(dev) != 0)
		return (ENXIO);

	rc = bus_set_resource(dev, SYS_RES_IOPORT, 0, AMDSB_PMIO_INDEX,
	    AMDSB_PMIO_WIDTH);
	if (rc != 0) {
		device_printf(dev, "bus_set_resource for IO failed\n");
		return (ENXIO);
	}
	rid = 0;
	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0ul, ~0ul,
	    AMDSB_PMIO_WIDTH, RF_ACTIVE | RF_SHAREABLE);
	if (res == NULL) {
		device_printf(dev, "bus_alloc_resource for IO failed\n");
		return (ENXIO);
	}

	smb_dev = pci_find_bsf(0, 20, 0);
	KASSERT(smb_dev != NULL, ("can't find SMBus PCI device\n"));
	if (pci_get_revid(smb_dev) < AMDSB8_SMBUS_REVID)
		amdsbwd_probe_sb7xx(dev, res, &addr);
	else
		amdsbwd_probe_sb8xx(dev, res, &addr);

	bus_release_resource(dev, SYS_RES_IOPORT, rid, res);
	bus_delete_resource(dev, SYS_RES_IOPORT, rid);

	amdsbwd_verbose_printf(dev, "memory base address = %#010x\n", addr);
	rc = bus_set_resource(dev, SYS_RES_MEMORY, 0, addr + AMDSB_WD_CTRL,
	    AMDSB_WDIO_REG_WIDTH);
	if (rc != 0) {
		device_printf(dev, "bus_set_resource for control failed\n");
		return (ENXIO);
	}
	rc = bus_set_resource(dev, SYS_RES_MEMORY, 1, addr + AMDSB_WD_COUNT,
	    AMDSB_WDIO_REG_WIDTH);
	if (rc != 0) {
		device_printf(dev, "bus_set_resource for count failed\n");
		return (ENXIO);
	}

	return (0);
}
예제 #4
0
int
legacy_pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
                    uint32_t *data)
{
    device_t bus, hostb;
    int error, func, slot;

    bus = device_get_parent(pcib);
    error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data);
    if (error)
        return (error);

    slot = legacy_get_pcislot(pcib);
    func = legacy_get_pcifunc(pcib);
    if (slot == -1 || func == -1)
        return (0);
    hostb = pci_find_bsf(0, slot, func);
    KASSERT(hostb != NULL, ("%s: missing hostb for 0:%d:%d", __func__,
                            slot, func));
    pci_ht_map_msi(hostb, *addr);
    return (0);
}
예제 #5
0
파일: qpi.c 프로젝트: runsisi/ufreebsdtcp
/*
 * Look for a PCI bus with the specified bus address.  If one is found,
 * add a pcib device and return 0.  Otherwise, return an error code.
 */
static int
qpi_probe_pcib(device_t dev, int bus)
{
	struct qpi_device *qdev;
	device_t child;
	uint32_t devid;

	/*
	 * If a PCI bus already exists for this bus number, then
	 * fail.
	 */
	if (pci_find_bsf(bus, 0, 0) != NULL)
		return (EEXIST);

	/*
	 * Attempt to read the device id for device 0, function 0 on
	 * the bus.  A value of 0xffffffff means that the bus is not
	 * present.
	 */
	devid = pci_cfgregread(bus, 0, 0, PCIR_DEVVENDOR, 4);
	if (devid == 0xffffffff)
		return (ENOENT);

	if ((devid & 0xffff) != 0x8086) {
		device_printf(dev,
		    "Device at pci%d.0.0 has non-Intel vendor 0x%x\n", bus,
		    devid & 0xffff);
		return (ENXIO);
	}

	child = BUS_ADD_CHILD(dev, 0, "pcib", -1);
	if (child == NULL)
		panic("%s: failed to add pci bus %d", device_get_nameunit(dev),
		    bus);
	qdev = bsd_malloc(sizeof(struct qpi_device), M_QPI, M_WAITOK);
	qdev->qd_pcibus = bus;
	device_set_ivars(child, qdev);
	return (0);
}
예제 #6
0
static int
agp_nvidia_attach (device_t dev)
{
	struct agp_nvidia_softc *sc = device_get_softc(dev);
	struct agp_gatt *gatt;
	u_int32_t apbase;
	u_int32_t aplimit;
	u_int32_t temp;
	int size;
	int i;
	int error;

	switch (pci_get_device(dev)) {
	case NVIDIA_DEVICEID_NFORCE:
		sc->wbc_mask = 0x00010000;
		break;
	case NVIDIA_DEVICEID_NFORCE2:
		sc->wbc_mask = 0x80000000;
		break;
	default:
		device_printf(dev, "Bad chip id\n");
		return (ENODEV);
	}

	/* AGP Controller */
	sc->dev = dev;

	/* Memory Controller 1 */
	sc->mc1_dev = pci_find_bsf(pci_get_bus(dev), 0, 1);
	if (sc->mc1_dev == NULL) {
		device_printf(dev,
			"Unable to find NVIDIA Memory Controller 1.\n");
		return (ENODEV);
	}

	/* Memory Controller 2 */
	sc->mc2_dev = pci_find_bsf(pci_get_bus(dev), 0, 2);
	if (sc->mc2_dev == NULL) {
		device_printf(dev,
			"Unable to find NVIDIA Memory Controller 2.\n");
		return (ENODEV);
	}

	/* AGP Host to PCI Bridge */
	sc->bdev = pci_find_bsf(pci_get_bus(dev), 30, 0);
	if (sc->bdev == NULL) {
		device_printf(dev,
			"Unable to find NVIDIA AGP Host to PCI Bridge.\n");
		return (ENODEV);
	}

	error = agp_generic_attach(dev);
	if (error)
		return (error);

	sc->initial_aperture = AGP_GET_APERTURE(dev);
	if (sc->initial_aperture == 0) {
		device_printf(dev, "bad initial aperture size, disabling\n");
		return ENXIO;
	}

	for (;;) {
		gatt = agp_alloc_gatt(dev);
		if (gatt)
			break;
		/*
		 * Probably contigmalloc failure. Try reducing the
		 * aperture so that the gatt size reduces.
		 */
		if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2))
			goto fail;
	}
	sc->gatt = gatt;

	apbase = rman_get_start(sc->agp.as_aperture);
	aplimit = apbase + AGP_GET_APERTURE(dev) - 1;
	pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APBASE, apbase, 4);
	pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APLIMIT, aplimit, 4);
	pci_write_config(sc->bdev, AGP_NVIDIA_3_APBASE, apbase, 4);
	pci_write_config(sc->bdev, AGP_NVIDIA_3_APLIMIT, aplimit, 4);

	error = nvidia_init_iorr(apbase, AGP_GET_APERTURE(dev));
	if (error) {
		device_printf(dev, "Failed to setup IORRs\n");
		goto fail;
	}

	/* directory size is 64k */
	size = AGP_GET_APERTURE(dev) / 1024 / 1024;
	sc->num_dirs = size / 64;
	sc->num_active_entries = (size == 32) ? 16384 : ((size * 1024) / 4);
	sc->pg_offset = 0;
	if (sc->num_dirs == 0) {
		sc->num_dirs = 1;
		sc->num_active_entries /= (64 / size);
		sc->pg_offset = (apbase & (64 * 1024 * 1024 - 1) &
				 ~(AGP_GET_APERTURE(dev) - 1)) / PAGE_SIZE;
	}

	/* (G)ATT Base Address */
	for (i = 0; i < 8; i++) {
		pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_ATTBASE(i),
				 (sc->gatt->ag_physical +
				   (i % sc->num_dirs) * 64 * 1024) | 1, 4);
	}

	/* GTLB Control */
	temp = pci_read_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, 4);
	pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, temp | 0x11, 4);

	/* GART Control */
	temp = pci_read_config(sc->dev, AGP_NVIDIA_0_APSIZE, 4);
	pci_write_config(sc->dev, AGP_NVIDIA_0_APSIZE, temp | 0x100, 4);

	return (0);
fail:
	agp_generic_detach(dev);
	return (ENOMEM);
}
예제 #7
0
static void
ichss_identify(driver_t *driver, device_t parent)
{
	device_t child;
	uint32_t pmbase;

	if (resource_disabled("ichss", 0))
		return;

	/*
	 * It appears that ICH SpeedStep only requires a single CPU to
	 * set the value (since the chipset is shared by all CPUs.)
	 * Thus, we only add a child to cpu 0.
	 */
	if (device_get_unit(parent) != 0)
		return;

	/* Avoid duplicates. */
	if (device_find_child(parent, "ichss", -1))
		return;

	/*
	 * ICH2/3/4-M I/O Controller Hub is at bus 0, slot 1F, function 0.
	 * E.g. see Section 6.1 "PCI Devices and Functions" and table 6.1 of
	 * Intel(r) 82801BA I/O Controller Hub 2 (ICH2) and Intel(r) 82801BAM
	 * I/O Controller Hub 2 Mobile (ICH2-M).
	 *
	 * TODO: add a quirk to disable if we see the 82815_MC along
	 * with the 82801BA and revision < 5.
	 */
	ich_device = pci_find_bsf(0, 0x1f, 0);
	if (ich_device == NULL ||
	    pci_get_vendor(ich_device) != PCI_VENDOR_INTEL ||
	    (pci_get_device(ich_device) != PCI_DEV_82801BA &&
	    pci_get_device(ich_device) != PCI_DEV_82801CA &&
	    pci_get_device(ich_device) != PCI_DEV_82801DB))
		return;

	/* Find the PMBASE register from our PCI config header. */
	pmbase = pci_read_config(ich_device, ICHSS_PMBASE_OFFSET,
	    sizeof(pmbase));
	if ((pmbase & ICHSS_IO_REG) == 0) {
		printf("ichss: invalid PMBASE memory type\n");
		return;
	}
	pmbase &= ICHSS_PMBASE_MASK;
	if (pmbase == 0) {
		printf("ichss: invalid zero PMBASE address\n");
		return;
	}
	DPRINT("ichss: PMBASE is %#x\n", pmbase);

	child = BUS_ADD_CHILD(parent, 20, "ichss", 0);
	if (child == NULL) {
		device_printf(parent, "add SpeedStep child failed\n");
		return;
	}

	/* Add the bus master arbitration and control registers. */
	bus_set_resource(child, SYS_RES_IOPORT, 0, pmbase + ICHSS_BM_OFFSET,
	    1);
	bus_set_resource(child, SYS_RES_IOPORT, 1, pmbase + ICHSS_CTRL_OFFSET,
	    1);
}