Index: apmbios.S
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/apmbios.S,v
retrieving revision 1.4
diff -u -w -r1.4 apmbios.S
--- apmbios.S	26 Dec 2005 10:35:51 -0000	1.4
+++ apmbios.S	3 May 2006 21:22:46 -0000
@@ -225,6 +225,7 @@
 APMSYM(05):
   cmp al, #0x05
   jne APMSYM(07)
+  sti
   hlt
   jmp APMSYM(ok)
 
Index: rombios.c
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/rombios.c,v
retrieving revision 1.160
diff -u -w -r1.160 rombios.c
--- rombios.c	25 Jan 2006 17:51:49 -0000	1.160
+++ rombios.c	3 May 2006 21:22:48 -0000
@@ -1816,6 +1816,7 @@
 {
   printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ",
     BIOS_BUILD_DATE, bios_cvs_version_string);
+#if 0
   printf(
 #ifdef BX_APM
   "apmbios "
@@ -1827,6 +1828,9 @@
   "eltorito "
 #endif
   "\n\n");
+#else
+  printf("apmbios pcibios eltorito \n\n");
+#endif
 }
 
 //--------------------------------------------------------------------------
@@ -3999,6 +4003,29 @@
 }
 #endif
 
+
+void set_e820_range(ES, DI, start, end, type)
+     Bit16u ES; 
+     Bit16u DI;
+     Bit32u start;
+     Bit32u end; 
+     Bit16u type;
+{
+    write_word(ES, DI, start);
+    write_word(ES, DI+2, start >> 16);
+    write_word(ES, DI+4, 0x00);
+    write_word(ES, DI+6, 0x00);
+    
+    end -= start;
+    write_word(ES, DI+8, end);
+    write_word(ES, DI+10, end >> 16);
+    write_word(ES, DI+12, 0x0000);
+    write_word(ES, DI+14, 0x0000);
+    
+    write_word(ES, DI+16, type);
+    write_word(ES, DI+18, 0x0);
+}
+
   void
 int15_function32(regs, ES, DS, FLAGS)
   pushad_regs_t regs; // REGS pushed via pushad
@@ -4063,19 +4090,8 @@
                 switch(regs.u.r16.bx)
                 {
                     case 0:
-                        write_word(ES, regs.u.r16.di, 0x00);
-                        write_word(ES, regs.u.r16.di+2, 0x00);
-                        write_word(ES, regs.u.r16.di+4, 0x00);
-                        write_word(ES, regs.u.r16.di+6, 0x00);
-
-                        write_word(ES, regs.u.r16.di+8, 0xFC00);
-                        write_word(ES, regs.u.r16.di+10, 0x0009);
-                        write_word(ES, regs.u.r16.di+12, 0x0000);
-                        write_word(ES, regs.u.r16.di+14, 0x0000);
-
-                        write_word(ES, regs.u.r16.di+16, 0x1);
-                        write_word(ES, regs.u.r16.di+18, 0x0);
-
+                        set_e820_range(ES, regs.u.r16.di, 
+                                       0x0000000L, 0x0009fc00L, 1);
                         regs.u.r32.ebx = 1;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
@@ -4083,6 +4099,24 @@
                         return;
                         break;
                     case 1:
+                        set_e820_range(ES, regs.u.r16.di, 
+                                       0x0009fc00L, 0x000a0000L, 2);
+                        regs.u.r32.ebx = 2;
+                        regs.u.r32.eax = 0x534D4150;
+                        regs.u.r32.ecx = 0x14;
+                        CLEAR_CF();
+                        return;
+                        break;
+                    case 2:
+                        set_e820_range(ES, regs.u.r16.di, 
+                                       0x000e8000L, 0x00100000L, 2);
+                        regs.u.r32.ebx = 3;
+                        regs.u.r32.eax = 0x534D4150;
+                        regs.u.r32.ecx = 0x14;
+                        CLEAR_CF();
+                        return;
+                        break;
+                    case 3:
                         extended_memory_size = inb_cmos(0x35);
                         extended_memory_size <<= 8;
                         extended_memory_size |= inb_cmos(0x34);
@@ -4092,9 +4126,9 @@
                             extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000
                         }
                         extended_memory_size *= 1024;
-                        extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off
+                        extended_memory_size += (16L * 1024 * 1024);
 
-                        if(extended_memory_size <= 15728640)
+                        if(extended_memory_size <= (16L * 1024 * 1024))
                         {
                             extended_memory_size = inb_cmos(0x31);
                             extended_memory_size <<= 8;
@@ -4102,28 +4136,23 @@
                             extended_memory_size *= 1024;
                         }
 
-                        write_word(ES, regs.u.r16.di, 0x0000);
-                        write_word(ES, regs.u.r16.di+2, 0x0010);
-                        write_word(ES, regs.u.r16.di+4, 0x0000);
-                        write_word(ES, regs.u.r16.di+6, 0x0000);
-
-                        write_word(ES, regs.u.r16.di+8, extended_memory_size);
-                        extended_memory_size >>= 16;
-                        write_word(ES, regs.u.r16.di+10, extended_memory_size);
-                        extended_memory_size >>= 16;
-                        write_word(ES, regs.u.r16.di+12, extended_memory_size);
-                        extended_memory_size >>= 16;
-                        write_word(ES, regs.u.r16.di+14, extended_memory_size);
-
-                        write_word(ES, regs.u.r16.di+16, 0x1);
-                        write_word(ES, regs.u.r16.di+18, 0x0);
-
-                        regs.u.r32.ebx = 0;
+                        set_e820_range(ES, regs.u.r16.di, 
+                                       0x00100000L, extended_memory_size, 1);
+                        regs.u.r32.ebx = 4;
                         regs.u.r32.eax = 0x534D4150;
                         regs.u.r32.ecx = 0x14;
                         CLEAR_CF();
                         return;
                         break;
+                    case 4:
+                        /* 256KB BIOS area at the end of 4 GB */
+                        set_e820_range(ES, regs.u.r16.di, 
+                                       0xfffc0000L, 0x00000000L, 2);
+                        regs.u.r32.ebx = 0;
+                        regs.u.r32.eax = 0x534D4150;
+                        regs.u.r32.ecx = 0x14;
+                        CLEAR_CF();
+                        return;
                     default:  /* AX=E820, DX=534D4150, BX unrecognized */
                         goto int15_unimplemented;
                         break;
@@ -8713,6 +8742,7 @@
   mov al, #0x80
 bios32_end:
   popf
+  and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu
   retf
 
 .align 16
@@ -8823,17 +8853,17 @@
 pci_pro_fail:
   pop edi
   pop esi
-  sti
   popf
   stc
+  and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu
   retf
 pci_pro_ok:
   xor ah, ah
   pop edi
   pop esi
-  sti
   popf
   clc
+  and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu
   retf
 
 pci_pro_select_reg:
@@ -8971,7 +9001,7 @@
   jmp pci_real_ok
 pci_real_f0d: ;; write configuration dword
   cmp al, #0x0d
-  jne pci_real_unknown
+  jne pci_real_f0e
   call pci_real_select_reg
   push dx
   mov dx, #0x0cfc
@@ -8979,6 +9009,46 @@
   out dx, eax
   pop dx
   jmp pci_real_ok
+pci_real_f0e: ;; get irq routing options
+  cmp al, #0x0e
+  jne pci_real_unknown
+  SEG ES
+  cmp word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start
+  jb pci_real_too_small    
+  SEG ES
+  mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start        
+  pushf
+  push ds
+  push es
+  push cx
+  push si
+  push di
+  cld
+  mov si, #pci_routing_table_structure_start
+  push cs
+  pop ds
+  SEG ES
+  mov cx, [di+2]
+  SEG ES
+  mov es, [di+4]
+  mov di, cx
+  mov cx, #pci_routing_table_structure_end - pci_routing_table_structure_start
+  rep 
+      movsb
+  pop di
+  pop si
+  pop cx
+  pop es
+  pop ds
+  popf
+  mov bx, #(1 << 9) | (1 << 11)   ;; irq 9 and 11 are used
+  jmp pci_real_ok
+pci_real_too_small:
+  SEG ES
+  mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start        
+  mov ah, #0x89
+  jmp pci_real_fail
+
 pci_real_unknown:
   mov ah, #0x81
 pci_real_fail:
@@ -9019,6 +9089,7 @@
   dw 0,0 ;; Miniport data
   db 0,0,0,0,0,0,0,0,0,0,0 ;; reserved
   db 0x07 ;; checksum
+pci_routing_table_structure_start:
   ;; first slot entry PCI-to-ISA (embedded)
   db 0 ;; pci bus number
   db 0x08 ;; pci device number (bit 7-3)
@@ -9097,6 +9168,7 @@
   dw 0xdef8 ;; IRQ bitmap INTD#
   db 5 ;; physical slot (0 = embedded)
   db 0 ;; reserved
+pci_routing_table_structure_end:
 
 pci_irq_list:
   db 11, 10, 9, 5;
