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