1 /////////////////////////////////////////////////////////////////////////
2 // $Id: siminterface.h 14189 2021-03-18 19:50:12Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2001-2021  The Bochs Project
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20 //
21 /////////////////////////////////////////////////////////////////////////
22 
23 #ifndef BX_SIM_INTERFACE_H
24 #define BX_SIM_INTERFACE_H
25 
26 //
27 // Intro to siminterface by Bryce Denney:
28 //
29 // Before I can describe what this file is for, I have to make the
30 // distinction between a configuration interface (CI) and the VGA display
31 // window (VGAW).  I will try to avoid the term 'GUI' because it is unclear
32 // if that means CI or VGAW, and because not all interfaces are graphical
33 // anyway.
34 //
35 // The traditional Bochs screen is a window with a large VGA display panel and
36 // a series of buttons (floppy, cdrom, snapshot, power).  Over the years, we
37 // have collected many implementations of the VGAW for different environments
38 // and platforms; each implementation is in a separate file under gui/*:
39 // x.cc, win32.cc, macintosh.cc, etc.  The files gui.h and gui.cc
40 // define the platform independent part of the VGAW, leaving about 15 methods
41 // of the bx_gui_c class undefined.  The platform dependent file must
42 // implement the remaining 15 methods.
43 //
44 // The configuration interface is relatively new, started by Bryce Denney in
45 // June 2001.  The CI is intended to allow the user to edit a variety of
46 // configuration and runtime options.  Some options, such as memory size or
47 // enabling the ethernet card, should only be changed before the simulation
48 // begins; others, such as floppy disk image, instructions per second, and
49 // logging options can be safely changed at runtime.  The CI allows the user to
50 // make these changes.  Before the CI existed, only a few things could be
51 // changed at runtime, all linked to clicking on the VGAW buttons.
52 //
53 // At the time that the CI was conceived, we were still debating what form the
54 // user interface part would take: stdin/stdout menus, a graphical application
55 // with menus and dialogs running in a separate thread, or even a tiny web
56 // server that you can connect to with a web browser.  As a result the
57 // interface to the CI was designed so that the user interface of the CI
58 // could be replaced easily at compile time, or maybe even at runtime via
59 // a plugin architecture.  To this end, we kept a clear separation between
60 // the user interface code and the siminterface, the code that interfaces with
61 // the simulator.  The same siminterface is used all the time, while
62 // different implementations of the CI can be switched in reasonably easily.
63 // Only the CI code uses library specific graphics and I/O functions; the
64 // siminterface deals in portable abstractions and callback functions.
65 // The first CI implementation was a series of text mode menus implemented in
66 // textconfig.cc.
67 //
68 // The configuration interface MUST use the siminterface methods to access the
69 // simulator.  It should not modify settings in some device with code like
70 // bx_floppy.s.media[2].heads = 17.  If such access is needed, then a
71 // siminterface method should be written to make the change on the CI's behalf.
72 // This separation is enforced by the fact that the CI does not even include
73 // bochs.h.  You'll notice that textconfig.cc includes osdep.h, paramtree.h
74 // and siminterface.h, so it doesn't know what bx_floppy or bx_cpu_c are.
75 // I'm sure some people will say is overly restrictive and/or annoying.  When I
76 // set it up this way, we were still talking about making the CI in a seperate
77 // process, where direct method calls would be impossible.  Also, we have been
78 // considering turning devices into plugin modules which are dynamically
79 // linked.  Any direct references to something like bx_floppy.s.media[2].heads
80 // would have to be reworked before a plugin interface was possible as well.
81 //
82 // The siminterface is the glue between the CI and the simulator.  There is
83 // just one global instance of the siminterface object, which can be referred
84 // to by the global variable bx_simulator_interface_c *SIM.  The base class
85 // bx_simulator_interface_c, contains only virtual functions and it defines the
86 // interface that the CI is allowed to use.  In siminterface.cc, a class
87 // called bx_real_sim_c is defined with bx_simulator_interface_c as its parent
88 // class.  Bx_real_sim_c implements each of the functions.  The separation into
89 // parent class and child class leaves the possibility of making a different
90 // child class that talks to the simulator in a different way (networking for
91 // example).  If you were writing a user interface in a separate process, you
92 // could define a subclass of bx_simulator_interface_c called
93 // bx_siminterface_proxy_c which opens up a network port and turns all method
94 // calls into network sends and receives.  Because the interface is defined
95 // entirely by the base class, the code that calls the methods would not know
96 // the difference.
97 //
98 // An important part of the siminterface implementation is the use of parameter
99 // classes, or bx_param_*.  The parameter classes are described below, where
100 // they are declared.  Search for "parameter classes" below for details.
101 //
102 // Also this header file declares data structures for certain events that pass
103 // between the siminterface and the CI.  Search for "event structures" below.
104 
105 
106 // base value for generated new parameter id
107 #define BXP_NEW_PARAM_ID 1001
108 
109 typedef enum {
110   BX_TOOLBAR_UNDEFINED,
111   BX_TOOLBAR_FLOPPYA,
112   BX_TOOLBAR_FLOPPYB,
113   BX_TOOLBAR_CDROM1,
114   BX_TOOLBAR_RESET,
115   BX_TOOLBAR_POWER,
116   BX_TOOLBAR_SAVE_RESTORE,
117   BX_TOOLBAR_COPY,
118   BX_TOOLBAR_PASTE,
119   BX_TOOLBAR_SNAPSHOT,
120   BX_TOOLBAR_CONFIG,
121   BX_TOOLBAR_MOUSE_EN,
122   BX_TOOLBAR_USER
123 } bx_toolbar_buttons;
124 
125 // normally all action choices are available for all event types. The exclude
126 // expression allows some choices to be eliminated if they don't make any
127 // sense.  For example, it would be stupid to ignore a panic.
128 #define BX_LOG_OPTS_EXCLUDE(type, choice)  (             \
129    /* can't die, ask or warn, on debug or info events */ \
130    (type <= LOGLEV_INFO && (choice >= ACT_WARN))         \
131    /* can't ignore panics */                             \
132    || (type == LOGLEV_PANIC && choice == ACT_IGNORE)     \
133    )
134 
135 // floppy / cdrom media status
136 enum { BX_EJECTED = 0, BX_INSERTED = 1 };
137 
138 // boot devices (using the same values as the rombios)
139 enum {
140   BX_BOOT_NONE,
141   BX_BOOT_FLOPPYA,
142   BX_BOOT_DISKC,
143   BX_BOOT_CDROM,
144   BX_BOOT_NETWORK
145 };
146 
147 ///////////////////////////////////////////////////////////////////
148 // event structures for communication between simulator and CI
149 ///////////////////////////////////////////////////////////////////
150 // Because the CI (configuration interface) might be in a different
151 // thread or even a different process, we pass events encoded in data
152 // structures to it instead of just calling functions.  Each type of
153 // event is declared as a different structure, and then all those
154 // structures are squished into a union in BxEvent.  (BTW, this is
155 // almost exactly how X windows event structs work.)
156 //
157 // These are simple structs, unblemished by C++ methods and tricks.
158 // No matter what event type it is, we allocate a BxEvent for each
159 // one, as opposed to trying to save a few bytes on small events by
160 // allocating only the bytes necessary for it.  This makes it easy and
161 // fast to store events in a queue, like this
162 //   BxEvent event_queue[MAX_EVENTS];
163 //
164 // Events come in two varieties: synchronous and asynchronous.  We
165 // have to worry about sync and async events because the CI and the
166 // simulation may be running in different threads.  An async event is
167 // the simplest.  Whichever thread originates the event just builds
168 // the data structure, sends it, and then continues with its business.
169 // Async events can go in either direction.  Synchronous events
170 // require the other thread to "respond" before the originating thread
171 // can continue.  It's like a function with a return value; you can't
172 // continue until you get the return value back.
173 //
174 // Examples:
175 //
176 // async event: In the wxWidgets implementation, both the CI and the
177 // VGAW operate in the wxWidgets GUI thread.  When the user presses a
178 // key, wxWidgets sends a wxKeyEvent to the VGAW event handler code in
179 // wx.cc.  The VGAW handler then builds a BxEvent with
180 // type=BX_ASYNC_EVT_KEY, and fills in the bx_key and raw_scancode
181 // fields.  The asynchronous event is placed on the event_queue for
182 // the simulator, then the VGAW handler returns.  (With wxWidgets and
183 // many other graphical libaries, the event handler must return
184 // quickly because the window will not be updated until it's done.)
185 // Some time later, the simulator reaches the point where it checks
186 // for new events from the user (actually controlled by
187 // bx_devices_c::timer() in iodev/devices.cc) and calls
188 // bx_gui->handle_events(). Then all the events in the queue are
189 // processed by the simulator.  There is no "response" sent back to
190 // the originating thread.
191 //
192 // sync event: Sometimes the simulator reaches a point where it needs
193 // to ask the user how to proceed.  In this case, the simulator sends
194 // a synchronous event because it requires a response before it can
195 // continue.  It builds an event structure, perhaps with type
196 // BX_SYNC_EVT_ASK_PARAM, sends it to the user interface
197 // using the event handler function defined by set_notify_callback(),
198 // and pauses the simulation.  The user interface asks the user the
199 // question, and puts the answer into the BxEvent.retcode field.  The
200 // event handler function returns the modified BxEvent with retcode
201 // filled in, and the simulation continues.  The details of this
202 // transaction can be complicated if the simulation and CI are not
203 // in the same thread, but the behavior is as described.
204 //
205 
206 ///// types and definitions used in event structures
207 
208 #define BX_EVT_IS_ASYNC(type) ((type) > __ALL_EVENTS_BELOW_ARE_ASYNC__)
209 
210 typedef enum {
211   __ALL_EVENTS_BELOW_ARE_SYNCHRONOUS__ = 2000,
212   BX_SYNC_EVT_GET_PARAM,          // CI -> simulator -> CI
213   BX_SYNC_EVT_ASK_PARAM,          // simulator -> CI -> simulator
214   BX_SYNC_EVT_TICK,               // simulator -> CI, wait for response.
215   BX_SYNC_EVT_LOG_DLG,            // simulator -> CI, wait for response.
216   BX_SYNC_EVT_GET_DBG_COMMAND,    // simulator -> CI, wait for response.
217   BX_SYNC_EVT_MSG_BOX,            // simulator -> CI, wait for response.
218   __ALL_EVENTS_BELOW_ARE_ASYNC__,
219   BX_ASYNC_EVT_KEY,               // vga window -> simulator
220   BX_ASYNC_EVT_MOUSE,             // vga window -> simulator
221   BX_ASYNC_EVT_SET_PARAM,         // CI -> simulator
222   BX_ASYNC_EVT_LOG_MSG,           // simulator -> CI
223   BX_ASYNC_EVT_DBG_MSG,           // simulator -> CI
224   BX_ASYNC_EVT_VALUE_CHANGED,     // simulator -> CI
225   BX_ASYNC_EVT_TOOLBAR,           // CI -> simulator
226   BX_ASYNC_EVT_STATUSBAR,         // simulator -> CI
227   BX_ASYNC_EVT_REFRESH,           // simulator -> CI
228   BX_ASYNC_EVT_QUIT_SIM           // simulator -> CI
229 } BxEventType;
230 
231 typedef union {
232   Bit32s s32;
233   char *charptr;
234 } AnyParamVal;
235 
236 // Define substructures which make up the interior of BxEvent.  The
237 // substructures, such as BxKeyEvent or BxMouseEvent, should never be
238 // allocated on their own.  They are only intended to be used within
239 // the union in the BxEvent structure.
240 
241 // Event type: BX_SYNC_EVT_TICK
242 //
243 // A tick event is synchronous, sent from the simulator to the GUI.  The
244 // event doesn't do anything visible.  Primarily it gives the GUI a chance
245 // to tell the simulator to quit, if necessary.  There may be other uses
246 // for the tick in the future, such as giving some kind of regular
247 // status report or mentioning watched values that changed, but so far
248 // it's just for that one thing.  There is no data associated with a
249 // tick event.
250 
251 // Event type: BX_ASYNC_EVT_KEY
252 //
253 // A key event can be sent from the VGA window to the Bochs simulator.
254 // It is asynchronous.
255 typedef struct {
256   // what was pressed?  This is a BX_KEY_* value.  For key releases,
257   // BX_KEY_RELEASED is ORed with the base BX_KEY_*.
258   Bit32u bx_key;
259   bool raw_scancode;
260 } BxKeyEvent;
261 
262 // Event type: BX_ASYNC_EVT_MOUSE
263 //
264 // A mouse event can be sent from the VGA window to the Bochs
265 // simulator.  It is asynchronous.
266 typedef struct {
267   // type is BX_EVT_MOUSE
268   Bit16s dx, dy, dz;       // mouse motion delta
269   Bit8u buttons;           // which buttons are pressed.
270                            // bit 0: 1=left button down, 0=up
271                            // bit 1: 1=right button down, 0=up
272                            // bit 2: 1=middle button down, 0=up
273 } BxMouseEvent;
274 
275 // Event type: BX_SYNC_EVT_GET_PARAM, BX_ASYNC_EVT_SET_PARAM
276 //
277 // Parameter set/get events are initiated by the CI, since Bochs can
278 // always access the parameters directly.  So far, I haven't used
279 // these event types.  In the CI I just call
280 // SIM->get_param(parameter_id) to get a pointer to the bx_param_c
281 // object and then call the get/set methods.  This is okay for
282 // configuration since bochs is not running.  However it could be
283 // dangerous for the GUI thread to poke around in Bochs structures
284 // while the thread is running.  For these cases, I may have to be
285 // more careful and actually build get/set events and place them on
286 // Bochs's event queue to be processed during SIM->periodic() or
287 // something.
288 typedef struct {
289   // type is BX_EVT_GET_PARAM, BX_EVT_SET_PARAM
290   class bx_param_c *param;         // pointer to param structure
291   AnyParamVal val;
292 } BxParamEvent;
293 
294 // Event type: BX_SYNC_EVT_ASK_PARAM
295 // Synchronous event sent from the simulator to the CI.  This tells the
296 // CI to ask the user to choose the value of a parameter.  The CI may
297 // need to discover the type of parameter so that it can use the right
298 // kind of graphical display.  The BxParamEvent is used for these events
299 // too.
300 // FIXME: at the moment the GUI implements the ASK_PARAM event for just
301 // a few parameter types.  I need to implement the event for all parameter
302 // types.
303 
304 // Event type: BX_ASYNC_EVT_VALUE_CHANGED
305 //
306 // Asynchronous event sent from the simulator to the CI, telling it that
307 // some value that it (hopefully) cares about has changed.  This isn't
308 // being used yet, but a good example is in a debugger interface, you might
309 // want to maintain a reasonably current display of the PC or some other
310 // simulation state.  The CI would set some kind of event mask (which
311 // doesn't exist now of course) and then when certain values change, the
312 // simulator would send this event so that the CI can update.  We may need
313 // some kind of "flow control" since the simulator will be able to produce
314 // new events much faster than the gui can accept them.
315 
316 // Event type: BX_ASYNC_EVT_LOG_MSG
317 //
318 // Asynchronous event from the simulator to the CI.  When a BX_PANIC,
319 // BX_ERROR, BX_INFO, or BX_DEBUG is found in the simulator code, this
320 // event type can be used to inform the CI of the condition.  There is
321 // no point in sending messages to the CI that will not be displayed; these
322 // would only slow the simulation.  So we will need some mechanism for
323 // choosing what kinds of events will be delivered to the CI.  Normally,
324 // you wouldn't want to look at the log unless something is going wrong.
325 // At that point, you might want to open up a window to watch the debug
326 // messages from one or two devices only.
327 //
328 // Idea: Except for panics that require user attention to continue, it
329 // might be most efficient to just append log messages to a file.
330 // When the user wants to look at the log messages, the gui can reopen
331 // the file (read only), skip to the end, and look backward for a
332 // reasonable number of lines to display (200?).  This allows it to
333 // skip over huge bursts of log entries without allocating memory,
334 // synchronizing threads, etc. for each.
335 typedef struct {
336   Bit8u level;
337   Bit8u mode;
338   const char *prefix;
339   const char *msg;
340 } BxLogMsgEvent;
341 
342 // Event type: BX_ASYNC_EVT_DBG_MSG
343 //
344 // Also uses BxLogMsgEvent, but this is a message to be displayed in
345 // the debugger history window.
346 
347 // Event type: BX_SYNC_EVT_LOG_DLG
348 //
349 // This is a synchronous version of BX_ASYNC_EVT_LOG_MSG, which is used
350 // when the "action=ask" setting is used.  If the simulator runs into a
351 // panic, it sends a synchronous BX_SYNC_EVT_LOG_DLG to the CI to be
352 // displayed.  The CI shows a dialog that asks if the user wants to
353 // continue, quit, etc. and sends the answer back to the simulator.
354 // This event also uses BxLogMsgEvent.
355 enum {
356   BX_LOG_ASK_CHOICE_CONTINUE,
357   BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS,
358   BX_LOG_ASK_CHOICE_DIE,
359   BX_LOG_ASK_CHOICE_DUMP_CORE,
360   BX_LOG_ASK_CHOICE_ENTER_DEBUG,
361   BX_LOG_ASK_N_CHOICES,
362   BX_LOG_NOTIFY_FAILED
363 };
364 
365 enum {
366   BX_LOG_DLG_ASK,
367   BX_LOG_DLG_WARN,
368   BX_LOG_DLG_QUIT
369 };
370 
371 // Event type: BX_SYNC_EVT_GET_DBG_COMMAND
372 //
373 // This is a synchronous event sent from the simulator to the debugger
374 // requesting the next action.  In a text mode debugger, this would prompt
375 // the user for the next command.  When a new command is ready, the
376 // synchronous event is sent back with its fields filled in.
377 typedef struct {
378   char *command;   // null terminated string. allocated by debugger interface
379                    // with new operator, freed by simulator with delete.
380 } BxDebugCommand;
381 
382 
383 
384 // Event type: BX_ASYNC_EVT_TOOLBAR
385 // Asynchronous event from the VGAW to the simulator, sent when the user
386 // clicks on a toolbar button.  This may one day become something more
387 // general, like a command event, but at the moment it's only needed for
388 // the toolbar events.
389 typedef struct {
390   bx_toolbar_buttons button;
391   bool on; // for toggling buttons, on=true means the toolbar button is
392               // pressed. on=false means it is not pressed.
393 } BxToolbarEvent;
394 
395 // Event type: BX_ASYNC_EVT_STATUSAR
396 typedef struct {
397   int element;
398   char *text;
399   bool active;
400   bool w;
401 } BxStatusbarEvent;
402 
403 // The BxEvent structure should be used for all events.  Every event has
404 // a type and a spot for a return code (only used for synchronous events).
405 typedef struct {
406   BxEventType type; // what kind is this?
407   Bit32s retcode;   // success or failure. only used for synchronous events.
408   union {
409     BxKeyEvent key;
410     BxMouseEvent mouse;
411     BxParamEvent param;
412     BxLogMsgEvent logmsg;
413     BxToolbarEvent toolbar;
414     BxStatusbarEvent statbar;
415     BxDebugCommand debugcmd;
416   } u;
417 } BxEvent;
418 
419 // These are the different start modes.
420 enum {
421   // Just start the simulation without running the configuration interface
422   // at all, unless something goes wrong.
423   BX_QUICK_START = 200,
424   // Run the configuration interface.  The default action will be to load a
425   // configuration file.  This makes sense if a config file could not be
426   // loaded, either because it wasn't found or because it had errors.
427   BX_LOAD_START,
428   // Run the configuration interface.  The default action will be to
429   // edit the configuration.
430   BX_EDIT_START,
431   // Run the configuration interface, but make the default action be to
432   // start the simulation.
433   BX_RUN_START
434 };
435 
436 enum {
437   BX_DDC_MODE_DISABLED,
438   BX_DDC_MODE_BUILTIN,
439   BX_DDC_MODE_FILE
440 };
441 
442 enum {
443   BX_MOUSE_TYPE_NONE,
444   BX_MOUSE_TYPE_PS2,
445   BX_MOUSE_TYPE_IMPS2,
446 #if BX_SUPPORT_BUSMOUSE
447   BX_MOUSE_TYPE_INPORT,
448   BX_MOUSE_TYPE_BUS,
449 #endif
450   BX_MOUSE_TYPE_SERIAL,
451   BX_MOUSE_TYPE_SERIAL_WHEEL,
452   BX_MOUSE_TYPE_SERIAL_MSYS
453 };
454 
455 enum {
456   BX_MOUSE_TOGGLE_CTRL_MB,
457   BX_MOUSE_TOGGLE_CTRL_F10,
458   BX_MOUSE_TOGGLE_CTRL_ALT,
459   BX_MOUSE_TOGGLE_F12
460 };
461 
462 #define BX_FDD_NONE  0 // floppy not present
463 #define BX_FDD_525DD 1 // 360K  5.25"
464 #define BX_FDD_525HD 2 // 1.2M  5.25"
465 #define BX_FDD_350DD 3 // 720K  3.5"
466 #define BX_FDD_350HD 4 // 1.44M 3.5"
467 #define BX_FDD_350ED 5 // 2.88M 3.5"
468 
469 #define BX_FLOPPY_NONE   10 // media not present
470 #define BX_FLOPPY_1_2    11 // 1.2M  5.25"
471 #define BX_FLOPPY_1_44   12 // 1.44M 3.5"
472 #define BX_FLOPPY_2_88   13 // 2.88M 3.5"
473 #define BX_FLOPPY_720K   14 // 720K  3.5"
474 #define BX_FLOPPY_360K   15 // 360K  5.25"
475 #define BX_FLOPPY_160K   16 // 160K  5.25"
476 #define BX_FLOPPY_180K   17 // 180K  5.25"
477 #define BX_FLOPPY_320K   18 // 320K  5.25"
478 #define BX_FLOPPY_LAST   18 // last legal value of floppy type
479 
480 #define BX_FLOPPY_AUTO     19 // autodetect image size
481 #define BX_FLOPPY_UNKNOWN  20 // image size doesn't match one of the types above
482 
483 #define BX_ATA_DEVICE_NONE       0
484 #define BX_ATA_DEVICE_DISK       1
485 #define BX_ATA_DEVICE_CDROM      2
486 
487 #define BX_ATA_BIOSDETECT_AUTO   0
488 #define BX_ATA_BIOSDETECT_CMOS   1
489 #define BX_ATA_BIOSDETECT_NONE   2
490 
491 enum {
492   BX_SECT_SIZE_512,
493   BX_SECT_SIZE_1024,
494   BX_SECT_SIZE_4096
495 };
496 
497 enum {
498   BX_ATA_TRANSLATION_NONE,
499   BX_ATA_TRANSLATION_LBA,
500   BX_ATA_TRANSLATION_LARGE,
501   BX_ATA_TRANSLATION_RECHS,
502   BX_ATA_TRANSLATION_AUTO
503 };
504 #define BX_ATA_TRANSLATION_LAST  BX_ATA_TRANSLATION_AUTO
505 
506 enum {
507   BX_CLOCK_SYNC_NONE,
508   BX_CLOCK_SYNC_REALTIME,
509   BX_CLOCK_SYNC_SLOWDOWN,
510   BX_CLOCK_SYNC_BOTH
511 };
512 #define BX_CLOCK_SYNC_LAST       BX_CLOCK_SYNC_BOTH
513 
514 enum {
515   BX_PCI_CHIPSET_I430FX,
516   BX_PCI_CHIPSET_I440FX,
517   BX_PCI_CHIPSET_I440BX
518 };
519 
520 enum {
521   BX_CPUID_SUPPORT_NOSSE,
522   BX_CPUID_SUPPORT_SSE,
523   BX_CPUID_SUPPORT_SSE2,
524   BX_CPUID_SUPPORT_SSE3,
525   BX_CPUID_SUPPORT_SSSE3,
526   BX_CPUID_SUPPORT_SSE4_1,
527   BX_CPUID_SUPPORT_SSE4_2,
528 #if BX_SUPPORT_AVX
529   BX_CPUID_SUPPORT_AVX,
530   BX_CPUID_SUPPORT_AVX2,
531 #if BX_SUPPORT_EVEX
532   BX_CPUID_SUPPORT_AVX512
533 #endif
534 #endif
535 };
536 
537 enum {
538   BX_CPUID_SUPPORT_LEGACY_APIC,
539   BX_CPUID_SUPPORT_XAPIC,
540 #if BX_CPU_LEVEL >= 6
541   BX_CPUID_SUPPORT_XAPIC_EXT,
542   BX_CPUID_SUPPORT_X2APIC
543 #endif
544 };
545 
546 #define BX_CLOCK_TIME0_LOCAL     1
547 #define BX_CLOCK_TIME0_UTC       2
548 
549 BOCHSAPI extern const char *floppy_devtype_names[];
550 BOCHSAPI extern const char *floppy_type_names[];
551 BOCHSAPI extern int floppy_type_n_sectors[];
552 BOCHSAPI extern const char *media_status_names[];
553 BOCHSAPI extern const char *bochs_bootdisk_names[];
554 
555 ////////////////////////////////////////////////////////////////////
556 // base class simulator interface, contains just virtual functions.
557 // I'm not longer sure that having a base class is going to be of any
558 // use... -Bryce
559 
560 #include <setjmp.h>
561 
562 enum ci_command_t { CI_START, CI_RUNTIME_CONFIG, CI_SHUTDOWN };
563 enum ci_return_t {
564   CI_OK,                  // normal return value
565   CI_ERR_NO_TEXT_CONSOLE  // err: can't work because there's no text console
566 };
567 typedef int (*config_interface_callback_t)(void *userdata, ci_command_t command);
568 typedef BxEvent* (*bxevent_handler)(void *theclass, BxEvent *event);
569 typedef void (*rt_conf_handler_t)(void *this_ptr);
570 typedef Bit32s (*addon_option_parser_t)(const char *context, int num_params, char *params[]);
571 typedef Bit32s (*addon_option_save_t)(FILE *fp);
572 
573 // bx_gui->set_display_mode() changes the mode between the configuration
574 // interface and the simulation.  This is primarily intended for display
575 // libraries which have a full-screen mode such as SDL or term.  The display
576 // mode is set to DISP_MODE_CONFIG before displaying any configuration
577 // menus, for panics that requires user input, when entering the debugger, etc.
578 // It is set to DISP_MODE_SIM when the Bochs simulation resumes.  The constants
579 // are defined here so that configuration interfaces can use them with the
580 // bx_simulator_interface_c::set_display_mode() method.
581 enum disp_mode_t { DISP_MODE_CONFIG=100, DISP_MODE_SIM };
582 
583 class BOCHSAPI bx_simulator_interface_c {
584 public:
bx_simulator_interface_c()585   bx_simulator_interface_c() {}
~bx_simulator_interface_c()586   virtual ~bx_simulator_interface_c() {}
set_quit_context(jmp_buf * context)587   virtual void set_quit_context(jmp_buf *context) {}
get_init_done()588   virtual bool get_init_done() { return 0; }
set_init_done(bool n)589   virtual int set_init_done(bool n) {return 0;}
reset_all_param()590   virtual void reset_all_param() {}
591   // new param methods
592   virtual bx_param_c *get_param(const char *pname, bx_param_c *base=NULL) {return NULL;}
593   virtual bx_param_num_c *get_param_num(const char *pname, bx_param_c *base=NULL) {return NULL;}
594   virtual bx_param_string_c *get_param_string(const char *pname, bx_param_c *base=NULL) {return NULL;}
595   virtual bx_param_bool_c *get_param_bool(const char *pname, bx_param_c *base=NULL) {return NULL;}
596   virtual bx_param_enum_c *get_param_enum(const char *pname, bx_param_c *base=NULL) {return NULL;}
gen_param_id()597   virtual unsigned gen_param_id() {return 0;}
get_n_log_modules()598   virtual int get_n_log_modules() {return -1;}
get_logfn_name(int mod)599   virtual const char *get_logfn_name(int mod) {return NULL;}
get_logfn_id(const char * name)600   virtual int get_logfn_id(const char *name) {return -1;}
get_prefix(int mod)601   virtual const char *get_prefix(int mod) {return NULL;}
get_log_action(int mod,int level)602   virtual int get_log_action(int mod, int level) {return -1;}
set_log_action(int mod,int level,int action)603   virtual void set_log_action(int mod, int level, int action) {}
get_default_log_action(int level)604   virtual int get_default_log_action(int level) {return -1;}
set_default_log_action(int level,int action)605   virtual void set_default_log_action(int level, int action) {}
get_action_name(int action)606   virtual const char *get_action_name(int action) {return NULL;}
is_action_name(const char * val)607   virtual int is_action_name(const char *val) {return -1;}
get_log_level_name(int level)608   virtual const char *get_log_level_name(int level) {return NULL;}
get_max_log_level()609   virtual int get_max_log_level() {return -1;}
610 
611   // exiting is somewhat complicated!  The preferred way to exit bochs is
612   // to call BX_EXIT(exitcode).  That is defined to call
613   // SIM->quit_sim(exitcode).  The quit_sim function first calls
614   // the cleanup functions in bochs so that it can destroy windows
615   // and free up memory, then sends a notify message to the CI
616   // telling it that bochs has stopped.
quit_sim(int code)617   virtual void quit_sim(int code) {}
618 
get_exit_code()619   virtual int get_exit_code() { return 0; }
620 
get_default_rc(char * path,int len)621   virtual int get_default_rc(char *path, int len) {return -1;}
read_rc(const char * path)622   virtual int read_rc(const char *path) {return -1;}
write_rc(const char * rc,int overwrite)623   virtual int write_rc(const char *rc, int overwrite) {return -1;}
get_log_file(char * path,int len)624   virtual int get_log_file(char *path, int len) {return -1;}
set_log_file(const char * path)625   virtual int set_log_file(const char *path) {return -1;}
get_log_prefix(char * prefix,int len)626   virtual int get_log_prefix(char *prefix, int len) {return -1;}
set_log_prefix(const char * prefix)627   virtual int set_log_prefix(const char *prefix) {return -1;}
get_debugger_log_file(char * path,int len)628   virtual int get_debugger_log_file(char *path, int len) {return -1;}
set_debugger_log_file(const char * path)629   virtual int set_debugger_log_file(const char *path) {return -1;}
630 
631   // The CI calls set_notify_callback to register its event handler function.
632   // This event handler function is called whenever the simulator needs to
633   // send an event to the CI.  For example, if the simulator hits a panic and
634   // wants to ask the user how to proceed, it would call the CI event handler
635   // to ask the CI to display a dialog.
636   //
637   // NOTE: At present, the standard VGAW buttons (floppy, snapshot, power,
638   // etc.) are displayed and handled by gui.cc, not by the CI or siminterface.
639   // gui.cc uses its own callback functions to implement the behavior of
640   // the buttons.  Some of these implementations call the siminterface.
set_notify_callback(bxevent_handler func,void * arg)641   virtual void set_notify_callback(bxevent_handler func, void *arg) {}
get_notify_callback(bxevent_handler * func,void ** arg)642   virtual void get_notify_callback(bxevent_handler *func, void **arg) {}
643 
644   // send an event from the simulator to the CI.
sim_to_ci_event(BxEvent * event)645   virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
646 
647   // called from simulator to display a gui dialog in particular situations.
648   // 1. When it hits serious errors, to ask if the user wants to continue or not.
649   // 2. When it hits errors, to warn the user before continuing simulation
650   // 3. When it hits critical errors, inform the user before terminating simulation.
log_dlg(const char * prefix,int level,const char * msg,int mode)651   virtual int log_dlg(const char *prefix, int level, const char *msg, int mode) {return -1;}
652   // called from simulator when writing a message to log file
log_msg(const char * prefix,int level,const char * msg)653   virtual void log_msg(const char *prefix, int level, const char *msg) {}
654   // set this to 1 if the gui has a log viewer
set_log_viewer(bool val)655   virtual void set_log_viewer(bool val) {}
has_log_viewer()656   virtual bool has_log_viewer() const {return 0;}
657 
658   // tell the CI to ask the user for the value of a parameter.
ask_param(bx_param_c * param)659   virtual int ask_param(bx_param_c *param) {return -1;}
ask_param(const char * pname)660   virtual int ask_param(const char *pname) {return -1;}
661 
662   // ask the user for a pathname
ask_filename(const char * filename,int maxlen,const char * prompt,const char * the_default,int flags)663   virtual int ask_filename(const char *filename, int maxlen, const char *prompt, const char *the_default, int flags) {return -1;}
664   // yes/no dialog
ask_yes_no(const char * title,const char * prompt,bool the_default)665   virtual int ask_yes_no(const char *title, const char *prompt, bool the_default) {return -1;}
666   // simple message box
message_box(const char * title,const char * message)667   virtual void message_box(const char *title, const char *message) {}
668   // called at a regular interval, currently by the bx_devices_c::timer()
periodic()669   virtual void periodic() {}
create_disk_image(const char * filename,int sectors,bool overwrite)670   virtual int create_disk_image(const char *filename, int sectors, bool overwrite) {return -3;}
671   // Tell the configuration interface (CI) that some parameter values have
672   // changed.  The CI will reread the parameters and change its display if it's
673   // appropriate.  Maybe later: mention which params have changed to save time.
refresh_ci()674   virtual void refresh_ci() {}
675   // forces a vga update.  This was added so that a debugger can force
676   // a vga update when single stepping, without having to wait thousands
677   // of cycles for the normal vga refresh triggered by the vga timer handler..
refresh_vga()678   virtual void refresh_vga() {}
679   // forces a call to bx_gui.handle_events.  This was added so that a debugger
680   // can force the gui events to be handled, so that interactive things such
681   // as a toolbar click will be processed.
handle_events()682   virtual void handle_events() {}
683   // return first hard disk in ATA interface
get_first_cdrom()684   virtual bx_param_c *get_first_cdrom() {return NULL;}
685   // return first cdrom in ATA interface
get_first_hd()686   virtual bx_param_c *get_first_hd() {return NULL;}
687   // return 1 if device is connected to a PCI slot
is_pci_device(const char * name)688   virtual bool is_pci_device(const char *name) {return 0;}
689   // return 1 if device is connected to the AGP slot
is_agp_device(const char * name)690   virtual bool is_agp_device(const char *name) {return 0;}
691 #if BX_DEBUGGER
692   // for debugger: same behavior as pressing control-C
debug_break()693   virtual void debug_break() {}
debug_interpret_cmd(char * cmd)694   virtual void debug_interpret_cmd(char *cmd) {}
debug_get_next_command()695   virtual char *debug_get_next_command() {return NULL;}
debug_puts(const char * text)696   virtual void debug_puts(const char *text) {}
697 #endif
register_configuration_interface(const char * name,config_interface_callback_t callback,void * userdata)698   virtual void register_configuration_interface(
699     const char* name,
700     config_interface_callback_t callback,
701     void *userdata) {}
configuration_interface(const char * name,ci_command_t command)702   virtual int configuration_interface(const char* name, ci_command_t command) {return -1; }
begin_simulation(int argc,char * argv[])703   virtual int begin_simulation(int argc, char *argv[]) {return -1;}
register_runtime_config_handler(void * dev,rt_conf_handler_t handler)704   virtual int register_runtime_config_handler(void *dev, rt_conf_handler_t handler) {return 0;}
unregister_runtime_config_handler(int id)705   virtual void unregister_runtime_config_handler(int id) {}
update_runtime_options()706   virtual void update_runtime_options() {}
707   typedef bool (*is_sim_thread_func_t)();
708   is_sim_thread_func_t is_sim_thread_func;
set_sim_thread_func(is_sim_thread_func_t func)709   virtual void set_sim_thread_func(is_sim_thread_func_t func) {
710     is_sim_thread_func = func;
711   }
is_sim_thread()712   virtual bool is_sim_thread() {return 1;}
is_wx_selected()713   virtual bool is_wx_selected() const {return 0;}
set_debug_gui(bool val)714   virtual void set_debug_gui(bool val) {}
has_debug_gui()715   virtual bool has_debug_gui() const {return 0;}
716   // provide interface to bx_gui->set_display_mode() method for config
717   // interfaces to use.
set_display_mode(disp_mode_t newmode)718   virtual void set_display_mode(disp_mode_t newmode) {}
test_for_text_console()719   virtual bool test_for_text_console() {return 1;}
720 
721   // add-on config option support
register_addon_option(const char * keyword,addon_option_parser_t parser,addon_option_save_t save_func)722   virtual bool register_addon_option(const char *keyword, addon_option_parser_t parser, addon_option_save_t save_func) {return 0;}
unregister_addon_option(const char * keyword)723   virtual bool unregister_addon_option(const char *keyword) {return 0;}
is_addon_option(const char * keyword)724   virtual bool is_addon_option(const char *keyword) {return 0;}
parse_addon_option(const char * context,int num_params,char * params[])725   virtual Bit32s parse_addon_option(const char *context, int num_params, char *params []) {return -1;}
save_addon_options(FILE * fp)726   virtual Bit32s save_addon_options(FILE *fp) {return -1;}
727 
728   // statistics
init_statistics()729   virtual void init_statistics() {}
cleanup_statistics()730   virtual void cleanup_statistics() {}
get_statistics_root()731   virtual bx_list_c *get_statistics_root() {return NULL;}
732 
733   // save/restore support
init_save_restore()734   virtual void init_save_restore() {}
cleanup_save_restore()735   virtual void cleanup_save_restore() {}
save_state(const char * checkpoint_path)736   virtual bool save_state(const char *checkpoint_path) {return 0;}
restore_config()737   virtual bool restore_config() {return 0;}
restore_logopts()738   virtual bool restore_logopts() {return 0;}
restore_hardware()739   virtual bool restore_hardware() {return 0;}
get_bochs_root()740   virtual bx_list_c *get_bochs_root() {return NULL;}
restore_bochs_param(bx_list_c * root,const char * sr_path,const char * restore_name)741   virtual bool restore_bochs_param(bx_list_c *root, const char *sr_path, const char *restore_name) { return 0; }
742 
743   // special config parameter and options functions for plugins
opt_plugin_ctrl(const char * plugname,bool load)744   virtual bool opt_plugin_ctrl(const char *plugname, bool load) {return 0;}
init_std_nic_options(const char * name,bx_list_c * menu)745   virtual void init_std_nic_options(const char *name, bx_list_c *menu) {}
init_usb_options(const char * usb_name,const char * pname,int maxports)746   virtual void init_usb_options(const char *usb_name, const char *pname, int maxports) {}
parse_param_from_list(const char * context,const char * param,bx_list_c * base)747   virtual int  parse_param_from_list(const char *context, const char *param, bx_list_c *base) {return 0;}
parse_nic_params(const char * context,const char * param,bx_list_c * base)748   virtual int  parse_nic_params(const char *context, const char *param, bx_list_c *base) {return 0;}
parse_usb_port_params(const char * context,const char * param,int maxports,bx_list_c * base)749   virtual int  parse_usb_port_params(const char *context, const char *param,
750                                      int maxports, bx_list_c *base) {return -1;}
split_option_list(const char * msg,const char * rawopt,char ** argv,int max_argv)751   virtual int  split_option_list(const char *msg, const char *rawopt, char **argv, int max_argv) {return 0;}
write_param_list(FILE * fp,bx_list_c * base,const char * optname,bool multiline)752   virtual int  write_param_list(FILE *fp, bx_list_c *base, const char *optname, bool multiline) {return 0;}
write_usb_options(FILE * fp,int maxports,bx_list_c * base)753   virtual int  write_usb_options(FILE *fp, int maxports, bx_list_c *base) {return 0;}
754 
755 #if BX_USE_GUI_CONSOLE
bx_printf(const char * fmt,...)756   virtual int  bx_printf(const char *fmt, ...) {return 0;}
bx_gets(char * s,int size,FILE * stream)757   virtual char* bx_gets(char *s, int size, FILE *stream) {return NULL;}
758 #endif
759 };
760 
761 BOCHSAPI extern bx_simulator_interface_c *SIM;
762 
763 extern void bx_init_siminterface();
764 
765 #if defined(__WXMSW__) || defined(WIN32)
766 // Just to provide HINSTANCE, etc. in files that have not included bochs.h.
767 // I don't like this at all, but I don't see a way around it.
768 #include <windows.h>
769 #endif
770 
771 // define structure to hold data that is passed into our main function.
772 typedef struct BOCHSAPI {
773   // standard argc,argv
774   int argc;
775   char **argv;
776 #ifdef WIN32
777   char initial_dir[MAX_PATH];
778 #endif
779 #ifdef __WXMSW__
780   // these are only used when compiling with wxWidgets.  This gives us a
781   // place to store the data that was passed to WinMain.
782   HINSTANCE hInstance;
783   HINSTANCE hPrevInstance;
784   LPSTR m_lpCmdLine;
785   int nCmdShow;
786 #endif
787 } bx_startup_flags_t;
788 
789 BOCHSAPI extern bx_startup_flags_t bx_startup_flags;
790 BOCHSAPI extern bool bx_user_quit;
791 
792 #endif
793