summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>2000-09-20 17:39:06 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>2000-09-20 17:39:06 +0000
commit52af272e9459618b0ddbe7123c1a2431a1226e86 (patch)
treea5cae08988fd82fea51268e3f9cbe261a8bca67d /sys
parent7d56032c82fa70600a62adf0a833a2d84915f79a (diff)
support 64bit BARs from NetBSD
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/pci_map.c62
-rw-r--r--sys/dev/pci/pcireg.h10
2 files changed, 56 insertions, 16 deletions
diff --git a/sys/dev/pci/pci_map.c b/sys/dev/pci/pci_map.c
index af1ed413ace..67e36544287 100644
--- a/sys/dev/pci/pci_map.c
+++ b/sys/dev/pci/pci_map.c
@@ -1,12 +1,12 @@
-/* $OpenBSD: pci_map.c,v 1.3 2000/06/09 16:09:09 chris Exp $ */
-/* $NetBSD: pci_map.c,v 1.5 1998/08/15 10:10:54 mycroft Exp $ */
+/* $OpenBSD: pci_map.c,v 1.4 2000/09/20 17:39:04 niklas Exp $ */
+/* $NetBSD: pci_map.c,v 1.7 2000/05/10 16:58:42 thorpej Exp $ */
/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
+ * by Charles M. Hannum; by William R. Studenmund; by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -117,11 +117,17 @@ nbsd_pci_mem_find(pc, tag, reg, type, basep, sizep, flagsp)
bus_size_t *sizep;
int *flagsp;
{
- pcireg_t address, mask;
- int s;
+ pcireg_t address, mask, address1 = 0, mask1 = 0xffffffff;
+ u_int64_t waddress, wmask;
+ int s, is64bit;
+
+ is64bit = (PCI_MAPREG_MEM_TYPE(type) == PCI_MAPREG_MEM_TYPE_64BIT);
if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
- panic("pci_find_mem: bad request");
+ panic("pci_mem_find: bad request");
+
+ if (is64bit && (reg + 4) >= PCI_MAPREG_END)
+ panic("pci_mem_find: bad 64-bit request");
/*
* Section 6.2.5.1, `Address Maps', tells us that:
@@ -138,6 +144,12 @@ nbsd_pci_mem_find(pc, tag, reg, type, basep, sizep, flagsp)
pci_conf_write(pc, tag, reg, 0xffffffff);
mask = pci_conf_read(pc, tag, reg);
pci_conf_write(pc, tag, reg, address);
+ if (is64bit) {
+ address1 = pci_conf_read(pc, tag, reg + 4);
+ pci_conf_write(pc, tag, reg + 4, 0xffffffff);
+ mask1 = pci_conf_read(pc, tag, reg + 4);
+ pci_conf_write(pc, tag, reg + 4, address1);
+ }
splx(s);
if (PCI_MAPREG_TYPE(address) != PCI_MAPREG_TYPE_MEM) {
@@ -152,7 +164,10 @@ nbsd_pci_mem_find(pc, tag, reg, type, basep, sizep, flagsp)
return (1);
}
- if (PCI_MAPREG_MEM_SIZE(mask) == 0) {
+ waddress = (u_int64_t)address1 << 32UL | address;
+ wmask = (u_int64_t)mask1 << 32UL | mask;
+
+ if (PCI_MAPREG_MEM64_SIZE(wmask) == 0) {
printf("pci_mem_find: void region\n");
return (1);
}
@@ -162,17 +177,36 @@ nbsd_pci_mem_find(pc, tag, reg, type, basep, sizep, flagsp)
case PCI_MAPREG_MEM_TYPE_32BIT_1M:
break;
case PCI_MAPREG_MEM_TYPE_64BIT:
- printf("pci_mem_find: 64-bit memory mapping register\n");
- return (1);
+ /*
+ * Handle the case of a 64-bit memory register on a
+ * platform with 32-bit addressing. Make sure that
+ * the address assigned and the device's memory size
+ * fit in 32 bits. We implicitly assume that if
+ * bus_addr_t is 64-bit, then so is bus_size_t.
+ */
+ if (sizeof(u_int64_t) > sizeof(bus_addr_t) &&
+ (address1 != 0 || mask1 != 0xffffffff)) {
+ printf("pci_mem_find: 64-bit memory map which is "
+ "inaccessible on a 32-bit platform\n");
+ return (1);
+ }
+ break;
default:
printf("pci_mem_find: reserved mapping register type\n");
return (1);
}
- if (basep != 0)
- *basep = PCI_MAPREG_MEM_ADDR(address);
- if (sizep != 0)
- *sizep = PCI_MAPREG_MEM_SIZE(mask);
+ if (sizeof(u_int64_t) > sizeof(bus_addr_t)) {
+ if (basep != 0)
+ *basep = PCI_MAPREG_MEM_ADDR(address);
+ if (sizep != 0)
+ *sizep = PCI_MAPREG_MEM_SIZE(mask);
+ } else {
+ if (basep != 0)
+ *basep = PCI_MAPREG_MEM64_ADDR(waddress);
+ if (sizep != 0)
+ *sizep = PCI_MAPREG_MEM64_SIZE(wmask);
+ }
if (flagsp != 0)
*flagsp = PCI_MAPREG_MEM_CACHEABLE(address)
#ifndef __OpenBSD__
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index e2074e06716..53f6c641a58 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: pcireg.h,v 1.13 2000/08/02 02:25:14 mickey Exp $ */
-/* $NetBSD: pcireg.h,v 1.11 1996/08/10 15:42:33 mycroft Exp $ */
+/* $OpenBSD: pcireg.h,v 1.14 2000/09/20 17:39:05 niklas Exp $ */
+/* $NetBSD: pcireg.h,v 1.26 2000/05/10 16:58:42 thorpej Exp $ */
/*
* Copyright (c) 1995, 1996 Christopher G. Demetriou. All rights reserved.
@@ -343,6 +343,12 @@ typedef u_int8_t pci_revision_t;
(PCI_MAPREG_MEM_ADDR(mr) & -PCI_MAPREG_MEM_ADDR(mr))
#define PCI_MAPREG_MEM_ADDR_MASK 0xfffffff0
+#define PCI_MAPREG_MEM64_ADDR(mr) \
+ ((mr) & PCI_MAPREG_MEM64_ADDR_MASK)
+#define PCI_MAPREG_MEM64_SIZE(mr) \
+ (PCI_MAPREG_MEM64_ADDR(mr) & -PCI_MAPREG_MEM64_ADDR(mr))
+#define PCI_MAPREG_MEM64_ADDR_MASK 0xfffffffffffffff0
+
#define PCI_MAPREG_IO_ADDR(mr) \
((mr) & PCI_MAPREG_IO_ADDR_MASK)
#define PCI_MAPREG_IO_SIZE(mr) \