1 /////////////////////////////////////////////////////////////////////////
2 // $Id: bochs.h,v 1.216 2007/11/22 17:30:40 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2002 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // bochs.h is the master header file for all C++ code. It includes all
29 // the system header files needed by bochs, and also includes all the bochs
30 // C++ header files. Because bochs.h and the files that it includes has
31 // structure and class definitions, it cannot be called from C code.
37 #include "config.h" /* generated by configure script from config.h.in */
44 // In a win32 compile (including cygwin), windows.h is required for several
45 // files in gui and iodev. It is important to include it here in a header
46 // file so that WIN32-specific data types can be used in fields of classes.
85 # include <sys/types.h>
86 # include <sys/stat.h>
87 # include <sys/param.h> /* for MAXPATHLEN */
91 # include <sys/time.h>
93 # include <sys/types.h>
94 # include <sys/stat.h>
101 # define SuperDrive "[fd:]"
108 #include "osdep.h" /* platform dependent includes and defines */
109 #include "bx_debug/debug.h"
110 #include "bxversion.h"
112 #include "gui/siminterface.h"
114 // BX_SHARE_PATH should be defined by the makefile. If not, give it
115 // a value of NULL to avoid compile problems.
116 #ifndef BX_SHARE_PATH
117 #define BX_SHARE_PATH NULL
121 int bx_begin_simulation(int argc
, char *argv
[]);
122 void bx_stop_simulation();
123 char *bx_find_bochsrc(void);
124 int bx_parse_cmdline(int arg
, int argc
, char *argv
[]);
125 int bx_read_configuration(const char *rcfile
);
126 int bx_write_configuration(const char *rcfile
, int overwrite
);
127 void bx_reset_options(void);
128 Bit32u
crc32(const Bit8u
*buf
, int len
);
129 // for param-tree testing only
130 void print_tree(bx_param_c
*node
, int level
= 0);
133 // some macros to interface the CPU and memory to external environment
134 // so that these functions can be redirected to the debugger when
138 #define BXRS_PARAM_SPECIAL(parent, name, maxvalue, save_handler, restore_handler) \
140 bx_param_num_c *param = new bx_param_num_c(parent, #name, "", "", 0, maxvalue, 0); \
141 param->set_base(BASE_HEX); \
142 param->set_sr_handlers(this, save_handler, restore_handler); \
145 #define BXRS_PARAM_SPECIAL64(parent, name, save_handler, restore_handler) \
146 BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT64U, save_handler, restore_handler)
147 #define BXRS_PARAM_SPECIAL32(parent, name, save_handler, restore_handler) \
148 BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT32U, save_handler, restore_handler)
149 #define BXRS_PARAM_SPECIAL16(parent, name, save_handler, restore_handler) \
150 BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT16U, save_handler, restore_handler)
151 #define BXRS_PARAM_SPECIAL8(parent, name, save_handler, restore_handler) \
152 BXRS_PARAM_SPECIAL(parent, name, BX_MAX_BIT8U, save_handler, restore_handler)
154 #define BXRS_HEX_PARAM_SIMPLE(parent, name) \
155 new bx_shadow_num_c(parent, #name, &(name), BASE_HEX)
156 #define BXRS_HEX_PARAM_FIELD(parent, name, field) \
157 new bx_shadow_num_c(parent, #name, &(field), BASE_HEX)
159 #define BXRS_DEC_PARAM_SIMPLE(parent, name) \
160 new bx_shadow_num_c(parent, #name, &(name), BASE_DEC)
161 #define BXRS_DEC_PARAM_FIELD(parent, name, field) \
162 new bx_shadow_num_c(parent, #name, &(field), BASE_DEC)
164 #define BXRS_PARAM_BOOL(parent, name, field) \
165 new bx_shadow_bool_c(parent, #name, (bx_bool*)(&(field)))
167 // =-=-=-=-=-=-=- Normal optimized use -=-=-=-=-=-=-=-=-=-=-=-=-=-=
168 // some pc_systems functions just redirect to the IO devices so optimize
169 // by eliminating call here
171 // #define BX_INP(addr, len) bx_pc_system.inp(addr, len)
172 // #define BX_OUTP(addr, val, len) bx_pc_system.outp(addr, val, len)
173 #define BX_INP(addr, len) bx_devices.inp(addr, len)
174 #define BX_OUTP(addr, val, len) bx_devices.outp(addr, val, len)
175 #define BX_TICK1() bx_pc_system.tick1()
176 #define BX_TICKN(n) bx_pc_system.tickn(n)
177 #define BX_INTR bx_pc_system.INTR
178 #define BX_SET_INTR(b) bx_pc_system.set_INTR(b)
179 #define BX_CPU_C bx_cpu_c
180 #define BX_MEM_C bx_mem_c
181 #define BX_HRQ (bx_pc_system.HRQ)
184 #define BX_CPU(x) (bx_cpu_array[x])
186 #define BX_CPU(x) (&bx_cpu)
189 #define BX_MEM(x) (&bx_mem)
191 #define BX_SET_ENABLE_A20(enabled) bx_pc_system.set_enable_a20(enabled)
192 #define BX_GET_ENABLE_A20() bx_pc_system.get_enable_a20()
195 # define A20ADDR(x) ((x) & bx_pc_system.a20_mask)
197 # define A20ADDR(x) (x)
201 # define BX_TICK1_IF_SINGLE_PROCESSOR() \
202 if (BX_SMP_PROCESSORS == 1) BX_TICK1()
204 # define BX_TICK1_IF_SINGLE_PROCESSOR() BX_TICK1()
207 // you can't use static member functions on the CPU, if there are going
208 // to be 2 cpus. Check this early on.
211 # error For SMP simulation, BX_USE_CPU_SMF must be 0.
216 // Ways for the the external environment to report back information
221 # define BX_DBG_ASYNC_INTR bx_guard.async.irq
222 # define BX_DBG_ASYNC_DMA bx_guard.async.dma
224 # define BX_DBG_DMA_REPORT(addr, len, what, val) \
225 if (bx_guard.report.dma) bx_dbg_dma_report(addr, len, what, val)
226 # define BX_DBG_IAC_REPORT(vector, irq) \
227 if (bx_guard.report.irq) bx_dbg_iac_report(vector, irq)
228 # define BX_DBG_A20_REPORT(val) \
229 if (bx_guard.report.a20) bx_dbg_a20_report(val)
230 # define BX_DBG_IO_REPORT(port, size, op, val) \
231 if (bx_guard.report.io) bx_dbg_io_report(port, size, op, val)
232 # define BX_DBG_UCMEM_REPORT(addr, size, op, val) \
233 if (bx_guard.report.ucmem) bx_dbg_ucmem_report(addr, size, op, val)
234 #else // #if BX_DEBUGGER
235 // debugger not compiled in, use empty stubs
236 # define BX_DBG_ASYNC_INTR 1
237 # define BX_DBG_ASYNC_DMA 1
238 # define BX_DBG_DMA_REPORT(addr, len, what, val)
239 # define BX_DBG_IAC_REPORT(vector, irq)
240 # define BX_DBG_A20_REPORT(val)
241 # define BX_DBG_IO_REPORT(addr, size, op, val)
242 # define BX_DBG_UCMEM_REPORT(addr, size, op, val)
243 #endif // #if BX_DEBUGGER
245 #define MAGIC_LOGNUM 0x12345678
247 typedef class BOCHSAPI logfunctions
{
250 // values of onoff: 0=ignore, 1=report, 2=ask, 3=fatal
257 class iofunctions
*logio
;
258 // default log actions for all devices, declared and initialized
260 BOCHSAPI_CYGONLY
static int default_onoff
[N_LOGLEV
];
263 logfunctions(class iofunctions
*);
266 void info(const char *fmt
, ...) BX_CPP_AttrPrintf(2, 3);
267 void error(const char *fmt
, ...) BX_CPP_AttrPrintf(2, 3);
268 void panic(const char *fmt
, ...) BX_CPP_AttrPrintf(2, 3);
269 void pass(const char *fmt
, ...) BX_CPP_AttrPrintf(2, 3);
270 void ldebug(const char *fmt
, ...) BX_CPP_AttrPrintf(2, 3);
271 void fatal (const char *prefix
, const char *fmt
, va_list ap
, int exit_status
);
272 #if BX_EXTERNAL_DEBUGGER
273 virtual void ask (int level
, const char *prefix
, const char *fmt
, va_list ap
);
275 void ask (int level
, const char *prefix
, const char *fmt
, va_list ap
);
277 void put(const char *);
279 void setio(class iofunctions
*);
280 void setonoff(int loglev
, int value
) {
281 assert (loglev
>= 0 && loglev
< N_LOGLEV
);
282 onoff
[loglev
] = value
;
284 char *getprefix () { return prefix
; }
285 int getonoff(int level
) {
286 assert (level
>=0 && level
<N_LOGLEV
);
289 static void set_default_action (int loglev
, int action
) {
290 assert (loglev
>= 0 && loglev
< N_LOGLEV
);
291 assert (action
>= 0 && action
< N_ACT
);
292 default_onoff
[loglev
] = action
;
294 static int get_default_action (int loglev
) {
295 assert (loglev
>= 0 && loglev
< N_LOGLEV
);
296 return default_onoff
[loglev
];
300 #define BX_LOGPREFIX_SIZE 51
303 IOLOG
=0, FDLOG
, GENLOG
, CMOSLOG
, CDLOG
, DMALOG
, ETHLOG
, G2HLOG
, HDLOG
, KBDLOG
,
304 NE2KLOG
, PARLOG
, PCILOG
, PICLOG
, PITLOG
, SB16LOG
, SERLOG
, VGALOG
,
305 DEVLOG
, MEMLOG
, DISLOG
, GUILOG
, IOAPICLOG
, APICLOG
, CPU0LOG
, CPU1LOG
,
306 CPU2LOG
, CPU3LOG
, CPU4LOG
, CPU5LOG
, CPU6LOG
, CPU7LOG
, CPU8LOG
, CPU9LOG
,
307 CPU10LOG
, CPU11LOG
, CPU12LOG
, CPU13LOG
, CPU14LOG
, CPU15LOG
, CTRLLOG
,
308 UNMAPLOG
, SERRLOG
, BIOSLOG
, PIT81LOG
, PIT82LOG
, IODEBUGLOG
, PCI2ISALOG
,
309 PLUGINLOG
, EXTFPUIRQLOG
, PCIVGALOG
, PCIUSBLOG
, VTIMERLOG
, STIMERLOG
,
310 PCIIDELOG
, PCIDEVLOG
, PCIPNICLOG
, SPEAKERLOG
, BUSMLOG
, GAMELOG
, ACPILOG
313 class BOCHSAPI iofunctions
{
315 char logprefix
[BX_LOGPREFIX_SIZE
];
317 class logfunctions
*log
;
326 iofunctions(const char *);
329 void out(int facility
, int level
, const char *pre
, const char *fmt
, va_list ap
);
331 void init_log(const char *fn
);
332 void init_log(int fd
);
333 void init_log(FILE *fs
);
335 void set_log_prefix(const char *prefix
);
336 int get_n_logfns() { return n_logfn
; }
337 logfunc_t
*get_logfn(int index
) { return logfn_list
[index
]; }
338 void add_logfn(logfunc_t
*fn
);
339 void remove_logfn(logfunc_t
*fn
);
340 void set_log_action(int loglevel
, int action
);
341 const char *getlevel(int i
) {
342 static const char *loglevel
[N_LOGLEV
] = {
349 if (i
>=0 && i
<N_LOGLEV
) return loglevel
[i
];
352 char *getaction(int i
) {
353 static const char *name
[] = { "ignore", "report", "ask", "fatal" };
354 assert (i
>=ACT_IGNORE
&& i
<N_ACT
);
355 return (char *) name
[i
];
360 #define MAX_LOGFNS 128
361 logfunc_t
*logfn_list
[MAX_LOGFNS
];
365 typedef class BOCHSAPI iofunctions iofunc_t
;
368 #define SAFE_GET_IOFUNC() \
369 ((io==NULL)? (io=new iofunc_t("/dev/stderr")) : io)
370 #define SAFE_GET_GENLOG() \
371 ((genlog==NULL)? (genlog=new logfunc_t(SAFE_GET_IOFUNC())) : genlog)
378 #define BX_PANIC(x) (LOG_THIS panic) x
379 #define BX_PASS(x) (LOG_THIS pass) x
383 #define BX_INFO(x) (LOG_THIS info) x
384 #define BX_DEBUG(x) (LOG_THIS ldebug) x
385 #define BX_ERROR(x) (LOG_THIS error) x
386 #define BX_PANIC(x) (LOG_THIS panic) x
387 #define BX_PASS(x) (LOG_THIS pass) x
391 BOCHSAPI
extern iofunc_t
*io
;
392 BOCHSAPI
extern logfunc_t
*genlog
;
395 # define UNUSED(x) ((void)x)
398 #if BX_SUPPORT_X86_64
399 #define FMT_ADDRX FMT_ADDRX64
401 #define FMT_ADDRX FMT_ADDRX32
405 // defines for GDB stub
406 void bx_gdbstub_init(void);
407 void bx_gdbstub_break(void);
408 int bx_gdbstub_check(unsigned int eip
);
409 #define GDBSTUB_STOP_NO_REASON (0xac0)
412 #error GDB stub was written for single processor support. If multiprocessor support is added, then we can remove this check.
413 // The big problem is knowing which CPU gdb is referring to. In other words,
414 // what should we put for "n" in BX_CPU(n)->dbg_xlate_linear2phy() and
415 // BX_CPU(n)->dword.eip, etc.
443 bx_bool unsupported_io
;
446 bx_bool print_timestamps
;
447 #if BX_MAGIC_BREAKPOINT
448 bx_bool magic_break_enabled
;
451 bx_bool gdbstub_enabled
;
458 bx_bool linux_syscall
;
463 #define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%d\n", #x, __FILE__, __LINE__));} while (0)
464 void bx_signal_handler (int signum
);
466 BOCHSAPI
extern bx_debug_t bx_dbg
;
469 // memory access type (read/write/rw)
474 #define DATA_ACCESS 0
475 #define CODE_ACCESS 1
477 #include "memory/memory.h"
478 #include "pc_system.h"
481 #include "gui/textconfig.h"
482 #include "gui/keymap.h"
484 /* --- EXTERNS --- */
486 #if BX_GUI_SIGHANDLER
487 extern bx_bool bx_gui_sighandler
;
490 // This value controls how often each I/O device's periodic() method
491 // gets called. The timer is set up in iodev/devices.cc.
492 #define BX_IODEV_HANDLER_PERIOD 100 // microseconds
493 //#define BX_IODEV_HANDLER_PERIOD 10 // microseconds
495 #define BX_PATHNAME_LEN 512
497 #define BX_KBD_XT_TYPE 0
498 #define BX_KBD_AT_TYPE 1
499 #define BX_KBD_MF_TYPE 2
501 #define BX_N_OPTROM_IMAGES 4
502 #define BX_N_OPTRAM_IMAGES 4
503 #define BX_N_SERIAL_PORTS 4
504 #define BX_N_PARALLEL_PORTS 2
505 #define BX_N_USB_HUBS 1
506 #define BX_N_PCI_SLOTS 5
509 #define BX_SMP_PROCESSORS (bx_cpu_count)
511 #define BX_SMP_PROCESSORS 1
514 void bx_center_print(FILE *file
, char *line
, int maxwidth
);
516 #define BX_USE_PS2_MOUSE 1
518 #include "instrument.h"
520 // These are some convenience macros which abstract out accesses between
521 // a variable in native byte ordering to/from guest (x86) memory, which is
522 // always in little endian format. You must deal with alignment (if your
523 // system cares) and endian rearranging. Don't assume anything. You could
524 // put some platform specific asm() statements here, to make use of native
525 // instructions to help perform these operations more efficiently than C++.
528 #ifdef BX_LITTLE_ENDIAN
530 #define WriteHostWordToLittleEndian(hostPtr, nativeVar16) \
531 *((Bit16u*)(hostPtr)) = (nativeVar16)
532 #define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) \
533 *((Bit32u*)(hostPtr)) = (nativeVar32)
534 #define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) \
535 *((Bit64u*)(hostPtr)) = (nativeVar64)
536 #define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) \
537 (nativeVar16) = *((Bit16u*)(hostPtr))
538 #define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) \
539 (nativeVar32) = *((Bit32u*)(hostPtr))
540 #define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) \
541 (nativeVar64) = *((Bit64u*)(hostPtr))
545 #define WriteHostWordToLittleEndian(hostPtr, nativeVar16) { \
546 ((Bit8u *)(hostPtr))[0] = (Bit8u) (nativeVar16); \
547 ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar16)>>8); \
549 #define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) { \
550 ((Bit8u *)(hostPtr))[0] = (Bit8u) (nativeVar32); \
551 ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar32)>>8); \
552 ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar32)>>16); \
553 ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar32)>>24); \
555 #define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) { \
556 ((Bit8u *)(hostPtr))[0] = (Bit8u) (nativeVar64); \
557 ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar64)>>8); \
558 ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar64)>>16); \
559 ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar64)>>24); \
560 ((Bit8u *)(hostPtr))[4] = (Bit8u) ((nativeVar64)>>32); \
561 ((Bit8u *)(hostPtr))[5] = (Bit8u) ((nativeVar64)>>40); \
562 ((Bit8u *)(hostPtr))[6] = (Bit8u) ((nativeVar64)>>48); \
563 ((Bit8u *)(hostPtr))[7] = (Bit8u) ((nativeVar64)>>56); \
565 #define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) { \
566 (nativeVar16) = ((Bit16u) ((Bit8u *)(hostPtr))[0]) | \
567 (((Bit16u) ((Bit8u *)(hostPtr))[1])<<8) ; \
569 #define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) { \
570 (nativeVar32) = ((Bit32u) ((Bit8u *)(hostPtr))[0]) | \
571 (((Bit32u) ((Bit8u *)(hostPtr))[1])<<8) | \
572 (((Bit32u) ((Bit8u *)(hostPtr))[2])<<16) | \
573 (((Bit32u) ((Bit8u *)(hostPtr))[3])<<24); \
575 #define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) { \
576 (nativeVar64) = ((Bit64u) ((Bit8u *)(hostPtr))[0]) | \
577 (((Bit64u) ((Bit8u *)(hostPtr))[1])<<8) | \
578 (((Bit64u) ((Bit8u *)(hostPtr))[2])<<16) | \
579 (((Bit64u) ((Bit8u *)(hostPtr))[3])<<24) | \
580 (((Bit64u) ((Bit8u *)(hostPtr))[4])<<32) | \
581 (((Bit64u) ((Bit8u *)(hostPtr))[5])<<40) | \
582 (((Bit64u) ((Bit8u *)(hostPtr))[6])<<48) | \
583 (((Bit64u) ((Bit8u *)(hostPtr))[7])<<56); \
588 #endif /* BX_BOCHS_H */