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