summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorFederico G. Schwindt <fgsch@cvs.openbsd.org>2008-07-02 03:00:01 +0000
committerFederico G. Schwindt <fgsch@cvs.openbsd.org>2008-07-02 03:00:01 +0000
commit2bbeb14e7d0899f31acede7fbb290dbc5480da3f (patch)
treef39071575f28d23f2b03197ef34e218abb2f48d0 /sys/arch/amd64
parent51e6641b4d0c8f6d4ba6f5724a6eda1b34251931 (diff)
* Dynamically set the rbus start address. from netbsd.
* For amd64, remove pcibios traces. * make RBUS_IO_START, RBUS_IO_SIZE, RBUS_MIN_START and RBUS_MEM_SIZE (on i386) configurable via kernel options. * Remove unneeded headers. * Some cleanups. originally reported in pr/5829 and tested by viq <viq at viq dot ath dot cx>. fixes ian@ laptop too. kettenis@ and miod@ agrees that although not perfect, this is the right direction.
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/rbus_machdep.c144
-rw-r--r--sys/arch/amd64/include/rbus_machdep.h22
2 files changed, 93 insertions, 73 deletions
diff --git a/sys/arch/amd64/amd64/rbus_machdep.c b/sys/arch/amd64/amd64/rbus_machdep.c
index 0e2ce763bc5..6d072e2f42d 100644
--- a/sys/arch/amd64/amd64/rbus_machdep.c
+++ b/sys/arch/amd64/amd64/rbus_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rbus_machdep.c,v 1.6 2007/12/20 13:34:48 kettenis Exp $ */
+/* $OpenBSD: rbus_machdep.c,v 1.7 2008/07/02 03:00:00 fgsch Exp $ */
/* $NetBSD: rbus_machdep.c,v 1.2 1999/10/15 06:43:06 haya Exp $ */
/*
@@ -31,104 +31,124 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*#include "pcibios.h"*/
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/extent.h>
#include <uvm/uvm_extern.h>
-#include <sys/sysctl.h>
-
#include <sys/device.h>
#include <machine/bus.h>
#include <dev/cardbus/rbus.h>
-#include <dev/isa/isareg.h>
-#include <dev/isa/isavar.h>
-
#include <dev/pci/pcivar.h>
+#ifndef RBUS_IO_START
+#define RBUS_IO_START 0xa000
+#endif
+#ifndef RBUS_IO_SIZE
+#define RBUS_IO_SIZE 0x1000
+#endif
+
+#ifndef RBUS_MIN_START
+#define RBUS_MIN_START 0x40000000 /* 1 GB */
+#endif
-/**********************************************************************
- * rbus_tag_t rbus_fakeparent_mem(struct pci_attach_args *pa)
+/*
+ * Dynamically set the start address for rbus. This must be called
+ * before rbus is initialized. The start address should be determined
+ * by the amount of installed memory. Generally 1 GB has been found
+ * to be a good value, but it fails on some Thinkpads (e.g. 2645-4AU),
+ * for which 0.5 GB is a good value. It also fails on (at least)
+ * Thinkpads with 2GB of RAM, for which 2 GB is a good value.
*
- * This function makes an rbus tag for memory space. This rbus tag
- * shares the all memory region of ex_iomem.
- **********************************************************************/
-#define RBUS_MEM_START 0x40000000
-#define RBUS_MEM_SIZE 0x00100000
+ * Thus, a general strategy of setting rbus_min_start to the amount of
+ * memory seems in order. However, the actually amount of memory is
+ * generally slightly more than the amount found, e.g. 1014MB vs 1024,
+ * or 2046 vs 2048.
+ */
+bus_addr_t
+rbus_min_start_hint(void)
+{
+ bus_addr_t rbus_min_start = RBUS_MIN_START;
+ size_t ram = ptoa(physmem);
+
+ if (ram <= 192 * 1024 * 1024UL) {
+ /*
+ * <= 192 MB, so try 0.5 GB. This will work on
+ * Thinkpad 600E (2645-4AU), which fails at 1 GB, and
+ * on some other older machines that may have trouble
+ * with addresses needing more than 20 bits.
+ */
+ rbus_min_start = 512 * 1024 * 1024UL;
+ }
+ if (ram >= 1024 * 1024 * 1024UL) {
+ /*
+ * > 1 GB, so try 2 GB.
+ */
+ rbus_min_start = 2 * 1024 * 1024 * 1024UL;
+ }
+
+ /* Not tested in > 2 GB case. */
+ if (ram > 2 * 1024 * 1024 * 1024UL) {
+ /*
+ * > 2 GB, so try 3 GB.
+ */
+ rbus_min_start = 3 * 1024 * 1024 * 1024UL;
+ }
+
+ return (rbus_min_start);
+}
+
+/*
+ * This function makes an rbus tag for memory space. This rbus tag
+ * shares the all memory region of ex_iomem.
+ */
rbus_tag_t
rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa)
{
- bus_addr_t start, min_start;
+ bus_addr_t start, rbus_min_start;
bus_size_t size;
- struct extent *ex;
+ extern struct extent *iomem_ex;
+ struct extent *ex = iomem_ex;
- size = RBUS_MEM_SIZE;
- start = min_start = max(RBUS_MEM_START, ptoa(physmem));
-#if NPCIBIOS > 0
- if ((ex = pciaddr_search(PCIADDR_SEARCH_MEM, &start, size)) == NULL)
-#endif
- {
- extern struct extent *iomem_ex;
- ex = iomem_ex;
- start = ex->ex_start;
-
- /* XXX: unfortunately, iomem_ex cannot be used for the
- * dynamic bus_space allocation. There are some
- * hidden memory (or some obstacles which do not
- * recognised by the kernel) in the region governed by
- * iomem_ex. So I decide to use only very high
- * address region.
- *
- * if defined PCIBIOS_ADDR_FIXUP, PCI device using
- * area which is not recognised by the kernel are
- * already reserved.
- */
+ start = ex->ex_start;
- if (start < min_start) {
- start = min_start;
- }
+ /* XXX: unfortunately, iomem_ex cannot be used for the
+ * dynamic bus_space allocation. There are some
+ * hidden memory (or some obstacles which do not
+ * recognised by the kernel) in the region governed by
+ * iomem_ex. So I decide to use only very high
+ * address region.
+ */
- size = ex->ex_end - start;
- }
-
- return rbus_new_root_share(pa->pa_memt, ex, start, size, 0);
-}
+ rbus_min_start = rbus_min_start_hint();
+ if (start < rbus_min_start)
+ start = rbus_min_start;
+ size = ex->ex_end - start;
-/**********************************************************************
- * rbus_tag_t rbus_pccbb_parent_io(struct pci_attach_args *pa)
- **********************************************************************/
-#define RBUS_IO_START 0xa000
-#define RBUS_IO_SIZE 0x1000
+ return (rbus_new_root_share(pa->pa_memt, ex, start, size, 0));
+}
rbus_tag_t
rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa)
{
- struct extent *ex;
bus_addr_t start;
bus_size_t size;
+ extern struct extent *ioport_ex;
+ struct extent *ex = ioport_ex;
- size = RBUS_IO_SIZE;
+ size = RBUS_IO_SIZE;
start = RBUS_IO_START;
-#if NPCIBIOS > 0
- if ((ex = pciaddr_search(PCIADDR_SEARCH_IO, &start, size)) == NULL)
-#endif
- {
- extern struct extent *ioport_ex;
- ex = ioport_ex;
- }
- return rbus_new_root_share(pa->pa_iot, ex, start, size, 0);
+ return (rbus_new_root_share(pa->pa_iot, ex, start, size, 0));
}
void
pccbb_attach_hook(struct device *parent, struct device *self,
struct pci_attach_args *pa)
{
-}
+}
diff --git a/sys/arch/amd64/include/rbus_machdep.h b/sys/arch/amd64/include/rbus_machdep.h
index 0ab405f539c..f61370b904a 100644
--- a/sys/arch/amd64/include/rbus_machdep.h
+++ b/sys/arch/amd64/include/rbus_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rbus_machdep.h,v 1.3 2007/12/20 13:34:48 kettenis Exp $ */
+/* $OpenBSD: rbus_machdep.h,v 1.4 2008/07/02 03:00:00 fgsch Exp $ */
/* $NetBSD: rbus_machdep.h,v 1.2 1999/10/15 06:43:05 haya Exp $ */
/*
@@ -31,9 +31,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-#if !defined _ARCH_AMD64_AMD64_RBUS_MACHDEP_H_
-#define _ARCH_AMD64_AMD64_RBUS_MACHDEP_H_
+#ifndef _AMD64_RBUS_MACHDEP_H_
+#define _AMD64_RBUS_MACHDEP_H_
struct pci_attach_args; /* XXX */
@@ -43,13 +42,14 @@ struct pci_attach_args; /* XXX */
#define md_space_unmap(bt, bsh, size, adrp) \
_bus_space_unmap((bt), (bsh), (size), (adrp))
+rbus_tag_t rbus_pccbb_parent_io(struct device *,
+ struct pci_attach_args *);
+rbus_tag_t rbus_pccbb_parent_mem(struct device *,
+ struct pci_attach_args *);
-rbus_tag_t rbus_pccbb_parent_io(struct device *self,
- struct pci_attach_args *pa);
-rbus_tag_t rbus_pccbb_parent_mem(struct device *self,
- struct pci_attach_args *pa);
+bus_addr_t rbus_min_start_hint(void);
-void pccbb_attach_hook(struct device *, struct device *,
- struct pci_attach_args *);
+void pccbb_attach_hook(struct device *, struct device *,
+ struct pci_attach_args *);
-#endif /* _ARCH_AMD64_AMD64_RBUS_MACHDEP_H_ */
+#endif /* _AMD64_RBUS_MACHDEP_H_ */