Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / docs / mmi / mmi.h.20050531
/*
* mmi.h
* SAM device-model API
*
* Copyright (C) 2001-2005 Sun Microsystems, Inc.
* All rights reserved.
*/
#ifndef _SAM_MMI_H
#define _SAM_MMI_H
#pragma ident "@(#)1.26 03/12/05 SAM-mmi.h"
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif
/* opaque type definitions for MMI device models */
typedef void * mmi_instance_t;
typedef void * mmi_module_t;
typedef enum {mmi_false=0, mmi_true=1} mmi_bool_t;
/* device operation in SAM
*
* 1. The simulator reads in the simulation configuration file containing "sysconf" lines at startup
* 2. Each sysconf line specifies a module-type name, an instance name and a set of properties in the form name=value
* For example:
* sysconf mydev dev0 baseaddr=0xffc00040 parent=bus0 debug=true logfile=mydev.0.log
* 3. The sysconf parser loads the mydev.so object (unless it is already loaded)
* 4. The sysconf parser calls the instance creator function in mydev.so to create the "dev0" instance
* 5. The dev0 instance creator retrieves its sysconf arguments using mmi_argc and mmi_argv calls and processes them
* 6. The dev0 instance creator maps its device registers into the SAM address space using mmi_map_physio
*/
/* An MMI device model is a shared object loaded using dlopen().
* In SAM, this mechanism requires an _init function in the shared object:
*
* extern "C" void _init()
*
* This function must be defined. For example:
*
* extern "C" void _init() {
* // mmi initialization code goes here
* }
* There are alternative means of automatically invoking an initialization function in a shared object
* For example, the constructor of a static object in the shared object written using C++
*
* In any event, SAM does not explicitly call a function in the shared object after dlopen().
* The _init() function is implicitly invoked by dlopen().
*/
/* Functions returning mmi_bool_t return an SUCCESS status (true=no error).
* An error typically indicates invalid arguments are being passed
*/
/* Devices are instantiated by SAM when specified in the config file.
* For each device instance, the device model needs to provide an INSTANCE CREATOR function
* which performs the instantiation.
*
* The instance creator function is invoked from SAM
* with the modname (device class name) and the instance-name
*/
typedef void (*mmi_instance_creator) (const char *modname, const char *instance_name);
mmi_bool_t mmi_register_instance_creator(const char * modname, mmi_instance_creator creatorfn);
/* the instance_creator function can retrieve its own handle (mmi_instance_t) by calling the mmi_register_instance
* function. This function is also used to provide a help string specific to this instance.
* This call is optional; the mmi_get_instance() call can be used to get the device's own handle. The help string is
* set to the name of the instance by default. This not being too helpful, device models are encouraged to provide
* a useful short help string. This help string is displayed in response to UI commands for listing all device nodes.
*/
mmi_instance_t mmi_register_instance(const char * modname, const char * instancename, const char * short_help);
/* Register a function that can respond to the modinfo UI command by printing out relevant module instance information */
typedef void (*mmi_modinfo_cb) (mmi_instance_t cb_instance);
/* this_instance can be obtained using the mmi_get_instance call
* defined below, and the instance_name parameter of the instance
* creator fn */
mmi_bool_t mmi_register_modinfo_cb(mmi_instance_t this_instance, mmi_modinfo_cb modinfo_fn);
/* These calls use the mmi_instance_t handle provided by the mmi_register_instance function above.
* They return the arguments specified on the sysconf line for this device instance
*/
int mmi_argc(mmi_instance_t this_instance);
char * mmi_argv(mmi_instance_t this_instance, int index);
/* A function of type mmi_access needs to be provided by the device model to handle accesses (load/store) to
* device registers in response to instructions executed by the simulated CPU.
*
* The mmi_map_physio function is used to register this function with the simulator. The device-model provides a pointer
* to user data which is returned in the call to the access function. This function should return an error indication (0 for success, some non-zero value for failure
*/
typedef int (*mmi_access) (uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask);
/* These calls lets the instance map/unmap its registers onto the physical address space of the simulated CPUs */
int mmi_map_physio (uint64_t base, uint64_t size, void* obj, mmi_access access_fn);
void mmi_unmap_physio(uint64_t base, uint64_t size, void* obj);
/* Memory access functions for devices: devices can do block read/write into simulated memory using mmi_memread and mmi_memwrite calls */
void mmi_memread(uint64_t paddr, uint8_t * data, uint64_t size);
void mmi_memwrite(uint64_t paddr, const uint8_t * data, uint64_t size);
/* interrupts: interrupts are not directly delivered to CPUs by devices. Instead,
* they are passed on up the device hierarchy through a bus and/or a bridge. The bridge model
* implements interrupt delivery to the appropriate CPU. We do not address this in MMI
*/
/* Interacting with other devices */
/*
* When a device is instantiated/deleted in response to a sysconf directive,
* a device module can receive about this config change by registering a config callback
* function.
*
* A config event can be of the type: instance-added, instance-deleted and config-init-done
* config-init-done refers to simulated system being initialized and ready to execute instructions.
* instance_deleted is deprecated and obsolete. Simulator should not delete a device instance.
* registering a config callback results in the callback function
* being called for config events that have occurred in the past as
* well as those that occur subsequently.
*/
typedef enum {MMI_CONFIG_NEW_MODULE, MMI_CONFIG_DELETE_MODULE, MMI_CONFIG_INIT_DONE} mmi_config_t;
typedef void (*mmi_config_cb) (void *callback_data, mmi_instance_t target, const char * target_name, mmi_config_t);
mmi_bool_t mmi_register_config_cb(mmi_instance_t this_instance, mmi_config_cb config_fn);
// get a device-instance handle by name
mmi_instance_t mmi_get_instance(const char * instancename);
// register a call-back function with the simulator to respond to mmi_get_interface calls from other modules
typedef void* (*mmi_interface_cb) (void *callback_data, const char *name);
mmi_bool_t mmi_register_interface_cb(mmi_instance_t this_instance, mmi_interface_cb);
// get a named interface from another device instance (eg pcie_device from pcie_bus).
// the return value should be typecast to the mutually-agreed-upon interface type
void * mmi_get_interface(mmi_instance_t instance, const char * interface_name);
/* old mmi functions (for backwards compatibility - eg the SN sync-device model) */
mmi_bool_t mmi_unregister_instance_creator(mmi_instance_t instance);
/* these have been deprecated in favor of mmi_map_physio (see above) */
typedef int (*mmi_io_action) (void *cb_data, uint64_t paddr, uint64_t *buf, int size, uint8_t bytemask, void *cpuptr);
int mmi_register_io_action (mmi_module_t *module, mmi_io_action ld_handler, mmi_io_action st_handler);
/* interrupt functions - these are described in the MMI documentation */
int mmi_interrupt_packet (int dest_cpuid, void *src, int src_iscpu, uint64_t *idata);
int mmi_interrupt_vector (int dest_cpuid, void *src, int src_iscpu, uint32_t vnum, int traptype);
#if 0
{
#endif
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _SAM_MMI_H