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);