321 lines
11 KiB
Plaintext
321 lines
11 KiB
Plaintext
----------------------------------------------------------------------
|
||
Patch name: patch.example-user-plugin
|
||
Author: Volker Ruppert
|
||
Date: 3 Jan 2009
|
||
Status: Demo
|
||
|
||
Detailed description:
|
||
This sample code can be used as a framework for writing user plugins.
|
||
It contains enough code for testing the existing user plugin support
|
||
in Bochs and creates a device that installs a 32-bit r/w register at
|
||
i/o address 0x1000.
|
||
This example also shows how to install and handle user-defined config
|
||
options for bochsrc, command line and the config interface. In this
|
||
demo it is used to specify the reset value.
|
||
For user plugin support Bochs must be configured with plugins enabled.
|
||
Compiling with plugin support is known to work on Linux and Windows
|
||
(Cygwin or MinGW/MSYS). Bochs supports loading of up to 16 different
|
||
user plugins when starting up. Loading / removing plugins at runtime
|
||
is not yet supported.
|
||
|
||
Patch was created with:
|
||
diff -u
|
||
Apply patch to what version:
|
||
cvs checked out on 8 Jan 2009
|
||
Instructions:
|
||
To patch, go to main bochs directory.
|
||
Type "patch -p0 < THIS_PATCH_FILE".
|
||
Regenerate the configure script and compile Bochs as usual
|
||
cd user-plugin
|
||
make
|
||
make install
|
||
----------------------------------------------------------------------
|
||
diff -urN ../bochs/configure.in ./configure.in
|
||
--- ../bochs/configure.in 2008-12-29 09:16:19.000000000 +0100
|
||
+++ ./configure.in 2009-01-03 17:51:43.000000000 +0100
|
||
@@ -3037,4 +3037,4 @@
|
||
build/linux/bochs-dlx \
|
||
bxversion.h bxversion.rc build/macosx/Info.plist \
|
||
build/win32/nsis/Makefile build/win32/nsis/bochs.nsi \
|
||
- host/linux/pcidev/Makefile)
|
||
+ host/linux/pcidev/Makefile user-plugin/Makefile)
|
||
diff -urN ../bochs/user-plugin/Makefile.in ./user-plugin/Makefile.in
|
||
--- ../bochs/user-plugin/Makefile.in 1970-01-01 01:00:00.000000000 +0100
|
||
+++ ./user-plugin/Makefile.in 2009-01-06 21:32:24.000000000 +0100
|
||
@@ -0,0 +1,108 @@
|
||
+# Copyright (C) 2009 Volker Ruppert
|
||
+#
|
||
+# This library is free software; you can redistribute it and/or
|
||
+# modify it under the terms of the GNU Lesser General Public
|
||
+# License as published by the Free Software Foundation; either
|
||
+# version 2 of the License, or (at your option) any later version.
|
||
+#
|
||
+# This library is distributed in the hope that it will be useful,
|
||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+# Lesser General Public License for more details.
|
||
+#
|
||
+# You should have received a copy of the GNU Lesser General Public
|
||
+# License along with this library; if not, write to the Free Software
|
||
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
+
|
||
+# Makefile for the user plugin example of bochs
|
||
+
|
||
+
|
||
+@SUFFIX_LINE@
|
||
+
|
||
+prefix = @prefix@
|
||
+exec_prefix = @exec_prefix@
|
||
+srcdir = @srcdir@
|
||
+VPATH = @srcdir@
|
||
+bindir = @bindir@
|
||
+libdir = @libdir@
|
||
+plugdir = @libdir@/bochs/plugins
|
||
+datarootdir = @datarootdir@
|
||
+mandir = @mandir@
|
||
+man1dir = $(mandir)/man1
|
||
+man5dir = $(mandir)/man5
|
||
+docdir = $(datarootdir)/doc/bochs
|
||
+sharedir = $(datarootdir)/bochs
|
||
+top_builddir = ..
|
||
+top_srcdir = @top_srcdir@
|
||
+
|
||
+SHELL = /bin/sh
|
||
+
|
||
+@SET_MAKE@
|
||
+
|
||
+CXX = @CXX@
|
||
+CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@ @GUI_CXXFLAGS@
|
||
+
|
||
+LDFLAGS = @LDFLAGS@
|
||
+LIBS = @LIBS@
|
||
+RANLIB = @RANLIB@
|
||
+PLUGIN_PATH=@libdir@
|
||
+top_builddir = ..
|
||
+LIBTOOL=@LIBTOOL@
|
||
+WIN32_DLL_IMPORT_LIBRARY=../dllexports.a
|
||
+
|
||
+BX_INCDIRS = -I.. -I$(srcdir)/.. -I../iodev -I$(srcdir)/../iodev -I../@INSTRUMENT_DIR@ -I$(srcdir)/../@INSTRUMENT_DIR@
|
||
+
|
||
+PLUGIN_OBJS = testdev.o
|
||
+
|
||
+plugins: $(PLUGIN_OBJS:@PLUGIN_LIBNAME_TRANSFORMATION@)
|
||
+
|
||
+install: @INSTALL_PLUGINS_VAR@
|
||
+
|
||
+install_libtool_plugins::
|
||
+ list=`echo *.la`; for i in $$list; do $(LIBTOOL) --mode=install install $$i $(DESTDIR)$(plugdir); done
|
||
+ $(LIBTOOL) --finish $(DESTDIR)$(plugdir)
|
||
+
|
||
+install_dll_plugins::
|
||
+ list=`echo *.dll`; for i in $$list; do cp $$i $(DESTDIR)$(plugdir); done
|
||
+
|
||
+# standard compile rule for C++ files
|
||
+.@CPP_SUFFIX@.o:
|
||
+ $(CXX) @DASH@c $(CXXFLAGS) $(LOCAL_CXXFLAGS) @CXXFP@$< @OFP@$@
|
||
+
|
||
+##### building plugins with libtool
|
||
+%.lo: %.@CPP_SUFFIX@
|
||
+ $(LIBTOOL) --mode=compile $(CXX) -c $(CXXFLAGS) $(LOCAL_CXXFLAGS) $< -o $@
|
||
+
|
||
+libbx_%.la: %.lo
|
||
+ $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH)
|
||
+
|
||
+#### building DLLs for win32 (tested on cygwin only)
|
||
+bx_%.dll: %.o
|
||
+ $(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)
|
||
+
|
||
+clean:
|
||
+ @RMCOMMAND@ -rf .libs *.lo *.o *.la *.a *.dll
|
||
+
|
||
+dist-clean: clean
|
||
+ @RMCOMMAND@ Makefile
|
||
+
|
||
+###########################################
|
||
+# dependencies generated by
|
||
+# gcc -MM -I.. -I../instrument/stubs *.cc | sed -e 's/\.cc/.@CPP_SUFFIX@/g'
|
||
+# gcc -MM -I.. -I../instrument/stubs *.cc | \
|
||
+# sed -e 's/\.cc/.@CPP_SUFFIX@/g' -e 's/\.o:/.lo:/g'
|
||
+#
|
||
+# This means that every source file is listed twice, once with a .o rule
|
||
+# and then again with an identical .lo rule. The .lo rules are used when
|
||
+# building plugins.
|
||
+###########################################
|
||
+testdev.o: testdev.@CPP_SUFFIX@ ../iodev/iodev.h ../bochs.h ../config.h ../osdep.h \
|
||
+ ../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
|
||
+ ../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
|
||
+ ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
|
||
+ ../gui/keymap.h ../instrument/stubs/instrument.h testdev.h
|
||
+testdev.lo: testdev.@CPP_SUFFIX@ ../iodev/iodev.h ../bochs.h ../config.h ../osdep.h \
|
||
+ ../bx_debug/debug.h ../config.h ../osdep.h ../bxversion.h \
|
||
+ ../gui/siminterface.h ../memory/memory.h ../pc_system.h ../plugin.h \
|
||
+ ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
|
||
+ ../gui/keymap.h ../instrument/stubs/instrument.h testdev.h
|
||
diff -urN ../bochs/user-plugin/testdev.cc ./user-plugin/testdev.cc
|
||
--- ../bochs/user-plugin/testdev.cc 1970-01-01 01:00:00.000000000 +0100
|
||
+++ ./user-plugin/testdev.cc 2009-01-07 18:01:50.000000000 +0100
|
||
@@ -0,0 +1,119 @@
|
||
+// Copyright (C) 2009 Volker Ruppert
|
||
+//
|
||
+// This library is free software; you can redistribute it and/or
|
||
+// modify it under the terms of the GNU Lesser General Public
|
||
+// License as published by the Free Software Foundation; either
|
||
+// version 2 of the License, or (at your option) any later version.
|
||
+//
|
||
+// This library is distributed in the hope that it will be useful,
|
||
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+// Lesser General Public License for more details.
|
||
+//
|
||
+// You should have received a copy of the GNU Lesser General Public
|
||
+// License along with this library; if not, write to the Free Software
|
||
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
+
|
||
+// User plugin example (see patch description for details)
|
||
+
|
||
+// Define BX_PLUGGABLE in files that can be compiled into plugins. For
|
||
+// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
||
+// is used to know when we are exporting symbols and when we are importing.
|
||
+#define BX_PLUGGABLE
|
||
+
|
||
+// Don't include other devices headers
|
||
+#define NO_DEVICE_INCLUDES
|
||
+
|
||
+#include "iodev.h"
|
||
+#include "testdev.h"
|
||
+
|
||
+#define LOG_THIS theTestDevice->
|
||
+
|
||
+bx_testdev_c *theTestDevice = NULL;
|
||
+
|
||
+Bit32s testdev_options_parser(const char *context, int num_params, char *params[]);
|
||
+Bit32s testdev_options_save(FILE *fp);
|
||
+
|
||
+int libuser_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
|
||
+{
|
||
+ theTestDevice = new bx_testdev_c();
|
||
+ BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theTestDevice, "testdev");
|
||
+ // add new configuration parameter for the config interface
|
||
+ bx_param_c *root_param = SIM->get_param("user");
|
||
+ bx_list_c *menu = new bx_list_c(root_param, "testdev", "Test Device");
|
||
+ menu->get_options()->set(bx_list_c::SHOW_PARENT);
|
||
+ new bx_param_num_c(menu, "test", "Test Parameter", "", 0, BX_MAX_BIT32U, 0);
|
||
+ // register user-defined option for bochsrc and command line
|
||
+ SIM->register_user_option("testdev", testdev_options_parser, testdev_options_save);
|
||
+ return(0); // Success
|
||
+}
|
||
+
|
||
+void libuser_LTX_plugin_fini(void)
|
||
+{
|
||
+ SIM->unregister_user_option("testdev");
|
||
+ bx_list_c *menu = (bx_list_c*)SIM->get_param("user");
|
||
+ menu->remove("testdev");
|
||
+ delete theTestDevice;
|
||
+}
|
||
+
|
||
+Bit32s testdev_options_parser(const char *context, int num_params, char *params[])
|
||
+{
|
||
+ if (!strcmp(params[0], "testdev")) {
|
||
+ if (!strncmp(params[1], "test=", 5)) {
|
||
+ SIM->get_param_num("user.testdev.test")->set(atoi(¶ms[1][5]));
|
||
+ } else {
|
||
+ BX_PANIC(("%s: testdev: unknown parameter '%s'", context, params[1]));
|
||
+ }
|
||
+ } else {
|
||
+ BX_PANIC(("%s: unknown directive '%s'", context, params[0]));
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+Bit32s testdev_options_save(FILE *fp)
|
||
+{
|
||
+ fprintf(fp, "testdev: test=%d\n", SIM->get_param_num("user.testdev.test")->get());
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+bx_testdev_c::bx_testdev_c(void)
|
||
+{
|
||
+ put("USER");
|
||
+ settype(DEVLOG);
|
||
+}
|
||
+
|
||
+bx_testdev_c::~bx_testdev_c(void)
|
||
+{
|
||
+ // nothing here yet
|
||
+}
|
||
+
|
||
+void bx_testdev_c::init(void)
|
||
+{
|
||
+ DEV_register_ioread_handler(this, read_handler, 0x1000, "Test Device", 4);
|
||
+ DEV_register_iowrite_handler(this, write_handler, 0x1000, "Test Device", 4);
|
||
+}
|
||
+
|
||
+void bx_testdev_c::reset(unsigned type)
|
||
+{
|
||
+ BX_USER_THIS s.reg0 = SIM->get_param_num("user.testdev.test")->get();
|
||
+}
|
||
+
|
||
+void bx_testdev_c::register_state(void)
|
||
+{
|
||
+ bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "testdev", "Test Device", 1);
|
||
+ BXRS_HEX_PARAM_FIELD(list, reg0, BX_USER_THIS s.reg0);
|
||
+}
|
||
+
|
||
+Bit32u bx_testdev_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
|
||
+{
|
||
+ UNUSED(this_ptr);
|
||
+
|
||
+ return BX_USER_THIS s.reg0;
|
||
+}
|
||
+
|
||
+void bx_testdev_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
|
||
+{
|
||
+ UNUSED(this_ptr);
|
||
+
|
||
+ BX_USER_THIS s.reg0 = value;
|
||
+}
|
||
diff -urN ../bochs/user-plugin/testdev.h ./user-plugin/testdev.h
|
||
--- ../bochs/user-plugin/testdev.h 1970-01-01 01:00:00.000000000 +0100
|
||
+++ ./user-plugin/testdev.h 2009-01-06 21:31:59.000000000 +0100
|
||
@@ -0,0 +1,40 @@
|
||
+// Copyright (C) 2009 Volker Ruppert
|
||
+//
|
||
+// This library is free software; you can redistribute it and/or
|
||
+// modify it under the terms of the GNU Lesser General Public
|
||
+// License as published by the Free Software Foundation; either
|
||
+// version 2 of the License, or (at your option) any later version.
|
||
+//
|
||
+// This library is distributed in the hope that it will be useful,
|
||
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
+// Lesser General Public License for more details.
|
||
+//
|
||
+// You should have received a copy of the GNU Lesser General Public
|
||
+// License along with this library; if not, write to the Free Software
|
||
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
+
|
||
+#ifndef BX_TESTDEV_H
|
||
+#define BX_TESTDEV_H
|
||
+
|
||
+#define BX_USER_THIS theTestDevice->
|
||
+
|
||
+class bx_testdev_c : public bx_devmodel_c {
|
||
+public:
|
||
+ bx_testdev_c();
|
||
+ virtual ~bx_testdev_c();
|
||
+
|
||
+ virtual void init(void);
|
||
+ virtual void reset(unsigned type);
|
||
+ virtual void register_state(void);
|
||
+
|
||
+private:
|
||
+ static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
|
||
+ static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
|
||
+
|
||
+ struct {
|
||
+ Bit32u reg0;
|
||
+ } s;
|
||
+};
|
||
+
|
||
+#endif
|