Port-amd64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: HP BL465c G7 (2x Opteron 6172) doesn't boot install CD
Probably this is a problem with A20 and the keyboard controller
Can you try this patch, it is not well-tested especially not on different
motherboards but it got a DL385 G7 to load a kernel some time ago (it
still had problems, but could at least load the kernel and start finding
devices).
The patch is loosely based on what linux does, I picked the same
adress to test, on the assumption it is a safe adress.
If someone who knows more about gate A20 can clean up this mess
I would be grateful.
This is a patch against current, it may not apply cleanly to 5.1,
in particular, i think the patch for cpufunc.S should be removed for 5.1
Also the bootroms will become too big so just try building the boot program
you need.
Index: sys/arch/i386/stand/lib/cpufunc.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/cpufunc.S,v
retrieving revision 1.4
diff -u -r1.4 cpufunc.S
--- sys/arch/i386/stand/lib/cpufunc.S 8 Jun 2011 16:03:42 -0000 1.4
+++ sys/arch/i386/stand/lib/cpufunc.S 2 Nov 2011 22:09:09 -0000
@@ -150,3 +150,7 @@
outsl
popl %esi
ret
+
+NENTRY(wbinvd)
+ wbinvd
+ ret
Index: sys/arch/i386/stand/lib/cpufunc.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/cpufunc.h,v
retrieving revision 1.2
diff -u -r1.2 cpufunc.h
--- sys/arch/i386/stand/lib/cpufunc.h 28 Apr 2008 20:23:25 -0000 1.2
+++ sys/arch/i386/stand/lib/cpufunc.h 2 Nov 2011 22:09:09 -0000
@@ -47,3 +47,5 @@
void outsw(unsigned, void *, int);
void outl(unsigned, uint32_t);
void outsl(unsigned, void *, int);
+
+void wbinvd(void);
Index: sys/arch/i386/stand/lib/gatea20.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/gatea20.c,v
retrieving revision 1.12
diff -u -r1.12 gatea20.c
--- sys/arch/i386/stand/lib/gatea20.c 23 Aug 2009 12:31:05 -0000 1.12
+++ sys/arch/i386/stand/lib/gatea20.c 2 Nov 2011 22:09:09 -0000
@@ -25,6 +25,10 @@
enable data line
disable clock line */
+static void gateA20_92(void);
+static void gateA20_kbd(void);
+static int testa20(void);
+
/*
* Gate A20 for high memory
*/
@@ -34,7 +38,16 @@
gateA20(void)
{
int biosA20(void);
- u_long psl;
+
+ /*
+ * First, check if A2 is enabled.
+ */
+ printf("Test if A20 is already enabled\n");
+ if (testa20()) {
+ printf("A20 already enabled\n");
+ return;
+ }
+ printf("A20 is not already enabled\n");
/*
* First, try asking the BIOS to enable A20.
@@ -45,36 +58,130 @@
* and playing with port 0x92 may cause some systems to break.
*
* Otherwise, use the traditional method (keyboard controller).
+ * If that fails try port 0x92 anyway.
*/
- if (!biosA20())
- return;
- psl = x86_read_psl();
- x86_disable_intr();
+ unsigned temp;
+
+ printf("Try biosA20\n");
+ temp = biosA20();
+ if (!temp) {
+ if (testa20()) {
+ printf("A20 biosA20 ok\n");
+ return;
+ }
+ printf("A20 nok\n");
+ } else {
+ printf("biosA20 fail\n");
+ }
+
if (
#ifdef SUPPORT_PS2
biosmca_ps2model == 0xf82 ||
#endif
(inb(K_STATUS) == 0xff && inb(K_RDWR) == 0xff)) {
- int data;
+ gateA20_92();
+ if (testa20()) {
+ printf("A20 92 ok\n");
+ return;
+ }
+ }
- data = inb(0x92);
- outb(0x92, data | 0x2);
+ gateA20_kbd();
+ if (testa20()) {
+ printf("A20 kbd ok\n");
+ return;
} else {
- while (inb(K_STATUS) & K_IBUF_FUL);
+ printf("A20 kbd nok\n");
+ }
- while (inb(K_STATUS) & K_OBUF_FUL)
- (void)inb(K_RDWR);
+ gateA20_92();
+ if (testa20()) {
+ printf("A20 92 ok\n");
+ return;
+ } else {
+ printf("A20 92 nok\n");
+ }
+ printf("failed to enable A20, reboot\n");
- outb(K_CMD, KC_CMD_WOUT);
+ delay(10000);
+ reboot();
+}
- while (inb(K_STATUS) & K_IBUF_FUL);
+void
+gateA20_92(void)
+{
+ u_long psl;
+ int data;
- outb(K_RDWR, x_20);
+ psl = x86_read_psl();
+ x86_disable_intr();
- while (inb(K_STATUS) & K_IBUF_FUL);
+ data = inb(0x92);
+ outb(0x92, data | 0x2);
+ x86_write_psl(psl);
+}
+
+static void
+gateA20_kbd(void)
+{
+ u_long psl;
+
+ psl = x86_read_psl();
+ x86_disable_intr();
+
+ while (inb(K_STATUS) & K_IBUF_FUL);
+
+ while (inb(K_STATUS) & K_OBUF_FUL)
+ (void)inb(K_RDWR);
+
+ outb(K_CMD, KC_CMD_WOUT);
+
+ while (inb(K_STATUS) & K_IBUF_FUL);
+
+ outb(K_RDWR, x_20);
+
+ while (inb(K_STATUS) & K_IBUF_FUL);
+
+ while (inb(K_STATUS) & K_OBUF_FUL)
+ (void)inb(K_RDWR);
- while (inb(K_STATUS) & K_OBUF_FUL)
- (void)inb(K_RDWR);
- }
x86_write_psl(psl);
}
+
+/*
+ * Test if A20 is enabled
+ * Returns 1 if A20 is enabled.
+ */
+static int
+testa20x(void)
+{
+ short *lo = (short *)0x200;
+ short * volatile hi = (short *)0x100200;
+ short oldval = *lo;
+ short i;
+
+ for (i = 0; i < 32; i++) {
+ *lo = i;
+ wbinvd();
+ if (*hi != i) {
+ *lo = oldval;
+ return 1;
+ }
+ }
+ *lo = oldval;
+ return 0;
+}
+static int
+testa20(void)
+{
+ int j;
+
+ for (j = 0; j < 10; j++) {
+ if (testa20x()) {
+ printf("testa20: %d iter\n", j);
+ return 1;
+ }
+ }
+ printf("testa20: failed\n");
+ return 0;
+}
Home |
Main Index |
Thread Index |
Old Index