SIM_arm_mem_trans_from_generic, SIM_mips_mem_trans_from_generic, SIM_ppc_mem_trans_from_generic, SIM_x86_mem_trans_from_generic, SIM_pci_mem_trans_from_generic — convert generic transaction to CPU specific
#include <simics/arch/arm.h> // in C
import "simics/arch/arm.dml"; // in DML
struct arm_memory_transaction *
SIM_arm_mem_trans_from_generic(generic_transaction_t *NOTNULL mop);
#include <simics/arch/mips.h> // in C
import "simics/arch/mips.dml"; // in DML
struct mips_memory_transaction *
SIM_mips_mem_trans_from_generic(generic_transaction_t *NOTNULL mop);
#include <simics/arch/ppc.h> // in C
import "simics/arch/ppc.dml"; // in DML
struct ppc_memory_transaction *
SIM_ppc_mem_trans_from_generic(generic_transaction_t *NOTNULL mop);
#include <simics/arch/x86.h> // in C
import "simics/arch/x86.dml"; // in DML
struct x86_memory_transaction *
SIM_x86_mem_trans_from_generic(generic_transaction_t *NOTNULL mop);
#include <simics/devs/pci.h> // in C
import "simics/devs/pci.dml"; // in DML
struct pci_memory_transaction *
SIM_pci_mem_trans_from_generic(generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_arm_mem_trans_from_generic(...)
simics.SIM_mips_mem_trans_from_generic(...)
simics.SIM_ppc_mem_trans_from_generic(...)
simics.SIM_x86_mem_trans_from_generic(...)
simics.SIM_pci_mem_trans_from_generic(...)
Converts a pointer to a generic memory transaction into a pointer to a CPU specific memory transaction. The generic memory transaction must be part of a CPU specific one for this function to succeed. The pointer returned will be the same the input pointer if conversion is allowed, and nullptr on failure.
SimExc_Type Thrown if the generic transaction is not part of a CPU specific transaction.
New memory transaction pointer, or nullptr on error.
Cell Context
SIM_c_get_mem_op_value_buf, SIM_get_mem_op_value_buf, SIM_get_mem_op_value_cpu, SIM_get_mem_op_value_le, SIM_get_mem_op_value_be — get value for a memory operation
#include <simics/device-api.h> // in C
// always available in DML
void
SIM_c_get_mem_op_value_buf(const generic_transaction_t *NOTNULL mop,
uint8 *NOTNULL dst);
attr_value_t
SIM_get_mem_op_value_buf(const generic_transaction_t *NOTNULL mop);
uint64
SIM_get_mem_op_value_cpu(const generic_transaction_t *NOTNULL mop);
uint64
SIM_get_mem_op_value_le(const generic_transaction_t *NOTNULL mop);
uint64
SIM_get_mem_op_value_be(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_get_mem_op_value_buf(...)
simics.SIM_get_mem_op_value_cpu(...)
simics.SIM_get_mem_op_value_le(...)
simics.SIM_get_mem_op_value_be(...)
Returns load or store value for a memory transaction. If the data size is 8 bytes or less the SIM_get_mem_op_value_be and SIM_get_mem_op_value_le functions can be used. For reads/writes larger than 8 bytes, the functions SIM_c_get_mem_op_value_buf or SIM_get_mem_op_value_buf should be used to get the data.
If your model is compiled with one of the DEVICE_IS_LITTLE_ENDIAN, DEVICE_IS_BIG_ENDIAN pre-processor defines, then the SIM_get_mem_op_value function can be used as an alias to the SIM_get_mem_op_value_le and SIM_get_mem_op_value_be versions.
The SIM_c_get_mem_op_value_buf function is only available from C/C++. It places the data into the buffer pointed to by dst. No endian conversion is performed, i.e. data is returned in target endianness. There is no alignment requirement on the dst parameter.
When called from a memory-hierarchy (timing-model) only store values can be retrieved, since the load has not yet performed. To get the load value, a snoop-device should be used.
SIM_c_get_mem_op_value_buf returns nothing. The out parameter dst is filled with the data buffer of the memory transaction. SIM_get_mem_op_value_buf returns an attr_value_t (type data) containing the data buffer of the memory transaction. SIM_get_mem_op_value_be returns the zero-extended value in host endian order (interpreted as big endian) for the memory transaction. SIM_get_mem_op_value_le returns the zero-extended value in host endian order (interpreted as little endian). SIM_get_mem_op_value_cpu interprets the data in the default endian order for the initiating processor. This function can only be used for processor initiated memory operations. It is recommended that one of the other functions are used instead.
SimExc_Memory Thrown if the size of the operation is illegal.
Cell Context
SIM_c_set_mem_op_value_buf, SIM_set_mem_op_value_buf, SIM_set_mem_op_value_cpu, SIM_set_mem_op_value_le, SIM_set_mem_op_value_be — set value for a memory operation
#include <simics/device-api.h> // in C
// always available in DML
void
SIM_c_set_mem_op_value_buf(generic_transaction_t *NOTNULL mop,
const uint8 *NOTNULL src);
void
SIM_set_mem_op_value_buf(generic_transaction_t *NOTNULL mop,
attr_value_t value);
void
SIM_set_mem_op_value_cpu(generic_transaction_t *NOTNULL mop, uint64 value);
void
SIM_set_mem_op_value_le(generic_transaction_t *NOTNULL mop, uint64 value);
void
SIM_set_mem_op_value_be(generic_transaction_t *NOTNULL mop, uint64 value);
import simics
simics.SIM_set_mem_op_value_buf(...)
simics.SIM_set_mem_op_value_cpu(...)
simics.SIM_set_mem_op_value_le(...)
simics.SIM_set_mem_op_value_be(...)
Set the value returned to the requester of a memory operation. If the data size is 8 bytes or less the SIM_set_mem_op_value_be and SIM_set_mem_op_value_le functions can be used. For sizes larger than 8 bytes, the functions SIM_c_set_mem_op_value_buf or SIM_set_mem_op_value_buf should be used to set the data as an attr_value_t of data type.
If your model is compiled with one of the DEVICE_IS_LITTLE_ENDIAN, DEVICE_IS_BIG_ENDIAN pre-processor defines, then the SIM_set_mem_op_value function can be used as an alias to the SIM_set_mem_op_value_le and SIM_set_mem_op_value_be versions.
SIM_c_set_mem_op_value_buf is only available from C/C++, it operates on data in target endian order. There is no alignment requirement on the buf parameter.
SIM_set_mem_op_value_be takes data in host endian order and sets it in big-endian.
SIM_set_mem_op_value_le takes data in host endian order and sets it in little-endian.
SIM_set_mem_op_value_cpu takes data in host endian order and sets it in the default endian order for the initiating processor. This function can only be used for processor initiated memory operations. It is recommended that one of the other functions are used instead.
The functions that set the memory operation based on a value will truncate the representation of that value if the memory operation is smaller than 8 bytes.
These functions cannot be called from a timing-model since the real operation will overwrite the value set. They should instead be used from a snoop-device.
SimExc_Memory Thrown if the size of the operation is illegal.
Cell Context
SIM_get_mem_op_page_cross — detect transaction split
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE unsigned
SIM_get_mem_op_page_cross(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_get_mem_op_page_cross(...)
If a memory transaction was split because it straddled an MMU page, return 1 if it is the first part and 2 for the second. If the transaction was not split, return zero.
Cell Context
SIM_get_mem_op_size — get transaction size
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE unsigned
SIM_get_mem_op_size(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_get_mem_op_size(...)
Retrieve the size, in bytes, of a memory transaction.
Cell Context
SIM_get_mem_op_type — get type of transaction
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE mem_op_type_t
SIM_get_mem_op_type(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_get_mem_op_type(...)
This function returns the type of the memory transaction.
generic_transaction_t, SIM_set_mem_op_type
Cell Context
SIM_get_mem_op_type_name — get name of memory operation type
#include <simics/device-api.h> // in C
// always available in DML
const char *
SIM_get_mem_op_type_name(mem_op_type_t type);
import simics
simics.SIM_get_mem_op_type_name(...)
Returns a string describing type or NULL if unknown.
Cell Context
SIM_make_mem_op_write, SIM_make_mem_op_read — create a memory transaction
#include <simics/device-api.h> // in C
// always available in DML
generic_transaction_t
SIM_make_mem_op_write(physical_address_t addr, bytes_t data,
bool inquiry, conf_object_t *initiator);
generic_transaction_t
SIM_make_mem_op_read(physical_address_t addr, buffer_t buffer,
bool inquiry, conf_object_t *initiator);
Create and return a memory transaction for writing data to addr, or reading from addr into buffer. The number of bytes to transfer is specified by data and buffer respectively. The initiator is the object issuing the transaction; it may be nullptr.
These functions do not actually perform any memory operation; they just construct the generic_transaction_t that can be used in other calls.
The buffer argument must refer to an allocated buffer, and data must contain valid data. They must remain valid and allocated during the life-time of the returned value.
All contexts (including Threaded Context)
SIM_mem_op_ensure_future_visibility — request transaction visibility
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_mem_op_ensure_future_visibility(generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_ensure_future_visibility(...)
Request that future accesses from the same virtual address (using a granularity given by the min_cacheline_size processor attribute) will be seen by the memory hierarchy. Otherwise, the simulator may cache accesses to this address for performance so that they are not seen by the memory model.
Cell Context
SIM_mem_op_is_atomic — detect transaction atomicity
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_atomic(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_atomic(...)
Return true if the transaction was part of an atomic instruction (usually a read followed by a write), false otherwise.
Cell Context
SIM_mem_op_is_control — transaction control predicates
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_control(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_control(...)
Checks whether mem_op is a control transaction (one that does not actually transfer any data, such as cache control operations).
Cell Context
SIM_mem_op_is_data, SIM_mem_op_is_instruction — transaction data/instruction predicates
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_data(const generic_transaction_t *NOTNULL mop);
FORCE_INLINE bool
SIM_mem_op_is_instruction(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_data(...)
simics.SIM_mem_op_is_instruction(...)
These functions check whether mem_op is a data or an instruction transaction. Currently, the only transactions that are instruction transactions are instruction fetches.
Cell Context
SIM_mem_op_is_from_cache — Cache initiated transaction
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_from_cache(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_from_cache(...)
Checks whether mem_op is sent from a cache timing model.
Cell Context
SIM_mem_op_is_from_cpu — CPU initiated transaction
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_from_cpu(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_from_cpu(...)
Checks whether mem_op is sent from a processor.
Cell Context
SIM_mem_op_is_from_cpu_arch — CPU initiated transaction
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_from_cpu_arch(const generic_transaction_t *NOTNULL mop,
ini_type_t arch);
import simics
simics.SIM_mem_op_is_from_cpu_arch(...)
Checks whether mem_op is sent from a processor of a specific architecture.
Cell Context
SIM_mem_op_is_from_device — Device initiated transaction
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_from_device(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_from_device(...)
Checks whether mem_op is sent from a device.
Cell Context
SIM_mem_op_is_prefetch — transaction control predicates
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_prefetch(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_prefetch(...)
Checks whether mem_op is prefetch transaction.
Cell Context
SIM_mem_op_is_read, SIM_mem_op_is_write — transaction read/write predicates
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_is_read(const generic_transaction_t *NOTNULL mop);
FORCE_INLINE bool
SIM_mem_op_is_write(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_is_read(...)
simics.SIM_mem_op_is_write(...)
These functions check whether mem_op is a read or a write transaction.
Cell Context
SIM_mem_op_may_stall — detect transaction stall possibility
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE bool
SIM_mem_op_may_stall(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_mem_op_may_stall(...)
If true, the simulator will allow the transaction to stall execution. When false, a memory hierarchy must not attempt any stalling.
Cell Context
SIM_set_mem_op_exception, SIM_get_mem_op_exception — get/set transaction exception
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_exception(generic_transaction_t *NOTNULL mop,
exception_type_t exc);
FORCE_INLINE exception_type_t
SIM_get_mem_op_exception(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_set_mem_op_exception(...)
simics.SIM_get_mem_op_exception(...)
Retrieve or change the transaction exception. If set to a value other than Sim_PE_No_Exception, the transaction will be interrupted and an exception will be taken.
Cell Context
SIM_set_mem_op_initiator, SIM_get_mem_op_initiator, SIM_get_mem_op_ini_type — get/set transaction initiator
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_initiator(generic_transaction_t *NOTNULL mop,
ini_type_t type, conf_object_t *obj);
FORCE_INLINE conf_object_t *
SIM_get_mem_op_initiator(const generic_transaction_t *NOTNULL mop);
FORCE_INLINE ini_type_t
SIM_get_mem_op_ini_type(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_set_mem_op_initiator(...)
simics.SIM_get_mem_op_initiator(...)
simics.SIM_get_mem_op_ini_type(...)
Retrieve or change the transaction initiator type and object. These two parameters must agree.
Cell Context
SIM_set_mem_op_inquiry, SIM_get_mem_op_inquiry — get/set transaction inquiry flag
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_inquiry(generic_transaction_t *NOTNULL mop, bool inquiry);
FORCE_INLINE bool
SIM_get_mem_op_inquiry(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_set_mem_op_inquiry(...)
simics.SIM_get_mem_op_inquiry(...)
Retrieve or change the transaction inquiry flag. An inquiry read has no side-effects. An inquiry write has no other side-effect than changing the bytes at the specified address and size.
Cell Context
SIM_set_mem_op_physical_address, SIM_get_mem_op_physical_address, SIM_set_mem_op_virtual_address, SIM_get_mem_op_virtual_address — get or set transaction address
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_physical_address(generic_transaction_t *NOTNULL mop,
physical_address_t pa);
FORCE_INLINE physical_address_t
SIM_get_mem_op_physical_address(const generic_transaction_t *NOTNULL mop);
FORCE_INLINE void
SIM_set_mem_op_virtual_address(generic_transaction_t *NOTNULL mop,
logical_address_t va);
FORCE_INLINE logical_address_t
SIM_get_mem_op_virtual_address(const generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_set_mem_op_physical_address(...)
simics.SIM_get_mem_op_physical_address(...)
simics.SIM_set_mem_op_virtual_address(...)
simics.SIM_get_mem_op_virtual_address(...)
Retrieve or set the physical or virtual (logical) addresses of a memory transaction.
Cell Context
SIM_set_mem_op_reissue — request transaction reissue
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_reissue(generic_transaction_t *NOTNULL mop);
import simics
simics.SIM_set_mem_op_reissue(...)
Request that the transaction will be re-issued if a non-zero stall time is returned from a memory hierarchy. Otherwise, the memory model will not see the transaction again.
Cell Context
SIM_set_mem_op_type — set type of transaction
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_type(generic_transaction_t *NOTNULL mop, mem_op_type_t type);
import simics
simics.SIM_set_mem_op_type(...)
This function sets the type of the memory transaction.
generic_transaction_t, SIM_get_mem_op_type
Cell Context
SIM_set_mem_op_user_data, SIM_get_mem_op_user_data — get/set transaction user data
#include <simics/device-api.h> // in C
// always available in DML
FORCE_INLINE void
SIM_set_mem_op_user_data(generic_transaction_t *NOTNULL mop,
void *data);
FORCE_INLINE void *
SIM_get_mem_op_user_data(const generic_transaction_t *NOTNULL mop);
Retrieve or change user data associated with the transaction. This data is not touched by Simics in any way and its handling and interpretation is left to the user. It can be used to pass information from a timing model to a snoop device, but the data does not survive across a stall.
Cell Context