notify_mode_change registers a callback function that will be called when processor cpu changes processor mode. The callback function will be called with the processor that changed mode cpu, the mode previous to the change old_mode and the mode after the change new_mode.
notify_exception registers a callback function that will be called when processor cpu takes an exception with exception number exc_num. The callback function cb will be called with the processor cpu causing the exception and exception number exc_num of that exception.
notify_control_reg registers a callback function that will be called when a control register, with register number reg_num, in processor cpu is updated. The callback function cb will be called with the processor cpu, register number reg_num and the written register value (see Core_Control_Register_Write documentation for more details) as arguments. The register number for a certain register can be retrieved with the get_register_number function.
notify_control_reg_read registers a callback function that will be called when a control register, with register number reg_num, in processor cpu is read. The callback function cb will be called with the processor cpu and register number reg_num as arguments. The register number for a certain register can be retrieved with the get_register_number function.
notify_exec_breakpoint, notify_read_breakpoint and notify_write_breakpoint plant breakpoints of length len for processor cpu on address. The breakpoint is of type execution, read, write respectively. The virt argument specifies if address is a virtual or physical address. The callback function cb is called when the breakpoint is hit. The arguments of the callback functions are the processor that the breakpoint hit on cpu and the address (virtual or physical depending on what the breakpoint was registered as) that was hit. Callbacks functions for notify_read_breakpoint and notify_write_breakpoint also gets the access size len of the read or write. The callback function for notify_write_breakpoint additionally has the previous value old_val at the address written and the new value new_val that is being written passed as arguments. Reading the actual memory from the callback will result in reading the new value that has been written as the callback is called after the write is done. On x86 virtual breakpoints use linear addresses (as opposed to logical addresses).
For all functions, the tracker argument should be the tracker calling this interface. This makes it possible for a hypervisor tracker to handle guests differently.
All methods that register a notification callback take data as an argument which will be passed on to callback function. These methods return a cancel ID to be used with the cancel method to cancel the callback. A returned value of 0 means that an error occurred and no callback was registered, in which case the caller is responsible for freeing the callback data.
cancel cancels the callback function with ID cancel_id and will free the callback data associated with the notification. This ID will have been returned from the function that registered the callback.
typedef enum { OSA_Read_One_Byte = 1, OSA_Read_Two_Byte = 2, OSA_Read_Four_Byte = 4, OSA_Read_Eight_Byte = 8, } osa_read_len_t; SIM_INTERFACE(osa_machine_notification) { cancel_id_t (*notify_mode_change)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, void (*cb)(cbdata_call_t data, conf_object_t *cpu, processor_mode_t old_mode, processor_mode_t new_mode), cbdata_register_t data); cancel_id_t (*notify_exception)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, int exc_num, void (*cb)(cbdata_call_t data, conf_object_t *cpu, int exc_num), cbdata_register_t data); cancel_id_t (*notify_control_reg)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, int reg_num, void (*cb)(cbdata_call_t data, conf_object_t *cpu, int reg_num, uint64 value), cbdata_register_t data); cancel_id_t (*notify_exec_breakpoint)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, uint64 address, uint64 len, bool virt, void (*cb)(cbdata_call_t data, conf_object_t *cpu, uint64 address), cbdata_register_t data); cancel_id_t (*notify_read_breakpoint)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, uint64 address, unsigned len, bool virt, void (*cb)(cbdata_call_t data, conf_object_t *NOTNULL cpu, uint64 address, unsigned len), cbdata_register_t data); cancel_id_t (*notify_write_breakpoint)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, uint64 address, unsigned len, bool virt, void (*cb)(cbdata_call_t data, conf_object_t *NOTNULL cpu, uint64 address, unsigned len, uint64 old_val, uint64 new_val), cbdata_register_t data); void (*cancel)(conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, cancel_id_t cancel_id); cancel_id_t (*notify_control_reg_read)( conf_object_t *NOTNULL obj, conf_object_t *NOTNULL tracker, conf_object_t *NOTNULL cpu, int reg_num, void (*cb)(cbdata_call_t data, conf_object_t *cpu, int reg_num), cbdata_register_t data); }; #define OSA_MACHINE_NOTIFICATION_INTERFACE "osa_machine_notification"