/* init_local() is called once when the device module is loaded into Simics */ void init_local(void) { const class_data_t funcs = { .new_instance = ls_new_instance, .class_desc = "hax and sploits", .description = "here we have a simix module which provides not" " only hax or sploits individually but rather a great" " conjunction of the two." }; /* Register the empty device class. */ conf_class_t *conf_class = SIM_register_class(SIM_MODULE_NAME, &funcs); /* Register the landslide class as a trace consumer. */ static const trace_consume_interface_t sploits = { /* argh, impossible to forward-declare trace_entry struct in header */ .consume = (void (*)(conf_object_t *, trace_entry_t *))landslide_entrypoint }; SIM_register_interface(conf_class, TRACE_CONSUME_INTERFACE, &sploits); /* Register attributes for the class. */ LS_ATTR_REGISTER(conf_class, decision_trace, "i", "Get a decision trace."); LS_ATTR_REGISTER(conf_class, trigger_count, "i", "Count of haxes"); LS_ATTR_REGISTER(conf_class, arbiter_choice, "i", "Tell the arbiter which thread to choose next " "(buffered, FIFO)"); LS_ATTR_REGISTER(conf_class, test_case, "s", "Which test case should we run?"); LS_ATTR_REGISTER(conf_class, cmd_file, "s", "Filename to use for communication with the wrapper"); LS_ATTR_REGISTER(conf_class, html_file, "s", "Filename to use for HTML preemption trace output"); LS_ATTR_REGISTER(conf_class, quicksand_pps, "s", "Filename for dynamic Quicksand-supplied PP config"); }
DLL_EXPORT void init_local(void) { id_splitter_data.new_instance = id_splitter_new_instance; id_splitter_data.description = "The id splitter module splits up memory operations into separate " "data and instruction streams. Data operations are forwarded to " "the timing interface of the object specified by the dbranch attribute and, " "in the same manner, instruction operations are forwarded to the ibranch."; if (!(id_splitter_class = SIM_register_class("id-splitter", &id_splitter_data))) { pr("Could not create id-splitter class\n"); } /* set up custom interfaces */ timing_interface.operate = id_splitter_operate; SIM_register_interface(id_splitter_class, "timing-model", &timing_interface); SIM_register_attribute(id_splitter_class, "ibranch", get_ibranch, 0, set_ibranch, 0, Sim_Attr_Optional, "Object to receive instruction transactions."); SIM_register_attribute(id_splitter_class, "dbranch", get_dbranch, 0, set_dbranch, 0, Sim_Attr_Optional, "Object to receive data transactions."); }
void ts_init_local(void) { ts_data.new_instance = ts_new_instance; ts_data.description = "A trans-splitter-ooo object can split a transaction that " "crosses a cache line in two non-crossing transactions.\n\n" "A trans-splitter-ooo can be inserted between the cpu and " "the caches if the cpu can issue cache-line crossing " "transactions (x86 being a good example). It can also be " "used between two caches to split transactions.\n\n" "A trans-splitter-ooo object supports multiple outstanding " "transactions. Note that it does not support splitting a " "transaction more than once, so transactions that crosses " "two cache lines or more will be split incorrectly."; if (!(ts_class = SIM_register_class("trans-splitter-ooo", &ts_data))) { pr_err("Could not create trans-splitter-ooo class\n"); } else { /* register the attributes */ ts_register(ts_class); /* register the timing model interface */ ts_ifc.operate = ts_operate; SIM_register_interface(ts_class, "timing-model", (void *) &ts_ifc); } }
void ts_init_local(void) { ts_data.new_instance = ts_new_instance; ts_data.description = "A trans-splitter object should be inserted between two caches if the higher-level " "cache has a larger cache line size than the lower-level cache, or between the " "processor and the id-splitter object if you have a processor that can do " "unaligned accesses or accesses larger than one cache line. It splits cacheable " "transactions that span more than one naturally aligned next-cache-line-size bytes " "big lines into multiple transactions that each fit within one line."; if (!(ts_class = SIM_register_class("trans-splitter", &ts_data))) { fputs("Could not create trans-splitter class\n", stderr); } else { /* register the attributes */ ts_register(ts_class); /* register the timing model interface */ ts_ifc.operate = ts_operate; SIM_register_interface(ts_class, "timing-model", &ts_ifc); } }
//************************************************************************** void hfa_init_local( void ) { attr_value_t attr; conf_class_t *conf_class; conf_object_t *conf_cpu; memset( &attr, 0, sizeof(attr) ); hfa_checkerr("BEGIN INIT"); if (SIM_number_processors() == 0) { #ifdef SIMICS22X printf("opal: No processors defined -- load a checkpoint first!\n"); printf("opal: Please restart simics and try again.\n"); return; #endif #ifdef SIMICS30 /* * This case arises because of Simics 3.0: * Simics 3.0 loads and "digitally signs" modules immediately after compiling them. * This raises havoc with Multifacet's modules, since most of them require a checkpoint * to be loaded BEFORE the module. */ printf("\033[34;1m\n"); printf(" /***************************************************************************\\\n"); printf(" > Opal found no processors. If you are NOT compiling Opal and you see this <\n"); printf(" > message, something is wrong. <\n"); printf(" > This message is part of the normal compilation process. <\n"); printf(" \\***************************************************************************/\033[m\n\n"); SIM_clear_exception(); return; #endif } /* Initialize and register the class "opal". */ memset(&hfa_class_data, 0, sizeof(class_data_t)); hfa_class_data.new_instance = hfa_new_instance; conf_class = SIM_register_class("opal", &hfa_class_data); /* Initialize and register the timing-model interface */ hfa_timing_interface.operate = NULL; SIM_register_interface(conf_class, TIMING_MODEL_INTERFACE, &hfa_timing_interface); /* Initialize and register the snoop-device interface */ hfa_snoop_interface.operate = NULL; SIM_register_interface(conf_class, SNOOP_MEMORY_INTERFACE, &hfa_snoop_interface); /* Initialize and register the event poster interface */ hfa_event_poster_interface.get_event_info = hfa_get_event; hfa_event_poster_interface.set_event_info = hfa_set_event; hfa_event_poster_interface.describe_event = hfa_describe_event; SIM_register_interface(conf_class, "event-poster", &hfa_event_poster_interface); /* Initialize and register multifacet-ruby interface */ memset(&hfa_ruby_interface, 0, sizeof(hfa_ruby_interface)); SIM_register_interface(conf_class, "mf-opal-api", &hfa_ruby_interface); /** create the hfa object */ hfa_conf_object = (hfa_object_t *) SIM_new_object(conf_class, "opal0"); /* register with cpu 0 event queue */ attr.kind = Sim_Val_Object; conf_cpu = SIM_next_queue(0); if (conf_cpu) { attr.u.object = conf_cpu; printf("Queue registration %s\n", conf_cpu->name ); set_error_t install_error = SIM_set_attribute( (conf_object_t *) hfa_conf_object, "queue", &attr ); if (install_error == Sim_Set_Ok) { printf( "successful installation of the opal queue.\n"); } else { printf( "error installing opal queue.\n"); exit(1); } } else { printf("error: unable to register queue interface\n"); } /* register interfaces on the hfa0 object */ /* event-poster interface */ SIM_register_attribute( conf_class, "install-event-poster", hfa_post_get, (void *) "install-event-poster", hfa_post_set, (void *) "install-event-poster", Sim_Attr_Pseudo, "Post a trace-related function to event queue" ); // Allocate and initialize a configuration reader hfa_construct_initvar(); hfa_checkerr("hfa_construct_initvar(): check"); // register a number of commands #define OPAL_COMMAND( COMMAND ) \ SIM_register_attribute( conf_class, COMMAND, \ initvar_dispatch_get, (void *) COMMAND, \ initvar_dispatch_set, (void *) COMMAND, \ Sim_Attr_Pseudo, \ "See documentation with associated opal command." ) /** read a configuration file */ OPAL_COMMAND( "init" ); OPAL_COMMAND( "readparam" ); OPAL_COMMAND( "saveparam" ); /** interfaces for recording a trace to disk */ OPAL_COMMAND( "trace-start" ); OPAL_COMMAND( "trace-stop" ); OPAL_COMMAND( "take-trace" ); OPAL_COMMAND( "skip-trace" ); OPAL_COMMAND( "branch-trace-start" ); OPAL_COMMAND( "branch-trace-stop" ); OPAL_COMMAND( "branch-trace-take" ); OPAL_COMMAND( "branch-trace-inf" ); OPAL_COMMAND( "stepper" ); OPAL_COMMAND( "param" ); /** interfaces to run inside of simics */ OPAL_COMMAND( "sim-flag" ); OPAL_COMMAND( "sim-start" ); OPAL_COMMAND( "sim-stop" ); OPAL_COMMAND( "sim-step" ); OPAL_COMMAND( "break_simulation" ); OPAL_COMMAND( "sim-inorder-step" ); OPAL_COMMAND( "sim-warmup" ); OPAL_COMMAND( "cycle" ); OPAL_COMMAND( "sim-stats" ); OPAL_COMMAND( "sim-inflight" ); OPAL_COMMAND( "sim-rd-check" ); OPAL_COMMAND( "sim-wr-check" ); OPAL_COMMAND( "debugtime" ); OPAL_COMMAND( "stall" ); OPAL_COMMAND( "togglemh" ); OPAL_COMMAND( "install-snoop" ); OPAL_COMMAND( "mlp-trace" ); // ADD_SIMCOMMAND // check for errors hfa_checkerr("class regististration"); // check that we are compatible with this version of the simulator hfa_simcheck(); hfa_checkerr("hfa_simcheck(): check"); printf("hfa_init_local done:\n"); return; }
/* * init_local() is called once when the device module is loaded into Simics. */ void init_local(void) { class_data_t funcs; conf_class_t *sample_class; sample_interface_t *sample_interface; io_memory_interface_t *memory_interface; /* * Register the sample device class. The 'sample_new_instance' * function serve as a constructor, and is called every time * a new instance is created. */ memset(&funcs, 0, sizeof(class_data_t)); funcs.new_instance = sample_new_instance; funcs.description = "The sample-device device is a dummy device that compiles and " "that can be loaded into Simics. Using it as a starting point " "when writing own devices for Simics is encouraged. Several " "device specific functions are included. The source is " "included in <tt>simics/src/devices/sample-device</tt>."; sample_class = SIM_register_class(DEVICE_NAME, &funcs); /* * Register the 'sample-interface', which is an example * of a unique, customized interface that we've implemented * for this device. */ sample_interface = MM_ZALLOC(1, sample_interface_t); sample_interface->simple_function = simple_function; SIM_register_interface(sample_class, "sample_interface", sample_interface); /* * Register the 'io-memory' interface, which is an example * of a generic interface that is implemented by a large * number of devices. */ memory_interface = MM_ZALLOC(1, io_memory_interface_t); memory_interface->operation = sample_operation; SIM_register_interface(sample_class, IO_MEMORY_INTERFACE, memory_interface); /* * Register attributes (device specific data) together with * functions for getting and setting these attributes. * The 'Sim_Attr_Optional' attribute will be saved with a configuration */ SIM_register_typed_attribute( sample_class, "value", get_value_attribute, NULL, set_value_attribute, NULL, Sim_Attr_Optional, "i", NULL, "The <i>value</i> field."); /* Pseudo attribute, not saved in configuration */ SIM_register_typed_attribute( sample_class, "add_log", 0, NULL, set_add_log_attribute, NULL, Sim_Attr_Pseudo, "s", NULL, "<i>Write-only</i>. Strings written to this " "attribute will end up in the device's log file."); /* Example of attribute using indexing */ SIM_register_typed_attribute( sample_class, "range_sum", get_range_sum_attribute, NULL, 0, NULL, (attr_attr_t)(Sim_Attr_Pseudo | Sim_Attr_List_Indexed), "i", "i", "<i>Read-only</i>. When read from index <tt>[<i>i0</i>, " "<i>i1</i>]</tt>, the sum of the integers between " "<tt><i>i0</i></tt> and <tt><i>i1</i></tt> will " "be returned."); }
//************************************************************************** void init_local() { class_data_t ruby_funcs; conf_class_t *ruby_class; conf_object_t *ruby_obj; attr_value_t val; conf_object_t *phys_mem0; /* Initialize and register the class "ruby-class". */ bzero(&ruby_funcs, sizeof(class_data_t)); ruby_funcs.new_instance = ruby_new_instance; ruby_funcs.delete_instance = NULL; ruby_class = SIM_register_class("ruby", &ruby_funcs); /* initialize the variable reader: sets all global variables to defaults */ init_variables(); /* Initialize and register the timing-model interface */ ruby_timing_interface = MM_ZALLOC(1, timing_model_interface_t); ruby_timing_interface->operate = ruby_operate; SIM_register_interface(ruby_class, "timing-model", ruby_timing_interface); ruby_obj = SIM_new_object(ruby_class, "ruby0"); phys_mem0 = SIM_get_object("phys_mem0"); if(phys_mem0 == NULL) { /* Look for an object called "phys_mem" instead */ SIM_clear_exception(); phys_mem0 = SIM_get_object("phys_mem"); } if(phys_mem0 == NULL) { /* Okay, now we can panic */ #ifndef SIMICS30 /* * Must load a checkpoint BEFORE load-module ruby */ printf("Please load a checkpoint BEFORE executing \"load-module ruby\"\n"); #endif #ifdef SIMICS30 /* * This case arises because of Simics 3.0: * Simics 3.0 loads and "digitally signs" modules immediately after compiling them. * This raises havoc with Multifacet's modules, since most of them require a checkpoint * to be loaded BEFORE the module. */ printf("\033[34;1m\n"); printf(" /***************************************************************************\\\n"); printf(" > Physical Memory object cannot be found. If you are NOT compiling Ruby and <\n"); printf(" > you see this message, something is wrong. <\n"); printf(" > This message is part of the normal compilation process. <\n"); printf(" \\***************************************************************************/\033[m\n\n"); #endif SIM_clear_exception(); return; } val.kind = Sim_Val_Object; val.u.object = ruby_obj; set_error_t install_error = SIM_set_attribute(phys_mem0, "timing_model", &val); if (install_error == Sim_Set_Ok) { printf( "successful installation of the ruby timing model.\n"); } else { printf( "error installing ruby timing model.\n"); exit(1); } /* Initialize the snoop interface if we are tracking values in simics */ if (init_use_snoop() == 1) { ruby_observe_interface = MM_ZALLOC(1, timing_model_interface_t); ruby_observe_interface->operate = ruby_observe; SIM_register_interface(ruby_class, "snoop-memory", ruby_observe_interface); SIM_set_attribute(phys_mem0, "snoop_device", &val); } /* init_opal_interface calls to a static function in OpalInterface.C * to determine is opal is installed. If it is, it registers itself, * and notifies opal that ruby is loaded. Otherwise, it does nothing. */ opal_interface = MM_ZALLOC(1, mf_ruby_api_t); SIM_register_interface(ruby_class, "mf-ruby-api", opal_interface); init_opal_interface( opal_interface ); // register a number of commands #define RUBY_COMMAND( COMMAND ) \ SIM_register_attribute( ruby_class, COMMAND, \ initvar_dispatch_get, (void *) COMMAND, \ initvar_dispatch_set, (void *) COMMAND, \ Sim_Attr_Session, \ "See documentation with associated ruby command." ) RUBY_COMMAND( "init" ); RUBY_COMMAND( "readparam" ); RUBY_COMMAND( "saveparam" ); RUBY_COMMAND( "param" ); RUBY_COMMAND( "dump-stats" ); RUBY_COMMAND( "dump-short-stats" ); RUBY_COMMAND( "periodic-stats-file" ); RUBY_COMMAND( "periodic-stats-interval" ); RUBY_COMMAND( "clear-stats" ); RUBY_COMMAND( "system-recovery" ); RUBY_COMMAND( "debug-verb" ); RUBY_COMMAND( "debug-filter" ); RUBY_COMMAND( "debug-output-file" ); RUBY_COMMAND( "debug-start-time" ); RUBY_COMMAND( "set-checkpoint-interval" ); RUBY_COMMAND( "load-caches" ); RUBY_COMMAND( "save-caches" ); RUBY_COMMAND( "dump-cache" ); RUBY_COMMAND( "dump-cache-data" ); RUBY_COMMAND( "tracer-output-file" ); RUBY_COMMAND( "set-procs-per-chip" ); RUBY_COMMAND( "abort-all" ); RUBY_COMMAND( "xact-visualizer-file" ); RUBY_COMMAND( "print-temp" ); RUBY_COMMAND( "reset-temp" ); RUBY_COMMAND( "print-reuse" ); RUBY_COMMAND( "reset-reuse" ); // Add end_transaction magic callback SIM_hap_add_callback("Core_Magic_Instruction", (obj_hap_func_t) magic_instruction_callback, NULL); #ifdef SPARC SIM_hap_add_callback("Core_Exception", (obj_hap_func_t) ctrl_exception_start, NULL); SIM_hap_add_callback("Core_Exception_Return", (obj_hap_func_t) ctrl_exception_done, NULL); SIM_hap_add_callback("Core_Mode_Change", (obj_hap_func_t) change_mode_callback, NULL); /// for MMU SIM_hap_add_callback("MMU_Data_TLB_Demap", (obj_hap_func_t) dtlb_demap_callback, NULL); SIM_hap_add_callback("MMU_Data_TLB_Map", (obj_hap_func_t) dtlb_map_callback, NULL); SIM_hap_add_callback("MMU_Data_TLB_Overwrite", (obj_hap_func_t) dtlb_overwrite_callback, NULL); SIM_hap_add_callback("MMU_Data_TLB_Replace", (obj_hap_func_t) dtlb_replace_callback, NULL); // Add callbacks to abort transactions on exceptions in Rock. // SIM_hap_add_callback("Core_Exception", (obj_hap_func_t) rock_exception_start, (void *) NULL); SIM_hap_add_callback("Core_Exception_Return", (obj_hap_func_t) rock_exception_done, (void *) NULL); // Add instruction decoder to install handlers for Rock-specific behavior. // decoder_t* decoder = ATMTP_create_instruction_decoder(); SIM_register_arch_decoder(decoder, NULL, 0); #endif // CM 2/2003: // Note: Please register other callbacks in the appropriate interface file, // instead of here. This module should only register callbacks that // are common to the "Driver" class (parent class to SimicsInterface // and OpalInterface). // If its only used by SimicsInterface, put it in that class. }
void init_local(void) { conf_class_t *conf_class; /* Initialize and register the class "consistency_controller". */ memset(&class_data, 0, sizeof(class_data_t)); class_data.new_instance = consistency_controller_new_instance; class_data.description = "The consistency controller class implements a " "memory hierarchy that communicates with the instruction tree " "(in an out of order Simics) to enforce the architecturally " "defined consistency model. This is done by stalling loads and stores " "that would violate the consistency model but are otherwise ready to " "issue to the memory system. The reason for not integrating the " "consistency controller into the Simics core is to allow the user to " "experiment with relaxed consistency model implementations. The user " "can replace the consistency controller or modify the default one to " "meet their needs (the source code is available in the distribution). " "\n\n" "The default consistency controller can be constrained through " "attributes"; conf_class = SIM_register_class("consistency-controller", &class_data); /* Initialize and register the timing-model interface */ consistency_controller_timing_interface = MM_ZALLOC(1, timing_model_interface_t); consistency_controller_timing_interface->operate = consistency_controller_operate; SIM_register_interface(conf_class, "timing-model", consistency_controller_timing_interface); /* Initialize attributes */ SIM_register_attribute(conf_class, "timing_model", get_timing_model_attribute, 0, set_timing_model_attribute, 0, Sim_Attr_Optional, "The next memory hierarchy object"); SIM_register_attribute(conf_class, "load-load", get_load_load, 0, set_load_load, 0, Sim_Attr_Optional, "If set to non-zero load-load memory consistency will be enforced."); SIM_register_attribute(conf_class, "load-store", get_load_store, 0, set_load_store, 0, Sim_Attr_Optional, "If set to non-zero load-store memory consistency will be enforced."); SIM_register_attribute(conf_class, "store-load", get_store_load, 0, set_store_load, 0, Sim_Attr_Optional, "If set to non-zero store-load memory consistency will be enforced. This is the default"); SIM_register_attribute(conf_class, "store-store", get_store_store, 0, set_store_store, 0, Sim_Attr_Optional, "If set to non-zero store-store memory consistency will be enforced. This is the default."); SIM_register_attribute(conf_class, "prefetch", get_prefetch, 0, set_prefetch, 0, Sim_Attr_Optional, "If set to non-zero prefetch memory transaction will be sent to the rest " "of the memory hierarchy for transactions that breaks the memory consistency. " "Zero is default."); }