- plugin unload mechanism implemented in the plugin and devices code

- added exit() method to the devmodel object for devices that need to do special
  cleanups on exit. Device plugins should call this method from their plugin_fini()
  function. If Bochs is compiled without plugin support, for non-core plugins
  the exit() method is called directly from bx_unload_plugins().
- exit() method implemented in the keyboard device
- wx "Show Keyboard" feature now only appear when the wxdebug keyboard subtree
  is not empty
- cpu cleanup must be done before the devices cleanup
- moved PCI chipset dump call to the devices exit method
This commit is contained in:
Volker Ruppert 2006-09-10 09:13:47 +00:00
parent e075c68f78
commit c07197758b
8 changed files with 131 additions and 50 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.cc,v 1.147 2006-09-09 08:05:07 vruppert Exp $
// $Id: wxmain.cc,v 1.148 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////
//
// wxmain.cc implements the wxWidgets frame, toolbar, menus, and dialogs.
@ -832,10 +832,16 @@ void MyFrame::OnShowCpu(wxCommandEvent& WXUNUSED(event))
void MyFrame::OnShowKeyboard(wxCommandEvent& WXUNUSED(event))
{
if (SIM->get_param(BXPN_WX_KBD_STATE) == NULL) {
bx_list_c *list = (bx_list_c*)SIM->get_param(BXPN_WX_KBD_STATE);
int list_size = 0;
if (list != NULL) {
list_size = list->get_size();
}
if (list_size == 0) {
// if params not initialized yet, then give up
wxMessageBox(wxT("Cannot show the debugger window until the simulation has begun."),
wxT("Sim not started"), wxOK | wxICON_ERROR, this );
wxT("Sim not running"), wxOK | wxICON_ERROR, this );
return;
}
if (showKbd == NULL) {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: devices.cc,v 1.102 2006-09-07 18:50:51 vruppert Exp $
// $Id: devices.cc,v 1.103 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -105,7 +105,7 @@ void bx_devices_c::init(BX_MEM_C *newmem)
{
unsigned i;
BX_DEBUG(("Init $Id: devices.cc,v 1.102 2006-09-07 18:50:51 vruppert Exp $"));
BX_DEBUG(("Init $Id: devices.cc,v 1.103 2006-09-10 09:13:47 vruppert Exp $"));
mem = newmem;
/* set no-default handlers, will be overwritten by the real default handler */
@ -385,8 +385,26 @@ void bx_devices_c::exit()
DEV_cmos_save_image();
if (DEV_hd_present())
DEV_hd_close_harddrive();
#if BX_SUPPORT_PCI
if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
pluginPciBridge->print_i440fx_state();
}
#endif
BX_INFO(("Last time is %u", (unsigned) DEV_cmos_get_timeval()));
PLUG_unload_plugin(unmapped);
PLUG_unload_plugin(biosdev);
PLUG_unload_plugin(cmos);
PLUG_unload_plugin(dma);
PLUG_unload_plugin(pic);
PLUG_unload_plugin(vga);
PLUG_unload_plugin(floppy);
#if BX_SUPPORT_PCI
PLUG_unload_plugin(pci);
PLUG_unload_plugin(pci2isa);
#endif
bx_unload_plugins();
}
Bit32u bx_devices_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: iodev.h,v 1.76 2006-09-07 18:50:51 vruppert Exp $
// $Id: iodev.h,v 1.77 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -85,6 +85,7 @@ class BOCHSAPI bx_devmodel_c : public logfunctions {
virtual void init_mem(BX_MEM_C *) {}
virtual void init(void) {}
virtual void reset(unsigned type) {}
virtual void exit(void) {}
#if BX_SUPPORT_SAVE_RESTORE
virtual void register_state(void) {}
virtual void after_restore_state(void) {}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: keyboard.cc,v 1.121 2006-08-25 18:26:27 vruppert Exp $
// $Id: keyboard.cc,v 1.122 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -76,7 +76,7 @@ int libkeyboard_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, c
void libkeyboard_LTX_plugin_fini(void)
{
BX_INFO(("keyboard plugin_fini"));
theKeyboard->exit();
}
bx_keyb_c::bx_keyb_c()
@ -108,7 +108,7 @@ void bx_keyb_c::resetinternals(bx_bool powerup)
void bx_keyb_c::init(void)
{
BX_DEBUG(("Init $Id: keyboard.cc,v 1.121 2006-08-25 18:26:27 vruppert Exp $"));
BX_DEBUG(("Init $Id: keyboard.cc,v 1.122 2006-09-10 09:13:47 vruppert Exp $"));
Bit32u i;
DEV_register_irq(1, "8042 Keyboard controller");
@ -198,10 +198,14 @@ void bx_keyb_c::init(void)
#if BX_WITH_WX
bx_param_num_c *param;
bx_list_c *list;
if (SIM->get_param("wxdebug") != NULL) {
// register shadow params (Experimental, not a complete list by far)
bx_list_c *list = new bx_list_c(SIM->get_param("wxdebug"), "keyboard",
"Keyboard State", 20);
list = (bx_list_c*)SIM->get_param(BXPN_WX_KBD_STATE);
if (list == NULL) {
list = new bx_list_c(SIM->get_param("wxdebug"), "keyboard",
"Keyboard State", 20);
}
new bx_shadow_bool_c(list, "irq1_req",
"Keyboard IRQ1 requested",
&BX_KEY_THIS s.kbd_controller.irq1_requested);
@ -252,6 +256,22 @@ void bx_keyb_c::reset(unsigned type)
}
}
void bx_keyb_c::exit(void)
{
// remove runtime parameter handler
SIM->get_param_bool(BXPN_MOUSE_ENABLED)->set_handler(NULL);
SIM->get_param_num(BXPN_KBD_PASTE_DELAY)->set_handler(NULL);
if (BX_KEY_THIS pastebuf != NULL) {
delete [] BX_KEY_THIS pastebuf;
}
#if BX_WITH_WX
bx_list_c *list = (bx_list_c*)SIM->get_param(BXPN_WX_KBD_STATE);
if (list != NULL) {
list->clear();
}
#endif
}
#if BX_SUPPORT_SAVE_RESTORE
void bx_keyb_c::register_state(void)
{

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: keyboard.h,v 1.36 2006-08-25 18:26:27 vruppert Exp $
// $Id: keyboard.h,v 1.37 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -53,6 +53,7 @@ public:
// implement bx_devmodel_c interface
virtual void init(void);
virtual void reset(unsigned type);
virtual void exit(void);
// override stubs from bx_keyb_stub_c
virtual void gen_scancode(Bit32u key);
virtual void paste_bytes(Bit8u *data, Bit32s length);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.340 2006-09-07 18:50:51 vruppert Exp $
// $Id: main.cc,v 1.341 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -1139,10 +1139,6 @@ int bx_atexit(void)
// so that the user can see any messages left behind on the console.
SIM->set_display_mode(DISP_MODE_CONFIG);
#if BX_PROVIDE_DEVICE_MODELS==1
bx_pc_system.exit();
#endif
#if BX_DEBUGGER == 0
if (SIM && SIM->get_init_done()) {
for (int cpu=0; cpu<BX_SMP_PROCESSORS; cpu++)
@ -1150,12 +1146,8 @@ int bx_atexit(void)
}
#endif
#if BX_SUPPORT_PCI
if (SIM && SIM->get_init_done()) {
if (SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get()) {
bx_devices.pluginPciBridge->print_i440fx_state();
}
}
#if BX_PROVIDE_DEVICE_MODELS==1
bx_pc_system.exit();
#endif
// restore signal handling to defaults

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: plugin.cc,v 1.18 2006-05-27 15:54:47 sshwarts Exp $
// $Id: plugin.cc,v 1.19 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// This file defines the plugin and plugin-device registration functions and
@ -325,45 +325,41 @@ plugin_init_one(plugin_t *plugin)
}
plugin_t *
plugin_unload(plugin_t *plugin)
plugin_t *plugin_unload(plugin_t *plugin)
{
plugin_t *dead_plug;
if (plugin->initialized)
plugin->plugin_fini ();
plugin->plugin_fini();
lt_dlclose (plugin->handle);
free (plugin->name);
free (plugin->args);
lt_dlclose(plugin->handle);
delete [] plugin->name;
dead_plug = plugin;
plugin = plugin->next;
free (dead_plug);
free(dead_plug);
return plugin;
}
void
plugin_fini_all (void)
void plugin_fini_all (void)
{
plugin_t *plugin;
for (plugin = plugins; plugin; plugin = plugin_unload (plugin));
for (plugin = plugins; plugin; plugin = plugin_unload(plugin));
return;
}
void
plugin_load (char *name, char *args, plugintype_t type)
void plugin_load(char *name, char *args, plugintype_t type)
{
plugin_t *plugin;
plugin = (plugin_t *)malloc (sizeof (plugin_t));
plugin = (plugin_t *)malloc (sizeof(plugin_t));
if (!plugin)
{
BX_PANIC (("malloc plugin_t failed"));
BX_PANIC(("malloc plugin_t failed"));
}
plugin->type = type;
@ -372,7 +368,7 @@ plugin_load (char *name, char *args, plugintype_t type)
plugin->initialized = 0;
char plugin_filename[BX_PATHNAME_LEN], buf[BX_PATHNAME_LEN];
sprintf (buf, PLUGIN_FILENAME_FORMAT, name);
sprintf(buf, PLUGIN_FILENAME_FORMAT, name);
sprintf(plugin_filename, "%s%s", PLUGIN_PATH, buf);
// Set context so that any devices that the plugin registers will
@ -437,8 +433,7 @@ plugin_load (char *name, char *args, plugintype_t type)
return;
}
void
plugin_abort (void)
void plugin_abort(void)
{
pluginlog->panic("plugin load aborted");
}
@ -562,13 +557,33 @@ bx_bool pluginDevicePresent(char *name)
/* Plugin system: Load one plugin */
/************************************************************************/
int bx_load_plugin (const char *name, plugintype_t type)
int bx_load_plugin(const char *name, plugintype_t type)
{
char *namecopy = new char[1+strlen(name)];
strcpy (namecopy, name);
plugin_load (namecopy, "", type);
strcpy(namecopy, name);
plugin_load(namecopy, "", type);
return 0;
}
void bx_unload_plugin(const char *name)
{
plugin_t *plugin, *prev = NULL;
for (plugin = plugins; plugin; plugin = plugin->next) {
if (!strcmp(plugin->name, name)) {
plugin = plugin_unload(plugin);
if (prev == NULL) {
plugins = plugin;
} else {
prev->next = plugin;
}
break;
} else {
prev = plugin;
}
}
}
#endif /* end of #if BX_PLUGINS */
/*************************************************************************/
@ -607,6 +622,30 @@ void bx_reset_plugins(unsigned signal)
}
}
/*******************************************************/
/* Plugin system: Unload all registered plugin-devices */
/*******************************************************/
void bx_unload_plugins()
{
device_t *device, *next;
device = devices;
do {
if (device->plugin != NULL) {
#if BX_PLUGINS
bx_unload_plugin(device->name);
#endif
} else {
device->devmodel->exit();
}
next = device->next;
free(device);
device = next;
} while (device != NULL);
devices = NULL;
}
#if BX_SUPPORT_SAVE_RESTORE
/**************************************************************************/
/* Plugin system: Register device state of all registered plugin-devices */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: plugin.h,v 1.52 2006-05-27 15:54:47 sshwarts Exp $
// $Id: plugin.h,v 1.53 2006-09-10 09:13:47 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// This file provides macros and types needed for plugins. It is based on
@ -56,6 +56,7 @@ extern "C" {
#define DEV_register_state() {bx_devices.register_state(); }
#define DEV_after_restore_state() {bx_devices.after_restore_state(); }
#define PLUG_load_plugin(name,type) {bx_load_plugin(#name,type);}
#define PLUG_unload_plugin(name) {bx_unload_plugin(#name);}
#define DEV_register_ioread_handler(b,c,d,e,f) pluginRegisterIOReadHandler(b,c,d,e,f)
#define DEV_register_iowrite_handler(b,c,d,e,f) pluginRegisterIOWriteHandler(b,c,d,e,f)
@ -80,6 +81,7 @@ extern "C" {
// When plugins are off, PLUG_load_plugin will call the plugin_init function
// directly.
#define PLUG_load_plugin(name,type) {lib##name##_LTX_plugin_init(NULL,type,0,NULL);}
#define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();}
#define DEV_register_ioread_handler(b,c,d,e,f) bx_devices.register_io_read_handler(b,c,d,e,f)
#define DEV_register_iowrite_handler(b,c,d,e,f) bx_devices.register_io_write_handler(b,c,d,e,f)
#define DEV_unregister_ioread_handler(b,c,d,e) bx_devices.unregister_io_read_handler(b,c,d,e)
@ -253,11 +255,11 @@ typedef struct _device_t
extern device_t *devices;
void plugin_startup (void);
void plugin_load (char *name, char *args, plugintype_t);
plugin_t *plugin_unload (plugin_t *plugin);
void plugin_init_all (void);
void plugin_fini_all (void);
void plugin_startup(void);
void plugin_load(char *name, char *args, plugintype_t);
plugin_t *plugin_unload(plugin_t *plugin);
void plugin_init_all(void);
void plugin_fini_all(void);
/* === Device Stuff === */
typedef void (*deviceInitMem_t)(BX_MEM_C *);
@ -335,8 +337,10 @@ BOCHSAPI extern Bit8u (*pluginWr_memType)(Bit32u addr);
void plugin_abort(void);
int bx_load_plugin(const char *name, plugintype_t type);
extern void bx_unload_plugin(const char *name);
extern void bx_init_plugins(void);
extern void bx_reset_plugins(unsigned);
extern void bx_unload_plugins(void);
#if BX_SUPPORT_SAVE_RESTORE
extern void bx_plugins_register_state();
extern void bx_plugins_after_restore_state();