Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. /* Real-mode call parameter block, as passed to real_call */
  14. struct real_call_params {
  15. struct i386_seg_regs;
  16. struct i386_regs;
  17. segoff_t rm_code;
  18. segoff_t reserved;
  19. } PACKED;
  20. /* Current location of librm in base memory */
  21. extern char *installed_librm;
  22. /* Start and size of our source copy of librm (i.e. the one that we
  23. * can install by copying it to base memory and setting
  24. * installed_librm)
  25. */
  26. extern char librm[];
  27. extern size_t _librm_size[];
  28. /* Linker symbols for offsets within librm. Other symbols should
  29. * almost certainly not be referred to from C code.
  30. */
  31. extern void (*_real_to_prot[]) ( void );
  32. extern void (*_prot_to_real[]) ( void );
  33. extern void (*_prot_call[]) ( void );
  34. extern void (*_real_call[]) ( void );
  35. extern uint32_t _librm_base[];
  36. extern segoff_t _rm_stack[];
  37. extern uint32_t _pm_stack[];
  38. extern char _librm_ref_count[];
  39. /* Symbols within current installation of librm */
  40. #define LIBRM_VAR( sym ) \
  41. ( * ( ( typeof ( * _ ## sym ) * ) \
  42. & ( installed_librm [ (int) _ ## sym ] ) ) )
  43. #define LIBRM_FN( sym ) \
  44. ( ( typeof ( * _ ## sym ) ) \
  45. & ( installed_librm [ (int) _ ## sym ] ) )
  46. #define LIBRM_CONSTANT( sym ) \
  47. ( ( typeof ( * _ ## sym ) ) ( _ ## sym ) )
  48. #define inst_real_to_prot LIBRM_FN ( real_to_prot )
  49. #define inst_prot_to_real LIBRM_FN ( prot_to_real )
  50. #define inst_prot_call LIBRM_FN ( prot_call )
  51. #define inst_real_call LIBRM_FN ( real_call )
  52. #define inst_librm_base LIBRM_VAR ( librm_base )
  53. #define inst_rm_stack LIBRM_VAR ( rm_stack )
  54. #define inst_pm_stack LIBRM_VAR ( pm_stack )
  55. #define inst_librm_ref_count LIBRM_VAR ( librm_ref_count )
  56. #define librm_size LIBRM_CONSTANT ( librm_size )
  57. /* Symbols within local (uninstalled) copy of librm */
  58. extern uint32_t librm_base;
  59. /* Functions that librm expects to be able to link to. Included here
  60. * so that the compiler will catch prototype mismatches.
  61. */
  62. extern void _phys_to_virt ( void );
  63. extern void _virt_to_phys ( void );
  64. extern void gateA20_set ( void );
  65. /*
  66. * librm_mgmt: functions for manipulating base memory and executing
  67. * real-mode code.
  68. *
  69. * Full API documentation for these functions is in realmode.h.
  70. *
  71. */
  72. /* Macro for obtaining a physical address from a segment:offset pair. */
  73. #define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
  74. /* Copy to/from base memory */
  75. static inline void copy_to_real_librm ( uint16_t dest_seg, uint16_t dest_off,
  76. void *src, size_t n ) {
  77. memcpy ( VIRTUAL ( dest_seg, dest_off ), src, n );
  78. }
  79. static inline void copy_from_real_librm ( void *dest,
  80. uint16_t src_seg, uint16_t src_off,
  81. size_t n ) {
  82. memcpy ( dest, VIRTUAL ( src_seg, src_off ), n );
  83. }
  84. #define put_real_librm( var, dest_seg, dest_off ) \
  85. do { \
  86. * ( ( typeof(var) * ) VIRTUAL ( dest_seg, dest_off ) ) = var; \
  87. } while ( 0 )
  88. #define get_real_librm( var, src_seg, src_off ) \
  89. do { \
  90. var = * ( ( typeof(var) * ) VIRTUAL ( src_seg, src_off ) ); \
  91. } while ( 0 )
  92. #define copy_to_real copy_to_real_librm
  93. #define copy_from_real copy_from_real_librm
  94. #define put_real put_real_librm
  95. #define get_real get_real_librm
  96. /* Copy to/from real-mode stack */
  97. extern uint16_t copy_to_rm_stack ( void *data, size_t size );
  98. extern void remove_from_rm_stack ( void *data, size_t size );
  99. /* Place/remove parameter on real-mode stack in a way that's
  100. * compatible with libkir
  101. */
  102. #define BASEMEM_PARAMETER_INIT_LIBRM( param ) \
  103. copy_to_rm_stack ( & ( param ), sizeof ( param ) )
  104. #define BASEMEM_PARAMETER_DONE_LIBRM( param ) \
  105. remove_from_rm_stack ( & ( param ), sizeof ( param ) )
  106. #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBRM
  107. #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBRM
  108. /* REAL_FRAGMENT: Declare and define a real-mode code fragment in .text16 */
  109. #define REAL_FRAGMENT( name, asm_code_str ) \
  110. extern void name ( void ); \
  111. extern char name ## _size[]; \
  112. __asm__ __volatile__ ( \
  113. ".section \".text16\"\n\t" \
  114. ".code16\n\t" \
  115. ".arch i386\n\t" \
  116. #name ":\n\t" \
  117. asm_code_str "\n\t" \
  118. "lret\n\t" \
  119. #name "_end:\n\t" \
  120. ".equ " #name "_size, " #name "_end - " #name "\n\t" \
  121. ".code32\n\t" \
  122. ".previous\n\t" \
  123. : : \
  124. )
  125. #define FRAGMENT_SIZE( fragment ) ( (size_t) fragment ## _size )
  126. /* REAL_CALL: call a real-mode routine via librm */
  127. #define OUT_CONSTRAINTS(...) __VA_ARGS__
  128. #define IN_CONSTRAINTS(...) "m" ( __routine ), ## __VA_ARGS__
  129. #define CLOBBER(...) __VA_ARGS__
  130. #define REAL_CALL( routine, num_out_constraints, out_constraints, \
  131. in_constraints, clobber ) \
  132. do { \
  133. segoff_t __routine = routine; \
  134. __asm__ __volatile__ ( \
  135. "pushl %" #num_out_constraints "\n\t" \
  136. "call 1f\n\t" \
  137. "jmp 2f\n\t" \
  138. "\n1:\n\t" \
  139. "pushl installed_librm\n\t" \
  140. "addl $_real_call, 0(%%esp)\n\t" \
  141. "ret\n\t" \
  142. "\n2:\n\t" \
  143. "addl $4, %%esp\n\t" \
  144. : out_constraints \
  145. : in_constraints \
  146. : clobber \
  147. ); \
  148. } while ( 0 )
  149. /* REAL_EXEC: combine RM_FRAGMENT and REAL_CALL into one handy unit */
  150. #define PASSTHRU(...) __VA_ARGS__
  151. #define REAL_EXEC( name, asm_code_str, num_out_constraints, out_constraints, \
  152. in_constraints, clobber ) \
  153. do { \
  154. segoff_t fragment; \
  155. \
  156. REAL_FRAGMENT ( name, asm_code_str ); \
  157. \
  158. fragment.segment = inst_rm_stack.segment; \
  159. fragment.offset = \
  160. copy_to_rm_stack ( name, FRAGMENT_SIZE ( name ) ); \
  161. \
  162. REAL_CALL ( fragment, num_out_constraints, \
  163. PASSTHRU ( out_constraints ), \
  164. PASSTHRU ( in_constraints ), \
  165. PASSTHRU ( clobber ) ); \
  166. \
  167. remove_from_rm_stack ( NULL, FRAGMENT_SIZE ( name ) ); \
  168. } while ( 0 )
  169. #endif /* ASSEMBLY */
  170. #endif /* LIBRM_H */