Annotation of qemu/roms/ipxe/src/arch/i386/include/realmode.h, revision 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.