diff options
author | Michael Brown <mcb30@etherboot.org> | 2005-04-08 15:01:17 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2005-04-08 15:01:17 +0000 |
commit | 0ff80b477dcff0726ebdbed95e8a93971e59e82b (patch) | |
tree | 860b7150212a07c24a9529ea072f3fb12700974c /src/arch/i386/include/realmode.h | |
parent | de5d935135bd536666b5fd03445b04d2ea82f1b4 (diff) | |
download | ipxe-0ff80b477dcff0726ebdbed95e8a93971e59e82b.tar.gz |
Merged mcb30-realmode-redesign back to HEAD
Diffstat (limited to 'src/arch/i386/include/realmode.h')
-rw-r--r-- | src/arch/i386/include/realmode.h | 218 |
1 files changed, 109 insertions, 109 deletions
diff --git a/src/arch/i386/include/realmode.h b/src/arch/i386/include/realmode.h index eca92b9b5..d641869f8 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 */ |