From c003148bb390f928acdc76ad77d787aa0e476013 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 1 Jan 2010 13:03:17 -0500 Subject: [PATCH 1/1] Implement native 32bit APM support. Add APM code to 32bit segmented code. Use 32bit APM code instead of jumping into 16bit mode. --- Makefile | 2 +- src/apm.c | 18 +++++++++++++++- src/config.h | 1 + src/romlayout.S | 57 +++++++++++-------------------------------------- src/util.h | 2 +- 5 files changed, 33 insertions(+), 47 deletions(-) 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); -- 2.25.1