Subject: heuristic for RBUS
To: None <port-i386@netbsd.org>
From: Greg Troxel <gdt@ir.bbn.com>
List: port-i386
Date: 01/06/2007 11:29:48
Long ago, I found that cardbus wouldn't work on my Thinkpad 600E, and
with help from the list determined that setting RBUS_MIN_START to 0.5
GB resulted in success; apparently mapped memory at 1 GB doesn't
really work. This summer, I found that 1 GB is a bad value for
a Thinkpad T43p with 2 GB of RAM, and also for my T60 with 2 GB.
The following patch changes the logic to choose a value for
rbus_min_start based on the amount of installed memory.
If RBUS_MIN_START is defined, it is respected.
Otherwise, the default remains at 1 GB. Then for machines <= 192 MB,
0.5 GB is used. For machines 1 >GB, 2 GB is used.
I believe that this will increase the number of machines on which
cardbus works out of the box, and break very few.
Is this ok to commit?
Index: share/man/man4/cardbus.4
===================================================================
RCS file: /cvsroot/src/share/man/man4/cardbus.4,v
retrieving revision 1.28
diff -u -u -r1.28 cardbus.4
--- share/man/man4/cardbus.4 7 Oct 2006 23:35:39 -0000 1.28
+++ share/man/man4/cardbus.4 6 Jan 2007 16:19:06 -0000
@@ -34,7 +34,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd October 7, 2006
+.Dd January 6, 2007
.Dt CARDBUS 4
.Os
.Sh NAME
@@ -174,10 +174,15 @@
abstraction.
When the mapping does not work, PCMCIA cards are typically ignored on
insert, and Cardbus cards are recognized but nonfunctional.
-The location is machine-specific, and the default location does not
-work on all hardware.
-On i386, the following kernel configuration line, which maps Cardbus
-space at 512M rather than 1GB, has been found to make Cardbus support
+On i386, the kernel has a heuristic to choose a memory address for
+mapping, defaulting to 1 GB, but choosing 0.5 GB on machines with less
+than 192 MB RAM and 2 GB on machines with more than 1 GB of RAM.
+The intent is to use an address that is larger than available RAM, but
+low enough to work; some systems seem to have trouble with
+addresses requiring more than 20 address lines.
+On i386, the following kernel configuration line disables the
+heuristics and forces Cardbus
+memory space to be mapped at 512M; this value makes Cardbus support
(including PCMCIA attachment under a cbb) work on some notebook
models, including the IBM Thinkpad 600E (2645-4AU) and the Compaq
ARMADA M700:
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.588
diff -u -u -r1.588 machdep.c
--- sys/arch/i386/i386/machdep.c 5 Jan 2007 04:07:23 -0000 1.588
+++ sys/arch/i386/i386/machdep.c 6 Jan 2007 16:19:07 -0000
@@ -191,6 +191,14 @@
#include "npx.h"
#include "ksyms.h"
+#include "cardbus.h"
+#if NCARDBUS > 0
+/* For rbus_min_start hint. */
+#include <machine/bus.h>
+#include <dev/cardbus/rbus.h>
+#include <machine/rbus_machdep.h>
+#endif
+
#include "mca.h"
#if NMCA > 0
#include <machine/mca_machdep.h> /* for mca_busprobe() */
@@ -446,6 +454,11 @@
format_bytes(pbuf, sizeof(pbuf), ptoa(physmem));
printf("total memory = %s\n", pbuf);
+#if NCARDBUS > 0
+ /* Tell RBUS how much RAM we have, so it can use heuristics. */
+ rbus_min_start_hint(ptoa(physmem));
+#endif
+
minaddr = 0;
/*
Index: sys/arch/i386/i386/rbus_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/rbus_machdep.c,v
retrieving revision 1.18
diff -u -u -r1.18 rbus_machdep.c
--- sys/arch/i386/i386/rbus_machdep.c 11 Dec 2005 12:17:41 -0000 1.18
+++ sys/arch/i386/i386/rbus_machdep.c 6 Jan 2007 16:19:07 -0000
@@ -65,10 +65,62 @@
#ifndef RBUS_MIN_START
#define RBUS_MIN_START 0x40000000 /* 1GB */
+#else
+/*
+ * Note that kernel config forced RBUS_MIN_START.
+ */
+#define RBUS_MIN_START_FORCED
#endif
bus_addr_t rbus_min_start = RBUS_MIN_START;
/*
+ * 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 actually amount of memory is
+ * generally slightly more than the amount found, e.g. 1014MB vs 1024,
+ * or 2046 vs 2048.
+ */
+void
+rbus_min_start_hint(size_t ram)
+{
+#ifdef RBUS_MIN_START_FORCED
+ printf("rbus: rbus_min_start from config at 0x%0lx\n", rbus_min_start);
+
+#else
+ if (ram <= 192*1024*1024UL) {
+ /*
+ * <= 192 MB, so try 0.5 GB. This will work on Thinkpad
+ * 600E (2645-4AU), which fails at 1GB, 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) {
+ /*
+ * >= 1GB, so try 2 GB.
+ */
+ rbus_min_start = 2 * 1024 * 1024 * 1024UL;
+ }
+
+ /*
+ * XXX For machines with more than 2G, the right choice is not
+ * clear.
+ */
+
+ printf("rbus: rbus_min_start set to 0x%0lx\n", rbus_min_start);
+#endif
+}
+
+
+/*
* rbus_tag_t rbus_fakeparent_mem(struct pci_attach_args *pa)
*
* This function makes an rbus tag for memory space. This rbus tag
Index: sys/arch/i386/include/rbus_machdep.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/rbus_machdep.h,v
retrieving revision 1.6
diff -u -u -r1.6 rbus_machdep.h
--- sys/arch/i386/include/rbus_machdep.h 26 Feb 2003 21:29:03 -0000 1.6
+++ sys/arch/i386/include/rbus_machdep.h 6 Jan 2007 16:19:07 -0000
@@ -46,4 +46,6 @@
rbus_tag_t rbus_pccbb_parent_io(struct pci_attach_args *);
rbus_tag_t rbus_pccbb_parent_mem(struct pci_attach_args *);
+void rbus_min_start_hint(size_t);
+
#endif /* _ARCH_I386_I386_RBUS_MACHDEP_H_ */