Ejemplo n.º 1
0
static int
tdfx_clrmtrr(device_t dev) {
	/* This function removes the MTRR set by the attach call, so it can be used
	 * in the future by other drivers. 
	 */
	int retval, act;
	struct tdfx_softc *tdfx_info = device_get_softc(dev);
	
	act = MEMRANGE_SET_REMOVE;
	retval = mem_range_attr_set(&tdfx_info->mrdesc, &act);
	return retval;
}
Ejemplo n.º 2
0
int
drm_mtrr_add(unsigned long offset, unsigned long size, unsigned int flags)
{
	int act;
	struct mem_range_desc mrdesc;

	mrdesc.mr_base = offset;
	mrdesc.mr_len = size;
	mrdesc.mr_flags = flags;
	act = MEMRANGE_SET_UPDATE;
	strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner));
	return (-mem_range_attr_set(&mrdesc, &act));
}
int
drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags)
{
	int act;
	struct mem_range_desc mrdesc;

	mrdesc.mr_base = offset;
	mrdesc.mr_len = size;
	mrdesc.mr_flags = flags;
	act = MEMRANGE_SET_REMOVE;
	strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner));
	return mem_range_attr_set(&mrdesc, &act);
}
Ejemplo n.º 4
0
/*
 * Operations for changing memory attributes.
 *
 * This is basically just an ioctl shim for mem_range_attr_get
 * and mem_range_attr_set.
 */
static int 
mmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
{
	int nd, error = 0;
	struct mem_range_op *mo = (struct mem_range_op *)data;
	struct mem_range_desc *md;
	
	/* is this for us? */
	if ((cmd != MEMRANGE_GET) &&
	    (cmd != MEMRANGE_SET))
		return (ENOTTY);

	/* any chance we can handle this? */
	if (mem_range_softc.mr_op == NULL)
		return (EOPNOTSUPP);

	/* do we have any descriptors? */
	if (mem_range_softc.mr_ndesc == 0)
		return (ENXIO);

	switch (cmd) {
	case MEMRANGE_GET:
		nd = imin(mo->mo_arg[0], mem_range_softc.mr_ndesc);
		if (nd > 0) {
			md = (struct mem_range_desc *)
				malloc(nd * sizeof(struct mem_range_desc),
				       M_MEMDESC, M_WAITOK);
			error = mem_range_attr_get(md, &nd);
			if (!error)
				error = copyout(md, mo->mo_desc, 
					nd * sizeof(struct mem_range_desc));
			free(md, M_MEMDESC);
		}
		else
			nd = mem_range_softc.mr_ndesc;
		mo->mo_arg[0] = nd;
		break;
		
	case MEMRANGE_SET:
		md = (struct mem_range_desc *)malloc(sizeof(struct mem_range_desc),
						    M_MEMDESC, M_WAITOK);
		error = copyin(mo->mo_desc, md, sizeof(struct mem_range_desc));
		/* clamp description string */
		md->mr_owner[sizeof(md->mr_owner) - 1] = 0;
		if (error == 0)
			error = mem_range_attr_set(md, &mo->mo_arg[0]);
		free(md, M_MEMDESC);
		break;
	}
	return (error);
}
Ejemplo n.º 5
0
int
drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags)
{
#ifndef DRM_NO_MTRR
	int act;
	struct mem_range_desc mrdesc;

	mrdesc.mr_base = offset;
	mrdesc.mr_len = size;
	mrdesc.mr_flags = flags;
	act = MEMRANGE_SET_REMOVE;
	strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner));
	return mem_range_attr_set(&mrdesc, &act);
#else
	return 0;
#endif
}
Ejemplo n.º 6
0
static int
tdfx_setmtrr(device_t dev) {
	/*
	 * This is the MTRR setting function for the 3dfx card. It is called from
	 * tdfx_attach. If we can't set the MTRR properly, it's not the end of the
	 * world. We can still continue, just with slightly (very slightly) degraded
	 * performance.
	 */
	int retval = 0, act;
	struct tdfx_softc *tdfx_info = device_get_softc(dev);

	/* The older Voodoo cards have a shorter memrange than the newer ones */
	if((pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO1) || (pci_get_devid(dev) ==
			PCI_DEVICE_3DFX_VOODOO2)) {
		tdfx_info->mrdesc.mr_len = 0x400000;

		/* The memory descriptor is described as the top 15 bits of the real
			address */
		tdfx_info->mrdesc.mr_base = tdfx_info->addr0 & 0xfffe0000;
	}
	else if((pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO3) ||
			(pci_get_devid(dev) == PCI_DEVICE_3DFX_BANSHEE)) {
		tdfx_info->mrdesc.mr_len = 0x1000000;
		/* The Voodoo3 and Banshee LFB is the second memory address */
		/* The memory descriptor is described as the top 15 bits of the real
			address */
		tdfx_info->mrdesc.mr_base = tdfx_info->addr1 & 0xfffe0000;
	}
	else
		 return 0;	
	/* 
    *	The Alliance Pro Motion AT3D was not mentioned in the linux
	 * driver as far as MTRR support goes, so I just won't put the
	 * code in here for it. This is where it should go, though. 
	 */

	/* Firstly, try to set write combining */
	tdfx_info->mrdesc.mr_flags = MDF_WRITECOMBINE;
	bcopy("tdfx", &tdfx_info->mrdesc.mr_owner, 4);
	act = MEMRANGE_SET_UPDATE;
	retval = mem_range_attr_set(&tdfx_info->mrdesc, &act);

	if(retval == 0) {
#ifdef DEBUG
		device_printf(dev, "MTRR Set Correctly for tdfx\n");
#endif
	} else if((pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO2) ||
		(pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO1)) {
		/* if, for some reason we can't set the WRCOMB range with the V1/V2, we
		 * can still possibly use the UNCACHEABLE region for it instead, and help
		 * out in a small way */
		tdfx_info->mrdesc.mr_flags = MDF_UNCACHEABLE;
		/* This length of 1000h was taken from the linux device driver... */
		tdfx_info->mrdesc.mr_len = 0x1000;

		/*
		 * If, for some reason, we can't set the MTRR (N/A?) we may still continue
		 */
#ifdef DEBUG
		device_printf(dev, "MTRR Set Type Uncacheable %x\n",
		    (u_int32_t)tdfx_info->mrdesc.mr_base);
#endif
	}
#ifdef DEBUG
	else {
		device_printf(dev, "Couldn't Set MTRR\n");
		return 0;
	}
#endif
	return 0;
}