Hi, As I reported some days ago in
http://marc.theaimsgroup.com/?l=linux-kernel&m=100876129529834&q=raw there are boot problems with new kernels on AMD SC410 processors. Symptom is that the machine reboots right in the middle of the initialisation of the serial port (indeed, right in the middle of a printk message). In the meantime I've tracked down the problem, but cannot fully find the origin. Here are some facts: - The problem came in in 2.4.15. Linus has merged in some changes to the boot code by H. Peter Anvin (which basically are a Good Thing(TM)). They affect arch/i386/boot/setup.S. - I could narrow it down to the A20 gate routines. My machine's BIOS doesn't seem to have the appropiate routine, so the algorithm falls back to using the keyboard controller method (which was also used in the old code). - The problem seems to come from the code that waits for A20 gate to be _really_ enabled (shortly after a20_kbc:). Attached is a experimental patch which demonstrates the problem: in line 687 you can change with a jump to "old_wait" or "new_wait" which routine shall be used. With the old one the machine starts, with the new one it reboots. I must say I do not really understand what the problem is. First I thought that maybe the loop counter overruns, but it doesn't seem to happen. I have written the counter value to a port with LEDs and it seems to contain "1" when the waiting loop detects the successful A20 switch. Any idea would be helpful... Robert -- +--------------------------------------------------------+ | Dipl.-Ing. Robert Schwebel | http://www.pengutronix.de | | Pengutronix - Linux Solutions for Science and Industry | | Braunschweiger Str. 79, 31134 Hildesheim, Germany | | Phone: +49-5121-28619-0 | Fax: +49-5121-28619-4 | +--------------------------------------------------------+
--- setup-2.4.15.S Fri Nov 9 22:58:02 2001 +++ setup.S Fri Dec 21 21:49:50 2001 @@ -684,6 +684,62 @@ outb %al, $0x60 call empty_8042 + jmp new_wait + +# ----- old wait routine ----- + +old_wait: + +# wait until a20 really *is* enabled; it can take a fair amount of +# time on certain systems; Toshiba Tecras are known to have this +# problem. The memory location used here (0x200) is the int 0x80 +# vector, which should be safe to use. + + + pushw %dx + pushw %cx + xorw %dx,%dx + xorw %cx,%cx + + xorw %ax, %ax # segment 0x0000 + movw %ax, %fs + decw %ax # segment 0xffff (HMA) + movw %ax, %gs +a20_wait_old: + incw %cx + jnz goon + incw %dx +goon: + incw %ax # unused memory location <0xfff0 + movw %ax, %fs:(0x200) # we use the "int 0x80" vector + cmpw %gs:(0x210), %ax # and its corresponding HMA addr + je a20_wait_old # loop until no longer aliased + + pushw %ax + + movb $0xa5,%al # select PAMR... + outb %al,$0x22 # ... via CSCIR + movb $0xff,%al # all lines are output + outb %al,$0x23 # ... on CSCDR + + movb $0xa9,%al # select PADR... + outb %al,$0x22 # ... via CSCIR + movb %ch,%al # + outb %al,$0x23 + + popw %ax + + + + popw %cx + popw %dx + + jmp rs_wait_done + +# ----- new wait routine ----- + +new_wait: + # Wait until a20 really *is* enabled; it can take a fair amount of # time on certain systems; Toshiba Tecras are known to have this # problem. @@ -694,6 +750,10 @@ jnz a20_done loop a20_kbc_wait_loop +rs_wait_done: + +# ----- end of wait ----- + # Final attempt: use "configuration port A" a20_fast: inb $0x92, %al # Configuration Port A @@ -909,12 +969,12 @@ pushw %cx pushw %ax xorw %cx, %cx - movw %cx, %fs # Low memory + movw %cx, %fs # Low memory (segment 0x0000) decw %cx - movw %cx, %gs # High memory area + movw %cx, %gs # High memory area (segment 0xffff) movw $A20_TEST_LOOPS, %cx - movw %fs:(A20_TEST_ADDR), %ax - pushw %ax + movw %fs:(A20_TEST_ADDR), %ax # put content of test address... + pushw %ax # ... on stack a20_test_wait: incw %ax movw %ax, %fs:(A20_TEST_ADDR)