Selon John Baldwin <[EMAIL PROTECTED]>:

> On Thursday 06 March 2008 08:31:26 am John Baldwin wrote:
> > The Linux AGP driver has the same code.  It appears to be forcing a read of
> > the TLB registers to force prior writes to clear the TLB entries to flush
> > perhaps?  I'm not sure why you are getting a panic.  What kind of fault did
> > you get?  (The original kernel panic messages would be needed.)
>
> Actually, it looks like you have a 64MB aperture and with either a 32MB or
> 64MB aperture this loop runs off the end of the GATT (GATT has 16384 entries
> * 4 bytes == 64k == 16 pages on x86) so if it dies before it starts the next
> loop that might explain it.  The patch below makes it walk the full GATT
> reading the first word from each page to force a flush w/o walking off the
> end of the GATT.
>
> Actually, this is what appears to have happened:
>
> (gdb) set $start = 0xd4d05000  (ag_virtual)
> (gdb) set $fva = 3570491392    (eva in trap_pfault() frame)
> (gdb) p ($fva - $start) / 4
> $2 = 17408
>
> That's well over your current ag_entries of 16384.  Try this patch (note
> Linux's in-kernel agp driver has the same bug):
>
> Index: agp_nvidia.c
> ===================================================================
> RCS file: /host/cvs/usr/cvs/src/sys/dev/agp/agp_nvidia.c,v
> retrieving revision 1.13
> diff -u -r1.13 agp_nvidia.c
> --- agp_nvidia.c      12 Nov 2007 21:51:37 -0000      1.13
> +++ agp_nvidia.c      6 Mar 2008 13:37:43 -0000
> @@ -347,7 +347,7 @@
>       struct agp_nvidia_softc *sc;
>       u_int32_t wbc_reg, temp;
>       volatile u_int32_t *ag_virtual;
> -     int i;
> +     int i, pages;
>
>       sc = (struct agp_nvidia_softc *)device_get_softc(dev);
>
> @@ -373,9 +373,10 @@
>       ag_virtual = (volatile u_int32_t *)sc->gatt->ag_virtual;
>
>       /* Flush TLB entries. */
> -     for(i = 0; i < 32 + 1; i++)
> +     pages = sc->gatt->ag_entries * sizeof(u_int32_t) / PAGE_SIZE;
> +     for(i = 0; i < pages; i++)
>               temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
> -     for(i = 0; i < 32 + 1; i++)
> +     for(i = 0; i < pages; i++)
>               temp = ag_virtual[i * PAGE_SIZE / sizeof(u_int32_t)];
>
>       return (0);
>
> --
> John Baldwin

Thanks a lot John, this code works. I have been able to launch X w/o crashing
the kernel.

Fred
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to