summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/include/realmode.h
diff options
context:
space:
mode:
authorMichael Brown2005-04-08 17:01:17 +0200
committerMichael Brown2005-04-08 17:01:17 +0200
commit0ff80b477dcff0726ebdbed95e8a93971e59e82b (patch)
tree860b7150212a07c24a9529ea072f3fb12700974c /src/arch/i386/include/realmode.h
parentMerged this file into HEAD (diff)
downloadipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.tar.gz
ipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.tar.xz
ipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.zip
Merged mcb30-realmode-redesign back to HEAD
Diffstat (limited to 'src/arch/i386/include/realmode.h')
-rw-r--r--src/arch/i386/include/realmode.h218
1 files changed, 109 insertions, 109 deletions
diff --git a/src/arch/i386/include/realmode.h b/src/arch/i386/include/realmode.h
index eca92b9b..d641869f 100644
--- a/src/arch/i386/include/realmode.h
+++ b/src/arch/i386/include/realmode.h
@@ -1,124 +1,124 @@
-/* Real-mode interface
- */
+#ifndef REALMODE_H
+#define REALMODE_H
#ifndef ASSEMBLY
-#include "etherboot.h"
-#include "segoff.h"
-
-typedef union {
- struct {
- union {
- uint8_t l;
- uint8_t byte;
- };
- uint8_t h;
- } PACKED;
- uint16_t word;
-} PACKED reg16_t;
-
-typedef union {
- reg16_t w;
- uint32_t dword;
-} PACKED reg32_t;
-
-/* Macros to help with defining inline real-mode trampoline fragments.
+#include "stdint.h"
+#include "compiler.h"
+#include "registers.h"
+#include "io.h"
+
+/*
+ * Data structures and type definitions
+ *
*/
-#define RM_XSTR(x) #x /* Macro hackery needed to stringify */
-#define RM_STR(x) RM_XSTR(x)
-#define RM_FRAGMENT(name, asm_code_str) \
- extern void name ( void ); \
- extern void name ## _end (void); \
- __asm__( \
- ".section \".text16\"\n\t" \
- ".code16\n\t" \
- ".arch i386\n\t" \
- ".globl " #name " \n\t" \
- #name ":\n\t" \
- asm_code_str "\n\t" \
- ".globl " #name "_end\n\t" \
- #name "_end:\n\t" \
- ".code32\n\t" \
- ".previous\n\t" \
- )
-
-#define FRAGMENT_SIZE(fragment) ( (size_t) ( ( (void*) fragment ## _end )\
- - ( (void*) (fragment) ) ) )
-
-/* Data structures in _prot_to_real and _real_to_prot. These
- * structures are accessed by assembly code as well as C code.
+
+/* All i386 registers, as passed in by prot_call or kir_call */
+struct real_mode_regs {
+ struct i386_all_regs;
+} PACKED;
+
+/* Segment:offset structure. Note that the order within the structure
+ * is offset:segment.
*/
typedef struct {
- uint32_t esp;
- uint16_t cs;
- uint16_t ss;
- uint32_t r2p_params;
-} PACKED prot_to_real_params_t;
+ uint16_t offset;
+ uint16_t segment;
+} segoff_t PACKED;
-typedef struct {
- uint32_t ret_addr;
- uint32_t esp;
- uint32_t ebx;
- uint32_t esi;
- uint32_t edi;
- uint32_t ebp;
- uint32_t out_stack;
- uint32_t out_stack_len;
-} PACKED real_to_prot_params_t;
-
-/* Function prototypes: realmode.c
+/* Macro hackery needed to stringify bits of inline assembly */
+#define RM_XSTR(x) #x
+#define RM_STR(x) RM_XSTR(x)
+
+/* Drag in the selected real-mode transition library header */
+#ifdef KEEP_IT_REAL
+#include "libkir.h"
+#else
+#include "librm.h"
+#endif
+
+/*
+ * The API to some functions is identical between librm and libkir, so
+ * they are documented here, even though the prototypes are in librm.h
+ * and libkir.h.
+ *
*/
-#define real_call( fragment, in_stack, out_stack ) \
- _real_call ( fragment, FRAGMENT_SIZE(fragment), \
- (void*)(in_stack), \
- ( (in_stack) == NULL ? 0 : sizeof(*(in_stack)) ), \
- (void*)(out_stack), \
- ( (out_stack) == NULL ? 0 : sizeof(*(out_stack)) ) )
-extern uint16_t _real_call ( void *fragment, int fragment_len,
- void *in_stack, int in_stack_len,
- void *out_stack, int out_stack_len );
-/* Function prototypes: realmode_asm.S
+
+/*
+ * void copy_to_real ( uint16_t dest_seg, uint16_t dest_off,
+ * void *src, size_t n )
+ * void copy_from_real ( void *dest, uint16_t src_seg, uint16_t src_off,
+ * size_t n )
+ *
+ * These functions can be used to copy data to and from arbitrary
+ * locations in base memory.
*/
-extern void rm_callback_interface;
-extern uint16_t rm_callback_interface_size;
-extern uint32_t rm_etherboot_location;
-extern void _rm_in_call ( void );
-extern void _rm_in_call_far ( void );
-
-extern void _prot_to_real_prefix ( void );
-extern void _prot_to_real_prefix_end ( void );
-extern uint16_t prot_to_real_prefix_size;
-
-extern void _real_to_prot_suffix ( void );
-extern void _real_to_prot_suffix_end ( void );
-extern uint16_t real_to_prot_suffix_size;
-
-/* PXE assembler bits */
-extern void pxe_callback_interface;
-extern uint16_t pxe_callback_interface_size;
-extern void _pxe_in_call_far ( void );
-extern void _pxenv_in_call_far ( void );
-extern void _pxe_intercept_int1a ( void );
-extern segoff_t _pxe_intercepted_int1a;
-extern segoff_t _pxe_pxenv_location;
-
-/* Global variables
+
+/*
+ * put_real ( variable, uint16_t dest_seg, uint16_t dest_off )
+ * get_real ( variable, uint16_t src_seg, uint16_t src_off )
+ *
+ * These macros can be used to read or write single variables to and
+ * from arbitrary locations in base memory. "variable" must be a
+ * variable of either 1, 2 or 4 bytes in length.
*/
-extern uint32_t real_mode_stack;
-extern size_t real_mode_stack_size;
+
+/*
+ * REAL_CALL ( routine, num_out_constraints, out_constraints,
+ * in_constraints, clobber )
+ * REAL_EXEC ( name, asm_code_str, num_out_constraints, out_constraints,
+ * in_constraints, clobber )
+ *
+ * If you have a pre-existing real-mode routine that you want to make
+ * a far call to, use REAL_CALL. If you have a code fragment that you
+ * want to copy down to base memory, execute, and then remove, use
+ * REAL_EXEC.
+ *
+ * out_constraints must be of the form OUT_CONSTRAINTS(constraints),
+ * and in_constraints must be of the form IN_CONSTRAINTS(constraints),
+ * where "constraints" is a constraints list as would be used in an
+ * inline __asm__()
+ *
+ * clobber must be of the form CLOBBER ( clobber_list ), where
+ * "clobber_list" is a clobber list as would be used in an inline
+ * __asm__().
+ *
+ * These are best illustrated by example. To write a character to the
+ * console using INT 10, you would do something like:
+ *
+ * REAL_EXEC ( rm_test_librm,
+ * "int $0x10",
+ * 1,
+ * OUT_CONSTRAINTS ( "=a" ( discard ) ),
+ * IN_CONSTRAINTS ( "a" ( 0x0e00 + character ),
+ * "b" ( 1 ) ),
+ * CLOBBER ( "ebx", "ecx", "edx", "ebp", "esi", "edi" ) );
+ *
+ * IMPORTANT: gcc does not automatically assume that input operands
+ * get clobbered. The only way to specify that an input operand may
+ * be modified is to also specify it as an output operand; hence the
+ * "(discard)" in the above code.
+ */
+
+#warning "realmode.h contains placeholders for obsolete macros"
+
+
+/* Just for now */
+#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
+#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
+#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
+
+/* To make basemem.c compile */
extern int lock_real_mode_stack;
+extern char *real_mode_stack;
+extern char real_mode_stack_size[];
+
+#define RM_FRAGMENT(name,asm) \
+ void name ( void ) {} \
+ extern char name ## _size[];
-/* Function prototypes from basemem.c
- */
-#ifdef LINUXBIOS
-/* A silly hard code that let's the code compile and work.
- * When this becomes a problem feel free to implement
- * something better.
- */
-static inline void allot_real_mode_stack(void) { real_mode_stack = 0x7c00; }
-#else
-void allot_real_mode_stack(void);
-#endif
#endif /* ASSEMBLY */
+
+#endif /* REALMODE_H */