librm.h

Go to the documentation of this file.
00001 #ifndef LIBRM_H
00002 #define LIBRM_H
00003 
00004 FILE_LICENCE ( GPL2_OR_LATER );
00005 
00006 /* Segment selectors as used in our protected-mode GDTs.
00007  *
00008  * Don't change these unless you really know what you're doing.
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 /* Variables in librm.S */
00031 extern unsigned long virt_offset;
00032 
00033 /**
00034  * Convert physical address to user pointer
00035  *
00036  * @v phys_addr         Physical address
00037  * @ret userptr         User pointer
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  * Convert user buffer to physical address
00046  *
00047  * @v userptr           User pointer
00048  * @v offset            Offset from user pointer
00049  * @ret phys_addr       Physical address
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  * Access to variables in .data16 and .text16
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 /* Variables in librm.S, present in the normal data segment */
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 /* Functions that librm expects to be able to link to.  Included here
00161  * so that the compiler will catch prototype mismatches.
00162  */
00163 extern void gateA20_set ( void );
00164 
00165 /**
00166  * Convert segment:offset address to user buffer
00167  *
00168  * @v segment           Real-mode segment
00169  * @v offset            Real-mode offset
00170  * @ret buffer          User buffer
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 /* TEXT16_CODE: declare a fragment of code that resides in .text16 */
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 /* REAL_CODE: declare a fragment of code that executes in real mode */
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 /* PHYS_CODE: declare a fragment of code that executes in flat physical mode */
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 /* ASSEMBLY */
00205 
00206 #endif /* LIBRM_H */

Generated on Tue Apr 6 20:00:50 2010 for gPXE by  doxygen 1.5.7.1