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