You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

librm.h 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #ifndef LIBRM_H
  2. #define LIBRM_H
  3. /* Drag in protected-mode segment selector values */
  4. #include "virtaddr.h"
  5. #include "realmode.h"
  6. #ifndef ASSEMBLY
  7. #include "stddef.h"
  8. #include "string.h"
  9. /*
  10. * Data structures and type definitions
  11. *
  12. */
  13. /* Access to variables in .data16 and .text16 */
  14. extern char *data16;
  15. extern char *text16;
  16. #define __data16( variable ) \
  17. __attribute__ (( section ( ".data16" ) )) \
  18. _data16_ ## variable __asm__ ( #variable )
  19. #define __data16_array( variable, array ) \
  20. __attribute__ (( section ( ".data16" ) )) \
  21. _data16_ ## variable array __asm__ ( #variable )
  22. #define __text16( variable ) \
  23. __attribute__ (( section ( ".text16.data" ) )) \
  24. _text16_ ## variable __asm__ ( #variable )
  25. #define __text16_array( variable, array ) \
  26. __attribute__ (( section ( ".text16.data" ) )) \
  27. _text16_ ## variable array __asm__ ( #variable )
  28. #define __use_data16( variable ) \
  29. ( * ( ( typeof ( _data16_ ## variable ) * ) \
  30. & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) )
  31. #define __use_text16( variable ) \
  32. ( * ( ( typeof ( _text16_ ## variable ) * ) \
  33. & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) )
  34. #define __from_data16( variable ) \
  35. ( * ( ( typeof ( variable ) * ) \
  36. ( ( ( void * ) &(variable) ) - ( ( void * ) data16 ) ) ) )
  37. #define __from_text16( variable ) \
  38. ( * ( ( typeof ( variable ) * ) \
  39. ( ( ( void * ) &(variable) ) - ( ( void * ) text16 ) ) ) )
  40. /* Variables in librm.S, present in the normal data segment */
  41. extern uint16_t rm_sp;
  42. extern uint16_t rm_ss;
  43. extern uint32_t pm_esp;
  44. extern uint16_t __data16 ( rm_cs );
  45. #define rm_cs __use_data16 ( rm_cs )
  46. extern uint16_t __text16 ( rm_ds );
  47. #define rm_ds __use_text16 ( rm_ds )
  48. /* Functions that librm expects to be able to link to. Included here
  49. * so that the compiler will catch prototype mismatches.
  50. */
  51. extern void gateA20_set ( void );
  52. /*
  53. * librm_mgmt: functions for manipulating base memory and executing
  54. * real-mode code.
  55. *
  56. * Full API documentation for these functions is in realmode.h.
  57. *
  58. */
  59. /* Macro for obtaining a physical address from a segment:offset pair. */
  60. #define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
  61. /* Copy to/from base memory */
  62. static inline __attribute__ (( always_inline )) void
  63. copy_to_real_librm ( unsigned int dest_seg, unsigned int dest_off,
  64. void *src, size_t n ) {
  65. memcpy ( VIRTUAL ( dest_seg, dest_off ), src, n );
  66. }
  67. static inline __attribute__ (( always_inline )) void
  68. copy_from_real_librm ( void *dest, unsigned int src_seg,
  69. unsigned int src_off, size_t n ) {
  70. memcpy ( dest, VIRTUAL ( src_seg, src_off ), n );
  71. }
  72. #define put_real_librm( var, dest_seg, dest_off ) \
  73. do { \
  74. * ( ( typeof(var) * ) VIRTUAL ( dest_seg, dest_off ) ) = var; \
  75. } while ( 0 )
  76. #define get_real_librm( var, src_seg, src_off ) \
  77. do { \
  78. var = * ( ( typeof(var) * ) VIRTUAL ( src_seg, src_off ) ); \
  79. } while ( 0 )
  80. #define copy_to_real copy_to_real_librm
  81. #define copy_from_real copy_from_real_librm
  82. #define put_real put_real_librm
  83. #define get_real get_real_librm
  84. /**
  85. * A pointer to a user buffer
  86. *
  87. * Even though we could just use a void *, we use an intptr_t so that
  88. * attempts to use normal pointers show up as compiler warnings. Such
  89. * code is actually valid for librm, but not for libkir (i.e. under
  90. * KEEP_IT_REAL), so it's good to have the warnings even under librm.
  91. */
  92. typedef intptr_t userptr_t;
  93. /**
  94. * Copy data to user buffer
  95. *
  96. * @v buffer User buffer
  97. * @v offset Offset within user buffer
  98. * @v src Source
  99. * @v len Length
  100. */
  101. static inline __attribute__ (( always_inline )) void
  102. copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) {
  103. memcpy ( ( void * ) buffer + offset, src, len );
  104. }
  105. /**
  106. * Copy data from user buffer
  107. *
  108. * @v dest Destination
  109. * @v buffer User buffer
  110. * @v offset Offset within user buffer
  111. * @v len Length
  112. */
  113. static inline __attribute__ (( always_inline )) void
  114. copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) {
  115. memcpy ( dest, ( void * ) buffer + offset, len );
  116. }
  117. /**
  118. * Convert virtual address to user buffer
  119. *
  120. * @v virtual Virtual address
  121. * @ret buffer User buffer
  122. *
  123. * This constructs a user buffer from an ordinary pointer. Use it
  124. * when you need to pass a pointer to an internal buffer to a function
  125. * that expects a @c userptr_t.
  126. */
  127. static inline __attribute__ (( always_inline )) userptr_t
  128. virt_to_user ( void * virtual ) {
  129. return ( ( intptr_t ) virtual );
  130. }
  131. /**
  132. * Convert segment:offset address to user buffer
  133. *
  134. * @v segment Real-mode segment
  135. * @v offset Real-mode offset
  136. * @ret buffer User buffer
  137. */
  138. static inline __attribute__ (( always_inline )) userptr_t
  139. real_to_user ( unsigned int segment, unsigned int offset ) {
  140. return virt_to_user ( VIRTUAL ( segment, offset ) );
  141. }
  142. /* Copy to/from real-mode stack */
  143. extern uint16_t copy_to_rm_stack ( void *data, size_t size );
  144. extern void remove_from_rm_stack ( void *data, size_t size );
  145. /* Place/remove parameter on real-mode stack in a way that's
  146. * compatible with libkir
  147. */
  148. #define BASEMEM_PARAMETER_INIT_LIBRM( param ) \
  149. copy_to_rm_stack ( & ( param ), sizeof ( param ) )
  150. #define BASEMEM_PARAMETER_DONE_LIBRM( param ) \
  151. remove_from_rm_stack ( & ( param ), sizeof ( param ) )
  152. #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBRM
  153. #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBRM
  154. /* TEXT16_CODE: declare a fragment of code that resides in .text16 */
  155. #define TEXT16_CODE( asm_code_str ) \
  156. ".section \".text16\", \"ax\", @progbits\n\t" \
  157. ".code16\n\t" \
  158. ".arch i386\n\t" \
  159. asm_code_str "\n\t" \
  160. ".code32\n\t" \
  161. ".previous\n\t"
  162. /* REAL_CODE: declare a fragment of code that executes in real mode */
  163. #define REAL_CODE( asm_code_str ) \
  164. "pushl $1f\n\t" \
  165. "call real_call\n\t" \
  166. "addl $4, %%esp\n\t" \
  167. TEXT16_CODE ( "\n1:\n\t" \
  168. asm_code_str \
  169. "\n\t" \
  170. "ret\n\t" )
  171. #endif /* ASSEMBLY */
  172. #endif /* LIBRM_H */