00001 #ifndef LIBRM_H
00002 #define LIBRM_H
00003
00004 FILE_LICENCE ( GPL2_OR_LATER );
00005
00006
00007
00008
00009
00010
00011 #define VIRTUAL_CS 0x08
00012 #define VIRTUAL_DS 0x10
00013 #define PHYSICAL_CS 0x18
00014 #define PHYSICAL_DS 0x20
00015 #define REAL_CS 0x28
00016 #define REAL_DS 0x30
00017 #if 0
00018 #define LONG_CS 0x38
00019 #define LONG_DS 0x40
00020 #endif
00021
00022 #ifndef ASSEMBLY
00023
00024 #ifdef UACCESS_LIBRM
00025 #define UACCESS_PREFIX_librm
00026 #else
00027 #define UACCESS_PREFIX_librm __librm_
00028 #endif
00029
00030
00031 extern unsigned long virt_offset;
00032
00033
00034
00035
00036
00037
00038
00039 static inline __always_inline userptr_t
00040 UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
00041 return ( phys_addr - virt_offset );
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051 static inline __always_inline unsigned long
00052 UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) {
00053 return ( userptr + offset + virt_offset );
00054 }
00055
00056 static inline __always_inline userptr_t
00057 UACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) {
00058 return trivial_virt_to_user ( addr );
00059 }
00060
00061 static inline __always_inline void *
00062 UACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) {
00063 return trivial_user_to_virt ( userptr, offset );
00064 }
00065
00066 static inline __always_inline userptr_t
00067 UACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) {
00068 return trivial_userptr_add ( userptr, offset );
00069 }
00070
00071 static inline __always_inline void
00072 UACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off,
00073 userptr_t src, off_t src_off,
00074 size_t len ) {
00075 trivial_memcpy_user ( dest, dest_off, src, src_off, len );
00076 }
00077
00078 static inline __always_inline void
00079 UACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off,
00080 userptr_t src, off_t src_off,
00081 size_t len ) {
00082 trivial_memmove_user ( dest, dest_off, src, src_off, len );
00083 }
00084
00085 static inline __always_inline void
00086 UACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset,
00087 int c, size_t len ) {
00088 trivial_memset_user ( buffer, offset, c, len );
00089 }
00090
00091 static inline __always_inline size_t
00092 UACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) {
00093 return trivial_strlen_user ( buffer, offset );
00094 }
00095
00096 static inline __always_inline off_t
00097 UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset,
00098 int c, size_t len ) {
00099 return trivial_memchr_user ( buffer, offset, c, len );
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 extern char *data16;
00110 extern char *text16;
00111
00112 #define __data16( variable ) \
00113 __attribute__ (( section ( ".data16" ) )) \
00114 _data16_ ## variable __asm__ ( #variable )
00115
00116 #define __data16_array( variable, array ) \
00117 __attribute__ (( section ( ".data16" ) )) \
00118 _data16_ ## variable array __asm__ ( #variable )
00119
00120 #define __bss16( variable ) \
00121 __attribute__ (( section ( ".bss16" ) )) \
00122 _data16_ ## variable __asm__ ( #variable )
00123
00124 #define __bss16_array( variable, array ) \
00125 __attribute__ (( section ( ".bss16" ) )) \
00126 _data16_ ## variable array __asm__ ( #variable )
00127
00128 #define __text16( variable ) \
00129 __attribute__ (( section ( ".text16.data" ) )) \
00130 _text16_ ## variable __asm__ ( #variable )
00131
00132 #define __text16_array( variable, array ) \
00133 __attribute__ (( section ( ".text16.data" ) )) \
00134 _text16_ ## variable array __asm__ ( #variable )
00135
00136 #define __use_data16( variable ) \
00137 ( * ( ( typeof ( _data16_ ## variable ) * ) \
00138 & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) )
00139
00140 #define __use_text16( variable ) \
00141 ( * ( ( typeof ( _text16_ ## variable ) * ) \
00142 & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) )
00143
00144 #define __from_data16( pointer ) \
00145 ( ( unsigned int ) \
00146 ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) )
00147
00148 #define __from_text16( pointer ) \
00149 ( ( unsigned int ) \
00150 ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) )
00151
00152
00153 extern uint16_t rm_sp;
00154 extern uint16_t rm_ss;
00155 extern uint16_t __data16 ( rm_cs );
00156 #define rm_cs __use_data16 ( rm_cs )
00157 extern uint16_t __text16 ( rm_ds );
00158 #define rm_ds __use_text16 ( rm_ds )
00159
00160
00161
00162
00163 extern void gateA20_set ( void );
00164
00165
00166
00167
00168
00169
00170
00171
00172 static inline __always_inline userptr_t
00173 real_to_user ( unsigned int segment, unsigned int offset ) {
00174 return ( phys_to_user ( ( segment << 4 ) + offset ) );
00175 }
00176
00177 extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size );
00178 extern void remove_user_from_rm_stack ( userptr_t data, size_t size );
00179
00180
00181 #define TEXT16_CODE( asm_code_str ) \
00182 ".section \".text16\", \"ax\", @progbits\n\t" \
00183 ".code16\n\t" \
00184 asm_code_str "\n\t" \
00185 ".code32\n\t" \
00186 ".previous\n\t"
00187
00188
00189 #define REAL_CODE( asm_code_str ) \
00190 "pushl $1f\n\t" \
00191 "call real_call\n\t" \
00192 "addl $4, %%esp\n\t" \
00193 TEXT16_CODE ( "\n1:\n\t" \
00194 asm_code_str \
00195 "\n\t" \
00196 "ret\n\t" )
00197
00198
00199 #define PHYS_CODE( asm_code_str ) \
00200 "call _virt_to_phys\n\t" \
00201 asm_code_str \
00202 "call _phys_to_virt\n\t"
00203
00204 #endif
00205
00206 #endif