Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

librm_mgmt.c 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * librm: a library for interfacing to real-mode code
  3. *
  4. * Michael Brown <mbrown@fensystems.co.uk>
  5. *
  6. */
  7. #ifdef KEEP_IT_REAL
  8. /* Build a null object under -DKEEP_IT_REAL */
  9. #else
  10. #include "stdint.h"
  11. #include "stddef.h"
  12. #include "string.h"
  13. #include "init.h"
  14. #include "basemem.h"
  15. #include "librm.h"
  16. /*
  17. * This file provides functions for managing librm.
  18. *
  19. */
  20. /* Current location of librm in base memory */
  21. char *installed_librm = librm;
  22. static uint32_t installed_librm_phys;
  23. /* Whether or not we have base memory currently allocated for librm.
  24. * Note that we *can* have a working librm present in unallocated base
  25. * memory; this is the situation at startup for all real-mode
  26. * prefixes.
  27. */
  28. static int allocated_librm = 0;
  29. /*
  30. * Allocate space on the real-mode stack and copy data there.
  31. *
  32. */
  33. uint16_t copy_to_rm_stack ( void *data, size_t size ) {
  34. #ifdef DEBUG_LIBRM
  35. if ( inst_rm_stack.offset <= size ) {
  36. printf ( "librm: out of space in RM stack\n" );
  37. lockup();
  38. }
  39. #endif
  40. inst_rm_stack.offset -= size;
  41. copy_to_real ( inst_rm_stack.segment, inst_rm_stack.offset,
  42. data, size );
  43. return inst_rm_stack.offset;
  44. };
  45. /*
  46. * Deallocate space on the real-mode stack, optionally copying back
  47. * data.
  48. *
  49. */
  50. void remove_from_rm_stack ( void *data, size_t size ) {
  51. if ( data ) {
  52. copy_from_real ( data,
  53. inst_rm_stack.segment, inst_rm_stack.offset,
  54. size );
  55. }
  56. inst_rm_stack.offset += size;
  57. };
  58. /*
  59. * Install librm to base memory
  60. *
  61. */
  62. static inline void install_librm ( char *addr ) {
  63. memcpy ( addr, librm, librm_size );
  64. installed_librm = addr;
  65. }
  66. /*
  67. * Uninstall librm from base memory. This copies librm back to the
  68. * "master" copy, so that it can be reinstalled to a new location,
  69. * preserving the values for rm_ss and rm_sp from the old installed
  70. * copy.
  71. *
  72. */
  73. static inline void uninstall_librm ( void ) {
  74. memcpy ( librm, installed_librm, librm_size );
  75. }
  76. /*
  77. * On entry, record the physical location of librm. Do this so that
  78. * we can update installed_librm after relocation.
  79. *
  80. * Doing this is probably more efficient than making installed_librm
  81. * be a physical address, because of the number of times that
  82. * installed_librm gets referenced in the remainder of the code.
  83. *
  84. */
  85. static void librm_init ( void ) {
  86. installed_librm_phys = virt_to_phys ( installed_librm );
  87. }
  88. /*
  89. * On exit, we want to leave a copy of librm in *unallocated* base
  90. * memory. It must be there so that we can exit via a 16-bit exit
  91. * path, but it must not be allocated because nothing will ever
  92. * deallocate it once we exit.
  93. *
  94. */
  95. static void librm_exit ( void ) {
  96. /* Free but do not zero the base memory */
  97. if ( allocated_librm ) {
  98. free_base_memory ( installed_librm, librm_size );
  99. allocated_librm = 0;
  100. }
  101. }
  102. /*
  103. * On reset, we want to free up our old installed copy of librm, if
  104. * any, then allocate a new base memory block and install there.
  105. *
  106. */
  107. static void librm_reset ( void ) {
  108. char *new_librm;
  109. /* Point installed_librm back at last known physical location */
  110. installed_librm = phys_to_virt ( installed_librm_phys );
  111. /* Uninstall old librm */
  112. uninstall_librm();
  113. /* Free allocated base memory, if applicable */
  114. librm_exit();
  115. /* Allocate space for new librm */
  116. new_librm = alloc_base_memory ( librm_size );
  117. allocated_librm = 1;
  118. /* Install new librm */
  119. install_librm ( new_librm );
  120. }
  121. INIT_FN ( INIT_LIBRM, librm_init, librm_reset, librm_exit );
  122. /*
  123. * Increment lock count of librm
  124. *
  125. */
  126. void lock_librm ( void ) {
  127. inst_librm_ref_count++;
  128. }
  129. /*
  130. * Decrement lock count of librm
  131. *
  132. */
  133. void unlock_librm ( void ) {
  134. #ifdef DEBUG_LIBRM
  135. if ( inst_librm_ref_count == 0 ) {
  136. printf ( "librm: ref count gone negative\n" );
  137. lockup();
  138. }
  139. #endif
  140. inst_librm_ref_count--;
  141. }
  142. #endif /* KEEP_IT_REAL */