Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/stacks.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/src/stacks.c b/src/stacks.c index 0c033d1..c6b7e8b 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -63,6 +63,11 @@ call32_smm_post(void) inb(PORT_CMOS_DATA); }
+#define ASM32_SWITCH16 " .code16\n" +#define ASM32_BACK32 " .code32\n" +#define ASM16_SWITCH32 " .code32\n" +#define ASM16_BACK16 " .code16gcc\n" + // Call a SeaBIOS C function in 32bit mode using smm trampoline static u32 call32_smm(void *func, u32 eax) @@ -85,8 +90,8 @@ call32_smm(void *func, u32 eax) " outb %%al, $" __stringify(PORT_SMI_CMD) "\n" " rep; nop\n" " hlt\n" - " .code32\n"
+ ASM16_SWITCH32 "1:movl %1, %%eax\n" " calll *%2\n" " movl %%eax, %1\n" @@ -99,7 +104,7 @@ call32_smm(void *func, u32 eax) " hlt\n"
// Restore esp - " .code16gcc\n" + ASM16_BACK16 "2:movl %0, %%esp\n" : "=&r" (bkup_esp), "+r" (eax) : "r" (func) @@ -143,7 +148,7 @@ call16_smm(u32 eax, u32 edx, void *func) " rep; nop\n" " hlt\n"
- " .code16\n" + ASM32_SWITCH16 "1:movl %1, %%eax\n" " movl %3, %%ecx\n" " calll _cfunc16_call16_smm_helper\n" @@ -157,7 +162,7 @@ call16_smm(u32 eax, u32 edx, void *func) " hlt\n"
// Set esp to flat stack location - " .code32\n" + ASM32_BACK32 "2:addl %0, %%esp\n" : "+r" (stackoffset), "+r" (eax), "+d" (edx) : "r" (func) @@ -232,13 +237,13 @@ call32_sloppy(void *func, u32 eax) // Transition to 32bit mode, call func, return to 16bit " movl $(" __stringify(BUILD_BIOS_ADDR) " + 1f), %%edx\n" " jmp transition32\n" - " .code32\n" + ASM16_SWITCH32 "1:calll *%3\n" " movl $2f, %%edx\n" " jmp transition16big\n"
// Restore ds/ss/esp - " .code16gcc\n" + ASM16_BACK16 "2:movl %0, %%ds\n" " movl %0, %%ss\n" " movl %1, %%esp\n" @@ -273,7 +278,7 @@ call16_sloppy(u32 eax, u32 edx, void *func) " movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n" " jmp transition16big\n" // Setup ss/esp and call func - " .code16\n" + ASM32_SWITCH16 "1:movl %3, %%ecx\n" " shll $4, %3\n" " movw %%cx, %%ss\n" @@ -285,7 +290,7 @@ call16_sloppy(u32 eax, u32 edx, void *func) // Return to 32bit and restore esp " movl $2f, %%edx\n" " jmp transition32\n" - " .code32\n" + ASM32_BACK32 "2:addl %3, %%esp\n" : "+a" (eax) : "r" (func), "r" (edx), "r" (stackseg) @@ -320,13 +325,13 @@ call16(u32 eax, u32 edx, void *func) " movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n" " jmp transition16\n" // Call func - " .code16\n" + ASM32_SWITCH16 "1:movl %2, %%edx\n" " calll *%1\n" // Return to 32bit " movl $2f, %%edx\n" " jmp transition32\n" - " .code32\n" + ASM32_BACK32 "2:\n" : "+a" (eax) : "r" (func), "r" (edx) @@ -347,13 +352,13 @@ call16big(u32 eax, u32 edx, void *func) " movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n" " jmp transition16big\n" // Call func - " .code16\n" + ASM32_SWITCH16 "1:movl %2, %%edx\n" " calll *%1\n" // Return to 32bit " movl $2f, %%edx\n" " jmp transition32\n" - " .code32\n" + ASM32_BACK32 "2:\n" : "+a" (eax) : "r" (func), "r" (edx)
The FUNCFSEG macro was introduced to force a C function into the f-segment. This was needed for some C functions that used inline assembler that contained some 16bit code. Instead of forcing the entire C function into the f-segment, just force the small subset of inline assembler into the f-segment.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/stacks.c | 12 ++++++------ src/types.h | 4 ---- 2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/stacks.c b/src/stacks.c index c6b7e8b..b2e2447 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -63,8 +63,8 @@ call32_smm_post(void) inb(PORT_CMOS_DATA); }
-#define ASM32_SWITCH16 " .code16\n" -#define ASM32_BACK32 " .code32\n" +#define ASM32_SWITCH16 " .pushsection .text.fseg." UNIQSEC "\n .code16\n" +#define ASM32_BACK32 " .popsection\n .code32\n" #define ASM16_SWITCH32 " .code32\n" #define ASM16_BACK16 " .code16gcc\n"
@@ -127,7 +127,7 @@ call16_smm_helper(u32 eax, u32 edx, u32 (*func)(u32 eax, u32 edx)) return ret; }
-u32 FUNCFSEG +static u32 call16_smm(u32 eax, u32 edx, void *func) { ASSERT32FLAT(); @@ -265,7 +265,7 @@ call16_sloppy_helper(u32 eax, u32 edx, u32 (*func)(u32 eax, u32 edx)) }
// Jump back to 16bit mode while in 32bit mode from call32_sloppy() -u32 FUNCFSEG +static u32 call16_sloppy(u32 eax, u32 edx, void *func) { ASSERT32FLAT(); @@ -313,7 +313,7 @@ call32(void *func, u32 eax, u32 errret) }
// Call a 16bit SeaBIOS function from a 32bit SeaBIOS function. -u32 FUNCFSEG +static u32 call16(u32 eax, u32 edx, void *func) { ASSERT32FLAT(); @@ -340,7 +340,7 @@ call16(u32 eax, u32 edx, void *func) }
// Call a 16bit SeaBIOS function in "big real" mode. -u32 FUNCFSEG +static u32 call16big(u32 eax, u32 edx, void *func) { ASSERT32FLAT(); diff --git a/src/types.h b/src/types.h index 6dd8c43..097372c 100644 --- a/src/types.h +++ b/src/types.h @@ -70,8 +70,6 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VARFSEG __section(".discard.varfseg." UNIQSEC) __VISIBLE __weak // Designate a variable at a specific address in the f-segment. # define VARFSEGFIXED(addr) __section(".discard.varfixed." UNIQSEC) __VISIBLE __weak -// Notes a 32bit flat function that must reside in the f-segment. -# define FUNCFSEG __section(".discard.32fseg." UNIQSEC) __VISIBLE __weak // Verify a variable is only accessable via 32bit "init" functions # define VARVERIFY32INIT __section(".discard.varinit." UNIQSEC) // Designate top-level assembler as 16bit only. @@ -92,7 +90,6 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak # define VARFSEG __section(".discard.varfseg." UNIQSEC) __VISIBLE __weak # define VARFSEGFIXED(addr) __section(".discard.varfixed." UNIQSEC) __VISIBLE __weak -# define FUNCFSEG __section(".discard.32fseg." UNIQSEC) __VISIBLE __weak # define VARVERIFY32INIT __section(".discard.varinit." UNIQSEC) # define ASM16(code) # define ASM32FLAT(code) @@ -109,7 +106,6 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VARLOW __section(".data.varlow." UNIQSEC) __VISIBLE __weak # define VARFSEG __section(".data.varfseg." UNIQSEC) __VISIBLE # define VARFSEGFIXED(addr) __section(".fixedaddr." __stringify(addr)) __VISIBLE __aligned(1) -# define FUNCFSEG __section(".text.32fseg." UNIQSEC) __VISIBLE # define VARVERIFY32INIT __section(".data.varinit." UNIQSEC) # define ASM16(code) # define ASM32FLAT(code) __ASM(code)
On Wed, Dec 03, 2014 at 01:01:48PM -0500, Kevin O'Connor wrote:
The FUNCFSEG macro was introduced to force a C function into the f-segment. This was needed for some C functions that used inline assembler that contained some 16bit code. Instead of forcing the entire C function into the f-segment, just force the small subset of inline assembler into the f-segment.
Signed-off-by: Kevin O'Connor kevin@koconnor.net
src/stacks.c | 12 ++++++------ src/types.h | 4 ---- 2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/stacks.c b/src/stacks.c index c6b7e8b..b2e2447 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -63,8 +63,8 @@ call32_smm_post(void) inb(PORT_CMOS_DATA); }
-#define ASM32_SWITCH16 " .code16\n" -#define ASM32_BACK32 " .code32\n" +#define ASM32_SWITCH16 " .pushsection .text.fseg." UNIQSEC "\n .code16\n"
That should have read ".text.32fseg". I've fixed it locally.
-Kevin
On Wed, Dec 03, 2014 at 01:01:47PM -0500, Kevin O'Connor wrote:
Signed-off-by: Kevin O'Connor kevin@koconnor.net
FYI - I committed these patches.
-Kevin