// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: module.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program 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
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
* Copyright 2004 by Sun Microsystems, Inc.
//extern devRegistry * samDevs;
//////////////////////////////////////////////////
// VIRTUAL FUNCTION STUBS //
// these should be implemented in each subclass //
//////////////////////////////////////////////////
Module::parse_arg(const char *)
// called once after blaze has initialized devices and cpu data structs
// called each time a new module instance has been created
Module::module_added(mmi_instance_t
, const char*)
// called each time a new module instance has been unloaded
Module::module_deleted(mmi_instance_t
, const char*)
// print interesting info about this module
printf("module name <%s>, instance name <%s>\n", MODNAME
, getName());
// return pointer to interface
Module::get_interface(const char*)
Module::debug_err(const char *fmt
, ...)
vfprintf(stderr
, fmt
, ap
);
Module::debug_info(const char *fmt
, ...)
vfprintf(stderr
, fmt
, ap
);
Module::debug_more(const char *fmt
, ...)
vfprintf(stderr
, fmt
, ap
);
// generate "module:file(Lnn)" for debug output
Module::_here(const char *f
, int n
)
const char *p
= strrchr(f
, '/');
snprintf(herebuf
, sizeof herebuf
, "%s:%s(L%d)", getName(), p
?(p
+1):f
, n
);
static mmi_bool_t
module_dump_restore(Module
* module
, const char * file_name
, bool isDump
)
char *non_v4_mod
[NON_V4_MOD_NUM
] = {"excalibur", "pci_bus", "bi", "rtc", "scsi", "fc"};
char fn
[PATH_MAX
], *ptr
, *v4_distinct_name
[V4_DISTINCT
] = {"schizo", "serial", "ll"};
// comment out when testing hh/parrot v5 modules with v4 blaze
if (restore_pure_v4_dump() && !isDump
) {
for (int i
= 0; i
< NON_V4_MOD_NUM
; i
++)
if (!strcmp(module
->get_mod_name(), non_v4_mod
[i
]))
for (int i
= 0; i
< V4_DISTINCT
; i
++)
if (!strcmp(module
->get_mod_name(), v4_distinct_name
[i
])) {
ptr
= (char *)strrchr(fn
, '/') + 1;
strcat((char *)fn
, v4_distinct_name
[i
]);
strcat((char *)fn
, ".dmp");
fp
= fopen (file_name
, isDump
? "w" : "r");
rc
= isDump
? module
->dump(fp
) : module
->restore(fp
);
static mmi_bool_t
module_dump(void * mydata
, const char * file_name
)
return module_dump_restore((Module
*)mydata
, file_name
, true);
static mmi_bool_t
module_restore(void * mydata
, const char * file_name
)
return module_dump_restore((Module
*)mydata
, file_name
, false);
extern "C" static void module_stop(void *ptr
)
Module
*module
= (Module
*) ptr
;
extern "C" static void module_restart(void *ptr
)
Module
*module
= (Module
*) ptr
;
static void module_parse_args(Module
*module
, mmi_instance_t instance
, bool allargs
)
int argc
= mmi_argc(instance
);
for (int i
= 0; i
< argc
; i
++) {
char *arg
= mmi_argv(instance
, i
);
if (!strncmp("-d", arg
, 2)) { // debug_level: -d#
module
->debug_level
= (int) strtol(&arg
[2], NULL
, 0);
} else if (allargs
&& !module
->parse_arg(arg
))
module
->debug_err("%s: WARNING: Ignoring arg '%s'\n", module
->HERE
, arg
);
extern "C" static void module_reconfig(void *cb_data
, mmi_instance_t target
, const char *target_name
, mmi_config_t ev
)
Module
*module
= (Module
*)cb_data
;
if (target
== module
->getInstance()) {
if (ev
== MMI_CONFIG_DELETE_MODULE
)
else if (ev
== MMI_CONFIG_INIT_DONE
)
} else if (ev
== MMI_CONFIG_NEW_MODULE
) {
module
->module_added(target
, target_name
);
} else if (ev
== MMI_CONFIG_DELETE_MODULE
) {
module
->module_deleted(target
, target_name
);
// callback to retrieve module information
extern "C" static void module_get_modinfo (mmi_instance_t instance
)
Module
*module
= (Module
*) instance
;
extern "C" static void *module_get_interface(void *cb_data
, const char *name
)
Module
*module
= (Module
*)cb_data
;
if (!strcmp(name
, MODULE_INTERFACE
))
return module
->get_interface(name
);
Module::Module(const char *_modname
, const char *_instance_name
)
instance_name
= makestr(_instance_name
, instance_name
);
modname
= makestr(_modname
, modname
);
instance
= mmi_get_instance(instance_name
);
memset(herebuf
, 0, sizeof herebuf
);
module_parse_args(this, instance
, false);
debug_more("%s: constructor\n", HERE
);
mmi_register_start_stop (module_restart
, module_stop
, (void*)this);
mmi_register_dump_restore(getName(), module_dump
, module_restore
, (void*)this);
plist
= new property_list();
if(mySamDevPtr
= (devRegistry
**)dlsym(RTLD_DEFAULT
,"samDevs")){
samId
= (*mySamDevPtr
)->registerDev(this);
debug_more("%s: destructor\n", getName());
free((void*)instance_name
);
// called during ldm and sysconf, after _init
extern "C" static void module_create_instance(const char *modname
, const char *instance_name
)
Module
*module
= Module::create(modname
, instance_name
);
fprintf(stderr
, "%s: Could not create <%s>\n", MODNAME
, instance_name
);
mmi_instance_t instance
= mmi_register_instance(modname
, instance_name
, (void*)module
, Module::get_help_string());
fprintf(stderr
, "%s: Could not register <%s>\n", MODNAME
,instance_name
);
fprintf(stderr
, "mmi_register_instance %s 0x%llx, data 0x%llx \n", instance_name
, instance
, (void*)module
);
module_parse_args(module
, instance
, true);
module
->debug_more("%s: modname <%s> instance_name <%s>\n", MODNAME
, modname
, instance_name
);
module
->debug_info("%s: Version <%s>\n",MODNAME
,module
->get_version());
if (!module
->check_args()) {
fprintf (stderr
, "%s: Could not create object for <%s>\n", MODNAME
,instance_name
);
mmi_register_modinfo_cb(instance
, module_get_modinfo
);
mmi_register_interface_cb(instance
, module_get_interface
);
mmi_register_config_cb(instance
, module_reconfig
);
// The _init() and _fini() routines are only needed when we compile
// a module into a .so. In case a module is linked statically to
// another module (.so) we get multiple defined _init() and _inif()
// routines. Currently modules for cosim are all linked statically.
// MODULE_STATIC_LINKAGE excludes _init() and _fini() when defined.
#ifndef MODULE_STATIC_LINKAGE
// module init, called during dlopen
if (! mmi_register_instance_creator (MODNAME
, module_create_instance
)) {
fprintf (stderr
, "%s: Failed to load\n", MODNAME
);
// called by dlclose during uldm and exit