Fixed compilation error
[bochs-mirror.git] / docs-html / cosimulation.html
blob8c8ee950a5cbe73f315121d18ca56308e60fc528
1 <HTML>
3 <HEAD>
4 <META NAME="copyright" CONTENT="Copyright 2001 by MandrakeSoft S.A.">
5 <META NAME="Author" CONTENT="Kevin Lawton">
6 <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
7 <TITLE>Cosimulating: Using Bochs debugger to drive 2 simulators</TITLE>
8 </HEAD>
10 <BODY TEXT="#000000" BGCOLOR="#ececec" LINK="#3333cc" VLINK="#666666">
12 <CENTER><H1><I>Welcome to the Bochs x86 PC Emulation Software Home Page!</I></H1></CENTER>
14 <CENTER><H1>Cosimulating: using Bochs debugger to drive 2 simulators</H1></CENTER>
16 <HR SIZE=5 NOSHADE>
17 <H2>What is Cosimulation?</H2>
19 <IMG SRC="../doc/docbook/images/undercon.png" ALT="Under Construction">
20 I'll add a discussion of cosimulation here soon.
22 <HR SIZE=5 NOSHADE>
23 <H2>Cosimulation Programmatic Interface</H2>
24 <IMG SRC="../doc/docbook/images/undercon.png" ALT="Under Construction">
25 This documentation is not yet complete, and this interface is
26 subject to change.
28 <HR>
29 <HR>
30 <H3>Callback Structure:</H3>
32 <P>Upon startup, the cosimulation controller (debugger) will initialize each
33 simulator (or emulator) by calling an init routine. There are 2
34 macro's in config.h (generated from config.h.in), which determine
35 the names of the initialization routines, one for each simulator.
36 These macro's are BX_SIM1_INIT and BX_SIM2_INIT. The first one
37 likely can be kept as is. You will need to edit the second
38 one, to be a routine in the second simulator which will receive
39 a few parameters, and fill in a callback structure. This is the
40 only routine in each simulator environment which is needed directly,
41 as the callback routines which are filled in, are used subsequently.
42 It should be of the type:
44 <PRE>
45 void some_name_here(bx_dbg_callback_t *, int argc, char *argv[]);
46 </PRE>
48 The <I>argc</I> and <I>argv</I> parameters are as you might expect.
49 They consist of any simulator specific command line options passed to
50 the bochs executable at program invocation time. Since there can be
51 more than one simulator, command line options are delimited by
52 <I>-sim1</I> and <I>-sim2</I> as in:
54 <PRE>
55 Usage: bochs [-rc path] [-sim1 ... ] [-sim2 ...]
56 </PRE>
58 The first parameter is the address of a callback structure, whose type
59 <I>bx_dbg_callback_t</I> is defined in bx_debug/debug.h. Most fields
60 are function pointers, though some are not. Below, is a description
61 of each field in the callback structure.
63 <P>
64 <PRE>
65 typedef struct {
66 bx_bool (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);
67 bx_bool (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);
68 void (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, bx_bool *valid);
69 bx_bool (*set_reg)(unsigned reg, Bit32u val);
70 Bit32u (*get_reg)(unsigned reg);
71 bx_bool (*set_cpu)(bx_dbg_cpu_t *cpu);
72 bx_bool (*get_cpu)(bx_dbg_cpu_t *cpu);
73 unsigned dirty_page_tbl_size;
74 unsigned char *dirty_page_tbl;
75 void (*atexit)(void);
76 unsigned (*query_pending)(void);
77 void (*execute)(void);
78 void (*take_irq)(void);
79 void (*take_dma)(void);
80 void (*reset_cpu)(unsigned source);
81 void (*init_mem)(int size_in_bytes);
82 void (*load_ROM)(const char *path, Bit32u romaddress);
84 void (*set_A20)(unsigned val);
85 void (*set_NMI)(unsigned val);
86 void (*set_RESET)(unsigned val);
87 void (*set_INTR)(unsigned val);
88 void (*force_interrupt)(unsigned vector);
90 #if BX_INSTRUMENTATION
91 void (*instr_start)(void);
92 void (*instr_stop)(void);
93 void (*instr_reset)(void);
94 void (*instr_print)(void);
95 #endif
96 #if BX_USE_LOADER
97 void (*loader)(char *path);
98 #endif
99 } bx_dbg_callback_t;
100 </PRE>
102 <P><B>bx_bool (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);</B>
103 <P>Set (write to) physical memory of simulator at address <I>addr</I> from the
104 <I>len</I> bytes in <I>buf</I>. The bytes in <I>buf</I> should be copied to the simulator's
105 physical memory byte-at-a-time with no concern for endian-ness. Return 1
106 if the write is OK, 0 if an error occurs.
108 <P><B>bx_bool (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);</B>
109 <P>Get (read from) physical memory of simulator at address <I>addr</I> to the
110 <I>len</I> bytes in <I>buf</I>. The bytes in <I>buf</I> should be copied from the simulator's
111 physical memory byte-at-a-time with no concern for endian-ness. Return 1
112 if the read is OK, 0 if an error occurs.
114 <P><B>void (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, bx_bool *valid);</B>
115 <P>Translate a linear to a physical address, without generating an exception
116 or updating the paging tables. The debugger passes the simulator the
117 <I>linear</I> address. The simulator is expected to set <I>phy</I> to
118 the corresponding physical address if available, and update <I>valid</I>,
119 which should be set to 1 if the physical address was available, and 0
120 if not. It is possible, the address is not in the paging tables, and
121 thus not available.
123 <P><B>bx_bool (*set_reg)(unsigned reg, Bit32u val);</B>
124 <P>Set a specific CPU register as determined by <I>reg</I> in the
125 simulator to <I>val</I>. The value of <I>reg</I> will be one of the
126 defines, such as BX_DBG_REG_EAX defined in <I>bx_debug/debug.h</I>. The
127 segment registers can only be set by this method in real mode. This
128 function should return a 1 if the operation is successful, and 0 if not.
130 <P><B>Bit32u (*get_reg)(unsigned reg);</B>
131 <P>Return the value of a specific CPU register in the simulator as
132 determined by <I>reg</I>, whose value is of the same range
133 as those passed into <I>set_reg()</I>
135 <P><B>bx_bool (*set_cpu)(bx_dbg_cpu_t *cpu);</B>
136 <P>Set all the registers in the CPU simulator to those in the structure
137 <I>cpu</I>. The <I>bx_dbg_cpu_t</I> structure is defined in bx_debug/debug.h.
139 <P><B>bx_bool (*get_cpu)(bx_dbg_cpu_t *cpu);</B>
140 <P>Get values for all the registers in the CPU simulator, and place them in
141 the structure <I>cpu</I>. The <I>bx_dbg_cpu_t</I> structure is defined in bx_debug/debug.h.
143 <P><B>unsigned dirty_page_tbl_size;</B>
144 <BR><B>unsigned char *dirty_page_tbl;</B>
145 <P>To keep track of what areas of memory have been written to, and allow
146 the debugger to efficiently compare regions of memory in each simulator,
147 each simulator should provide a dirty page table. It is expected that
148 each byte in the array represents one 4K page of physical memory. A value
149 of 1 represents that the page has been written to, since the last time it
150 was cleared by the debugger, and a value of 0 represents that no write
151 has occurred within that physical page.
152 <P>You should fill in the field <I>dirty_page_tbl</I> with a pointer
153 to an array of bytes. And <I>dirty_page_tbl_size</I> should be set
154 to the size of the array in bytes. If possible, make the array big
155 enough to span the largest amount of physical memory you might request.
156 I chose to not make this size dynamic with the user's requested memory size,
157 to eliminate an extra access via a pointer.
159 <P><B>void (*atexit)(void);</B>
160 <P>Called when the debugger needs to terminate execution. This function
161 should close files and do all necessary shutdown of the simulator.
162 <B>NOTE:</B> Do not call exit() directly from
163 the simulator, but instead call <I>bx_dbg_exit()</I>. As there may be multiple
164 simulators, <I>bx_dbg_exit()</I> will handle invoking the <I>atexit</I> callback in
165 each simulator first, and then it will call exit().
167 <P><B>void (*execute)(void);</B>
168 <P>The debugger calls <I>execute()</I> in either slave or master simulator,
169 commanding either to execute instructions until a guard is reached, in which
170 case control should be returned back to the debugger.
172 <P><B>void (*reset_cpu)(unsigned source);</B>
173 <P>This function is called once by the debugger to initialize the simulator's
174 CPU upon program startup. <I>Source</I> will be either
175 BX_RESET_HARDWARE or BX_RESET_SOFTWARE.
177 <P><B>void (*init_mem)(int size_in_bytes);</B>
178 <P>This function is called once by the debugger to initialize the simulator's
179 memory upon program startup. <I>Size_in_bytes</I> denotes
180 the size of physical memory the user has requested, so that both simulators
181 can use the same physical memory size. This would be an appropriate
182 time to allocate memory for the simulator.
184 <P><B>void (*load_ROM)(const char *path, Bit32u romaddress);</B>
185 <P>Commands the simulator to load a ROM image stored in the filename
186 <I>path</I> into physical memory at address <I>romaddress</I>.
188 <P><B>void (*set_A20)(unsigned val);</B>
189 <P>This function is called by the cosim controller to command either master
190 or slave simulator to change it's A20 setting. If the value of <I>val</I> passed
191 is 1, then the A20 address line is passed through and used. This will give
192 normal addressing of the entire 32bit address space. If the value is 0,
193 then A20 is masked out, and addressing at the 1Meg boundary will wrap, modeling
194 8086 addressing.
195 <P>The cosim controller also commands the <I>bx_pc_system</I> class to
196 maintain the same A20 state as passed in this function, so you may alternatively
197 use values directly from that class, rather than keep your own A20 state.
198 If so, set the value of <I>set_A20</I> to NULL, and use the following
199 members from <I>bx_pc_system</I>. In this case, <I>set_A20</I> won't be
200 called.
201 <UL>
202 <LI><B>bx_pc_system.enable_a20:</B> Same value as passed to <I>set_A20</I>.
203 <LI><B>bx_pc_system.a20_mask:</B> Logical AND this with a physical address to obtain the
204 address after application of the A20 gate.
205 </UL>
207 <P><B>void (*set_NMI)(unsigned val);</B>
208 <P>Not supported yet. Will tell the simulator that the value of
209 the NMI pin, is currently <I>val</I>. Use an empty stub function
210 for this for now.
212 <P><B>void (*set_RESET)(unsigned val);</B>
213 <P>Not supported yet. Will tell the simulator that the value of
214 the RESET pin, is currently <I>val</I>. Use an empty stub function
215 for this for now.
217 <P><B>void (*set_INTR)(unsigned val);</B>
218 <P>The INTR pin is driven by the device models. When the INTR pin is
219 raised due to an interrupt request by the PIC, or lowered after the
220 interrupt is acknowledged, this function is called to notify the
221 simulator of the new status. Only the master simulator will receive
222 notification, as INTR is always 0 for the slave simulator. Interrupts
223 are forced in the slave simulator, synchronizing it to the execution
224 path of the master, using <I>force_interrupt()</I> described below.
225 A value in <I>val</I> of 0 indicates no interrupt is requested. A value
226 of 1 indicates an interrupt request.
228 <P><B>void (*force_interrupt)(unsigned vector);</B>
229 <P>In order for the debugger to force the slave simulator to take an
230 interrupt at the same point as the master simulator, the interrupt vector
231 is recorded when taken by the master simulator. The debugger commands
232 the slave to the same point, and calls this routine, forcing the slave
233 to take the given interrupt, <I>vector</I>.
235 <P><B>void (*instr_start)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
236 <P>Called when the user types in "<I>instrument start</I>" at the debug prompt.
237 The instrumentation package can use this function to do whatever is
238 necessary to initialize the instrumentation package and/or command
239 it to begin collecting data.
241 <P><B>void (*instr_stop)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
242 <P>Called when the user types in "<I>instrument stop</I>" at the debug prompt.
243 The instrumentation package can use this function to do whatever is
244 necessary to temporarily or permanently stop the instrumentation package
245 from collecting data.
247 <P><B>void (*instr_reset)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
248 <P>Called when the user types in "<I>instrument reset</I>" at the debug prompt.
249 The instrumentation package can use this function to command the instrumentation
250 package to reset it's data collection mechanisms.
252 <P><B>void (*instr_print)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
253 <P>Called when the user types in "<I>instrument print</I>" at the debug prompt.
254 The instrumentation package can use this function to output it's collected
255 data.
257 <P><B>void (*loader)(char *path);</B> (Only defined if macro BX_USE_LOADER is 1)
258 <P>Called when the user types in "<I>loader pathname</I>" at the debug prompt.
259 The idea is to allow a loader routine to read in a program which is specific
260 to the OS you are running within the emulator, from a file on your native
261 workstation, load it properly into simulator memory and run it on the
262 simulator. This loader must be specific to the OS you are running within the
263 simulator, and I do not provide one with bochs.
265 <P><B>void (*take_irq)(void);</B>
266 <BR><B>void (*take_dma)(void);</B>
267 <BR><B>unsigned (*query_pending)(void);</B>
268 <P>These are vestiges of a past interface. They correspond to the
269 "take irq", "take dma", and "query pending" commands, which you
270 shouldn't use. They will be removed. Set these fields to NULL,
271 or to empty stub functions.
273 <HR>
274 <HR>
275 <H3>Debugger (Cosimulation Controller) Functions:</H3>
277 <P><B>void bx_dbg_exit(int code)</B>
278 <P>When there is a situation in the simulator, where you need to terminate
279 due to an unrecoverable error (panic), call <I>bx_dbg_exit()</I>. Among
280 other things, this function will call the <I>at_exit</I> callback function
281 in each simulator, and ultimately call the system exit() function.
283 <P><B>Bit8u bx_dbg_IAC(void)</B>
284 <P>The simulator's CPU code should call this function when it is acknowledging an
285 interrupt from the PIC via the INTR line. The interrupt vector number from the PIC
286 is returned.
288 <P><B>Bit32u bx_dbg_inp(Bit16u addr, unsigned len)</B>
289 <P>To read data from an IO device, the simulator should call this function.
290 Pass in the IO address <I>addr</I>, and the size of the IO operation <I>len</I>.
292 <P><B>void bx_dbg_outp(Bit16u addr, Bit32u value, unsigned len)</B>
293 <P>To write data to an IO device, the simulator should call this function.
294 Pass in the IO address <I>addr</I>, and the size of the IO operation <I>len</I>.
296 <P><B>Bit8u bx_dbg_ucmem_read(Bit32u addr)</B>
297 <BR><B>void bx_dbg_ucmem_write(Bit32u addr, Bit8u value)</B>
298 <P>For memory read/write accesses which fall in the range of 0xA0000 to 0xBFFFF,
299 the accesses should not be to directed to the simulator's memory, since
300 these are UnCacheable MEMory addresses. The VGA adapter maps it's memory to this
301 range. Instead, call these functions to perform reads/writes to memory
302 accesses in this range. For <I>bx_dbg_ucmem_read()</I>, pass the physical address
303 <I>addr</I>, and the value of the read is returned. For <I>bx_dbg_ucmem_write()</I>,
304 pass the physical address <I>addr</I> and value <I>value</I> of the write.
306 <P><B>void bx_dbg_async_pin_ack(unsigned what, bx_bool val)</B>
307 <P>In order for the master and slave simulators to accept changes in pins
308 such as the A20 line, at the same point, the debugger provides a mechanism
309 for pending the pin change, until it is acknowledged by the master simulator.
310 The place where the change is ack'd, is recorded by the debugger. This
311 information is used to run the slave simulator, forcing it to accept the
312 changes at the same locale as did the master.
314 <P>Initially, the IO devices call a function <I>bx_dbg_async_pin_request()</I>,
315 not listed here, to record the pin change as pending. The pending status
316 is recorded along with the guard information in <I>bx_guard.async_changes_pending.which</I>.
317 This field contains a binary OR'd set of pending pin changes. Currently
318 only A20 is supported, which is represented by the macro BX_DBG_ASYNC_PENDING_A20.
320 <P>At a time prudent to your CPU simulator, check to see if there are
321 any pending changes, that the CPU should acknowledge. If so, acknowledge
322 them by calling <I>bx_dbg_async_pin_ack()</I>. The pending value of
323 the A20 enable is stored in <I>bx_guard.async_changes_pending.a20</I>.
324 Here is some sample code which performs this task, that you can insert
325 into the appropriate place in your CPU simulator.
327 <PRE>
328 if (bx_guard.async_changes_pending.which) {
329 if (bx_guard.async_changes_pending.which & BX_DBG_ASYNC_PENDING_A20)
330 bx_dbg_async_pin_ack(BX_DBG_ASYNC_PENDING_A20,
331 bx_guard.async_changes_pending.a20);
332 // ...other checks here when they are supported
334 </PRE>
336 The <I>bx_dbg_async_pin_ack()</I> function will in turn, invoke
337 the <I>set_A20()</I> callback function in the master simulator, so you
338 don't have to deal with updating local A20 state in your simulator here,
339 as long as you handle it in <I>set_A20()</I>. Keep in mind, the slave
340 simulator will never see the code inside this sample code if-construct,
341 since changes are forced in the slave by the debugger at points where the master
342 simulator acknowledged them, not as a direct effect of the IO devices.
344 <HR>
345 <HR>
346 <H3>Guards:</H3>
348 Guards are a mechanism by which the debugger requests each simulator
349 to stop execution and return control back to the debugger. The debugger
350 runs each simulator for a particular number of instructions, or until
351 certain events occur. Guards are set by the debugger, and it is up
352 to each simulator to examine them upon and during execution of the <I>execute()</I>
353 callback, and return control back to the debugger when the guard criteria
354 are met.
356 <P>Guard information set by the debugger is stored in global structure
357 <I>bx_guard</I> of type <I>bx_guard_t</I>. For reference, it's declaration
358 is shown here, followed by an explanation of the purpose of each field.
359 Information about the guard encountered by the simulator, and which
360 caused control to return to the debugger is stored in the global structure
361 <I>bx_guard_found[]</I> of type <I>bx_guard_found_t</I>. This is actually
362 an array of structures, where <I>bx_guard_found[0]</I> is the first simulator
363 with ID 0, and <I>bx_guard_found[1]</I> is the second simulator with
364 ID 1. This structure is also declared below, and the text explains
365 the information which should be returned in this structure based on
366 the guard encountered.
368 <PRE>
369 typedef struct {
370 unsigned long guard_for;
372 // instruction address breakpoints
373 struct {
374 #if BX_DBG_SUPPORT_VIR_BPOINT
375 unsigned num_virtual;
376 struct {
377 Bit32u cs; // only use 16 bits
378 Bit32u eip;
379 unsigned bpoint_id;
380 } vir[BX_DBG_MAX_VIR_BPOINTS];
381 #endif
383 #if BX_DBG_SUPPORT_LIN_BPOINT
384 unsigned num_linear;
385 struct {
386 Bit32u addr;
387 unsigned bpoint_id;
388 } lin[BX_DBG_MAX_LIN_BPOINTS];
389 #endif
391 #if BX_DBG_SUPPORT_PHY_BPOINT
392 unsigned num_physical;
393 struct {
394 Bit32u addr;
395 unsigned bpoint_id;
396 } phy[BX_DBG_MAX_PHY_BPOINTS];
397 #endif
398 } iaddr;
400 bx_dbg_icount_t icount; // stop after completing this many instructions
402 // user typed Ctrl-C, requesting simulator stop at next convient spot
403 volatile bx_bool interrupt_requested;
405 // booleans to control whether simulator should report events
406 // to debug controller
407 struct {
408 bx_bool irq;
409 bx_bool a20;
410 bx_bool io;
411 bx_bool ucmem;
412 bx_bool dma;
413 } report;
415 struct {
416 bx_bool irq; // should process IRQs asynchronously
417 bx_bool dma; // should process DMAs asynchronously
418 } async;
420 #define BX_DBG_ASYNC_PENDING_A20 0x01
421 #define BX_DBG_ASYNC_PENDING_RESET 0x02
422 #define BX_DBG_ASYNC_PENDING_NMI 0x04
424 // Asynchronous changes which are pending. These are Q'd by
425 // the debugger, as the master simulator is notified of a pending
426 // async change. At the simulator's next point, where it checks for
427 // such events, it notifies the debugger with acknowlegement. This
428 // field contains a logically or'd list of all events which should
429 // be checked, and ack'd.
430 struct {
431 unsigned which; // logical OR of above constants
432 bx_bool a20;
433 bx_bool reset;
434 bx_bool nmi;
435 } async_changes_pending;
436 } bx_guard_t;
438 typedef struct {
439 unsigned long guard_found;
440 unsigned iaddr_index;
441 bx_dbg_icount_t icount; // number of completed instructions
442 Bit32u cs; // cs:eip and linear addr of instruction at guard point
443 Bit32u eip;
444 Bit32u laddr;
445 bx_bool is_32bit_code; // CS seg size at guard point
446 bx_bool ctrl_c; // simulator stopped due to Ctrl-C request
447 } bx_guard_found_t;
449 extern bx_guard_t bx_guard;
450 extern bx_guard_found_t bx_guard_found[];
451 </PRE>
453 <HR>
454 <H3>bx_guard_found[]:</H3>
455 It is the task of each simulator to update the <I>bx_guard_found</I>
456 structure.
457 There are some fields which are specific to the type of guard in
458 question, and you should update those when a particular guard is
459 encountered. Those fields are explained in more detail in the section
460 relating to the specific guard. There are some fields which are
461 updated for every case, no matter what the guard is. Below is a list
462 and explanation of the usage of each field.
464 <P><B>unsigned long guard_found;</B> this should be filled in with the
465 particular guard encountered, for example if an instruction count
466 guard is hit, set this to BX_DBG_GUARD_ICOUNT.
468 <P><B>unsigned iaddr_index;</B>
469 This field is updated, whenever a virtual/linear/physical instruction
470 address guard is hit. It is the array index into the bx_guard.iaddr.vir[],
471 bx_guard.iaddr.lin[], or bx_guard.iaddr.phy[] arrays, whichever is appropriate.
473 <P><B>bx_dbg_icount_t icount;</B>
474 This contains the number of instructions which have been completely
475 executed, when the guard was encountered.
477 <P><B>Bit32u cs;</B>
478 <BR><B>Bit32u eip;</B>
479 <BR><B>Bit32u laddr;</B>
480 <BR><B>bx_bool is_32bit_code;</B>
481 These all relate to the same instruction address. From the debugger's
482 point of view, instruction addresses can be only at the beginning of
483 the instruction. Once an instruction is completed, use the address
484 of the next instruction.
485 Set <I>cs</I> and <I>eip</I> to the instruction's address (CS:EIP).
486 Set <I>laddr</I> to the instruction's corresponding linear address.
487 Set <I>is_32bit_code</I> to the size (0=16bit, 1=32bit) of the code
488 segment when the guard is encountered. This is used for disassembly.
490 <P><B>bx_bool ctrl_c;</B>
491 To allow the user to interrupt a simulator from the debug prompt, the
492 debugger traps Ctrl-C interrupts, and sets <I>bx_guard.interrupt_requested</I>.
493 Your simulator can optionally look for this, provided that the
494 BX_DBG_GUARD_CTRL_C bit is set in <I>bx_guard.guard_for</I> structure.
495 If you chose to do so, you may look for this occurrance whenever is
496 convenient. Set <I>ctrl_c</I> to 1 to signify this guard has occurred.
497 Here' some sample code to demonstrate this:
498 <PRE>
499 // convenient point to see if user typed Ctrl-C
500 if (bx_guard.interrupt_requested && (bx_guard.guard_for & BX_DBG_GUARD_CTRL_C)) {
501 bx_guard_found[BX_SIM_ID].guard_found = BX_DBG_GUARD_CTRL_C;
502 return; // some mechanism to return control here
504 </PRE>
506 <HR>
507 <H3>bx_guard:</H3>
508 <P><B>unsigned long guard_for;</B>
509 <P>This is a binary OR'd list of guards the debugger is requesting each
510 simulator to stop on. Only if the corresponding bit is set in this field,
511 should the simulator examine the rest of the criteria for that guard.
512 Currently, each simulator must be capable of recognizing the following
513 guards, and returning to the debugger when they occur:
514 <UL>
515 <LI>BX_DBG_GUARD_ICOUNT: Instruction count.
516 <LI>BX_DBG_GUARD_CTRL_C: User requested interrupt via Ctrl-C
517 <LI>BX_DBG_GUARD_IADDR_VIR: Stop on this virtual instruction address
518 <LI>BX_DBG_GUARD_IADDR_LIN: Stop on this linear instruction address
519 <LI>BX_DBG_GUARD_IADDR_PHY: Stop on this physical instruction address
520 </UL>
522 <P><B>struct { .. } iaddr;</B>
523 <P>This structure holds the guard information for instruction address
524 guards (breakpoints). Depending upon your selections, after editing
525 <I>config.h</I> in the main directory (generated by running ./configure),
526 certain types of instruction address guards are supported. Which ones,
527 are determined by the BX_DBG_SUPPORT_VIR_BPOINT, BX_DBG_SUPPORT_LIN_BPOINT,
528 and BX_DBG_SUPPORT_PHY_BPOINT macros.
530 <P>If the <I>guard_for</I> field contains a set bit represented by
531 BX_DBG_GUARD_IADDR_VIR, then the <I>iaddr.num_virtual</I> field holds
532 the number of virtual instruction address guards to examine and compare
533 to the current address. For each, you must examine the CS:EIP values
534 stored in <I>iaddr.vir[n]</I>, in the <I>cs</I> and <I>eip</I> subfields.
535 If there is a match, record this in the guard found structure, and
536 return control to the debugger:
537 <PRE>
538 bx_guard_found[ID].guard_found = BX_DBG_GUARD_IADDR_VIR;
539 bx_guard_found[ID].iaddr_index = n; // array index in bx_guard.iaddr.vir[]
540 bx_guard_found[ID].icount = .. // number of completed instructions
541 bx_guard_found[ID].cs = .. // CS selector value
542 bx_guard_found[ID].eip = .. // EIP value
543 bx_guard_found[ID].laddr = .. // linear address of CS:EIP
544 bx_guard_found[ID].is_32bit_code = .. // 0=16bit code, 1=32bit code
545 // return control here
546 </PRE>
548 <P>If the <I>guard_for</I> field contains a set bit represented by
549 BX_DBG_GUARD_IADDR_LIN, then the <I>iaddr.num_linear</I> field holds
550 the number of linear instruction address guards to examine and compare
551 to the current address. For each, you must examine the linear address values
552 stored in <I>iaddr.lin[n]</I>, in the <I>addr</I> subfield.
553 If there is a match, record this in the guard found structure, and
554 return control to the debugger:
555 <PRE>
556 bx_guard_found[ID].guard_found = BX_DBG_GUARD_IADDR_LIN;
557 bx_guard_found[ID].iaddr_index = n; // array index in bx_guard.iaddr.lin[]
558 bx_guard_found[ID].icount = .. // number of completed instructions
559 bx_guard_found[ID].cs = .. // CS selector value
560 bx_guard_found[ID].eip = .. // EIP value
561 bx_guard_found[ID].laddr = .. // linear address of CS:EIP
562 bx_guard_found[ID].is_32bit_code = .. // 0=16bit code, 1=32bit code
563 // return control here
564 </PRE>
566 <P>If the <I>guard_for</I> field contains a set bit represented by
567 BX_DBG_GUARD_IADDR_PHY, then the <I>iaddr.num_physical</I> field holds
568 the number of physical instruction address guards to examine and compare
569 to the current address. For each, you must examine the physical address values
570 stored in <I>iaddr.phy[n]</I>, in the <I>addr</I> subfield.
571 If there is a match, record this in the guard found structure, and
572 return control to the debugger:
573 <PRE>
574 bx_guard_found[ID].guard_found = BX_DBG_GUARD_IADDR_PHY;
575 bx_guard_found[ID].iaddr_index = n; // array index in bx_guard.iaddr.phy[]
576 bx_guard_found[ID].icount = .. // number of completed instructions
577 bx_guard_found[ID].cs = .. // CS selector value
578 bx_guard_found[ID].eip = .. // EIP value
579 bx_guard_found[ID].laddr = .. // linear address of CS:EIP
580 bx_guard_found[ID].is_32bit_code = .. // 0=16bit code, 1=32bit code
581 // return control here
582 </PRE>
585 <P><B>volatile bx_bool interrupt_requested;</B>
586 <P>If the debugger has turned on the guard for a user interrupt, and
587 the user has indeed requested one (Ctrl-C), the debugger will set
588 this field to 1. The simulator should record this in the guard found
589 information, and return control back to the debugger. Look above at the
590 explanation for the <I>bx_guard.interrupt_requested</I> field for some sample code
591 on how to do this.
593 <P><B>struct { .. } async;</B>
594 <P><B>struct { .. } async_changes_pending;</B>
597 <HR SIZE=5 NOSHADE>
599 Related Links:
600 <UL>
601 <LI><A HREF="debugger.html">Debugger</A>
602 <LI><A HREF="instrumentation.html">Instrumentation</A>
603 </UL>
605 </BODY>
606 </HTML>