Message ID | 20190119014347.27441-8-leo.yan@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | perf cs-etm: Add support for sample flags | expand |
On Sat, Jan 19, 2019 at 09:43:46AM +0800, Leo Yan wrote: > The exception taken and returning are typical flow for instruction jump > but it needs to be handled with exception packets. This patch is to set > sample flags for exception packet. > > Since the exception packet contains the exception number, according to > the exception number this patch makes decision for belonging to which > exception types. > > The decoder have defined different exception number for ETMv3 and ETMv4 > separately, hence this patch needs firstly decide the ETM version by > using the metadata magic number, and this patch adds helper function > cs_etm__get_magic() for easily getting magic number. > > Based on different ETM version, the exception packet contains the > exception number, according to the exception number this patch makes > decision for the exception belonging to which exception types. > > In this patch, it introduces helper function cs_etm__is_svc_instr(); > for ETMv4 CS_ETMV4_EXC_CALL covers SVC, SMC and HVC cases in the > single exception number, thus need to use cs_etm__is_svc_instr() to > decide an exception taken for system call. > > Reviewed-by: Robert Walker <robert.walker@arm.com> > Signed-off-by: Leo Yan <leo.yan@linaro.org> This is the other way around, i.e you wrote the code and then Robert reviewed it. With this change: Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org> > --- > tools/perf/util/cs-etm.c | 215 +++++++++++++++++++++++++++++++++++++++ > tools/perf/util/cs-etm.h | 44 ++++++++ > 2 files changed, 259 insertions(+) > > diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c > index e89989fe0a5c..052805de6513 100644 > --- a/tools/perf/util/cs-etm.c > +++ b/tools/perf/util/cs-etm.c > @@ -97,6 +97,20 @@ static u32 cs_etm__get_v7_protocol_version(u32 etmidr) > return CS_ETM_PROTO_ETMV3; > } > > +static int cs_etm__get_magic(u8 trace_chan_id, u64 *magic) > +{ > + struct int_node *inode; > + u64 *metadata; > + > + inode = intlist__find(traceid_list, trace_chan_id); > + if (!inode) > + return -EINVAL; > + > + metadata = inode->priv; > + *magic = metadata[CS_ETM_MAGIC]; > + return 0; > +} > + > int cs_etm__get_cpu(u8 trace_chan_id, int *cpu) > { > struct int_node *inode; > @@ -1122,10 +1136,174 @@ static int cs_etm__end_block(struct cs_etm_queue *etmq) > return 0; > } > > +static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, > + struct cs_etm_packet *packet, > + u64 end_addr) > +{ > + u16 instr16; > + u32 instr32; > + u64 addr; > + > + switch (packet->isa) { > + case CS_ETM_ISA_T32: > + /* > + * The SVC of T32 is defined in ARM DDI 0487D.a, F5.1.247: > + * > + * b'15 b'8 > + * +-----------------+--------+ > + * | 1 1 0 1 1 1 1 1 | imm8 | > + * +-----------------+--------+ > + * > + * According to the specifiction, it only defines SVC for T32 > + * with 16 bits instruction and has no definition for 32bits; > + * so below only read 2 bytes as instruction size for T32. > + */ > + addr = end_addr - 2; > + cs_etm__mem_access(etmq, addr, sizeof(instr16), (u8 *)&instr16); > + if ((instr16 & 0xFF00) == 0xDF00) > + return true; > + > + break; > + case CS_ETM_ISA_A32: > + /* > + * The SVC of A32 is defined in ARM DDI 0487D.a, F5.1.247: > + * > + * b'31 b'28 b'27 b'24 > + * +---------+---------+-------------------------+ > + * | !1111 | 1 1 1 1 | imm24 | > + * +---------+---------+-------------------------+ > + */ > + addr = end_addr - 4; > + cs_etm__mem_access(etmq, addr, sizeof(instr32), (u8 *)&instr32); > + if ((instr32 & 0x0F000000) == 0x0F000000 && > + (instr32 & 0xF0000000) != 0xF0000000) > + return true; > + > + break; > + case CS_ETM_ISA_A64: > + /* > + * The SVC of A64 is defined in ARM DDI 0487D.a, C6.2.294: > + * > + * b'31 b'21 b'4 b'0 > + * +-----------------------+---------+-----------+ > + * | 1 1 0 1 0 1 0 0 0 0 0 | imm16 | 0 0 0 0 1 | > + * +-----------------------+---------+-----------+ > + */ > + addr = end_addr - 4; > + cs_etm__mem_access(etmq, addr, sizeof(instr32), (u8 *)&instr32); > + if ((instr32 & 0xFFE0001F) == 0xd4000001) > + return true; > + > + break; > + case CS_ETM_ISA_UNKNOWN: > + default: > + break; > + } > + > + return false; > +} > + > +static bool cs_etm__is_syscall(struct cs_etm_queue *etmq, u64 magic) > +{ > + struct cs_etm_packet *packet = etmq->packet; > + struct cs_etm_packet *prev_packet = etmq->prev_packet; > + > + if (magic == __perf_cs_etmv3_magic) > + if (packet->exception_number == CS_ETMV3_EXC_SVC) > + return true; > + > + /* > + * ETMv4 exception type CS_ETMV4_EXC_CALL covers SVC, SMC and > + * HVC cases; need to check if it's SVC instruction based on > + * packet address. > + */ > + if (magic == __perf_cs_etmv4_magic) { > + if (packet->exception_number == CS_ETMV4_EXC_CALL && > + cs_etm__is_svc_instr(etmq, prev_packet, > + prev_packet->end_addr)) > + return true; > + } > + > + return false; > +} > + > +static bool cs_etm__is_async_exception(struct cs_etm_queue *etmq, u64 magic) > +{ > + struct cs_etm_packet *packet = etmq->packet; > + > + if (magic == __perf_cs_etmv3_magic) > + if (packet->exception_number == CS_ETMV3_EXC_DEBUG_HALT || > + packet->exception_number == CS_ETMV3_EXC_ASYNC_DATA_ABORT || > + packet->exception_number == CS_ETMV3_EXC_PE_RESET || > + packet->exception_number == CS_ETMV3_EXC_IRQ || > + packet->exception_number == CS_ETMV3_EXC_FIQ) > + return true; > + > + if (magic == __perf_cs_etmv4_magic) > + if (packet->exception_number == CS_ETMV4_EXC_RESET || > + packet->exception_number == CS_ETMV4_EXC_DEBUG_HALT || > + packet->exception_number == CS_ETMV4_EXC_SYSTEM_ERROR || > + packet->exception_number == CS_ETMV4_EXC_INST_DEBUG || > + packet->exception_number == CS_ETMV4_EXC_DATA_DEBUG || > + packet->exception_number == CS_ETMV4_EXC_IRQ || > + packet->exception_number == CS_ETMV4_EXC_FIQ) > + return true; > + > + return false; > +} > + > +static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq, u64 magic) > +{ > + struct cs_etm_packet *packet = etmq->packet; > + struct cs_etm_packet *prev_packet = etmq->prev_packet; > + > + if (magic == __perf_cs_etmv3_magic) > + if (packet->exception_number == CS_ETMV3_EXC_SMC || > + packet->exception_number == CS_ETMV3_EXC_HYP || > + packet->exception_number == CS_ETMV3_EXC_JAZELLE_THUMBEE || > + packet->exception_number == CS_ETMV3_EXC_UNDEFINED_INSTR || > + packet->exception_number == CS_ETMV3_EXC_PREFETCH_ABORT || > + packet->exception_number == CS_ETMV3_EXC_DATA_FAULT || > + packet->exception_number == CS_ETMV3_EXC_GENERIC) > + return true; > + > + if (magic == __perf_cs_etmv4_magic) { > + if (packet->exception_number == CS_ETMV4_EXC_TRAP || > + packet->exception_number == CS_ETMV4_EXC_ALIGNMENT || > + packet->exception_number == CS_ETMV4_EXC_INST_FAULT || > + packet->exception_number == CS_ETMV4_EXC_DATA_FAULT) > + return true; > + > + /* > + * For CS_ETMV4_EXC_CALL, except SVC other instructions > + * (SMC, HVC) are taken as sync exceptions. > + */ > + if (packet->exception_number == CS_ETMV4_EXC_CALL && > + !cs_etm__is_svc_instr(etmq, prev_packet, > + prev_packet->end_addr)) > + return true; > + > + /* > + * ETMv4 has 5 bits for exception number; if the numbers > + * are in the range ( CS_ETMV4_EXC_FIQ, CS_ETMV4_EXC_END ] > + * they are implementation defined exceptions. > + * > + * For this case, simply take it as sync exception. > + */ > + if (packet->exception_number > CS_ETMV4_EXC_FIQ && > + packet->exception_number <= CS_ETMV4_EXC_END) > + return true; > + } > + > + return false; > +} > + > static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq) > { > struct cs_etm_packet *packet = etmq->packet; > struct cs_etm_packet *prev_packet = etmq->prev_packet; > + u64 magic; > + int ret; > > switch (packet->sample_type) { > case CS_ETM_RANGE: > @@ -1206,6 +1384,43 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq) > PERF_IP_FLAG_TRACE_END; > break; > case CS_ETM_EXCEPTION: > + ret = cs_etm__get_magic(packet->trace_chan_id, &magic); > + if (ret) > + return ret; > + > + /* The exception is for system call. */ > + if (cs_etm__is_syscall(etmq, magic)) > + packet->flags = PERF_IP_FLAG_BRANCH | > + PERF_IP_FLAG_CALL | > + PERF_IP_FLAG_SYSCALLRET; > + /* > + * The exceptions are triggered by external signals from bus, > + * interrupt controller, debug module, PE reset or halt. > + */ > + else if (cs_etm__is_async_exception(etmq, magic)) > + packet->flags = PERF_IP_FLAG_BRANCH | > + PERF_IP_FLAG_CALL | > + PERF_IP_FLAG_ASYNC | > + PERF_IP_FLAG_INTERRUPT; > + /* > + * Otherwise, exception is caused by trap, instruction & > + * data fault, or alignment errors. > + */ > + else if (cs_etm__is_sync_exception(etmq, magic)) > + packet->flags = PERF_IP_FLAG_BRANCH | > + PERF_IP_FLAG_CALL | > + PERF_IP_FLAG_INTERRUPT; > + > + /* > + * When the exception packet is inserted, since exception > + * packet is not used standalone for generating samples > + * and it's affiliation to the previous instruction range > + * packet; so set previous range packet flags to tell perf > + * it is an exception taken branch. > + */ > + if (prev_packet->sample_type == CS_ETM_RANGE) > + prev_packet->flags = packet->flags; > + break; > case CS_ETM_EXCEPTION_RET: > case CS_ETM_EMPTY: > default: > diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h > index 5d70d10f3907..7bd16ea8a62d 100644 > --- a/tools/perf/util/cs-etm.h > +++ b/tools/perf/util/cs-etm.h > @@ -53,6 +53,50 @@ enum { > CS_ETMV4_PRIV_MAX, > }; > > +/* > + * ETMv3 exception encoding number: > + * See Embedded Trace Macrocell spcification (ARM IHI 0014Q) > + * table 7-12 Encoding of Exception[3:0] for non-ARMv7-M processors. > + */ > +enum { > + CS_ETMV3_EXC_NONE = 0, > + CS_ETMV3_EXC_DEBUG_HALT = 1, > + CS_ETMV3_EXC_SMC = 2, > + CS_ETMV3_EXC_HYP = 3, > + CS_ETMV3_EXC_ASYNC_DATA_ABORT = 4, > + CS_ETMV3_EXC_JAZELLE_THUMBEE = 5, > + CS_ETMV3_EXC_PE_RESET = 8, > + CS_ETMV3_EXC_UNDEFINED_INSTR = 9, > + CS_ETMV3_EXC_SVC = 10, > + CS_ETMV3_EXC_PREFETCH_ABORT = 11, > + CS_ETMV3_EXC_DATA_FAULT = 12, > + CS_ETMV3_EXC_GENERIC = 13, > + CS_ETMV3_EXC_IRQ = 14, > + CS_ETMV3_EXC_FIQ = 15, > +}; > + > +/* > + * ETMv4 exception encoding number: > + * See ARM Embedded Trace Macrocell Architecture Specification (ARM IHI 0064D) > + * table 6-12 Possible values for the TYPE field in an Exception instruction > + * trace packet, for ARMv7-A/R and ARMv8-A/R PEs. > + */ > +enum { > + CS_ETMV4_EXC_RESET = 0, > + CS_ETMV4_EXC_DEBUG_HALT = 1, > + CS_ETMV4_EXC_CALL = 2, > + CS_ETMV4_EXC_TRAP = 3, > + CS_ETMV4_EXC_SYSTEM_ERROR = 4, > + CS_ETMV4_EXC_INST_DEBUG = 6, > + CS_ETMV4_EXC_DATA_DEBUG = 7, > + CS_ETMV4_EXC_ALIGNMENT = 10, > + CS_ETMV4_EXC_INST_FAULT = 11, > + CS_ETMV4_EXC_DATA_FAULT = 12, > + CS_ETMV4_EXC_IRQ = 14, > + CS_ETMV4_EXC_FIQ = 15, > + CS_ETMV4_EXC_END = 31, > +}; > + > /* RB tree for quick conversion between traceID and metadata pointers */ > struct intlist *traceid_list; > > -- > 2.17.1 >
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index e89989fe0a5c..052805de6513 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -97,6 +97,20 @@ static u32 cs_etm__get_v7_protocol_version(u32 etmidr) return CS_ETM_PROTO_ETMV3; } +static int cs_etm__get_magic(u8 trace_chan_id, u64 *magic) +{ + struct int_node *inode; + u64 *metadata; + + inode = intlist__find(traceid_list, trace_chan_id); + if (!inode) + return -EINVAL; + + metadata = inode->priv; + *magic = metadata[CS_ETM_MAGIC]; + return 0; +} + int cs_etm__get_cpu(u8 trace_chan_id, int *cpu) { struct int_node *inode; @@ -1122,10 +1136,174 @@ static int cs_etm__end_block(struct cs_etm_queue *etmq) return 0; } +static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, + struct cs_etm_packet *packet, + u64 end_addr) +{ + u16 instr16; + u32 instr32; + u64 addr; + + switch (packet->isa) { + case CS_ETM_ISA_T32: + /* + * The SVC of T32 is defined in ARM DDI 0487D.a, F5.1.247: + * + * b'15 b'8 + * +-----------------+--------+ + * | 1 1 0 1 1 1 1 1 | imm8 | + * +-----------------+--------+ + * + * According to the specifiction, it only defines SVC for T32 + * with 16 bits instruction and has no definition for 32bits; + * so below only read 2 bytes as instruction size for T32. + */ + addr = end_addr - 2; + cs_etm__mem_access(etmq, addr, sizeof(instr16), (u8 *)&instr16); + if ((instr16 & 0xFF00) == 0xDF00) + return true; + + break; + case CS_ETM_ISA_A32: + /* + * The SVC of A32 is defined in ARM DDI 0487D.a, F5.1.247: + * + * b'31 b'28 b'27 b'24 + * +---------+---------+-------------------------+ + * | !1111 | 1 1 1 1 | imm24 | + * +---------+---------+-------------------------+ + */ + addr = end_addr - 4; + cs_etm__mem_access(etmq, addr, sizeof(instr32), (u8 *)&instr32); + if ((instr32 & 0x0F000000) == 0x0F000000 && + (instr32 & 0xF0000000) != 0xF0000000) + return true; + + break; + case CS_ETM_ISA_A64: + /* + * The SVC of A64 is defined in ARM DDI 0487D.a, C6.2.294: + * + * b'31 b'21 b'4 b'0 + * +-----------------------+---------+-----------+ + * | 1 1 0 1 0 1 0 0 0 0 0 | imm16 | 0 0 0 0 1 | + * +-----------------------+---------+-----------+ + */ + addr = end_addr - 4; + cs_etm__mem_access(etmq, addr, sizeof(instr32), (u8 *)&instr32); + if ((instr32 & 0xFFE0001F) == 0xd4000001) + return true; + + break; + case CS_ETM_ISA_UNKNOWN: + default: + break; + } + + return false; +} + +static bool cs_etm__is_syscall(struct cs_etm_queue *etmq, u64 magic) +{ + struct cs_etm_packet *packet = etmq->packet; + struct cs_etm_packet *prev_packet = etmq->prev_packet; + + if (magic == __perf_cs_etmv3_magic) + if (packet->exception_number == CS_ETMV3_EXC_SVC) + return true; + + /* + * ETMv4 exception type CS_ETMV4_EXC_CALL covers SVC, SMC and + * HVC cases; need to check if it's SVC instruction based on + * packet address. + */ + if (magic == __perf_cs_etmv4_magic) { + if (packet->exception_number == CS_ETMV4_EXC_CALL && + cs_etm__is_svc_instr(etmq, prev_packet, + prev_packet->end_addr)) + return true; + } + + return false; +} + +static bool cs_etm__is_async_exception(struct cs_etm_queue *etmq, u64 magic) +{ + struct cs_etm_packet *packet = etmq->packet; + + if (magic == __perf_cs_etmv3_magic) + if (packet->exception_number == CS_ETMV3_EXC_DEBUG_HALT || + packet->exception_number == CS_ETMV3_EXC_ASYNC_DATA_ABORT || + packet->exception_number == CS_ETMV3_EXC_PE_RESET || + packet->exception_number == CS_ETMV3_EXC_IRQ || + packet->exception_number == CS_ETMV3_EXC_FIQ) + return true; + + if (magic == __perf_cs_etmv4_magic) + if (packet->exception_number == CS_ETMV4_EXC_RESET || + packet->exception_number == CS_ETMV4_EXC_DEBUG_HALT || + packet->exception_number == CS_ETMV4_EXC_SYSTEM_ERROR || + packet->exception_number == CS_ETMV4_EXC_INST_DEBUG || + packet->exception_number == CS_ETMV4_EXC_DATA_DEBUG || + packet->exception_number == CS_ETMV4_EXC_IRQ || + packet->exception_number == CS_ETMV4_EXC_FIQ) + return true; + + return false; +} + +static bool cs_etm__is_sync_exception(struct cs_etm_queue *etmq, u64 magic) +{ + struct cs_etm_packet *packet = etmq->packet; + struct cs_etm_packet *prev_packet = etmq->prev_packet; + + if (magic == __perf_cs_etmv3_magic) + if (packet->exception_number == CS_ETMV3_EXC_SMC || + packet->exception_number == CS_ETMV3_EXC_HYP || + packet->exception_number == CS_ETMV3_EXC_JAZELLE_THUMBEE || + packet->exception_number == CS_ETMV3_EXC_UNDEFINED_INSTR || + packet->exception_number == CS_ETMV3_EXC_PREFETCH_ABORT || + packet->exception_number == CS_ETMV3_EXC_DATA_FAULT || + packet->exception_number == CS_ETMV3_EXC_GENERIC) + return true; + + if (magic == __perf_cs_etmv4_magic) { + if (packet->exception_number == CS_ETMV4_EXC_TRAP || + packet->exception_number == CS_ETMV4_EXC_ALIGNMENT || + packet->exception_number == CS_ETMV4_EXC_INST_FAULT || + packet->exception_number == CS_ETMV4_EXC_DATA_FAULT) + return true; + + /* + * For CS_ETMV4_EXC_CALL, except SVC other instructions + * (SMC, HVC) are taken as sync exceptions. + */ + if (packet->exception_number == CS_ETMV4_EXC_CALL && + !cs_etm__is_svc_instr(etmq, prev_packet, + prev_packet->end_addr)) + return true; + + /* + * ETMv4 has 5 bits for exception number; if the numbers + * are in the range ( CS_ETMV4_EXC_FIQ, CS_ETMV4_EXC_END ] + * they are implementation defined exceptions. + * + * For this case, simply take it as sync exception. + */ + if (packet->exception_number > CS_ETMV4_EXC_FIQ && + packet->exception_number <= CS_ETMV4_EXC_END) + return true; + } + + return false; +} + static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq) { struct cs_etm_packet *packet = etmq->packet; struct cs_etm_packet *prev_packet = etmq->prev_packet; + u64 magic; + int ret; switch (packet->sample_type) { case CS_ETM_RANGE: @@ -1206,6 +1384,43 @@ static int cs_etm__set_sample_flags(struct cs_etm_queue *etmq) PERF_IP_FLAG_TRACE_END; break; case CS_ETM_EXCEPTION: + ret = cs_etm__get_magic(packet->trace_chan_id, &magic); + if (ret) + return ret; + + /* The exception is for system call. */ + if (cs_etm__is_syscall(etmq, magic)) + packet->flags = PERF_IP_FLAG_BRANCH | + PERF_IP_FLAG_CALL | + PERF_IP_FLAG_SYSCALLRET; + /* + * The exceptions are triggered by external signals from bus, + * interrupt controller, debug module, PE reset or halt. + */ + else if (cs_etm__is_async_exception(etmq, magic)) + packet->flags = PERF_IP_FLAG_BRANCH | + PERF_IP_FLAG_CALL | + PERF_IP_FLAG_ASYNC | + PERF_IP_FLAG_INTERRUPT; + /* + * Otherwise, exception is caused by trap, instruction & + * data fault, or alignment errors. + */ + else if (cs_etm__is_sync_exception(etmq, magic)) + packet->flags = PERF_IP_FLAG_BRANCH | + PERF_IP_FLAG_CALL | + PERF_IP_FLAG_INTERRUPT; + + /* + * When the exception packet is inserted, since exception + * packet is not used standalone for generating samples + * and it's affiliation to the previous instruction range + * packet; so set previous range packet flags to tell perf + * it is an exception taken branch. + */ + if (prev_packet->sample_type == CS_ETM_RANGE) + prev_packet->flags = packet->flags; + break; case CS_ETM_EXCEPTION_RET: case CS_ETM_EMPTY: default: diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 5d70d10f3907..7bd16ea8a62d 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -53,6 +53,50 @@ enum { CS_ETMV4_PRIV_MAX, }; +/* + * ETMv3 exception encoding number: + * See Embedded Trace Macrocell spcification (ARM IHI 0014Q) + * table 7-12 Encoding of Exception[3:0] for non-ARMv7-M processors. + */ +enum { + CS_ETMV3_EXC_NONE = 0, + CS_ETMV3_EXC_DEBUG_HALT = 1, + CS_ETMV3_EXC_SMC = 2, + CS_ETMV3_EXC_HYP = 3, + CS_ETMV3_EXC_ASYNC_DATA_ABORT = 4, + CS_ETMV3_EXC_JAZELLE_THUMBEE = 5, + CS_ETMV3_EXC_PE_RESET = 8, + CS_ETMV3_EXC_UNDEFINED_INSTR = 9, + CS_ETMV3_EXC_SVC = 10, + CS_ETMV3_EXC_PREFETCH_ABORT = 11, + CS_ETMV3_EXC_DATA_FAULT = 12, + CS_ETMV3_EXC_GENERIC = 13, + CS_ETMV3_EXC_IRQ = 14, + CS_ETMV3_EXC_FIQ = 15, +}; + +/* + * ETMv4 exception encoding number: + * See ARM Embedded Trace Macrocell Architecture Specification (ARM IHI 0064D) + * table 6-12 Possible values for the TYPE field in an Exception instruction + * trace packet, for ARMv7-A/R and ARMv8-A/R PEs. + */ +enum { + CS_ETMV4_EXC_RESET = 0, + CS_ETMV4_EXC_DEBUG_HALT = 1, + CS_ETMV4_EXC_CALL = 2, + CS_ETMV4_EXC_TRAP = 3, + CS_ETMV4_EXC_SYSTEM_ERROR = 4, + CS_ETMV4_EXC_INST_DEBUG = 6, + CS_ETMV4_EXC_DATA_DEBUG = 7, + CS_ETMV4_EXC_ALIGNMENT = 10, + CS_ETMV4_EXC_INST_FAULT = 11, + CS_ETMV4_EXC_DATA_FAULT = 12, + CS_ETMV4_EXC_IRQ = 14, + CS_ETMV4_EXC_FIQ = 15, + CS_ETMV4_EXC_END = 31, +}; + /* RB tree for quick conversion between traceID and metadata pointers */ struct intlist *traceid_list;