up a good bit, I think. Also, remove the agp_uninit() function which
has lain around as a noop for years now. The FreeBSD DRM is now all
compiling, with the exception of via. One known sleeping-with-lock-held
issue remains.
radeon_cp.c to use a drm_local_map_t-type mapping (drm_core_ioremap
rather than drm_ioremap), which contains private device mapping
information on BSD. I also changed the ati_pcigart interface to use
"void *" for pointers to kva rather than "unsigned long". While PCIGART
support appears to be broken on FreeBSD currently, I think this is not
new, and BusType PCI remains working on my r100 in Linux.
allocate the resource RF_ACTIVE, pull out the appropriate value, and
return it. However, allocating large framebuffers RF_ACTIVE would run
the system out of KVA, and this also left open the possibility of the
resource getting moved after getting the offset. Instead, when either
of these are called, allocate the resource if it isn't allocated
already (non-RF_ACTIVE) and store it in the DRM device, to be cleaned
up on lastclose.
understandable: preinit -> load postinit -> (removed) presetup ->
firstopen postsetup -> (removed) open_helper -> open prerelease ->
preclose free_filp_priv -> postclose pretakedown -> lastclose
postcleanup -> unload release -> reclaim_buffers_locked version ->
(removed)
postinit and version were replaced with generic code in the Linux DRM
(drivers now set their version numbers and description in the driver
structure, like on BSD). postsetup wasn't used at all. Fixes the savage
hooks for initializing and tearing down mappings at the right times.
Testing involved at least starting X, running glxgears, killing
glxgears, exiting X, and repeating.
Tested on: FreeBSD (g200, g400, r200, r128) Linux (r200, savage4)
driver's preinit routine, and by using DRM_COPY_TO_USER_IOCTL when
copying out to an ioctl's data pointer. Pulled from the latest version
of my drm-hook-rename.diff and only compile-tested after that.
This patch adds serveral new ioctls and a new query to get_param query to
support PCI MGA cards.
Two ioctls were added to implement interrupt based waiting. With this
change, the client-side driver no longer needs to map the primary DMA
region or the MMIO region. Previously, end-of-frame waiting was done by
busy waiting in the client-side driver until one of the MMIO registers
(the current DMA pointer) matched a pointer to the end of primary DMA
space. By using interrupts, the busy waiting and the extra mappings are
removed.
A third ioctl was added to bootstrap DMA. This ioctl, which is used by the
X-server, moves a *LOT* of code from the X-server into the kernel. This
allows the kernel to do whatever needs to be done to setup DMA buffers.
The entire process and the locations of the buffers are hidden from
user-mode.
Additionally, a get_param query was added to differentiate between G4x0
cards and G550 cards. A gap was left in the numbering sequence so that,
if needed, G450 cards could be distinguished from G400 cards. According
to Ville Syrjälä, the G4x0 cards and the G550 cards handle
anisotropic filtering differently. This seems the most compatible way
to let the client-side driver know which card it's own. Doing this very
small change now eliminates the need to bump the DRM minor version
twice.
http://marc.theaimsgroup.com/?l=dri-devel&m=106625815319773&w=2
A number of ioctl handlers in linux-core were also modified so that they
could be called in-kernel. In these cases, the in-kernel callable
version kept the existing name (e.g., drm_agp_acquire) and the ioctl
handler added _ioctl to the name (e.g., drm_agp_acquire_ioctl).
This patch also replaces the drm_agp_do_release function with
drm_agp_release. drm_agp_release (drm_core_agp_release in the previous
patch) is very similar to drm_agp_do_release, and I saw no reason to
have both.
This commit *breaks the build* on BSD. Eric said that he would make the
required updates to the BSD side soon.
Xorg bug: 3259 Reviewed by: Eric Anholt
that a device absolutely is, absolutely is not, or may or may not be
AGP. Modify the i915 DRM to use this to force all i9x5 devices to be
"AGP" (even the PCI-e devices).
Reported by: Lukas Hejtmanek
platform-specific drm_device_is_agp function. Added implementation of
this function the the Linux-specific portion of the MGA driver to
detect PCI G450 cards. Added code to the Linux-specific portion of the
generic DRM layer to not initialize AGP infrastructure if the card is
not AGP (this matches what already existed in BSD).
Bumped the driver date and the driver patch-level for MGA.
This mostly fixes bugzilla #3248. The BSD side still needs an
implementation of mga_driver_device_is_agp.
with IOMMUs and such. There is one usage of the forbidden vtophys()
left in drm_scatter.c which will be fixed up soon. This required a KPI
change for drm_pci_alloc/free() to return/use a drm_dma_handle_t that
keeps track of os-specific bits, rather than just passing around the
vaddr/busaddr/size.
Submitted by: Tonnerre Lombard (partially) Tested on: FreeBSD: Rage128
AGP/PCI Linux: Savage4 AGP/PCI
privileges on Radeon hardware. Essentially, a malicious program could
submit a packet containing an offset (possibly in main memory) to be
rendered from/to, while a separate thread switched that offset in
userspace rapidly between a valid value and an invalid one.
radeon_check_and_fixup_offset() would pull the offset in from user
space, check it, and spit it back out to user space to be copied in
later by the emit code. It would sometimes catch the bad value, but
sometimes the malicious program could modify it after the check and get
an invalid offset rendered from/to.
Fix this by allocating a temporary buffer and copying the data in at once.
While here, make the cliprects stuff not do the VERIFYAREA_READ and
COPY_FROM_USER_UNCHECKED gymnastics, avoiding a lock order reversal on
FreeBSD. Performance impact is negligible -- no difference on r200 to
~1% improvement on rv200 in quake3 tests (P4 1Ghz, demofour at
1024x768, n=4 or 5).
FreeBSD. Add drm_get_resource_{start|len} so linux-specific stuff
doesn't need to be in shared code.
- Fix mach64 build by using __DECONST to work around passing a const
pointer to useracc, which is unfortunately not marked const.
- Get rid of a lot of maplist code by not having dev->maplist be a pointer,
and by sticking the link entries directly in drm_local_map_t rather
than having a separate structure for the linked list.
- Factor out map uninit and removal into its own routine, rather than
duplicating in both drm_takedown() and drm_rmmap().
- Hook up more driver functions, and correct FreeBSD-specific bits of
radeon_cp.c, making radeon work.
- Baby steps towards using bus_space as we should.
ioctls with dev_lock, which is a major step toward being able to remove
Giant. Covers some new pieces (dev->unique*) in the core, and avoids
one call down into system internals with the drm lock held, which is
usually bad (FreeBSD LOR #23, #27).
martinlexa dot cz). Now that we've got porting for all three major BSDs
(and the fourth being very similar to FreeBSD), move the
mostly-duplication drm_os_* files into drmP.h. Remove some cruft from
linux heritage and from pieces of the DRM that have since been removed.
Note that things are still not quite working for even FreeBSD, but these
are first steps at cleanup, and just a WIP checkpoint.
a busid that doesn't correspond to the device the DRM is attached to.
This is a breaking of backwards-compatibility only for the
multiple-DRI-head case with X Servers that don't use interface 1.1.
- Move irq_busid to drm_irq.h and make it only return the IRQ for the
current device. Retains compatibility with previous X Servers, cleans
up unnecessary code. This means no irq_busid on !__HAVE_IRQ, but can be
changed if necessary.
- Bump interface version to 1.2. This version when set signifies that the
control ioctl should ignore the irq number passed in and enable the
interrupt handler for the attached device. Otherwise it errors out when
the passed-in irq is not equal to the device's.
- Store the highest version the interface has been set to in the device.
- Fix a recursion on DRM_LOCK in irq_uninstall on FreeBSD. This leaves
irq_uninstall being done without the lock in some cases, but it was
racey anyways.
the 2D driver initializes MC_FB_LOCATION and related registers sanely
the DRM deduces the layout from these registers
clients use the new SETPARAM ioctl to tell the DRM where they think the
framebuffer is located in the card's address space
the DRM uses all this information to check client state and fix it up if
necessary
This is a prerequisite for things like direct rendering with IGP chips and
video capturing.
server or client to notify the DRM that it expects a certain version of
the device dependent or device independent interface. If the major
doesn't match or minor is too large, EINVAL is returned. A major of -1
means that the requestor doesn't care about that portion of the
interface. The ioctl returns the actual versions in the same struct.
- Introduce DRM DI interface version 1.1. If the server requests version
1.1, then the DRM sets the unique itself according to the busid of the
device it probed, which may then be accessed as normal using getunique.
- Request version 1.1 in libdrm's drmOpenByBusID, allowing the X Server to
request based on a BusID. Introduce a wrapper for DRM_IOCTL_SET_VERSION
and bump libdrm minor version.
- Pass the busid in DRIScreenInit if libdrm can handle both a busid and
name. This allows drmOpenByBusID to be used to find the DRM instead of
just the driver name, which allows us in the future to tie a DRM more
strongly to the device it probed to. Introduce a function
DRICreatePCIBusID which creates a busid in the form pci:oooo:bb:dd.f
similar to linux's pci_name() function. This matches the format used by
the DRM in version 1.1. libdrm knows how to match both this format and
the old PCI🅱️d:f format.
- Use the new DRICreatePCIBusID function in the *_dri.c to request the new,
more exact busid format.
used by root (the X Server) which are not locked. However, it should
deal with lost-IRQ issues on -current which I think people have been
experiencing but I am unable to reproduce (though I understand why they
would occur, because of a bug of mine). Note that most of the locking
(DRM_LOCK()/UNLOCK()) is all covered by Giant still, so it doesn't
matter yet.
- Remove locking on FreeBSD-stable and NetBSD. These are covered by the
fact that there is no reentrancy of the kernel except by interrupts,
which are locked using spldrm()/splx() instead.
from __HAVE_DMA. This will be useful for adding vblank sync support to
sis and tdfx. Rename dma_service to irq_handler, which is more
accurately what it is.
- Fix the #if _HAVE_DMA_IRQ in radeon, r128, mga, i810, i830, gamma to have
the right number of underscores. This may have been a problem in the
case that the server died without doing its DRM_IOCTL_CONTROL to
uninit.
just a single instance. Moved the PCI ID lists from <card>_drv.c in BSD
to <card>.h. The PCI ID lists include a driver private field, which may
be used by drivers for chip family or other information. Based on work
by jonsmirl.
- Make tdfx_drv.c and tdfx.h match other drivers.
- Fixed up linking of sis shared files.
Tested with Radeon and SiS on Linux and FreeBSD, including a Linux setup
with
2 SiS cards in a machine, but only one head being used (with DRI)
it. To do this we need to save the bus address along with the virtual
address in the seglist. Also fix some error handling and a few bits of
whitespace.
DRM(write_string). This is the first part of removing much of the
support code for gamma from the BSD DRM, since it appears that no new
drivers are using it and nobody has ever shown interest in gamma on
BSD.
post-drm-filp-0-1-branch world. The filp is a void * cast from the
current pid. This is a temporary solution which maintains the status
quo until a proper solution is implemented.
What is really needed is a unique pointer per open, hopefully with a device
private area. This can be done in FreeBSD for all entry points except
mmap, but is difficult (sys/dev/streams/streams.c is an example). I
have partially completed code for this but have not had time to debug,
so this is a temporary fix.