|
|
1.1 ! root 1: #ifndef REALMODE_H ! 2: #define REALMODE_H ! 3: ! 4: #include <stdint.h> ! 5: #include <registers.h> ! 6: #include <ipxe/uaccess.h> ! 7: ! 8: /* ! 9: * Data structures and type definitions ! 10: * ! 11: */ ! 12: ! 13: FILE_LICENCE ( GPL2_OR_LATER ); ! 14: ! 15: /* ! 16: * Declaration of variables in .data16 ! 17: * ! 18: * To place a variable in the .data16 segment, declare it using the ! 19: * pattern: ! 20: * ! 21: * int __data16 ( foo ); ! 22: * #define foo __use_data16 ( foo ); ! 23: * ! 24: * extern uint32_t __data16 ( bar ); ! 25: * #define bar __use_data16 ( bar ); ! 26: * ! 27: * static long __data16 ( baz ) = 0xff000000UL; ! 28: * #define baz __use_data16 ( baz ); ! 29: * ! 30: * i.e. take a normal declaration, add __data16() around the variable ! 31: * name, and add a line saying "#define <name> __use_data16 ( <name> ) ! 32: * ! 33: * You can then access them just like any other variable, for example ! 34: * ! 35: * int x = foo + bar; ! 36: * ! 37: * This magic is achieved at a cost of only around 7 extra bytes per ! 38: * group of accesses to .data16 variables. When using KEEP_IT_REAL, ! 39: * there is no extra cost. ! 40: * ! 41: * You should place variables in .data16 when they need to be accessed ! 42: * by real-mode code. Real-mode assembly (e.g. as created by ! 43: * REAL_CODE()) can access these variables via the usual data segment. ! 44: * You can therefore write something like ! 45: * ! 46: * static uint16_t __data16 ( foo ); ! 47: * #define foo __use_data16 ( foo ) ! 48: * ! 49: * int bar ( void ) { ! 50: * __asm__ __volatile__ ( REAL_CODE ( "int $0xff\n\t" ! 51: * "movw %ax, foo" ) ! 52: * : : ); ! 53: * return foo; ! 54: * } ! 55: * ! 56: * Variables may also be placed in .text16 using __text16 and ! 57: * __use_text16. Some variables (e.g. chained interrupt vectors) fit ! 58: * most naturally in .text16; most should be in .data16. ! 59: * ! 60: * If you have only a pointer to a magic symbol within .data16 or ! 61: * .text16, rather than the symbol itself, you can attempt to extract ! 62: * the underlying symbol name using __from_data16() or ! 63: * __from_text16(). This is not for the faint-hearted; check the ! 64: * assembler output to make sure that it's doing the right thing. ! 65: */ ! 66: ! 67: /** ! 68: * Copy data to base memory ! 69: * ! 70: * @v dest_seg Destination segment ! 71: * @v dest_off Destination offset ! 72: * @v src Source ! 73: * @v len Length ! 74: */ ! 75: static inline __always_inline void ! 76: copy_to_real ( unsigned int dest_seg, unsigned int dest_off, ! 77: void *src, size_t n ) { ! 78: copy_to_user ( real_to_user ( dest_seg, dest_off ), 0, src, n ); ! 79: } ! 80: ! 81: /** ! 82: * Copy data to base memory ! 83: * ! 84: * @v dest Destination ! 85: * @v src_seg Source segment ! 86: * @v src_off Source offset ! 87: * @v len Length ! 88: */ ! 89: static inline __always_inline void ! 90: copy_from_real ( void *dest, unsigned int src_seg, ! 91: unsigned int src_off, size_t n ) { ! 92: copy_from_user ( dest, real_to_user ( src_seg, src_off ), 0, n ); ! 93: } ! 94: ! 95: /** ! 96: * Write a single variable to base memory ! 97: * ! 98: * @v var Variable to write ! 99: * @v dest_seg Destination segment ! 100: * @v dest_off Destination offset ! 101: */ ! 102: #define put_real( var, dest_seg, dest_off ) \ ! 103: copy_to_real ( (dest_seg), (dest_off), &(var), sizeof (var) ) ! 104: ! 105: /** ! 106: * Read a single variable from base memory ! 107: * ! 108: * @v var Variable to read ! 109: * @v src_seg Source segment ! 110: * @v src_off Source offset ! 111: */ ! 112: #define get_real( var, src_seg, src_off ) \ ! 113: copy_from_real ( &(var), (src_seg), (src_off), sizeof (var) ) ! 114: ! 115: /* ! 116: * REAL_CODE ( asm_code_str ) ! 117: * ! 118: * This can be used in inline assembly to create a fragment of code ! 119: * that will execute in real mode. For example: to write a character ! 120: * to the BIOS console using INT 10, you would do something like: ! 121: * ! 122: * __asm__ __volatile__ ( REAL_CODE ( "int $0x16" ) ! 123: * : "=a" ( character ) : "a" ( 0x0000 ) ); ! 124: * ! 125: */ ! 126: ! 127: #endif /* REALMODE_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.