Home | History | Annotate | Download | only in include
      1 #ifndef LIBRM_H
      2 #define LIBRM_H
      3 
      4 FILE_LICENCE ( GPL2_OR_LATER );
      5 
      6 /* Segment selectors as used in our protected-mode GDTs.
      7  *
      8  * Don't change these unless you really know what you're doing.
      9  */
     10 
     11 #define VIRTUAL_CS 0x08
     12 #define VIRTUAL_DS 0x10
     13 #define PHYSICAL_CS 0x18
     14 #define PHYSICAL_DS 0x20
     15 #define REAL_CS 0x28
     16 #define REAL_DS 0x30
     17 #if 0
     18 #define LONG_CS 0x38
     19 #define LONG_DS 0x40
     20 #endif
     21 
     22 #ifndef ASSEMBLY
     23 
     24 #ifdef UACCESS_LIBRM
     25 #define UACCESS_PREFIX_librm
     26 #else
     27 #define UACCESS_PREFIX_librm __librm_
     28 #endif
     29 
     30 /* Variables in librm.S */
     31 extern unsigned long virt_offset;
     32 
     33 /**
     34  * Convert physical address to user pointer
     35  *
     36  * @v phys_addr		Physical address
     37  * @ret userptr		User pointer
     38  */
     39 static inline __always_inline userptr_t
     40 UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
     41 	return ( phys_addr - virt_offset );
     42 }
     43 
     44 /**
     45  * Convert user buffer to physical address
     46  *
     47  * @v userptr		User pointer
     48  * @v offset		Offset from user pointer
     49  * @ret phys_addr	Physical address
     50  */
     51 static inline __always_inline unsigned long
     52 UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) {
     53 	return ( userptr + offset + virt_offset );
     54 }
     55 
     56 static inline __always_inline userptr_t
     57 UACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) {
     58 	return trivial_virt_to_user ( addr );
     59 }
     60 
     61 static inline __always_inline void *
     62 UACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) {
     63 	return trivial_user_to_virt ( userptr, offset );
     64 }
     65 
     66 static inline __always_inline userptr_t
     67 UACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) {
     68 	return trivial_userptr_add ( userptr, offset );
     69 }
     70 
     71 static inline __always_inline void
     72 UACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off,
     73 					userptr_t src, off_t src_off,
     74 					size_t len ) {
     75 	trivial_memcpy_user ( dest, dest_off, src, src_off, len );
     76 }
     77 
     78 static inline __always_inline void
     79 UACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off,
     80 					 userptr_t src, off_t src_off,
     81 					 size_t len ) {
     82 	trivial_memmove_user ( dest, dest_off, src, src_off, len );
     83 }
     84 
     85 static inline __always_inline void
     86 UACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset,
     87 					int c, size_t len ) {
     88 	trivial_memset_user ( buffer, offset, c, len );
     89 }
     90 
     91 static inline __always_inline size_t
     92 UACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) {
     93 	return trivial_strlen_user ( buffer, offset );
     94 }
     95 
     96 static inline __always_inline off_t
     97 UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset,
     98 					int c, size_t len ) {
     99 	return trivial_memchr_user ( buffer, offset, c, len );
    100 }
    101 
    102 
    103 /******************************************************************************
    104  *
    105  * Access to variables in .data16 and .text16
    106  *
    107  */
    108 
    109 extern char *data16;
    110 extern char *text16;
    111 
    112 #define __data16( variable )						\
    113 	__attribute__ (( section ( ".data16" ) ))			\
    114 	_data16_ ## variable __asm__ ( #variable )
    115 
    116 #define __data16_array( variable, array )				\
    117 	__attribute__ (( section ( ".data16" ) ))			\
    118 	_data16_ ## variable array __asm__ ( #variable )
    119 
    120 #define __bss16( variable )						\
    121 	__attribute__ (( section ( ".bss16" ) ))			\
    122 	_data16_ ## variable __asm__ ( #variable )
    123 
    124 #define __bss16_array( variable, array )				\
    125 	__attribute__ (( section ( ".bss16" ) ))			\
    126 	_data16_ ## variable array __asm__ ( #variable )
    127 
    128 #define __text16( variable )						\
    129 	__attribute__ (( section ( ".text16.data" ) ))			\
    130 	_text16_ ## variable __asm__ ( #variable )
    131 
    132 #define __text16_array( variable, array )				\
    133 	__attribute__ (( section ( ".text16.data" ) ))			\
    134 	_text16_ ## variable array __asm__ ( #variable )
    135 
    136 #define __use_data16( variable )					\
    137 	( * ( ( typeof ( _data16_ ## variable ) * )			\
    138 	      & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) )
    139 
    140 #define __use_text16( variable )					\
    141 	( * ( ( typeof ( _text16_ ## variable ) * )			\
    142 	      & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) )
    143 
    144 #define __from_data16( pointer )					\
    145 	( ( unsigned int )						\
    146 	  ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) )
    147 
    148 #define __from_text16( pointer )					\
    149 	( ( unsigned int )						\
    150 	  ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) )
    151 
    152 /* Variables in librm.S, present in the normal data segment */
    153 extern uint16_t rm_sp;
    154 extern uint16_t rm_ss;
    155 extern uint16_t __data16 ( rm_cs );
    156 #define rm_cs __use_data16 ( rm_cs )
    157 extern uint16_t __text16 ( rm_ds );
    158 #define rm_ds __use_text16 ( rm_ds )
    159 
    160 /* Functions that librm expects to be able to link to.  Included here
    161  * so that the compiler will catch prototype mismatches.
    162  */
    163 extern void gateA20_set ( void );
    164 
    165 /**
    166  * Convert segment:offset address to user buffer
    167  *
    168  * @v segment		Real-mode segment
    169  * @v offset		Real-mode offset
    170  * @ret buffer		User buffer
    171  */
    172 static inline __always_inline userptr_t
    173 real_to_user ( unsigned int segment, unsigned int offset ) {
    174 	return ( phys_to_user ( ( segment << 4 ) + offset ) );
    175 }
    176 
    177 extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size );
    178 extern void remove_user_from_rm_stack ( userptr_t data, size_t size );
    179 
    180 /* TEXT16_CODE: declare a fragment of code that resides in .text16 */
    181 #define TEXT16_CODE( asm_code_str )			\
    182 	".section \".text16\", \"ax\", @progbits\n\t"	\
    183 	".code16\n\t"					\
    184 	asm_code_str "\n\t"				\
    185 	".code32\n\t"					\
    186 	".previous\n\t"
    187 
    188 /* REAL_CODE: declare a fragment of code that executes in real mode */
    189 #define REAL_CODE( asm_code_str )			\
    190 	"pushl $1f\n\t"					\
    191 	"call real_call\n\t"				\
    192 	"addl $4, %%esp\n\t"				\
    193 	TEXT16_CODE ( "\n1:\n\t"			\
    194 		      asm_code_str			\
    195 		      "\n\t"				\
    196 		      "ret\n\t" )
    197 
    198 /* PHYS_CODE: declare a fragment of code that executes in flat physical mode */
    199 #define PHYS_CODE( asm_code_str )			\
    200 	"call _virt_to_phys\n\t"			\
    201 	asm_code_str					\
    202 	"call _phys_to_virt\n\t"
    203 
    204 #endif /* ASSEMBLY */
    205 
    206 #endif /* LIBRM_H */
    207