|
int | nexusrv_trace_decoder_init (nexusrv_trace_decoder *decoder, nexusrv_msg_decoder *msg_decoder) |
| Initialize the trace decoder. More...
|
|
void | nexusrv_trace_decoder_fini (nexusrv_trace_decoder *decoder) |
| Finialize the trace decoder. More...
|
|
int32_t | nexusrv_trace_try_retire (nexusrv_trace_decoder *decoder, uint32_t icnt, unsigned *event) |
| Try to retire icnt from trace. More...
|
|
int | nexusrv_trace_sync_reset (nexusrv_trace_decoder *decoder, nexusrv_trace_sync *sync) |
| Synchronize the trace decoder. More...
|
|
int | nexusrv_trace_next_tnt (nexusrv_trace_decoder *decoder) |
| Get the next taken-not-taken. More...
|
|
void | nexusrv_trace_push_call (nexusrv_trace_decoder *decoder, uint64_t callsite) |
|
int | nexusrv_trace_pop_ret (nexusrv_trace_decoder *decoder, uint64_t *callsite) |
|
unsigned | nexusrv_trace_callstack_used (nexusrv_trace_decoder *decoder) |
|
int | nexusrv_trace_next_indirect (nexusrv_trace_decoder *decoder, nexusrv_trace_indirect *indirect) |
| Get the next indirect branch. More...
|
|
int | nexusrv_trace_next_sync (nexusrv_trace_decoder *decoder, nexusrv_trace_sync *sync) |
| Get the next Sync event. More...
|
|
int | nexusrv_trace_next_error (nexusrv_trace_decoder *decoder, nexusrv_trace_error *error) |
| Get the next Error event. More...
|
|
int | nexusrv_trace_next_stop (nexusrv_trace_decoder *decoder, nexusrv_trace_stop *stop) |
| Get the next Stop event. More...
|
|
Trace decoder usage model, events, and common error codes.
The main function is nexusrv_trace_try_retire. The user of the trace decoder is expected to be calling this function a lot. Assuming we are currently synchronized to a code block (a sequence of instructions without branch in between). The caller can try to retire the whole block by calling it, and see how many instructions can be successfully retired before hitting a event. This allows the caller to determine if there's any interrupt/exception occurred in the middle of the block, and if the Direct/Indirect branch or other expected event is pending at the end of the block. The events can then be consumed by calling the corresponding nexusrv_trace_next_x function.
- NEXUSRV_Trace_Event_None: In BTM mode, no event pending. In HTM mode, a TNT might be pending. Use nexusrv_trace_next_tnt to retrieve it
- NEXUSRV_Trace_Event_Direct: A direct branch is pending. Use nexusrv_trace_next_tnt to retrieve it
- NEXUSRV_Trace_Event_DirectSync: A direct branch+sync is pending. Use nexusrv_trace_next_tnt to retrieve the direct branch, or Use nexusrv_trace_next_sync to retrieve the sync. Note: use nexusrv_trace_next_sync will discard the direct branch.
- NEXUSRV_Trace_Event_Indirect: An indirect branch is pending Use nexusrv_trace_next_indirect to retrieve it
- NEXUSRV_Trace_Event_IndirectSync: An indirect branch+sync is pending Use nexusrv_trace_next_indirect to retrieve the indirect branch, or Use nexusrv_trace_next_sync to retrieve the sync. Note: use nexusrv_trace_next_sync will discard the indirect branch.
- NEXUSRV_Trace_Event_Sync: Use nexusrv_trace_next_sync to retrieve it
- NEXUSRV_Trace_Event_Stop: Use nexusrv_trace_next_stop to retrieve it
- NEXUSRV_Trace_Event_Error: Use nexusrv_trace_next_error to retrieve it
Error handling: For all the hard errors listed below, decoding should be aborted, and the only thing the caller can do is to free the trace decoder by calling nexusrv_trace_decoder_fini.
Trace decoder returns error codes at different levels:
- -nexus_no_mem: Failed to allocate memory. This is a hard error.
- -nexus_stream_bad_mseo, -nexus_stream_truncate, -nexus_stream_read_failed: Failed to fetch Message from trace file. It's reported by the Message decoder. This is a hard error.
- -nexus_msg_invalid, -nexus_msg_missing_field: Failed to decoder the Message from trace file. It's reported by the Message decoder. This is a hard error.
- -nexus_msg_unsupported: The Message is unsupported by the trace decoder. The caller can resolve the situation by handling Message itself. (via nexusrv_msg_decoder_next) Once the Message is consumed, it can retry the trace decoder function.
- -nexus_trace_eof: Expecting to decode more Messages, but there's no Message left. Decoding should be terminated. This is expected when the trace has been terminated, with or without a stop event.
- -nexus_trace_not_synced: Trace decoder hasn't been synced. The trace decoder must be synced once before calling try_retire and next_x(). The next_stop() and next_error() will also desync the decoder if returned success, and decoder should be synced again.
- -nexus_trace_hist_overflow, -nexus_trace_icnt_overflow: There are too many HIST or I-CNT ResourceFull Messages being consumed, and exceeds the capability of the trace decoder. This is a hard error
- nexus_trace_mismatch: This happens when the caller tries to get certain event (branch,sync...), but there's no such event pending. It typically means the caller is misusing the trace decoder.
Synchronize the trace decoder.
If the decoder is already synchronized, do nothing. Else, forward till we get the next SYNC Message, and synchronize the trace decoder using it. The I-CNT and HIST will be cleared. The Address and Timestamp will be set to the Message. To not lose track of the reason of the SYNC Message, the caller should store the sync
event when there is one.
- Parameters
-
[in] | decoder | The decoder context |
[out] | sync | The Sync event |
- Return values
-
==0 | Trace decoder is already synchronized |
>0 | Trace decoder is unsynced -> synced. The sync is set to the synchronization event indicating the address and reason. |
<0 | Error occurred, refer to common errors section |
Try to retire icnt
from trace.
This is the main function the trace encoder provides. Usually it's intended to be used by the caller who has the knowledge of the context and the instructions to execute. The caller can try to retire icnt
that represents the block of sequential instructions (without branch) and see if successful. The decoder will report the maximum I-CNT it can retire before it hits any event, and report the first in event
. If there's no event less than the range of icnt
, no event will be reported, and icnt
will be returned. To avoid overflow, icnt
will be capped at INT32_MAX
For the caller that has no knowledge of context or instructions, it can try to retire INT32_MAX I-CNT, and check the actual I-CNT retired.
Breakdown of events reported:
NEXUSRV_Trace_Event_None: None or potentially a TNT (in HTM mode).
NEXUSRV_Trace_Event_Direct: Direct branch, use nexusrv_trace_next_tnt to retrieve
NEXUSRV_Trace_Event_Trap, NEXUSRV_Trace_Event_Indirect: Indirect branch, use nexusrv_trace_next_indirect to retrieve
NEXUSRV_Trace_Event_Sync: Sync event, use nexusrv_trace_next_sync to retrieve
NEXUSRV_Trace_Event_Stop: Stop event, use nexusrv_trace_next_stop to retrieve
NEXUSRV_Trace_Event_Error: Error event, use nexusrv_trace_next_error to retrieve
- Parameters
-
[in] | decoder | The decoder context |
| icnt | I-CNT intended to retire |
[out] | event | Encountered event to report |
- Return values
-
>=0 | No error occurred, and the actual I-CNT retired |
<0 | Error occurred, refer to common errors section |