Annotation of qemu/roms/ipxe/src/arch/i386/include/libkir.h, revision 1.1

1.1     ! root        1: #ifndef LIBKIR_H
        !             2: #define LIBKIR_H
        !             3: 
        !             4: #include "realmode.h"
        !             5: 
        !             6: #ifndef ASSEMBLY
        !             7: 
        !             8: /*
        !             9:  * Full API documentation for these functions is in realmode.h.
        !            10:  *
        !            11:  */
        !            12: 
        !            13: /* Access to variables in .data16 and .text16 in a way compatible with librm */
        !            14: #define __data16( variable ) variable
        !            15: #define __data16_array( variable, array ) variable array
        !            16: #define __bss16( variable ) variable
        !            17: #define __bss16_array( variable, array ) variable array
        !            18: #define __text16( variable ) variable
        !            19: #define __text16_array( variable,array ) variable array
        !            20: #define __use_data16( variable ) variable
        !            21: #define __use_text16( variable ) variable
        !            22: #define __from_data16( pointer ) pointer
        !            23: #define __from_text16( pointer ) pointer
        !            24: 
        !            25: /* Real-mode data and code segments */
        !            26: static inline __attribute__ (( always_inline )) unsigned int _rm_cs ( void ) {
        !            27:        uint16_t cs;
        !            28:        __asm__ __volatile__ ( "movw %%cs, %w0" : "=r" ( cs ) );
        !            29:        return cs;
        !            30: }
        !            31: 
        !            32: static inline __attribute__ (( always_inline )) unsigned int _rm_ds ( void ) {
        !            33:        uint16_t ds;
        !            34:        __asm__ __volatile__ ( "movw %%ds, %w0" : "=r" ( ds ) );
        !            35:        return ds;
        !            36: }
        !            37: 
        !            38: #define rm_cs ( _rm_cs() )
        !            39: #define rm_ds ( _rm_ds() )
        !            40: 
        !            41: /* Copy to/from base memory */
        !            42: 
        !            43: static inline void copy_to_real_libkir ( unsigned int dest_seg,
        !            44:                                         unsigned int dest_off,
        !            45:                                         const void *src, size_t n ) {
        !            46:        unsigned int discard_D, discard_S, discard_c;
        !            47: 
        !            48:        __asm__ __volatile__ ( "pushw %%es\n\t"
        !            49:                               "movw %3, %%es\n\t"
        !            50:                               "rep movsb\n\t"
        !            51:                               "popw %%es\n\t"
        !            52:                               : "=D" ( discard_D ), "=S" ( discard_S ),
        !            53:                                 "=c" ( discard_c )
        !            54:                               : "r" ( dest_seg ), "D" ( dest_off ),
        !            55:                                 "S" ( src ),
        !            56:                                 "c" ( n )
        !            57:                               : "memory" );
        !            58: }
        !            59: 
        !            60: static inline void copy_from_real_libkir ( void *dest,
        !            61:                                           unsigned int src_seg,
        !            62:                                           unsigned int src_off,
        !            63:                                           size_t n ) {
        !            64:        unsigned int discard_D, discard_S, discard_c;
        !            65: 
        !            66:        __asm__ __volatile__ ( "pushw %%ds\n\t"
        !            67:                               "movw %4, %%ds\n\t"
        !            68:                               "rep movsb\n\t"
        !            69:                               "popw %%ds\n\t"
        !            70:                               : "=D" ( discard_D ), "=S" ( discard_S ),
        !            71:                                 "=c" ( discard_c )
        !            72:                               : "D" ( dest ),
        !            73:                                 "r" ( src_seg ), "S" ( src_off ),
        !            74:                                 "c" ( n )
        !            75:                               : "memory" );
        !            76: }
        !            77: 
        !            78: #define copy_to_real copy_to_real_libkir
        !            79: #define copy_from_real copy_from_real_libkir
        !            80: 
        !            81: /*
        !            82:  * Transfer individual values to/from base memory.  There may well be
        !            83:  * a neater way to do this.  We have two versions: one for constant
        !            84:  * offsets (where the mov instruction must be of the form "mov
        !            85:  * %es:123, %xx") and one for non-constant offsets (where the mov
        !            86:  * instruction must be of the form "mov %es:(%xx), %yx".  If it's
        !            87:  * possible to incorporate both forms into one __asm__ instruction, I
        !            88:  * don't know how to do it.
        !            89:  *
        !            90:  * Ideally, the mov instruction should be "mov%z0"; the "%z0" is meant
        !            91:  * to expand to either "b", "w" or "l" depending on the size of
        !            92:  * operand 0.  This would remove the (minor) ambiguity in the mov
        !            93:  * instruction.  However, gcc on at least my system barfs with an
        !            94:  * "internal compiler error" when confronted with %z0.
        !            95:  *
        !            96:  */
        !            97: 
        !            98: #define put_real_kir_const_off( var, seg, off )                                     \
        !            99:        __asm__ ( "movw %w1, %%es\n\t"                                       \
        !           100:                  "mov %0, %%es:%c2\n\t"                                     \
        !           101:                  "pushw %%ds\n\t" /* restore %es */                         \
        !           102:                  "popw %%es\n\t"                                            \
        !           103:                  :                                                          \
        !           104:                  : "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off )           \
        !           105:                  )
        !           106: 
        !           107: #define put_real_kir_nonconst_off( var, seg, off )                          \
        !           108:        __asm__ ( "movw %w1, %%es\n\t"                                       \
        !           109:                  "mov %0, %%es:(%2)\n\t"                                    \
        !           110:                  "pushw %%ds\n\t" /* restore %es */                         \
        !           111:                  "popw %%es\n\t"                                            \
        !           112:                  :                                                          \
        !           113:                  : "r" ( var ), "rm" ( seg ), "r" ( off )                   \
        !           114:                  )
        !           115: 
        !           116: #define put_real_kir( var, seg, off )                                       \
        !           117:        do {                                                                 \
        !           118:          if ( __builtin_constant_p ( off ) )                                \
        !           119:                  put_real_kir_const_off ( var, seg, off );                  \
        !           120:          else                                                               \
        !           121:                  put_real_kir_nonconst_off ( var, seg, off );               \
        !           122:        } while ( 0 )
        !           123: 
        !           124: #define get_real_kir_const_off( var, seg, off )                                     \
        !           125:        __asm__ ( "movw %w1, %%es\n\t"                                       \
        !           126:                  "mov %%es:%c2, %0\n\t"                                     \
        !           127:                  "pushw %%ds\n\t" /* restore %es */                         \
        !           128:                  "popw %%es\n\t"                                            \
        !           129:                  : "=r,r" ( var )                                           \
        !           130:                  : "rm,rm" ( seg ), "i,!r" ( off )                          \
        !           131:                  )
        !           132: 
        !           133: #define get_real_kir_nonconst_off( var, seg, off )                          \
        !           134:        __asm__ ( "movw %w1, %%es\n\t"                                       \
        !           135:                  "mov %%es:(%2), %0\n\t"                                    \
        !           136:                  "pushw %%ds\n\t" /* restore %es */                         \
        !           137:                  "popw %%es\n\t"                                            \
        !           138:                  : "=r" ( var )                                             \
        !           139:                  : "rm" ( seg ), "r" ( off )                                \
        !           140:                  )
        !           141: 
        !           142: #define get_real_kir( var, seg, off )                                       \
        !           143:        do {                                                                 \
        !           144:          if ( __builtin_constant_p ( off ) )                                \
        !           145:                  get_real_kir_const_off ( var, seg, off );                  \
        !           146:          else                                                               \
        !           147:                  get_real_kir_nonconst_off ( var, seg, off );               \
        !           148:        } while ( 0 )
        !           149: 
        !           150: #define put_real put_real_kir
        !           151: #define get_real get_real_kir
        !           152: 
        !           153: /**
        !           154:  * A pointer to a user buffer
        !           155:  *
        !           156:  * This is actually a struct segoff, but encoded as a uint32_t to
        !           157:  * ensure that gcc passes it around efficiently.
        !           158:  */
        !           159: typedef uint32_t userptr_t;
        !           160: 
        !           161: /**
        !           162:  * Copy data to user buffer
        !           163:  *
        !           164:  * @v buffer   User buffer
        !           165:  * @v offset   Offset within user buffer
        !           166:  * @v src      Source
        !           167:  * @v len      Length
        !           168:  */
        !           169: static inline __attribute__ (( always_inline )) void
        !           170: copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) {
        !           171:        copy_to_real ( ( buffer >> 16 ), ( ( buffer & 0xffff ) + offset ),
        !           172:                       src, len );
        !           173: }
        !           174: 
        !           175: /**
        !           176:  * Copy data from user buffer
        !           177:  *
        !           178:  * @v dest     Destination
        !           179:  * @v buffer   User buffer
        !           180:  * @v offset   Offset within user buffer
        !           181:  * @v len      Length
        !           182:  */
        !           183: static inline __attribute__ (( always_inline )) void
        !           184: copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) {
        !           185:        copy_from_real ( dest, ( buffer >> 16 ),
        !           186:                         ( ( buffer & 0xffff ) + offset ), len );
        !           187: }
        !           188: 
        !           189: /**
        !           190:  * Convert segment:offset address to user buffer
        !           191:  *
        !           192:  * @v segment  Real-mode segment
        !           193:  * @v offset   Real-mode offset
        !           194:  * @ret buffer User buffer
        !           195:  */
        !           196: static inline __attribute__ (( always_inline )) userptr_t
        !           197: real_to_user ( unsigned int segment, unsigned int offset ) {
        !           198:        return ( ( segment << 16 ) | offset );
        !           199: }
        !           200: 
        !           201: /**
        !           202:  * Convert virtual address to user buffer
        !           203:  *
        !           204:  * @v virtual  Virtual address
        !           205:  * @ret buffer User buffer
        !           206:  *
        !           207:  * This constructs a user buffer from an ordinary pointer.  Use it
        !           208:  * when you need to pass a pointer to an internal buffer to a function
        !           209:  * that expects a @c userptr_t.
        !           210:  */
        !           211: static inline __attribute__ (( always_inline )) userptr_t
        !           212: virt_to_user ( void * virtual ) {
        !           213:        return real_to_user ( rm_ds, ( intptr_t ) virtual );
        !           214: }
        !           215: 
        !           216: /* TEXT16_CODE: declare a fragment of code that resides in .text16 */
        !           217: #define TEXT16_CODE( asm_code_str )                    \
        !           218:        ".section \".text16\", \"ax\", @progbits\n\t"   \
        !           219:        ".code16\n\t"                                   \
        !           220:        ".arch i386\n\t"                                \
        !           221:        asm_code_str "\n\t"                             \
        !           222:        ".code16gcc\n\t"                                \
        !           223:        ".previous\n\t"
        !           224: 
        !           225: /* REAL_CODE: declare a fragment of code that executes in real mode */
        !           226: #define REAL_CODE( asm_code_str )      \
        !           227:        ".code16\n\t"                   \
        !           228:        asm_code_str "\n\t"             \
        !           229:        ".code16gcc\n\t"
        !           230: 
        !           231: #endif /* ASSEMBLY */
        !           232: 
        !           233: #endif /* LIBKIR_H */

unix.superglobalmegacorp.com

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