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