cleanup and rename old doc abou cosimulation

This commit is contained in:
Stanislav Shwartsman 2011-08-01 07:50:31 +00:00
parent ea7d5e74ee
commit 77f025b9b0

View File

@ -1,278 +1,12 @@
<HTML>
<HEAD>
<META NAME="copyright" CONTENT="Copyright 2001 by MandrakeSoft S.A.">
<META NAME="Author" CONTENT="Kevin Lawton">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<TITLE>Cosimulating: Using Bochs debugger to drive 2 simulators</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#ececec" LINK="#3333cc" VLINK="#666666">
<CENTER><H1><I>Welcome to the Bochs x86 PC Emulation Software Home Page!</I></H1></CENTER>
<CENTER><H1>Cosimulating: using Bochs debugger to drive 2 simulators</H1></CENTER>
<HR SIZE=5 NOSHADE>
<H2>What is Cosimulation?</H2>
<IMG SRC="../doc/docbook/images/undercon.png" ALT="Under Construction">
I'll add a discussion of cosimulation here soon.
<HR SIZE=5 NOSHADE>
<H2>Cosimulation Programmatic Interface</H2>
<IMG SRC="../doc/docbook/images/undercon.png" ALT="Under Construction">
This documentation is not yet complete, and this interface is
subject to change.
<HR>
<HR>
<H3>Callback Structure:</H3>
<P>Upon startup, the cosimulation controller (debugger) will initialize each
simulator (or emulator) by calling an init routine. There are 2
macro's in config.h (generated from config.h.in), which determine
the names of the initialization routines, one for each simulator.
These macro's are BX_SIM1_INIT and BX_SIM2_INIT. The first one
likely can be kept as is. You will need to edit the second
one, to be a routine in the second simulator which will receive
a few parameters, and fill in a callback structure. This is the
only routine in each simulator environment which is needed directly,
as the callback routines which are filled in, are used subsequently.
It should be of the type:
<PRE>
void some_name_here(bx_dbg_callback_t *, int argc, char *argv[]);
</PRE>
The <I>argc</I> and <I>argv</I> parameters are as you might expect.
They consist of any simulator specific command line options passed to
the bochs executable at program invocation time. Since there can be
more than one simulator, command line options are delimited by
<I>-sim1</I> and <I>-sim2</I> as in:
<PRE>
Usage: bochs [-rc path] [-sim1 ... ] [-sim2 ...]
</PRE>
The first parameter is the address of a callback structure, whose type
<I>bx_dbg_callback_t</I> is defined in bx_debug/debug.h. Most fields
are function pointers, though some are not. Below, is a description
of each field in the callback structure.
<P>
<PRE>
typedef struct {
bx_bool (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);
bx_bool (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);
void (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, bx_bool *valid);
bx_bool (*set_reg)(unsigned reg, Bit32u val);
Bit32u (*get_reg)(unsigned reg);
bx_bool (*set_cpu)(bx_dbg_cpu_t *cpu);
bx_bool (*get_cpu)(bx_dbg_cpu_t *cpu);
unsigned dirty_page_tbl_size;
unsigned char *dirty_page_tbl;
void (*atexit)(void);
unsigned (*query_pending)(void);
void (*execute)(void);
void (*take_irq)(void);
void (*take_dma)(void);
void (*reset_cpu)(unsigned source);
void (*init_mem)(int size_in_bytes);
void (*load_ROM)(const char *path, Bit32u romaddress);
void (*set_A20)(unsigned val);
void (*set_NMI)(unsigned val);
void (*set_RESET)(unsigned val);
void (*set_INTR)(unsigned val);
void (*force_interrupt)(unsigned vector);
#if BX_INSTRUMENTATION
void (*instr_start)(void);
void (*instr_stop)(void);
void (*instr_reset)(void);
void (*instr_print)(void);
#endif
#if BX_USE_LOADER
void (*loader)(char *path);
#endif
} bx_dbg_callback_t;
</PRE>
<P><B>bx_bool (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);</B>
<P>Set (write to) physical memory of simulator at address <I>addr</I> from the
<I>len</I> bytes in <I>buf</I>. The bytes in <I>buf</I> should be copied to the simulator's
physical memory byte-at-a-time with no concern for endian-ness. Return 1
if the write is OK, 0 if an error occurs.
<P><B>bx_bool (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);</B>
<P>Get (read from) physical memory of simulator at address <I>addr</I> to the
<I>len</I> bytes in <I>buf</I>. The bytes in <I>buf</I> should be copied from the simulator's
physical memory byte-at-a-time with no concern for endian-ness. Return 1
if the read is OK, 0 if an error occurs.
<P><B>void (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, bx_bool *valid);</B>
<P>Translate a linear to a physical address, without generating an exception
or updating the paging tables. The debugger passes the simulator the
<I>linear</I> address. The simulator is expected to set <I>phy</I> to
the corresponding physical address if available, and update <I>valid</I>,
which should be set to 1 if the physical address was available, and 0
if not. It is possible, the address is not in the paging tables, and
thus not available.
<P><B>bx_bool (*set_reg)(unsigned reg, Bit32u val);</B>
<P>Set a specific CPU register as determined by <I>reg</I> in the
simulator to <I>val</I>. The value of <I>reg</I> will be one of the
defines, such as BX_DBG_REG_EAX defined in <I>bx_debug/debug.h</I>. The
segment registers can only be set by this method in real mode. This
function should return a 1 if the operation is successful, and 0 if not.
<P><B>Bit32u (*get_reg)(unsigned reg);</B>
<P>Return the value of a specific CPU register in the simulator as
determined by <I>reg</I>, whose value is of the same range
as those passed into <I>set_reg()</I>
<P><B>bx_bool (*set_cpu)(bx_dbg_cpu_t *cpu);</B>
<P>Set all the registers in the CPU simulator to those in the structure
<I>cpu</I>. The <I>bx_dbg_cpu_t</I> structure is defined in bx_debug/debug.h.
<P><B>bx_bool (*get_cpu)(bx_dbg_cpu_t *cpu);</B>
<P>Get values for all the registers in the CPU simulator, and place them in
the structure <I>cpu</I>. The <I>bx_dbg_cpu_t</I> structure is defined in bx_debug/debug.h.
<P><B>unsigned dirty_page_tbl_size;</B>
<BR><B>unsigned char *dirty_page_tbl;</B>
<P>To keep track of what areas of memory have been written to, and allow
the debugger to efficiently compare regions of memory in each simulator,
each simulator should provide a dirty page table. It is expected that
each byte in the array represents one 4K page of physical memory. A value
of 1 represents that the page has been written to, since the last time it
was cleared by the debugger, and a value of 0 represents that no write
has occurred within that physical page.
<P>You should fill in the field <I>dirty_page_tbl</I> with a pointer
to an array of bytes. And <I>dirty_page_tbl_size</I> should be set
to the size of the array in bytes. If possible, make the array big
enough to span the largest amount of physical memory you might request.
I chose to not make this size dynamic with the user's requested memory size,
to eliminate an extra access via a pointer.
<P><B>void (*atexit)(void);</B>
<P>Called when the debugger needs to terminate execution. This function
should close files and do all necessary shutdown of the simulator.
<B>NOTE:</B> Do not call exit() directly from
the simulator, but instead call <I>bx_dbg_exit()</I>. As there may be multiple
simulators, <I>bx_dbg_exit()</I> will handle invoking the <I>atexit</I> callback in
each simulator first, and then it will call exit().
<P><B>void (*execute)(void);</B>
<P>The debugger calls <I>execute()</I> in either slave or master simulator,
commanding either to execute instructions until a guard is reached, in which
case control should be returned back to the debugger.
<P><B>void (*reset_cpu)(unsigned source);</B>
<P>This function is called once by the debugger to initialize the simulator's
CPU upon program startup. <I>Source</I> will be either
BX_RESET_HARDWARE or BX_RESET_SOFTWARE.
<P><B>void (*init_mem)(int size_in_bytes);</B>
<P>This function is called once by the debugger to initialize the simulator's
memory upon program startup. <I>Size_in_bytes</I> denotes
the size of physical memory the user has requested, so that both simulators
can use the same physical memory size. This would be an appropriate
time to allocate memory for the simulator.
<P><B>void (*load_ROM)(const char *path, Bit32u romaddress);</B>
<P>Commands the simulator to load a ROM image stored in the filename
<I>path</I> into physical memory at address <I>romaddress</I>.
<P><B>void (*set_A20)(unsigned val);</B>
<P>This function is called by the cosim controller to command either master
or slave simulator to change it's A20 setting. If the value of <I>val</I> passed
is 1, then the A20 address line is passed through and used. This will give
normal addressing of the entire 32bit address space. If the value is 0,
then A20 is masked out, and addressing at the 1Meg boundary will wrap, modeling
8086 addressing.
<P>The cosim controller also commands the <I>bx_pc_system</I> class to
maintain the same A20 state as passed in this function, so you may alternatively
use values directly from that class, rather than keep your own A20 state.
If so, set the value of <I>set_A20</I> to NULL, and use the following
members from <I>bx_pc_system</I>. In this case, <I>set_A20</I> won't be
called.
<UL>
<LI><B>bx_pc_system.enable_a20:</B> Same value as passed to <I>set_A20</I>.
<LI><B>bx_pc_system.a20_mask:</B> Logical AND this with a physical address to obtain the
address after application of the A20 gate.
</UL>
<P><B>void (*set_NMI)(unsigned val);</B>
<P>Not supported yet. Will tell the simulator that the value of
the NMI pin, is currently <I>val</I>. Use an empty stub function
for this for now.
<P><B>void (*set_RESET)(unsigned val);</B>
<P>Not supported yet. Will tell the simulator that the value of
the RESET pin, is currently <I>val</I>. Use an empty stub function
for this for now.
<P><B>void (*set_INTR)(unsigned val);</B>
<P>The INTR pin is driven by the device models. When the INTR pin is
raised due to an interrupt request by the PIC, or lowered after the
interrupt is acknowledged, this function is called to notify the
simulator of the new status. Only the master simulator will receive
notification, as INTR is always 0 for the slave simulator. Interrupts
are forced in the slave simulator, synchronizing it to the execution
path of the master, using <I>force_interrupt()</I> described below.
A value in <I>val</I> of 0 indicates no interrupt is requested. A value
of 1 indicates an interrupt request.
<P><B>void (*force_interrupt)(unsigned vector);</B>
<P>In order for the debugger to force the slave simulator to take an
interrupt at the same point as the master simulator, the interrupt vector
is recorded when taken by the master simulator. The debugger commands
the slave to the same point, and calls this routine, forcing the slave
to take the given interrupt, <I>vector</I>.
<P><B>void (*instr_start)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
<P>Called when the user types in "<I>instrument start</I>" at the debug prompt.
The instrumentation package can use this function to do whatever is
necessary to initialize the instrumentation package and/or command
it to begin collecting data.
<P><B>void (*instr_stop)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
<P>Called when the user types in "<I>instrument stop</I>" at the debug prompt.
The instrumentation package can use this function to do whatever is
necessary to temporarily or permanently stop the instrumentation package
from collecting data.
<P><B>void (*instr_reset)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
<P>Called when the user types in "<I>instrument reset</I>" at the debug prompt.
The instrumentation package can use this function to command the instrumentation
package to reset it's data collection mechanisms.
<P><B>void (*instr_print)(void);</B> (Only defined if macro BX_INSTRUMENTATION is 1)
<P>Called when the user types in "<I>instrument print</I>" at the debug prompt.
The instrumentation package can use this function to output it's collected
data.
<P><B>void (*loader)(char *path);</B> (Only defined if macro BX_USE_LOADER is 1)
<P>Called when the user types in "<I>loader pathname</I>" at the debug prompt.
The idea is to allow a loader routine to read in a program which is specific
to the OS you are running within the emulator, from a file on your native
workstation, load it properly into simulator memory and run it on the
simulator. This loader must be specific to the OS you are running within the
simulator, and I do not provide one with bochs.
<P><B>void (*take_irq)(void);</B>
<BR><B>void (*take_dma)(void);</B>
<BR><B>unsigned (*query_pending)(void);</B>
<P>These are vestiges of a past interface. They correspond to the
"take irq", "take dma", and "query pending" commands, which you
shouldn't use. They will be removed. Set these fields to NULL,
or to empty stub functions.
<HR>
<HR>
<H3>Debugger (Cosimulation Controller) Functions:</H3>
<H3>Debugger Functions:</H3>
<P><B>void bx_dbg_exit(int code)</B>
<P>When there is a situation in the simulator, where you need to terminate
@ -593,14 +327,8 @@ on how to do this.
<P><B>struct { .. } async;</B>
<P><B>struct { .. } async_changes_pending;</B>
<HR SIZE=5 NOSHADE>
<P>
Related Links:
<UL>
<LI><A HREF="debugger.html">Debugger</A>
<LI><A HREF="instrumentation.html">Instrumentation</A>
</UL>
</BODY>
</HTML>