Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Enable 36-bit addressing for chipsets that suppo...



details:   https://anonhg.NetBSD.org/src/rev/0a13781e68bf
branches:  trunk
changeset: 761512:0a13781e68bf
user:      gsutre <gsutre%NetBSD.org@localhost>
date:      Sun Jan 30 23:43:08 2011 +0000

description:
Enable 36-bit addressing for chipsets that support it.  While there,
factorize offset computation.  Inspired from OpenBSD and Intel docs.

Note: agp_i810_bind/unbind_page will now fail with EINVAL if the
physical address is too large for the chipset (instead of silently
truncating it).

ok jmcneill@

diffstat:

 sys/dev/pci/agp_i810.c |  55 +++++++++++++++++++++++++++++++++++--------------
 1 files changed, 39 insertions(+), 16 deletions(-)

diffs (108 lines):

diff -r 9f93120d0204 -r 0a13781e68bf sys/dev/pci/agp_i810.c
--- a/sys/dev/pci/agp_i810.c    Sun Jan 30 23:29:24 2011 +0000
+++ b/sys/dev/pci/agp_i810.c    Sun Jan 30 23:43:08 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: agp_i810.c,v 1.70 2011/01/25 10:52:11 gsutre Exp $     */
+/*     $NetBSD: agp_i810.c,v 1.71 2011/01/30 23:43:08 gsutre Exp $     */
 
 /*-
  * Copyright (c) 2000 Doug Rabson
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.70 2011/01/25 10:52:11 gsutre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.71 2011/01/30 23:43:08 gsutre Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -100,8 +100,8 @@
 static int agp_i810_init(struct agp_softc *);
 
 static int agp_i810_init(struct agp_softc *);
-static void agp_i810_write_gtt_entry(struct agp_i810_softc *, off_t,
-                                    u_int32_t);
+static int agp_i810_write_gtt_entry(struct agp_i810_softc *, off_t,
+                                   bus_addr_t);
 
 static struct agp_methods agp_i810_methods = {
        agp_i810_get_aperture,
@@ -116,12 +116,37 @@
        agp_i810_unbind_memory,
 };
 
-static void
-agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, u_int32_t v)
+static int
+agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, bus_addr_t v)
 {
-       u_int32_t base_off;
+       u_int32_t pte;
+       bus_size_t base_off, wroff;
+
+       /* Bits 11:4 (physical start address extension) should be zero. */
+       if ((v & 0xff0) != 0)
+               return EINVAL;
+
+       pte = (u_int32_t)v;
+       /*
+        * We need to massage the pte if bus_addr_t is wider than 32 bits.
+        * The compiler isn't smart enough, hence the casts to uintmax_t.
+        */
+       if (sizeof(bus_addr_t) > sizeof(u_int32_t)) {
+               /* 965+ can do 36-bit addressing, add in the extra bits. */
+               if (isc->chiptype == CHIP_I965 ||
+                   isc->chiptype == CHIP_G33 ||
+                   isc->chiptype == CHIP_G4X) {
+                       if (((uintmax_t)v >> 36) != 0)
+                               return EINVAL;
+                       pte |= (v >> 28) & 0xf0;
+               } else {
+                       if (((uintmax_t)v >> 32) != 0)
+                               return EINVAL;
+               }
+       }
 
        base_off = 0;
+       wroff = (off >> AGP_PAGE_SHIFT) * 4;
 
        switch (isc->chiptype) {
        case CHIP_I810:
@@ -137,12 +162,12 @@
                break;
        case CHIP_I915:
        case CHIP_G33:
-               bus_space_write_4(isc->gtt_bst, isc->gtt_bsh,
-                   (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, (v));
-               return;
+               bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte);
+               return 0;
        }
-               
-       WRITE4(base_off + (u_int32_t)(off >> AGP_PAGE_SHIFT) * 4, v);
+
+       WRITE4(base_off + wroff, pte);
+       return 0;
 }
 
 /* XXXthorpej -- duplicated code (see arch/x86/pci/pchb.c) */
@@ -829,8 +854,7 @@
                }
        }
 
-       agp_i810_write_gtt_entry(isc, offset, physical | 1);
-       return 0;
+       return agp_i810_write_gtt_entry(isc, offset, physical | 1);
 }
 
 static int
@@ -851,8 +875,7 @@
                }
        }
 
-       agp_i810_write_gtt_entry(isc, offset, 0);
-       return 0;
+       return agp_i810_write_gtt_entry(isc, offset, 0);
 }
 
 /*



Home | Main Index | Thread Index | Old Index