[rfc] Radeon AGP support patches
Konstantin Belousov
kostikbel at gmail.com
Wed Oct 29 17:03:35 UTC 2014
On Mon, Oct 27, 2014 at 10:10:58PM +0100, Tijl Coosemans wrote:
> On Mon, 27 Oct 2014 18:27:53 +0200 Konstantin Belousov <kostikbel at gmail.com> wrote:
> > On Mon, Oct 27, 2014 at 05:00:55PM +0100, Tijl Coosemans wrote:
> >> In ttm_agp_bind the ttm->pages array is already populated. These are
> >> the pages that need to be put into the GTT. The patch modifies struct
> >> agp_memory in sys/dev/agp such that ttm->pages can be passed via
> >> agp_bind_memory. Maybe it would be better to add two new functions to
> >> sys/dev/agp/agp.c: agp_bind_pages and agp_unbind_pages. These would
> >> take a vm_page_t array as argument and bind/unbind the pages directly
> >> in the GTT. There's no need for ttm_agp_bind to call agp_alloc_memory
> >> then and struct agp_memory would not be involved at all. Does that
> >> sound better?
> >
> > Yes, this approach is much better IMO. Having discriminated storage
> > for the bound pages is too ugly;
>
> New patch 1 & 3 attached.
>
> > was the whole code audited for correctness after the change ?
>
> I'm fairly confident these patches are all that's needed yes. I made
> a first implementation on Sunday afternoon. It got to the point that
> X showed a mouse pointer and background colour and then it crashed.
> It took the rest of the week to figure out why (NULL dereference in
> ttm_bo_vm_fault) and how to solve it (mark aperture range fictitious).
> It's hard to debug something without a screen. I read the code front
> to back and back to front in that time and compared it with the old DRM
> code and with the Linux DRM code. That's where patch 2 & 4 come from.
Looks good, commit. See trivial notes below.
> Index: sys/dev/agp/agp.c
> ===================================================================
> --- sys/dev/agp/agp.c (revision 273255)
> +++ sys/dev/agp/agp.c (working copy)
> @@ -996,3 +996,68 @@ void agp_memory_info(device_t dev, void
> mi->ami_offset = mem->am_offset;
> mi->ami_is_bound = mem->am_is_bound;
> }
> +
> +int agp_bind_pages(device_t dev, vm_page_t *pages, vm_size_t size,
> + vm_offset_t offset) {
Style:
return type of separate line, continuation line should use 4 spaces.
Opening '{' on the new line.
> + struct agp_softc *sc = device_get_softc(dev);
Initialization in declaration.
> + vm_offset_t i, j, k, pa;
> + vm_page_t m;
> + int error;
> +
> + if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
> + (offset & (AGP_PAGE_SIZE - 1)) != 0)
> + return (EINVAL);
> +
> + mtx_lock(&sc->as_lock);
> + for (i = 0; i < size; i += PAGE_SIZE) {
> + m = pages[i >> PAGE_SHIFT];
Use OFF_TO_IDX().
> +
> + /*
> + * Install entries in the GATT, making sure that if
> + * AGP_PAGE_SIZE < PAGE_SIZE and size is not
> + * aligned to PAGE_SIZE, we don't modify too many GATT
> + * entries.
> + */
> + for (j = 0; j < PAGE_SIZE && i + j < size; j += AGP_PAGE_SIZE) {
> + pa = VM_PAGE_TO_PHYS(m) + j;
> + AGP_DPF("binding offset %#jx to pa %#jx\n",
> + (uintmax_t)offset + i + j, (uintmax_t)pa);
> + error = AGP_BIND_PAGE(dev, offset + i + j, pa);
> + if (error) {
> + /*
> + * Bail out. Reverse all the mappings.
> + */
> + for (k = 0; k < i + j; k += AGP_PAGE_SIZE)
> + AGP_UNBIND_PAGE(dev, offset + k);
> +
> + mtx_unlock(&sc->as_lock);
> + return (error);
> + }
> + }
> + }
> +
> + agp_flush_cache();
> + AGP_FLUSH_TLB(dev);
> +
> + mtx_unlock(&sc->as_lock);
> + return (0);
> +}
> +
> +int agp_unbind_pages(device_t dev, vm_size_t size, vm_offset_t offset) {
> + struct agp_softc *sc = device_get_softc(dev);
Same style problems.
> + vm_offset_t i;
More information about the freebsd-x11
mailing list