Make amd64/i386 boot(8) work when 64KB

2012-09-30 Thread Joel Sing
The amd64/i386 boot(8) code runs in protected mode, however switches back
to real mode for BIOS calls. The real mode code uses a scratch area located
in the BSS section to load/store registers across BIOS calls. However, once
the BSS moves beyond an offset of 0x (a logical address of 0x5
since the base is 0x4) it is inaccessible from the real mode code and
results in access failures.

The following diff removes this restriction by loading the necessary registers
(ES, BX) from the scratch area while still in protected mode, then patching
them into the real mode instructions. The same is done when returning from
real mode to protected mode, allowing the registers to be preserved and then
stored into the scratch area from protected mode.

This has been tested on amd64 and i386, however it needs further testing to
ensure that it does not introduce any unexpected regressions. Please report
successes or failures directly to me.

ok?

Index: arch/amd64/stand/libsa/gidt.S
===
RCS file: /cvs/src/sys/arch/amd64/stand/libsa/gidt.S,v
retrieving revision 1.6
diff -u -p -r1.6 gidt.S
--- arch/amd64/stand/libsa/gidt.S   29 Dec 2006 11:44:01 -  1.6
+++ arch/amd64/stand/libsa/gidt.S   29 Sep 2012 16:15:11 -
@@ -312,6 +312,10 @@ IEMUENT(44); IEMUENT(45); IEMUENT(46); I
  * entry point for BIOS real-mode interface
  * all the magic for real-prot mode switching is here
  *
+ * Note: Once in real mode access to .data or .bss should be avoided since it
+ * may not be reachable within the current segment. The code also assumes that
+ * .text is writeable.
+ *
  * Call:   %eax, %ecx, %edx, %ebx, %ebp, %esi, %edi, %es, %ds
  * Return: %eax, %edx, %ecx, %eflags (as returned from BIOS)
  *
@@ -320,7 +324,7 @@ IEMUENT(44); IEMUENT(45); IEMUENT(46); I
.align  8, 0x90
 EMUh:
/* save %eax */
-   mov %eax, 3f
+   mov %eax, 5f
pop %eax
 
pusha
@@ -332,18 +336,29 @@ EMUh:
/* save BIOS int vector */
mov %al, intno
 
+   /* Load BIOS registers prior to switching to real mode. */
+   movl _C_LABEL(BIOS_regs)+BIOSR_ES, %eax
+   mov %eax, 7f
+   movl _C_LABEL(BIOS_regs)+BIOSR_DS, %eax
+   mov %eax, 6f
+
prot2real
 
push%ds
 
-   addr32  movw (_C_LABEL(BIOS_regs)+(BIOSR_ES) - LINKADDR), %ax
-   movw%ax, %es
-   addr32  movw (_C_LABEL(BIOS_regs)+(BIOSR_DS) - LINKADDR), %ax
-   movw%ax, %ds
+   # data32 movl $Leax, %eax
+   .byte   0x66, 0xb8
+7: .long   0x90909090
+   mov %ax, %es
+
+   # data32 movl $Leax, %eax
+   .byte   0x66, 0xb8
+6: .long   0x90909090
+   mov %ax, %ds
 
# data32 movl $Leax, %eax
.byte   0x66, 0xb8
-3: .long   0x90909090
+5: .long   0x90909090
 
;sti
int $0
@@ -352,19 +367,35 @@ intno = . - 1
 
pop %ds
 
-   addr32 movl %ebx, (_C_LABEL(BIOS_regs)+(BIOSR_BX) - LINKADDR)
-   movw%es, %bx
-   addr32 movw %bx, (_C_LABEL(BIOS_regs)+(BIOSR_ES) - LINKADDR)
+   /* Preserve BX and ES for protected mode. */
+   addr32 movl %eax, (2f - LINKADDR)
+   movl%ebx, %eax
+   addr32 movl %eax, (4f - LINKADDR)
+   movl%es, %eax
+   addr32 movl %eax, (3f - LINKADDR)
+   addr32 movl (2f - LINKADDR), %eax
+
movb%ah, %bh
lahf
xchgb   %ah, %bh
 
+   /* Preserve AX for protected mode. */
addr32 movl %eax, (2f - LINKADDR)
 
real2prot
 
# movl $Leax, %eax
.byte 0xb8
+4: .long 0x90909090
+   movl%eax, _C_LABEL(BIOS_regs)+BIOSR_BX
+
+   # movl $Leax, %eax
+   .byte 0xb8
+3: .long 0x90909090
+   movl%eax, _C_LABEL(BIOS_regs)+BIOSR_ES
+
+   # movl $Leax, %eax
+   .byte 0xb8
 2: .long 0x90909090
 
/* pass BIOS return values back to caller */
Index: arch/i386/stand/libsa/gidt.S
===
RCS file: /cvs/src/sys/arch/i386/stand/libsa/gidt.S,v
retrieving revision 1.32
diff -u -p -r1.32 gidt.S
--- arch/i386/stand/libsa/gidt.S26 Dec 2006 19:30:44 -  1.32
+++ arch/i386/stand/libsa/gidt.S29 Sep 2012 16:15:11 -
@@ -314,6 +314,10 @@ IEMUENT(44); IEMUENT(45); IEMUENT(46); I
  * entry point for BIOS real-mode interface
  * all the magic for real-prot mode switching is here
  *
+ * Note: Once in real mode access to .data or .bss should be avoided since it
+ * may not be reachable within the current segment. The code also assumes that
+ * .text is writeable.
+ *
  * Call:   %eax, %ecx, %edx, %ebx, %ebp, %esi, %edi, %es, %ds
  * Return: %eax, %edx, %ecx, %eflags (as returned from BIOS)
  *
@@ -322,7 +326,7 @@ IEMUENT(44); IEMUENT(45); IEMUENT(46); I
.align  8, 0x90
 EMUh:
/* save %eax */
-   mov %eax, 3f
+   mov %eax, 5f
pop %eax
 

Re: ral rt2661 tx interrupt race fix

2012-09-30 Thread Tom Murphy
Stefan,

  Your patch works well on my system:

  ral0 at pci0 dev 14 function 0 Ralink RT2661 rev 0x00: irq 10, address 
  00:14:85:d5:39:bb
  ral0: MAC/BBP RT2661D, RF RT2529 (MIMO XR)

  Only problem is downloading from the net is extremely slow. Benchmarks
  have it at 512 KB/sec as opposed to 10 megabits/s.

  This is (internet) - OpenBSD - ral0 - wifi client

  But it doesn't crash or bring up OACTIVE flag anymore which is
  fantastic.. however, it's a little to slow to use with any regularity.

  Uploads are fine (wifi - ral(4) - OpenBSD - out to the net). 

  Tom