Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #ifndef LIBKIR_H
  2. #define LIBKIR_H
  3. #include "realmode.h"
  4. #ifndef ASSEMBLY
  5. /*
  6. * Full API documentation for these functions is in realmode.h.
  7. *
  8. */
  9. /* Copy to/from base memory */
  10. static inline void copy_to_real_libkir ( uint16_t dest_seg, uint16_t dest_off,
  11. void *src, size_t n ) {
  12. __asm__ ( "movw %4, %%es\n\t"
  13. "cld\n\t"
  14. "rep movsb\n\t"
  15. "pushw %%ds\n\t" /* restore %es */
  16. "popw %%es\n\t"
  17. : "=S" ( src ), "=D" ( dest_off ), "=c" ( n ) /* clobbered */
  18. : "S" ( src ), "r" ( dest_seg ), "D" ( dest_off ), "c" ( n )
  19. : "memory"
  20. );
  21. }
  22. static inline void copy_from_real_libkir ( void *dest,
  23. uint16_t src_seg, uint16_t src_off,
  24. size_t n ) {
  25. __asm__ ( "movw %%ax, %%ds\n\t"
  26. "cld\n\t"
  27. "rep movsb\n\t"
  28. "pushw %%es\n\t" /* restore %ds */
  29. "popw %%ds\n\t"
  30. : "=S" ( src_off ), "=D" ( dest ), "=c" ( n ) /* clobbered */
  31. : "a" ( src_seg ), "S" ( src_off ), "D" ( dest ), "c" ( n )
  32. : "memory"
  33. );
  34. }
  35. #define copy_to_real copy_to_real_libkir
  36. #define copy_from_real copy_from_real_libkir
  37. /*
  38. * Transfer individual values to/from base memory. There may well be
  39. * a neater way to do this. We have two versions: one for constant
  40. * offsets (where the mov instruction must be of the form "mov
  41. * %es:123, %xx") and one for non-constant offsets (where the mov
  42. * instruction must be of the form "mov %es:(%xx), %yx". If it's
  43. * possible to incorporate both forms into one __asm__ instruction, I
  44. * don't know how to do it.
  45. *
  46. * Ideally, the mov instruction should be "mov%z0"; the "%z0" is meant
  47. * to expand to either "b", "w" or "l" depending on the size of
  48. * operand 0. This would remove the (minor) ambiguity in the mov
  49. * instruction. However, gcc on at least my system barfs with an
  50. * "internal compiler error" when confronted with %z0.
  51. *
  52. */
  53. #define put_real_kir_const_off( var, seg, off ) \
  54. __asm__ ( "movw %w1, %%es\n\t" \
  55. "mov %0, %%es:%c2\n\t" \
  56. "pushw %%ds\n\t" /* restore %es */ \
  57. "popw %%es\n\t" \
  58. : \
  59. : "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off ) \
  60. )
  61. #define put_real_kir_nonconst_off( var, seg, off ) \
  62. __asm__ ( "movw %w1, %%es\n\t" \
  63. "mov %0, %%es:(%2)\n\t" \
  64. "pushw %%ds\n\t" /* restore %es */ \
  65. "popw %%es\n\t" \
  66. : \
  67. : "r" ( var ), "rm" ( seg ), "r" ( off ) \
  68. )
  69. #define put_real_kir( var, seg, off ) \
  70. do { \
  71. if ( __builtin_constant_p ( off ) ) \
  72. put_real_kir_const_off ( var, seg, off ); \
  73. else \
  74. put_real_kir_nonconst_off ( var, seg, off ); \
  75. } while ( 0 )
  76. #define get_real_kir_const_off( var, seg, off ) \
  77. __asm__ ( "movw %w1, %%es\n\t" \
  78. "mov %%es:%c2, %0\n\t" \
  79. "pushw %%ds\n\t" /* restore %es */ \
  80. "popw %%es\n\t" \
  81. : "=r,r" ( var ) \
  82. : "rm,rm" ( seg ), "i,!r" ( off ) \
  83. )
  84. #define get_real_kir_nonconst_off( var, seg, off ) \
  85. __asm__ ( "movw %w1, %%es\n\t" \
  86. "mov %%es:(%2), %0\n\t" \
  87. "pushw %%ds\n\t" /* restore %es */ \
  88. "popw %%es\n\t" \
  89. : "=r" ( var ) \
  90. : "rm" ( seg ), "r" ( off ) \
  91. )
  92. #define get_real_kir( var, seg, off ) \
  93. do { \
  94. if ( __builtin_constant_p ( off ) ) \
  95. get_real_kir_const_off ( var, seg, off ); \
  96. else \
  97. get_real_kir_nonconst_off ( var, seg, off ); \
  98. } while ( 0 )
  99. #define put_real put_real_kir
  100. #define get_real get_real_kir
  101. /* Place/remove parameter on real-mode stack in a way that's
  102. * compatible with libkir
  103. */
  104. #define BASEMEM_PARAMETER_INIT_LIBKIR( param ) \
  105. ( ( uint16_t ) ( ( uint32_t ) & ( param ) ) )
  106. #define BASEMEM_PARAMETER_DONE_LIBKIR( param )
  107. #define BASEMEM_PARAMETER_INIT BASEMEM_PARAMETER_INIT_LIBKIR
  108. #define BASEMEM_PARAMETER_DONE BASEMEM_PARAMETER_DONE_LIBKIR
  109. /* REAL_CALL: call an external real-mode routine */
  110. #define OUT_CONSTRAINTS(...) __VA_ARGS__
  111. #define IN_CONSTRAINTS(...) "m" ( __routine ), ## __VA_ARGS__
  112. #define CLOBBER(...) __VA_ARGS__
  113. #define REAL_CALL( routine, num_out_constraints, out_constraints, \
  114. in_constraints, clobber ) \
  115. do { \
  116. segoff_t __routine = routine; \
  117. __asm__ __volatile__ ( \
  118. "pushl %" #num_out_constraints "\n\t" \
  119. ".code16\n\t" \
  120. "pushw %%gs\n\t" /* preserve segs */ \
  121. "pushw %%fs\n\t" \
  122. "pushw %%es\n\t" \
  123. "pushw %%ds\n\t" \
  124. "pushw %%cs\n\t" /* lcall to routine */ \
  125. "call 1f\n\t" \
  126. "jmp 2f\n\t" \
  127. "\n1:\n\t" \
  128. "addr32 pushl 12(%%esp)\n\t" \
  129. "lret\n\t" \
  130. "\n2:\n\t" \
  131. "popw %%ds\n\t" /* restore segs */ \
  132. "popw %%es\n\t" \
  133. "popw %%fs\n\t" \
  134. "popw %%gs\n\t" \
  135. "addw $4, %%sp\n\t" \
  136. ".code16gcc\n\t" \
  137. : out_constraints : in_constraints : clobber \
  138. ); \
  139. } while ( 0 )
  140. /* REAL_EXEC: execute some inline assembly code in a way that matches
  141. * the interface of librm
  142. */
  143. #define IN_CONSTRAINTS_NO_ROUTINE( routine, ... ) __VA_ARGS__
  144. #define REAL_EXEC( name, asm_code_str, num_out_constraints, out_constraints, \
  145. in_constraints, clobber ) \
  146. __asm__ __volatile__ ( \
  147. ".code16\n\t" \
  148. "pushw %%gs\n\t" \
  149. "pushw %%fs\n\t" \
  150. "pushw %%es\n\t" \
  151. "pushw %%ds\n\t" \
  152. "\n" #name ":\n\t" \
  153. asm_code_str \
  154. "popw %%ds\n\t" \
  155. "popw %%es\n\t" \
  156. "popw %%fs\n\t" \
  157. "popw %%gs\n\t" \
  158. ".code16gcc\n\t" \
  159. : out_constraints \
  160. : IN_CONSTRAINTS_NO_ROUTINE ( in_constraints ) \
  161. : clobber \
  162. );
  163. #endif /* ASSEMBLY */
  164. #endif /* LIBKIR_H */