cpu_instrumentation_subscribe cycle
API Reference Manual  /  5 Model-to-Simulator Interfaces  / 

cpu_memory_query

Description
The cpu_memory_query interface is used by callbacks of the cpu_memory_cb_t type and requires a valid memory_handle_t handle. The handle is only valid during the call of the callback. It is used to request information about the memory operation being issued by the processor cpu.

SIM_INTERFACE(cpu_memory_query) {
        logical_address_t (*logical_address)(
                conf_object_t *cpu, memory_handle_t *handle);
        physical_address_t (*physical_address)(
                conf_object_t *cpu, memory_handle_t *handle);
#ifndef PYWRAP
        void (*set_host_ptr)(
                conf_object_t *cpu, memory_handle_t *handle,
                void *p);
#endif
        cpu_bytes_t (*get_bytes)(conf_object_t *cpu,
                                 memory_handle_t *handle);

        void (*set_bytes)(
                conf_object_t *cpu, memory_handle_t *handle,
                cpu_bytes_t bytes);

        bool (*atomic)(
                conf_object_t *obj, memory_handle_t *handle);
        ini_type_t (*arch)(
                conf_object_t *obj, memory_handle_t *handle);
        page_crossing_info_t (*get_page_crossing_info)(
                conf_object_t *obj, memory_handle_t *handle);
        buffer_t (*get_surrounding_bytes)(
                conf_object_t *cpu, memory_handle_t *handle,
                unsigned granularity_log2);
        
};

#define CPU_MEMORY_QUERY_INTERFACE "cpu_memory_query"        

The logical_address and physical_address methods are used to get the different addresses of the memory operation.

Below, callbacks registered by the register_read_before_cb or the register_write_before_cb in the cpu_instrumentation_subscribe interface or in the cpu_cached_instruction interface are referred to as being in before context. Callbacks registered by the register_read_after_cb or the register_write_after_cb in the cpu_instrumentation_subscribe interface or in the cpu_cached_instruction interface are referred to as being in after context.

The set_host_ptr method can be used to redirect where data should be read from or written to depending on if it is a read or a write operation. The method is only useful for callbacks registered in before context. The data pointer p needs to be valid during the execution of the instruction and must point to enough space to carry out the operation. This method is not available in Python.

The get_bytes method is used to retrieve the bytes that is going to be read/written if called in a before context and is used to read out value that was read/written in after context. The value is returned as cpu_bytes_t:

typedef struct cpu_bytes {
        size_t size;
#ifndef PYWRAP
        const uint8 *data;
#endif
} cpu_bytes_t;

The member data contains the data pointer, and the member size contains tha size of the data. It is illegal to access beyond the limit. For such access, see the get_surrounding_bytes below.

The read value in before context may not be available (a device access for example) and in this case the data member will be NULL.

The set_bytes method is used to override the bytes to be read or written. The method is only valid in the before context. This method can be used instead of the set_host_ptr to change the value of the operation. The value is passed as cpu_bytes_t and the supplied data in the data member need not to be valid after the callback returns since the data is copied. The length of the data cannot be changes and must be the same as returned by the get_bytes method.

The atomic method returned true if the operation is considered atomic, false otherwise.

The arch method returns the ini_type_t of the memory operation.

Accesses that cross a page boundary are split into two subsequent accesses, one for the first page and one for the second page. The get_page_crossing_info method can be used to distinguish the different cases from each other. The returned value from the method is of type page_crossing_info_t and can be one of: Sim_Page_Crossing_None (no crossing access), Sim_Page_Crossing_First (first part of a crossing access), or Sim_Page_Crossing_Second (second part of a crossing access).

The get_surrounding_bytes method provides quick access to the data surrounding the access. The granularity_log2 specifies the size and alignment of the buffer being returned. For example using 6 for granularity_log2, will fetch 64 aligned bytes around the address of the access. Typically, the largest supported granularity_log2 size is 12, meaning a 4 KiB page. The returned value is of type buffer_t and is only valid in the cpu_memory_cb_t callback. The data can be accessed by using the buffer_t.data member in the returned value. Data can only be read up to the size of the buffer, which is stored in the buffer_t.len member. Valid memory is only returned if the access terminates in simulator cached memory. If not, the buffer_t.len will be is 0, buffer_t.data cannot be used.

Additional information can be read out with an architectural specific query interface, see x86_memory_query interface for details.

Execution Context
Threaded Context for all methods, but must be called from a callback receiving a handle of type memory_handle_t.

cpu_instrumentation_subscribe cycle