libnexus-rv
Classes | Typedefs | Enumerations | Functions
trace-decoder.h File Reference

Trace decoder usage model, events, and common error codes. More...

#include "msg-decoder.h"
#include "hist-array.h"
#include "return-stack.h"
Include dependency graph for trace-decoder.h:

Go to the source code of this file.

Classes

struct  nexusrv_trace_indirect
 NexusRV Trace Indirect Branch Event. More...
 
struct  nexusrv_trace_sync
 NexusRV Trace Sync Event. More...
 
struct  nexusrv_trace_error
 NexusRV Trace Error Event. More...
 
struct  nexusrv_trace_stop
 NexusRV Stop Event. More...
 
struct  nexusrv_trace_decoder
 NexusRV Trace decoder context. More...
 

Typedefs

typedef struct nexusrv_trace_indirect nexusrv_trace_indirect
 NexusRV Trace Indirect Branch Event. More...
 
typedef struct nexusrv_trace_sync nexusrv_trace_sync
 NexusRV Trace Sync Event.
 
typedef struct nexusrv_trace_error nexusrv_trace_error
 NexusRV Trace Error Event.
 
typedef struct nexusrv_trace_stop nexusrv_trace_stop
 NexusRV Stop Event.
 
typedef struct nexusrv_trace_decoder nexusrv_trace_decoder
 NexusRV Trace decoder context. More...
 

Enumerations

enum  nexusrv_trace_events {
  NEXUSRV_Trace_Event_None , NEXUSRV_Trace_Event_Direct , NEXUSRV_Trace_Event_DirectSync , NEXUSRV_Trace_Event_Trap ,
  NEXUSRV_Trace_Event_Indirect , NEXUSRV_Trace_Event_IndirectSync , NEXUSRV_Trace_Event_Sync , NEXUSRV_Trace_Event_Stop ,
  NEXUSRV_Trace_Event_Error
}
 NexusRV trace events.
 

Functions

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...
 

Detailed Description

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.

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:

Typedef Documentation

◆ nexusrv_trace_decoder

NexusRV Trace decoder context.

This should be initialized by nexusrv_trace_decoder_init before calling trace decoder functions, and finalized by nexusrv_trace_decoder_fini to release resources.

◆ nexusrv_trace_indirect

NexusRV Trace Indirect Branch Event.

If neither interrupt or exception is set, is a synchronous branch If both are set, it can be either but NexusRV Message doesn't report the exact type due to HW limitation

Function Documentation

◆ nexusrv_trace_decoder_fini()

void nexusrv_trace_decoder_fini ( nexusrv_trace_decoder decoder)

Finialize the trace decoder.

Memory allocated by the trace decoder will be free'ed

Parameters
[in]decoderThe decoder context

◆ nexusrv_trace_decoder_init()

int nexusrv_trace_decoder_init ( nexusrv_trace_decoder decoder,
nexusrv_msg_decoder msg_decoder 
)

Initialize the trace decoder.

The trace decoder will start using the Message decoder msg_decoder It'll not keep state of the Message decoder, so the Message decoder can still be invoked out of trace decoder context to handle non-standard Messages or custom Messages the trace decoder can't handle.

Parameters
[out]decoderThe decoder context
[in]msg_decoderThe Message decoder context
Return values
==0Success
-nexus_no_memOut of memory

◆ nexusrv_trace_next_error()

int nexusrv_trace_next_error ( nexusrv_trace_decoder decoder,
nexusrv_trace_error error 
)

Get the next Error event.

Parameters
[in]decoderThe decoder context
[out]errorThe consumed Error Event
Return values
>0Successfully got Error event
<0Error occurred, refer to common errors section

◆ nexusrv_trace_next_indirect()

int nexusrv_trace_next_indirect ( nexusrv_trace_decoder decoder,
nexusrv_trace_indirect indirect 
)

Get the next indirect branch.

Parameters
[in]decoderThe decoder context
[out]indirectThe consumed indirect branch
Return values
>0Successfully got Indirect branch
<0Error occurred, refer to common errors section

◆ nexusrv_trace_next_stop()

int nexusrv_trace_next_stop ( nexusrv_trace_decoder decoder,
nexusrv_trace_stop stop 
)

Get the next Stop event.

Parameters
[in]decoderThe decoder context
[out]stopThe consumed Stop Event
Return values
>0Successfully got Stop event
<0Error occurred, refer to common errors section

◆ nexusrv_trace_next_sync()

int nexusrv_trace_next_sync ( nexusrv_trace_decoder decoder,
nexusrv_trace_sync sync 
)

Get the next Sync event.

Parameters
[in]decoderThe decoder context
[out]syncThe consumed Sync Event
Return values
>0Successfully got Sync event
<0Error occurred, refer to common errors section

◆ nexusrv_trace_next_tnt()

int nexusrv_trace_next_tnt ( nexusrv_trace_decoder decoder)

Get the next taken-not-taken.

Parameters
[in]decoderThe decoder context
Return values
==0Branch not taken
>0Branch taken
<0Error occurred, refer to common errors section

◆ nexusrv_trace_sync_reset()

int nexusrv_trace_sync_reset ( nexusrv_trace_decoder decoder,
nexusrv_trace_sync sync 
)

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]decoderThe decoder context
[out]syncThe Sync event
Return values
==0Trace decoder is already synchronized
>0Trace decoder is unsynced -> synced. The sync is set to the synchronization event indicating the address and reason.
<0Error occurred, refer to common errors section

◆ nexusrv_trace_try_retire()

int32_t nexusrv_trace_try_retire ( nexusrv_trace_decoder decoder,
uint32_t  icnt,
unsigned *  event 
)

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]decoderThe decoder context
icntI-CNT intended to retire
[out]eventEncountered event to report
Return values
>=0No error occurred, and the actual I-CNT retired
<0Error occurred, refer to common errors section