ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
|
ETISS uses plugins to provide functionality beyond the simple simulation of instructions.
The etiss::plugin::gdb::Server plugin for example allows to debug simulated software and usually etiss::CPUArch implementations provide a plugin that implements timer functionality (see How to implement a cpu architecture for ETISS: Step 4)
The plugin interface has been split into different classes for performance reasons.The base class of all plugins is etiss::Plugin. Plugin subclasses inherit etiss::Plugin virtual, thus allowing to combine multiple plugin sub classes. A plugin should only inherit the plugin sub classes it needs.
The plugin base class (etiss::Plugin) defines an init and cleanup function which are called at the start and end of a simulation (NOTE: therefore a plugin may only be added to one running cpu core) Furthermore etiss::Plugin has 3 protected fields (etiss::Plugin::plugin_cpu_,etiss::Plugin::plugin_arch_,etiss::Plugin::plugin_system_) which hold the current ETISS_CPU,etiss::CPUArch and ETISS_System pointer. Those fields become valid just before the etiss::Plugin::init call and become invalid right after the etiss::Plugin::cleanup() call.
The following plugin classes are available:
Class | Function(s) | Description |
---|---|---|
etiss::TranslationPlugin | void initInstrSet(etiss::instr::ModedInstructionSet & ) const; void finalizeInstrSet(etiss::instr::ModedInstructionSet & ) const; void initCodeBlock(etiss::CodeBlock & ) const; void finalizeCodeBlock(etiss::CodeBlock & ) const; void * getPluginHandle() | Allows to add code generation callbacks to the Instruction tree (etiss::instr::ModedInstructionSet,etiss::instr::VariableInstructionSet,etiss::instr::InstructionSet,etiss::instr::Instruction). etiss::TranslationPlugin::process also allows to edit a whole block of translated instructions. The pointer from etiss::TranslatorPlugin::getPluginHandle will be available in the translated code. The returned pointer can be read in the generated code by using the code snippet returned by getPointerCode() (e.g. std::string code = std::string("void * mypointer = ") + getPointerCode() + ";";).NOTE: these functions will only be called by ETISS while plugin_cpu_, plugin_arch_ and plugin_system_ are valid. |
etiss::CoroutinePlugin | etiss::int32 execute() | etiss::Coroutine::execute will be called before a block of translated code gets executed. The returned code will be handled in the same way return codes from a translated Block are handled. See etiss/jit/ReturnCodes.h for global return codes. This function is usefull e.g. for periodical interrupt checks and signaling. The execute function may also read/manipulate the cpu structure since it is required to be consistent after a block. NOTE: this function will only be called by ETISS while plugin_cpu_, plugin_arch_ and plugin_system_ are valid. |
etiss::SystemWrapperPlugin | ETISS_System * wrap(ETISS_CPU * cpu,ETISS_System * system) ETISS_System * unwrap(ETISS_CPU * cpu,ETISS_System * system) | The wrap function allows to replace the ETISS_System structure.This is for example useful to wrap the original system in a logger system to view accesses or enforce breakpoints (see etiss::plugin::gdb::Server). IMPORTANT: etiss::SystemWrapperPlugin::wrap/etiss::SystemWrapperPlugin::unwrap functions are called BEFORE/AFTER plugin_cpu_, plugin_arch_ and plugin_system_ are valid and BEFORE/AFTER the init/cleanup calls. |
etiss::RegisterDevicePlugin | void changedRegister (const char *name) | This plugin is notified about changes to a register. etiss::CPUArch::getListenerSupportedRegisters defines registers that trigger this call.NOTE: this function will only be called by ETISS while plugin_cpu_, plugin_arch_ and plugin_system_ are valid. |
For examples please have a look at the example Timer implementation for a etiss::CPUArch and at other plugins located in include/etiss/IntegratedLibrary and src/IntegratedLibrary
ETISS preferably loads plugins as a shared library at runtime. To do this it is necessary to implement some functions to find the plugin implementation(s).
XPluginLib.cpp:
Finally a makefile is needed to build the new library as a shared library
Makefile
Once the shared library was build it is available in ETISS by default if placed in PluginImpl/X/ or can be loaded with void etiss::loadLibrary(std::string path,std::string name). Use etiss::listLibraries() and etiss::listPlugins() to view the status of loaded libraries.
Refer to Removing symbols from a shared library once the api of the new library is out of it's testing state or runtime linkage errors arise.