summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-02-01 14:53:05 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-02-01 14:53:05 +0000
commit3f890f4049b4c195ade9ca5b99cb1a44a5d2ab36 (patch)
tree16f93912749ca4d876bdaf36274bec4d5a117518 /sys
parent431ad02309f63a5909d5c6b47ebb1a1208566516 (diff)
Fix the logic in mbus_add_mapping() to correctly handle requests spanning
more than one flex ``tile'', when the first one is already mapped. Some sti(4) devices have such requests. ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/hppa/hppa/mainbus.c123
-rw-r--r--sys/arch/hppa/include/cpu.h3
2 files changed, 73 insertions, 53 deletions
diff --git a/sys/arch/hppa/hppa/mainbus.c b/sys/arch/hppa/hppa/mainbus.c
index 9868262bef7..3718475056c 100644
--- a/sys/arch/hppa/hppa/mainbus.c
+++ b/sys/arch/hppa/hppa/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.69 2007/12/28 19:48:50 kettenis Exp $ */
+/* $OpenBSD: mainbus.c,v 1.70 2009/02/01 14:53:02 miod Exp $ */
/*
* Copyright (c) 1998-2004 Michael Shalayeff
@@ -79,8 +79,9 @@ mbus_add_mapping(bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
static u_int32_t bmm[0x4000/32];
- int bank, off, flex = HPPA_FLEX(bpa);
- u_int64_t spa, epa;
+ int bank, off, flex;
+ vaddr_t pa, spa, epa;
+ vsize_t len;
#ifdef BTLBDEBUG
printf("bus_mem_add_mapping(%x,%x,%scachable,%p)\n",
@@ -90,14 +91,6 @@ mbus_add_mapping(bus_addr_t bpa, bus_size_t size, int flags,
if ((bank = vm_physseg_find(atop(bpa), &off)) >= 0)
panic("mbus_add_mapping: mapping real memory @0x%lx", bpa);
- /*
- * determine if we are mapping IO space, or beyond the physmem
- * region. use block mapping then
- *
- * we map the whole bus module (there are 1024 of those max)
- * so, check here if it's mapped already, map if needed.
- * all mappings are equal mappings.
- */
#ifdef DEBUG
if (flags & BUS_SPACE_MAP_CACHEABLE) {
printf("WARNING: mapping I/O space cachable\n");
@@ -105,61 +98,87 @@ mbus_add_mapping(bus_addr_t bpa, bus_size_t size, int flags,
}
#endif
- /* need a new mapping */
- if (!(bmm[flex / 32] & (1 << (flex % 32)))) {
- spa = bpa & HPPA_FLEX_MASK;
- epa = ((u_long)((u_int64_t)bpa + size +
- ~HPPA_FLEX_MASK - 1) & HPPA_FLEX_MASK) - 1;
+ /*
+ * Mappings are established in HPPA_FLEX_SIZE units,
+ * either with BTLB, or regular mappings of the whole area.
+ */
+ pa = bpa;
+ while (size != 0) {
+ flex = HPPA_FLEX(pa);
+ spa = pa & HPPA_FLEX_MASK;
+ epa = spa + HPPA_FLEX_SIZE; /* may wrap to 0... */
+
+ size -= min(size, HPPA_FLEX_SIZE - (pa - spa));
+
+ /* do need a new mapping? */
+ if (!(bmm[flex / 32] & (1 << (flex % 32)))) {
#ifdef BTLBDEBUG
- printf("bus_mem_add_mapping: adding flex=%x "
- "%qx-%qx, ", flex, spa, epa);
+ printf("bus_mem_add_mapping: adding flex=%x "
+ "%x-%x, ", flex, spa, epa - 1);
#endif
- while (spa < epa) {
- vsize_t len = epa - spa;
- u_int64_t pa;
- if (len > pdc_btlb.max_size << PGSHIFT)
- len = pdc_btlb.max_size << PGSHIFT;
- if (btlb_insert(HPPA_SID_KERNEL, spa, spa, &len,
- pmap_sid2pid(HPPA_SID_KERNEL) |
- pmap_prot(pmap_kernel(), UVM_PROT_RW)) >= 0) {
- pa = spa + len - 1;
+ while (spa != epa) {
+ len = epa - spa;
+
+ /*
+ * Try to map with a BTLB first (might map
+ * much more than what we are requesting
+ * for, and cross HPPA_FLEX boundaries).
+ *
+ * Note that this code assumes that
+ * BTLB size are a power of two, so if
+ * the size is larger than HPPA_FLEX_SIZE
+ * it will span an integral number of
+ * HPPA_FLEX_SIZE slots.
+ */
+ if (len > pdc_btlb.max_size << PGSHIFT)
+ len = pdc_btlb.max_size << PGSHIFT;
+
+ if (btlb_insert(HPPA_SID_KERNEL, spa, spa, &len,
+ pmap_sid2pid(HPPA_SID_KERNEL) |
+ pmap_prot(pmap_kernel(), UVM_PROT_RW))
+ >= 0) {
+ pa = spa + len; /* may wrap to 0... */
#ifdef BTLBDEBUG
- printf("--- %x/%x, %qx, %qx-%qx",
- flex, HPPA_FLEX(pa), pa, spa, epa);
+ printf("--- %x/%x, %x-%x ",
+ flex, HPPA_FLEX(pa - 1),
+ spa, pa - 1);
#endif
- /* do the mask */
- for (; flex <= HPPA_FLEX(pa); flex++) {
+ /* register all ranges */
+ for (; flex <= HPPA_FLEX(pa - 1);
+ flex++) {
#ifdef BTLBDEBUG
- printf("mask %x ", flex);
+ printf("mask %x ", flex);
#endif
- bmm[flex / 32] |= (1 << (flex % 32));
- }
- spa = pa;
- } else {
- spa = trunc_page(bpa);
- epa = round_page(bpa + size);
-
- if (epa - 1 > ~0U)
- epa = (u_int64_t)~0U + 1;
-
+ bmm[flex / 32] |=
+ (1 << (flex % 32));
+ }
+ if (len > epa - spa)
+ spa = epa;
+ else
+ spa = pa;
+ } else {
#ifdef BTLBDEBUG
- printf("kenter 0x%qx-0x%qx", spa, epa);
+ printf("kenter 0x%x-0x%x", spa, epa);
#endif
- for (; spa < epa; spa += PAGE_SIZE)
- pmap_kenter_pa(spa, spa, UVM_PROT_RW);
- }
+ for (; spa != epa; spa += PAGE_SIZE)
+ pmap_kenter_pa(spa, spa,
+ UVM_PROT_RW);
+ }
#ifdef BTLBDEBUG
- printf("\n");
+ printf("\n");
#endif
+ }
}
- }
#ifdef BTLBDEBUG
- else {
- printf("+++ already b-mapped flex=%x, mask=%x",
- flex, bmm[flex / 8]);
- }
+ else {
+ printf("+++ already b-mapped flex=%x, mask=%x\n",
+ flex, bmm[flex / 32]);
+ }
#endif
+ pa = epa;
+ }
+
*bshp = bpa;
return (0);
}
diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h
index 8763c036dca..fa72e7b52ea 100644
--- a/sys/arch/hppa/include/cpu.h
+++ b/sys/arch/hppa/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.59 2008/10/15 23:23:47 deraadt Exp $ */
+/* $OpenBSD: cpu.h,v 1.60 2009/02/01 14:53:04 miod Exp $ */
/*
* Copyright (c) 2000-2004 Michael Shalayeff
@@ -142,6 +142,7 @@ extern register_t kpsw;
#define HPPA_FLEX_DATA 0xfff80001
#define HPPA_DMA_ENABLE 0x00000001
#define HPPA_FLEX_MASK 0xfffc0000
+#define HPPA_FLEX_SIZE (1 + ~HPPA_FLEX_MASK)
#define HPPA_FLEX(a) (((a) & HPPA_FLEX_MASK) >> 18)
#define HPPA_SPA_ENABLE 0x00000020
#define HPPA_NMODSPBUS 64