summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/rbus_machdep.c110
1 files changed, 29 insertions, 81 deletions
diff --git a/sys/arch/amd64/amd64/rbus_machdep.c b/sys/arch/amd64/amd64/rbus_machdep.c
index f5cd151c092..f4a2ebdf53d 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.8 2008/07/07 23:41:58 brad Exp $ */
+/* $OpenBSD: rbus_machdep.c,v 1.9 2009/04/28 18:37:13 kettenis Exp $ */
/* $NetBSD: rbus_machdep.c,v 1.2 1999/10/15 06:43:06 haya Exp $ */
/*
@@ -33,101 +33,39 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/device.h>
#include <sys/extent.h>
#include <uvm/uvm_extern.h>
-#include <sys/device.h>
-
#include <machine/bus.h>
#include <dev/cardbus/rbus.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
+#ifndef RBUS_MEM_START
+/* Avoid the ISA hole and everything below it. */
+#define RBUS_MEM_START 0x00100000
#endif
-#ifndef RBUS_MIN_START
-#define RBUS_MIN_START 0x40000000 /* 1 GB */
+#ifndef RBUS_IO_START
+/* Try to avoid onboard legacy devices; just a guess. */
+#define RBUS_IO_START 0xa000
#endif
-/*
- * 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.
- *
- * Thus, a general strategy of setting rbus_min_start to the amount of
- * memory seems in order. However, the actual 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;
- }
+struct rbustag rbus_null;
- /* 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, rbus_min_start;
+ struct extent *ex = pa->pa_memex;
+ bus_addr_t start;
bus_size_t size;
- extern struct extent *iomem_ex;
- struct extent *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.
- */
-
- rbus_min_start = rbus_min_start_hint();
- if (start < rbus_min_start)
- start = rbus_min_start;
+ if (ex == NULL)
+ return &rbus_null;
+ start = RBUS_MEM_START;
size = ex->ex_end - start;
return (rbus_new_root_share(pa->pa_memt, ex, start, size, 0));
@@ -136,13 +74,23 @@ rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa)
rbus_tag_t
rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa)
{
+ struct extent *ex = pa->pa_ioex;
bus_addr_t start;
bus_size_t size;
- extern struct extent *ioport_ex;
- struct extent *ex = ioport_ex;
- size = RBUS_IO_SIZE;
- start = RBUS_IO_START;
+ if (ex == NULL)
+ return &rbus_null;
+
+ start = ex->ex_start;
+ if (pa->pa_bridgetag == NULL) {
+ /*
+ * If we're not behind a PCI-PCI bridge, we must be on
+ * the root bus. To avoid conflicts with onboard
+ * legacy devices, we only make a subregion available.
+ */
+ start = max(start, RBUS_IO_START);
+ }
+ size = ex->ex_end - start;
return (rbus_new_root_share(pa->pa_iot, ex, start, size, 0));
}
@@ -151,4 +99,4 @@ void
pccbb_attach_hook(struct device *parent, struct device *self,
struct pci_attach_args *pa)
{
-}
+}