summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/image/com32.c2
-rw-r--r--src/arch/i386/image/comboot.c2
-rw-r--r--src/arch/i386/include/comboot.h2
-rw-r--r--src/arch/i386/include/setjmp.h36
-rw-r--r--src/arch/i386/interface/syslinux/comboot_call.c12
5 files changed, 40 insertions, 14 deletions
diff --git a/src/arch/i386/image/com32.c b/src/arch/i386/image/com32.c
index 00f75263..d1b9a59f 100644
--- a/src/arch/i386/image/com32.c
+++ b/src/arch/i386/image/com32.c
@@ -52,7 +52,7 @@ static int com32_exec ( struct image *image ) {
int state;
uint32_t avail_mem_top;
- state = setjmp ( comboot_return );
+ state = rmsetjmp ( comboot_return );
switch ( state ) {
case 0: /* First time through; invoke COM32 program */
diff --git a/src/arch/i386/image/comboot.c b/src/arch/i386/image/comboot.c
index d9b16c57..40e32185 100644
--- a/src/arch/i386/image/comboot.c
+++ b/src/arch/i386/image/comboot.c
@@ -133,7 +133,7 @@ static int comboot_exec ( struct image *image ) {
userptr_t seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 );
int state;
- state = setjmp ( comboot_return );
+ state = rmsetjmp ( comboot_return );
switch ( state ) {
case 0: /* First time through; invoke COMBOOT program */
diff --git a/src/arch/i386/include/comboot.h b/src/arch/i386/include/comboot.h
index 6b8ea6b6..b5b1f8a0 100644
--- a/src/arch/i386/include/comboot.h
+++ b/src/arch/i386/include/comboot.h
@@ -78,7 +78,7 @@ extern void com32_cfarcall_wrapper ( );
extern int comboot_resolv ( const char *name, struct in_addr *address );
/* setjmp/longjmp context buffer used to return after loading an image */
-extern jmp_buf comboot_return;
+extern rmjmp_buf comboot_return;
/* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */
extern struct image *comboot_replacement_image;
diff --git a/src/arch/i386/include/setjmp.h b/src/arch/i386/include/setjmp.h
index 60e4b120..c18d03e1 100644
--- a/src/arch/i386/include/setjmp.h
+++ b/src/arch/i386/include/setjmp.h
@@ -1,12 +1,38 @@
#ifndef ETHERBOOT_SETJMP_H
#define ETHERBOOT_SETJMP_H
+#include <stdint.h>
+#include <realmode.h>
-/* Define a type for use by setjmp and longjmp */
-#define JBLEN 6
-typedef unsigned long jmp_buf[JBLEN];
+/** A jump buffer */
+typedef struct {
+ uint32_t retaddr;
+ uint32_t ebx;
+ uint32_t esp;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+} jmp_buf[1];
-extern int __asmcall setjmp (jmp_buf env);
-extern void __asmcall longjmp (jmp_buf env, int val);
+/** A real-mode-extended jump buffer */
+typedef struct {
+ jmp_buf env;
+ uint16_t rm_ss;
+ uint16_t rm_sp;
+} rmjmp_buf[1];
+
+extern int __asmcall setjmp ( jmp_buf env );
+extern void __asmcall longjmp ( jmp_buf env, int val );
+
+#define rmsetjmp( _env ) ( { \
+ (_env)->rm_ss = rm_ss; \
+ (_env)->rm_sp = rm_sp; \
+ setjmp ( (_env)->env ); } ) \
+
+#define rmlongjmp( _env, _val ) do { \
+ rm_ss = (_env)->rm_ss; \
+ rm_sp = (_env)->rm_sp; \
+ longjmp ( (_env)->env, (_val) ); \
+ } while ( 0 )
#endif /* ETHERBOOT_SETJMP_H */
diff --git a/src/arch/i386/interface/syslinux/comboot_call.c b/src/arch/i386/interface/syslinux/comboot_call.c
index c641c840..290d94ac 100644
--- a/src/arch/i386/interface/syslinux/comboot_call.c
+++ b/src/arch/i386/interface/syslinux/comboot_call.c
@@ -67,7 +67,7 @@ extern void int21_wrapper ( void );
extern void int22_wrapper ( void );
/* setjmp/longjmp context buffer used to return after loading an image */
-jmp_buf comboot_return;
+rmjmp_buf comboot_return;
/* Replacement image when exiting with COMBOOT_EXIT_RUN_KERNEL */
struct image *comboot_replacement_image;
@@ -235,7 +235,7 @@ static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) {
* Terminate program interrupt handler
*/
static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
- longjmp ( comboot_return, COMBOOT_EXIT );
+ rmlongjmp ( comboot_return, COMBOOT_EXIT );
}
@@ -248,7 +248,7 @@ static __asmcall void int21 ( struct i386_all_regs *ix86 ) {
switch ( ix86->regs.ah ) {
case 0x00:
case 0x4C: /* Terminate program */
- longjmp ( comboot_return, COMBOOT_EXIT );
+ rmlongjmp ( comboot_return, COMBOOT_EXIT );
break;
case 0x01: /* Get Key with Echo */
@@ -347,13 +347,13 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
DBG ( "COMBOOT: executing command '%s'\n", cmd );
system ( cmd );
DBG ( "COMBOOT: exiting after executing command...\n" );
- longjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
+ rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
}
break;
case 0x0004: /* Run default command */
/* FIXME: just exit for now */
- longjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
+ rmlongjmp ( comboot_return, COMBOOT_EXIT_COMMAND );
break;
case 0x0005: /* Force text mode */
@@ -552,7 +552,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
* part of the COMBOOT program's memory space.
*/
DBG ( "COMBOOT: exiting to run kernel...\n" );
- longjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL );
+ rmlongjmp ( comboot_return, COMBOOT_EXIT_RUN_KERNEL );
}
break;