SIM_INTERFACE(x86_msr) {
void (*register_handlers)(
conf_object_t *cpu,
int64 number,
x86_msr_getter_func_t getter,
lang_void *getter_data,
x86_msr_setter_func_t setter,
lang_void *setter_data,
const char *name);
void (*unregister_handlers)(
conf_object_t *cpu,
int64 number);
x86_msr_getter_ret_t (*get)(
conf_object_t *cpu,
int64 number,
x86_msr_access_type_t type);
x86_msr_ret_t (*set)(
conf_object_t *cpu,
int64 number,
uint64 value,
x86_msr_access_type_t type);
const char *(*get_name)(
conf_object_t *cpu,
int64 number);
int64 (*get_number)(
conf_object_t *cpu,
const char *name);
attr_value_t (*get_all_valid_numbers)(
conf_object_t *cpu);
};
#define X86_MSR_INTERFACE "x86_msr"
The register_handlers function will register get and set functions that will be called every time a read or write access is made to the MSR with number msr.
typedef struct {
x86_msr_ret_t status;
uint64 value;
} x86_msr_getter_ret_t;
typedef enum {
Sim_X86_Msr_Ok = Sim_Gen_Spr_Ok, /* Access was OK */
Sim_X86_Msr_GP_Fault, /* Raise #GP fault */
Sim_X86_Msr_Not_Handled /* Pass on to next handler */
} x86_msr_ret_t;
typedef x86_msr_getter_ret_t (*x86_msr_getter_func_t)(
conf_object_t *cpu,
int64 number,
x86_msr_access_type_t type,
lang_void *user_data);
typedef x86_msr_ret_t (*x86_msr_setter_func_t)(
conf_object_t *cpu,
int64 spr_number,
uint64 value,
x86_msr_access_type_t type,
lang_void *user_data);
The type parameter in the get and set functions is one of the following, depending on where from the access originated:
typedef enum {
/* Access from a rdmsr/wrmsr instruction */
Sim_X86_Msr_Instruction_Access = Sim_Gen_Spr_Instruction_Access,
/* Access through attribute */
Sim_X86_Msr_Attribute_Access = Sim_Gen_Spr_Attribute_Access,
/* Access through int_register interface */
Sim_X86_Msr_Int_Register_Access = Sim_Gen_Spr_Int_Register_Access,
/* Access during VMX entry/exit */
Sim_X86_Msr_VMX_Access,
/* Architectural access without side effects within the CPU model, only
reads or writes the register value. However, if it is sent to the
platform as a non-inquiry access, that may cause side effects. */
Sim_X86_Msr_Architectural_Access
} x86_msr_access_type_t;
The getter function returns the status just like the setter together with the read MSR value. A getter or setter may return the Sim_X86_MSR_Not_Handled return code, in which case the access will pass through to the earlier registered handler (or the default handler if there is no earlier registered handler).
The function unregister_handlers will remove any non-default handlers for a particular MSR.
The get and set functions get and set MSRs, using both model default MSR handlers and handlers installed through this interface.
The function get_name takes number as parameter and returns the name of the MSR.
The function get_number takes the name and returns the MSR number.
The function get_all_valid_numbers returns a list of integers corresponding to all the valid MSRs, including both model default MSRs and MSRs installed through this interface.