00001 #ifndef LIBKIR_H
00002 #define LIBKIR_H
00003
00004 #include "realmode.h"
00005
00006 #ifndef ASSEMBLY
00007
00008
00009
00010
00011
00012
00013
00014 #define __data16( variable ) variable
00015 #define __data16_array( variable, array ) variable array
00016 #define __bss16( variable ) variable
00017 #define __bss16_array( variable, array ) variable array
00018 #define __text16( variable ) variable
00019 #define __text16_array( variable,array ) variable array
00020 #define __use_data16( variable ) variable
00021 #define __use_text16( variable ) variable
00022 #define __from_data16( pointer ) pointer
00023 #define __from_text16( pointer ) pointer
00024
00025
00026 static inline __attribute__ (( always_inline )) unsigned int _rm_cs ( void ) {
00027 uint16_t cs;
00028 __asm__ __volatile__ ( "movw %%cs, %w0" : "=r" ( cs ) );
00029 return cs;
00030 }
00031
00032 static inline __attribute__ (( always_inline )) unsigned int _rm_ds ( void ) {
00033 uint16_t ds;
00034 __asm__ __volatile__ ( "movw %%ds, %w0" : "=r" ( ds ) );
00035 return ds;
00036 }
00037
00038 #define rm_cs ( _rm_cs() )
00039 #define rm_ds ( _rm_ds() )
00040
00041
00042
00043 static inline void copy_to_real_libkir ( unsigned int dest_seg,
00044 unsigned int dest_off,
00045 const void *src, size_t n ) {
00046 unsigned int discard_D, discard_S, discard_c;
00047
00048 __asm__ __volatile__ ( "pushw %%es\n\t"
00049 "movw %3, %%es\n\t"
00050 "rep movsb\n\t"
00051 "popw %%es\n\t"
00052 : "=D" ( discard_D ), "=S" ( discard_S ),
00053 "=c" ( discard_c )
00054 : "r" ( dest_seg ), "D" ( dest_off ),
00055 "S" ( src ),
00056 "c" ( n )
00057 : "memory" );
00058 }
00059
00060 static inline void copy_from_real_libkir ( void *dest,
00061 unsigned int src_seg,
00062 unsigned int src_off,
00063 size_t n ) {
00064 unsigned int discard_D, discard_S, discard_c;
00065
00066 __asm__ __volatile__ ( "pushw %%ds\n\t"
00067 "movw %4, %%ds\n\t"
00068 "rep movsb\n\t"
00069 "popw %%ds\n\t"
00070 : "=D" ( discard_D ), "=S" ( discard_S ),
00071 "=c" ( discard_c )
00072 : "D" ( dest ),
00073 "r" ( src_seg ), "S" ( src_off ),
00074 "c" ( n )
00075 : "memory" );
00076 }
00077
00078 #define copy_to_real copy_to_real_libkir
00079 #define copy_from_real copy_from_real_libkir
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #define put_real_kir_const_off( var, seg, off ) \
00099 __asm__ ( "movw %w1, %%es\n\t" \
00100 "mov %0, %%es:%c2\n\t" \
00101 "pushw %%ds\n\t" \
00102 "popw %%es\n\t" \
00103 : \
00104 : "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off ) \
00105 )
00106
00107 #define put_real_kir_nonconst_off( var, seg, off ) \
00108 __asm__ ( "movw %w1, %%es\n\t" \
00109 "mov %0, %%es:(%2)\n\t" \
00110 "pushw %%ds\n\t" \
00111 "popw %%es\n\t" \
00112 : \
00113 : "r" ( var ), "rm" ( seg ), "r" ( off ) \
00114 )
00115
00116 #define put_real_kir( var, seg, off ) \
00117 do { \
00118 if ( __builtin_constant_p ( off ) ) \
00119 put_real_kir_const_off ( var, seg, off ); \
00120 else \
00121 put_real_kir_nonconst_off ( var, seg, off ); \
00122 } while ( 0 )
00123
00124 #define get_real_kir_const_off( var, seg, off ) \
00125 __asm__ ( "movw %w1, %%es\n\t" \
00126 "mov %%es:%c2, %0\n\t" \
00127 "pushw %%ds\n\t" \
00128 "popw %%es\n\t" \
00129 : "=r,r" ( var ) \
00130 : "rm,rm" ( seg ), "i,!r" ( off ) \
00131 )
00132
00133 #define get_real_kir_nonconst_off( var, seg, off ) \
00134 __asm__ ( "movw %w1, %%es\n\t" \
00135 "mov %%es:(%2), %0\n\t" \
00136 "pushw %%ds\n\t" \
00137 "popw %%es\n\t" \
00138 : "=r" ( var ) \
00139 : "rm" ( seg ), "r" ( off ) \
00140 )
00141
00142 #define get_real_kir( var, seg, off ) \
00143 do { \
00144 if ( __builtin_constant_p ( off ) ) \
00145 get_real_kir_const_off ( var, seg, off ); \
00146 else \
00147 get_real_kir_nonconst_off ( var, seg, off ); \
00148 } while ( 0 )
00149
00150 #define put_real put_real_kir
00151 #define get_real get_real_kir
00152
00153
00154
00155
00156
00157
00158
00159 typedef uint32_t userptr_t;
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 static inline __attribute__ (( always_inline )) void
00170 copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) {
00171 copy_to_real ( ( buffer >> 16 ), ( ( buffer & 0xffff ) + offset ),
00172 src, len );
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static inline __attribute__ (( always_inline )) void
00184 copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) {
00185 copy_from_real ( dest, ( buffer >> 16 ),
00186 ( ( buffer & 0xffff ) + offset ), len );
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196 static inline __attribute__ (( always_inline )) userptr_t
00197 real_to_user ( unsigned int segment, unsigned int offset ) {
00198 return ( ( segment << 16 ) | offset );
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 static inline __attribute__ (( always_inline )) userptr_t
00212 virt_to_user ( void * virtual ) {
00213 return real_to_user ( rm_ds, ( intptr_t ) virtual );
00214 }
00215
00216
00217 #define TEXT16_CODE( asm_code_str ) \
00218 ".section \".text16\", \"ax\", @progbits\n\t" \
00219 ".code16\n\t" \
00220 ".arch i386\n\t" \
00221 asm_code_str "\n\t" \
00222 ".code16gcc\n\t" \
00223 ".previous\n\t"
00224
00225
00226 #define REAL_CODE( asm_code_str ) \
00227 ".code16\n\t" \
00228 asm_code_str "\n\t" \
00229 ".code16gcc\n\t"
00230
00231 #endif
00232
00233 #endif