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.

setup.S 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /****************************************************************************
  2. * This file provides the setup() and setup16() functions. The
  3. * purpose of these functions is to set up the internal environment so
  4. * that C code can execute. This includes setting up the internal
  5. * stack and (where applicable) setting up a GDT for virtual
  6. * addressing.
  7. *
  8. * These functions are designed to be called by the prefix.
  9. *
  10. * The same basic assembly code is used to compile both setup()
  11. * and setup16().
  12. ****************************************************************************
  13. */
  14. .text
  15. .arch i386
  16. #ifdef CODE16
  17. /****************************************************************************
  18. * setup16 (real-mode far call)
  19. *
  20. * This function can be called by a 16-bit prefix in order to set up
  21. * the internal (either 16-bit or 32-bit) environment.
  22. *
  23. * Parameters: none
  24. *
  25. * %cs:0000, %ds:0000 and %es:0000 must point to the start of the
  26. * (decompressed) runtime image.
  27. *
  28. * If KEEP_IT_REAL is defined, then %ds:0000 may instead point to the
  29. * start of the (decompressed) data segment portion of the runtime
  30. * image. If %ds==%cs, then it will be assumed that the data segment
  31. * follows immediately after the code segment.
  32. ****************************************************************************
  33. */
  34. #ifdef KEEP_IT_REAL
  35. #define ENTER_FROM_EXTERNAL call ext_to_kir
  36. #define RETURN_TO_EXTERNAL call kir_to_ext
  37. #define ENTRY_POINT kir_call
  38. #define ENTRY_POINT_REGISTER di
  39. #define INIT_FUNC initialise
  40. #else /* KEEP_IT_REAL */
  41. #define ENTER_FROM_EXTERNAL \
  42. pushw %cs ; \
  43. call real_to_prot ; \
  44. .code32
  45. #define RETURN_TO_EXTERNAL \
  46. call prot_to_real ; \
  47. .code16
  48. #define ENTRY_POINT _prot_call /* _prot_call = OFFSET ( prot_call ) in librm */
  49. #define ENTRY_POINT_REGISTER di
  50. #define INIT_FUNC initialise_via_librm
  51. #endif /* KEEP_IT_REAL */
  52. .section ".text16"
  53. .code16
  54. .globl setup16
  55. setup16:
  56. #else /* CODE16 */
  57. /****************************************************************************
  58. * setup (32-bit protected-mode near call)
  59. *
  60. * This function can be called by a 32-bit prefix in order to set up
  61. * the internal 32-bit environment.
  62. *
  63. * Parameters: none
  64. ****************************************************************************
  65. */
  66. #define ENTER_FROM_EXTERNAL call ext_to_int
  67. #define RETURN_TO_EXTERNAL call int_to_ext
  68. #define ENTRY_POINT int_call
  69. #define ENTRY_POINT_REGISTER edi
  70. #define INIT_FUNC initialise
  71. .section ".text"
  72. .code32
  73. .globl setup
  74. setup:
  75. #endif /* CODE16 */
  76. /* Preserve flags (including interrupt status) and registers */
  77. pushfl
  78. pushl %ebp
  79. /* Switch to (uninitialised) internal environment. This will
  80. * preserve the external environment for when we call
  81. * RETURN_TO_EXTERNAL.
  82. */
  83. ENTER_FROM_EXTERNAL
  84. /* NOTE: We may have only four bytes of stack at this point */
  85. #if defined(CODE16) && defined(KEEP_IT_REAL)
  86. /* If %ds == %cs, then the data segment is located immediately
  87. * after the code segment.
  88. */
  89. pushw %ax
  90. movw %cs, %ax
  91. movw %ds, %bp
  92. cmpw %ax, %bp
  93. jne 1f
  94. addw $_text_load_size_pgh, %ax
  95. movw %ax, %ds
  96. 1: popw %ax
  97. /* Switch to internal stack */
  98. pushw %ds
  99. popw %ss
  100. movl $_estack, %esp
  101. #else /* CODE16 && KEEP_IT_REAL */
  102. /* Work out where we're running and switch to internal pmode
  103. * stack
  104. */
  105. call 1f
  106. 1: popl %ebp
  107. leal (_estack-1b)(%ebp), %esp
  108. /* Set up GDT for virtual addressing */
  109. call run_here
  110. #endif /* CODE16 && KEEP_IT_REAL */
  111. /* Switch back to external environment. This will preserve
  112. * the internal environment ready for the next call.
  113. */
  114. RETURN_TO_EXTERNAL
  115. /* Set %es:[e]di to point to entry-point function.
  116. */
  117. push %cs
  118. pop %es
  119. mov $ENTRY_POINT, %ENTRY_POINT_REGISTER
  120. /* Far call to initialise via the entry-point function.
  121. * initialise() (or the entry-point function itself) may
  122. * update %es:[e]di to point to a new entry-point function for
  123. * subsequent calls. librm will use this facility, since
  124. * initialise() causes librm to be relocated.
  125. */
  126. pushl $INIT_FUNC
  127. push %cs /* lcall %es:[x]di == %cs:[x]di */
  128. call *%ENTRY_POINT_REGISTER
  129. popl %ebp /* discard */
  130. /* Restore flags (including interrupt status) and return */
  131. popl %ebp
  132. popfl
  133. lret
  134. /****************************************************************************
  135. * Internal stack
  136. ****************************************************************************
  137. */
  138. .section ".stack"
  139. .align 8
  140. _stack:
  141. .space 4096
  142. _estack: