[SeaBIOS] [PATCH] Implement native 32bit APM support

Kevin O'Connor kevin at koconnor.net
Fri Jan 1 19:11:22 CET 2010


The current code jumps into 16bit mode when the 32bit APM entry point
is called.  Now that there is a 32bit segmented code section (for pci
bios), add the apm code there so the jump to 16bit mode can be
avoided.


diff --git a/Makefile b/Makefile
index b71d1a1..a4463bd 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ SRC16=$(SRCBOTH) system.c disk.c apm.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
       lzmadecode.c
-SRC32SEG=util.c output.c pci.c pcibios.c
+SRC32SEG=util.c output.c pci.c pcibios.c apm.c
 
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
               /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
diff --git a/src/apm.c b/src/apm.c
index 86d5051..f30c22c 100644
--- a/src/apm.c
+++ b/src/apm.c
@@ -189,7 +189,7 @@ handle_1553XX(struct bregs *regs)
     set_unimplemented(regs);
 }
 
-void VISIBLE16
+void
 handle_1553(struct bregs *regs)
 {
     if (! CONFIG_APMBIOS) {
@@ -216,3 +216,19 @@ handle_1553(struct bregs *regs)
     default:   handle_1553XX(regs); break;
     }
 }
+
+void VISIBLE16
+handle_apm16(struct bregs *regs)
+{
+    debug_enter(regs, DEBUG_HDL_apm);
+    handle_1553(regs);
+}
+
+#if MODE16 == 0 && MODESEGMENT == 1
+void VISIBLE32SEG
+handle_apm32(struct bregs *regs)
+{
+    debug_enter(regs, DEBUG_HDL_apm);
+    handle_1553(regs);
+}
+#endif
diff --git a/src/config.h b/src/config.h
index 1450bf7..58c0ffc 100644
--- a/src/config.h
+++ b/src/config.h
@@ -193,6 +193,7 @@
 #define DEBUG_HDL_pnp 1
 #define DEBUG_HDL_pmm 1
 #define DEBUG_HDL_pcibios32 9
+#define DEBUG_HDL_apm 9
 
 #define DEBUG_unimplemented 2
 #define DEBUG_invalid 3
diff --git a/src/romlayout.S b/src/romlayout.S
index 43af112..54e5a4d 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -348,7 +348,7 @@ entry_pnp_real:
 apm16protected_entry:
         pushfw          // save flags
         pushl %eax      // dummy
-        ENTRY_ARG handle_1553
+        ENTRY_ARG handle_apm16
         addw $4, %sp    // pop dummy
         popfw           // restore flags
         lretw
@@ -356,55 +356,24 @@ apm16protected_entry:
         .code32
         DECLFUNC apm32protected_entry
 apm32protected_entry:
-        pushfw
-        pushw %cs       // Setup for long jump to 16bit mode
-        pushw $1f
-        addw $8, 2(%esp)
-        ljmpw *(%esp)
-        .code16gcc
-1:
-        ENTRY_ARG_ESP handle_1553
-
-        movw $2f,(%esp) // Setup for long jump back to 32bit mode
-        subw $8, 2(%esp)
-        ljmpw *(%esp)
-        .code32
-2:
-        addl $4, %esp   // pop call address
-        popfw
+        pushfl
+        pushl %gs
+        pushl %cs               // Move second descriptor after %cs to %gs
+        addl $16, (%esp)
+        popl %gs
+        ENTRY_ARG_ESP handle_apm32
+        popl %gs
+        popfl
         lretl
 
 // PCI-BIOS 32bit entry point
         DECLFUNC pcibios32_entry
 pcibios32_entry:
         pushfl
-        pushl %gs               // Backup %gs
-        cli
-        cld
-        pushl %eax              // Save registers (matches struct bregs)
-        pushl %ecx
-        pushl %edx
-        pushl %ebx
-        pushl %ebp
-        pushl %esi
-        pushl %edi
-        pushw %es
-        pushw %ds
-        movl %ds, %eax          // Move %ds to %gs
-        movl %eax, %gs
-        movl %ss, %eax          // Move %ss to %ds
-        movl %eax, %ds
-        movl %esp, %eax         // First arg is pointer to struct bregs
-        calll handle_pcibios32
-        popw %ds                // Restore registers (from struct bregs)
-        popw %es
-        popl %edi
-        popl %esi
-        popl %ebp
-        popl %ebx
-        popl %edx
-        popl %ecx
-        popl %eax
+        pushl %gs               // Backup %gs and set %gs=%ds
+        pushl %ds
+        popl %gs
+        ENTRY_ARG_ESP handle_pcibios32
         popl %gs
         popfl
         lretl
diff --git a/src/util.h b/src/util.h
index 7117fa5..f4593ae 100644
--- a/src/util.h
+++ b/src/util.h
@@ -264,7 +264,7 @@ void useRTC();
 void releaseRTC();
 
 // apm.c
-void VISIBLE16 handle_1553(struct bregs *regs);
+void handle_1553(struct bregs *regs);
 
 // pcibios.c
 void handle_1ab1(struct bregs *regs);



More information about the SeaBIOS mailing list