Annotation of qemu/roms/ipxe/src/arch/i386/include/realmode.h, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.