INT10.HOWTO 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. INT10 X86 Real Mode executor
  2. =============================
  3. PRELIMINARY
  4. INT10 is a XFree86 module for soft-booting and executing real mode
  5. int10 BIOS calls. The BIOS call code is largely untested, yet.
  6. 1. Usage
  7. ========
  8. To use the int10 module in a driver the header file
  9. xfree86/os-support/int10/xf86int10.h must be included.
  10. a. Initialization
  11. -----------------
  12. The int10-executer gets initialized by calling:
  13. xf86Int10InfoPtr xf86InitInt10(int entityIndex);
  14. The function will soft-boot any non-primary device and return a
  15. pointer to a xf86Int10InfoRec on success. If anything fails or if
  16. int10 execution is disabled by an option in the device section NULL
  17. will be returned. The driver should store this pointer for later
  18. calls to other int10 module functions.
  19. b. Memory allocation
  20. --------------------
  21. To allocate memory in the real mode execution environment
  22. void * xf86Int10AllocPages(xf86Int10InfoPtr pInt,int num, int *off);
  23. can be called. It allocates num consecutive pagesize chunks. It
  24. returns the address of the allocated area. off is set to its offset in
  25. the real mode memory space.
  26. void xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num);
  27. Is used to free num pages beginning at pbase.
  28. c. Doing int10 BIOS calls
  29. -------------------------
  30. The BIOS call is executed by calling:
  31. void xf86ExecX86int10(xf86Int10InfoPtr pInt);
  32. The number of the interrupt (normally 10) and the initial values of
  33. the ax, bx, cx, dx, si, di and es x86-CPU registers can be set in the
  34. xf86Int10InfoRec passed to the function. On return this structure
  35. contains the exit values of the registers listed above and the CPU
  36. flag register.
  37. d. De-initializing
  38. -----------------
  39. If no further int10 calls are required for a certain chipset
  40. the driver should call:
  41. void xf86FreeInt10(xf86Int10InfoPtr pInt);
  42. to free the memory allocated for real mode int10 calls.
  43. 2. Porting issues
  44. =================
  45. The int10 real mode executor is designed to run on top of various x86
  46. CPU emulators as well as in vm86 mode of a real x86 CPU. If used with
  47. a CPU emulator the emulator and CPU specific interfaces can be held
  48. separate thus requiring minimal efforts to port the int10 module to
  49. new platforms. Currently an interface to the x86emu real mode
  50. emulator is provided. Since details of setting up and running the
  51. vm86 mode is platform dependent both the platform dependent
  52. environment and the emulation layer have to be ported. Several helper
  53. functions are provided for that.
  54. A CPU emulator should meet certain requirements to be usable
  55. for the INT10 executor:
  56. 1. It must trap calls to intXX instructions and pass execution to an
  57. external function which is allowed to modify CPU registers
  58. including the instruction pointer (IP) before returning to the
  59. emulator for continuing execution. When the external function is
  60. called the IP must point to the instruction past the intXX call.
  61. 2. The emulator should use externally provided functions to handle
  62. PIO.
  63. 3. The emulator should be able to use externally provided functions
  64. to access memory from the real mode memory environment. Note, that
  65. the vm86 mode usually requires one hunk of consecutive memory
  66. starting at address 0 in the process virtual memory space. Thus if
  67. this mode is to be used, the OS environment has to be able to provide
  68. that, ie. it must be able to remap the processes virtual memory space
  69. onto itself. If the emulator is able to handle memory access thru
  70. externally provided functions the real mode process memory can be
  71. located anywhere in the processes virtual memory. It does not even
  72. have to be consecutive.
  73. 4. The executor should terminate on encountering a 'hlt' instruction.
  74. Functions to implement:
  75. To simplify development the code has been split into a general setup
  76. part and an emulator specific one. A generic setup code is provided in
  77. generic.c. It should be usable with any emulator satisfying the
  78. conditions mentioned above. Therefore the following section on int10
  79. setup may be skipped when porting int10 to new emulator.
  80. If the vm86() is to be used no memory access functions can be used.
  81. Therefore the layout of the real mode memory image has to meet certain
  82. requirements. Therefore when porting to other platforms a new setup
  83. code may have to be designed, too. The following section will give
  84. guidelines how this may be done. A sample implementation using SysV
  85. IPC to map the appropriate real mode memory image to address 0 in
  86. virtual address space just prior to execution may be found in
  87. xfree86/os-support/linux/int10/linux.c.
  88. On non-PC like platforms emulation of certain PC features such as
  89. initialization of BIOS int vectors, sys_BIOS constants or PCI config
  90. method 1 can be turned on by defining _PC.
  91. I. Setup Code
  92. -------------
  93. This sets up the real mode memory image, calls the emulator to POST
  94. the chipset if required and maintains memory allocations in real mode
  95. address space.
  96. 1. xf86Int10InfoPtr xf86InitInt10(int entityIndex);
  97. This function should first find the screen assigned to the entity
  98. carrying entitiyIndex and then call
  99. Bool int10skip(ScrnInfoPtr pScrn)
  100. to find out if the user has requested not to initialize int10. If so
  101. xf86InitInt10() should return NULL. Otherwise an xf86Int10InfoRec
  102. should be allocated. This structure contains the following fields:
  103. a. int entityIndex - index of the entity whose BIOS is to be
  104. executed.
  105. b. int scrnIndex - index of the screen assigned the entity.
  106. c. pointer cpuRegs - pointer to a emulator/vm86-mode private
  107. structure. May hold cpu register values
  108. for the emulator.
  109. d. CARD16 BIOSseg - Video BIOS segment address.
  110. e. pointer private - pointer to a os specific data structure.
  111. f. struct _int10Mem* - pointer to a structure to hold the memory
  112. access functions for use by an emulator.
  113. g. int num - number of the int to be called.
  114. h. int ax..es,flags - CPU register values to pass to int-call.
  115. The Init function should initialize a-f. To initialize the emulator
  116. specific execute environment the function
  117. Bool xf86Int10ExecSetup(xf86Int10InfoPtr pInt)
  118. should be called. If this function returns FALSE any already allocated
  119. memory should be freed and xf86Int10Init(0 should exit returning NULL.
  120. If the platform has a PC like system BIOS it may be copied to or
  121. mapped into memory locations SYS_BIOS to SYS_SIZE-1 of the real mode
  122. memory environment of this process. Otherwise the helper function:
  123. int setup_system_bios(CARD32 base_addr);
  124. may be called to set up a rudimentary system BIOS sufficient to be
  125. used to boot video BIOSes. base_addr specifies the virtual address
  126. corresponding to SYS_BIOS in the real mode environment. If a PC-like
  127. int vector and BIOS data area is available it should be copied to 0 to
  128. LOW_PAGE_SIZE of the entities real mode environment. In this case the
  129. video interrupt related entries should be reset for all non-primary
  130. cards by calling:
  131. void reset_int_vect(xf86Int10InfoPtr pInt); To initialize the
  132. correct video BIOS entry points the BIOS must be warm-booted. If no
  133. PC-like int vector is available one can be set up by calling
  134. void setup_int_vect(xf86Int10InfoPtr pInt);
  135. In this case the video BIOS has to be warm-booted always. If the
  136. video BIOS for this entity has been installed during boot it may be
  137. mapped (or copied) directly to the correct address in the real mode
  138. memory environment. Otherwise
  139. int mapPciRom(xf86Int10InfoPtr pInt, unsigned char * address);
  140. should be called to copy the BIOS image from PCI ROM. 'address'
  141. specifies the address this image should be copied to. Sufficient space
  142. to hold an entire BIOS image should be allocated prior to calling
  143. mapPciRom(). This function will return the size of the BIOS image in
  144. bytes if it was able to successfully copy the image and 0
  145. otherwise. To create a well defined point to exit the softbooter
  146. void set_return_trap(xf86Int10Ptr pInt);
  147. may be called. It sets up a 'hlt' instruction in the emulator memory
  148. just above the BIOS variable area. Before entering real mode execution
  149. this address will be pushed onto the return stack. If the BIOS needs
  150. to be warm-booted this should be done before leaving xf86InitInt10()
  151. by setting num in the xf86Int10InfoRec to 0xe6 and calling
  152. void xf86ExecX86int10(xf86Int10IfoPtr pInt);
  153. The implementation of this function will be discussed below. This
  154. function should be wrapped by calls to void LockLegacyVGA(screen,
  155. legacyVGAPtr vga); and void UnlockLegacyVGA(screen, legacyVGAPtr vga);
  156. The struct vga is used to hold the state of the legacy VGA access
  157. registers if a legacy VGA device exists. xf86InitInt10() should
  158. return a pointer to the xf86Int10InfoRec allocated.
  159. 2. Bool MapCurrentInt10(xf86Int10InfoPtr pInt);
  160. In case a platform specific mapping has to be performed to map the
  161. memory allocated for the real mode memory environment into a specific
  162. location prior to executing the x86 real mode code a function
  163. Bool MapCurrentInt10(xf86Int10InfoPtr pInt);
  164. has to be provided. It will be called by a helper function whenever
  165. the active entity changes. If the vm86 mode is used it is most likely
  166. that the 1MB real mode memory space located somewhere in the processes
  167. virtual memory will have to be remapped to address 0 of the virtual
  168. memory space.
  169. 3. void xf86FreeInt10(xf86Int10InfoPtr pInt);
  170. To free all memory allocated for video BIOS calls of a specific entity
  171. the function
  172. void xf86FreeInt10(xf86Int10InfoPtr pInt);
  173. should be provided. If the entity to be freed was mapped by
  174. MapCurrentInt10() this mapping needs to be undone also.
  175. 4.
  176. void * xf86Int10AllocPages(xf86Int10InfoPtr pInt,int num, int *off)
  177. void xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
  178. xf86Int10AllocPages() should allocate 'num' consecutive page-size
  179. chunks of memory. In real mode memory space this range needs to occupy
  180. consecutive addresses, too. The function must return the address of
  181. this memory. The offset in real mode memory needs to be returned in
  182. 'off'. If no block of 'num' pages are available the function should
  183. return NULL.
  184. xf86Int10FreePages() will free the 'num' pages starting at 'pbase'.
  185. 'num' is equal to the number of pages allocated by a single
  186. xf86Int10AllocatePages() call. 'pbase' is the address of the range
  187. previously returned by xf86Int10AllocatePages().
  188. II. Emulator specific functions
  189. -------------------------------
  190. 1. Bool xf86Int10ExecSetup(xf86Int10InfoPtr pInt);
  191. This function will be called from xf86InitInt10(). It may be used to
  192. set up the static emulator specific part of the real mode
  193. environment. On success it should return TRUE.
  194. 2. xf86ExecX86int10(xf86Int10InfoPtr pInt);
  195. This function gets called to execute an int call. It may call the
  196. helper function:
  197. void setup_int(xf86Int10InfoPrt pInt);
  198. to copy the register values to the emulator specific locations and to
  199. set up the non-static real mode execution environment. On return from
  200. setup_int() 'Int10Current' holds a pointer to the current
  201. xf86Int10InfoRec.
  202. It should start execution by calling
  203. Bool int_handler(xf86Int10InfoPtr pInt);
  204. and if this function returns TRUE it should call whatever necessary to
  205. continue execution until a 'hlt' instruction is encountered. To copy
  206. the resulting register values back to the xf86Int10InfoRec structure
  207. void finish_int(xf86Int10InfoPtr pInt);
  208. should be called.
  209. Helper functions are provided to aid the implementation of a vm86
  210. call:
  211. Bool vm86_GP_fault(xf86Int10InfoPtr pInt);
  212. This function handles instructions which cause a vm86 call to
  213. trap. PIO access is handled by the in/out calls as defined in
  214. compiler.h. Optionally the PIO instructions can be logged by defining
  215. PRINT_PORT in xf86int10.h. This is meant for debugging purposes.
  216. Unknown instructions and 'hlt' cause vm86_GP_fault() to return
  217. FALSE. Otherwise TRUE is returned.
  218. Note: This function is currently based on the Linux vm86 call. It
  219. might have to be modified or even rewritten for other OS. So your
  220. milage may vary.
  221. Functions to dump memory, code, xf86 CPU register values and stack are
  222. also provided. Take a look at helper.c To view a memory range the
  223. function
  224. void dprint(unsigned long start, unsigned long size)
  225. is provided. The use should be self explanatory.
  226. Register and memory access functions are provided in helper_mem.c.
  227. The PIO register access functions can trap access to PCI config space
  228. access register (config method 1) if _PC is not defined.
  229. A header file 'defines.h' is required to define OS/emulator specific
  230. ways to access memory and xf86 CPU registers: Defines need to be
  231. provided for memory byte/work/long read/write access
  232. (MEM_RB(name,addr),MEM_RW(name,addr),MEM_RL(name,addr),
  233. MEM_WB(name,addr,val),MEM_WL(name,addr,val),MEM_WL(name,addr,val)) of
  234. the real mode memory environment. 'name' will contain a pointer to the
  235. current xf86Int10InfoRec. Currently defines are available for
  236. vm86-mode under Linux and x86emu. They may be activated by defining
  237. _X86EMU or _VM86_LINUX respectively.
  238. Note: Emulators usually are not able to pass this pointer when calling
  239. memory access functions. In this case a global variable should be
  240. defined which can hold this pointer. This variable can be set in
  241. MapCurrentInt10(). It also must be set in xf86InitInt10() if this
  242. function calls the memory access functions either directly or by
  243. calling xf86ExecX86int10(pInt). Defines to access the emulator
  244. specific xf86 CPU register locations are also required:
  245. X86_EAX,...,X86_EFLAGS for access of the full 32 bit registers,
  246. X86_AX...X86_FLAGS for access of the 16 bit registers and
  247. XF86_AL,XF86_BL,XF86_CL,XF86_DL to access the lower byte of the
  248. AX,BX,CX and DX register.
  249. $XFree86: xc/programs/Xserver/hw/xfree86/int10/INT10.HOWTO,v 1.2 2000/02/08 13:13:22 eich Exp $