/**
* @file daemon/opd_ibs.h
* AMD Family10h Instruction Based Sampling (IBS) handling.
*
* @remark Copyright 2008-2010 OProfile authors
* @remark Read the file COPYING
*
* @author Jason Yeh <jason.yeh@amd.com>
* @author Paul Drongowski <paul.drongowski@amd.com>
* @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
* Copyright (c) 2008 Advanced Micro Devices, Inc.
*/
#ifndef OPD_IBS_H
#define OPD_IBS_H
#include <stdint.h>
#include "opd_ibs_macro.h"
struct transient;
struct opd_event;
/**
* IBS information is processed in two steps. The first step decodes
* hardware-level IBS information and saves it in decoded form. The
* second step translates the decoded IBS information into IBS derived
* events. IBS information is tallied and is reported as derived events.
*/
struct ibs_sample {
struct ibs_fetch_sample * fetch;
struct ibs_op_sample * op;
};
/**
* This struct represents the hardware-level IBS fetch information.
* Each field corresponds to a model-specific register (MSR.) See the
* BIOS and Kernel Developer's Guide for AMD Model Family 10h Processors
* for further details.
*/
struct ibs_fetch_sample {
unsigned long int rip;
/* MSRC001_1030 IBS Fetch Control Register */
unsigned int ibs_fetch_ctl_low;
unsigned int ibs_fetch_ctl_high;
/* MSRC001_1031 IBS Fetch Linear Address Register */
unsigned int ibs_fetch_lin_addr_low;
unsigned int ibs_fetch_lin_addr_high;
/* MSRC001_1032 IBS Fetch Physical Address Register */
unsigned int ibs_fetch_phys_addr_low;
unsigned int ibs_fetch_phys_addr_high;
unsigned int dummy_event;
};
/** This struct represents the hardware-level IBS op information. */
struct ibs_op_sample {
unsigned long int rip;
/* MSRC001_1034 IBS Op Logical Address Register */
unsigned int ibs_op_lin_addr_low;
unsigned int ibs_op_lin_addr_high;
/* MSRC001_1035 IBS Op Data Register */
unsigned int ibs_op_data1_low;
unsigned int ibs_op_data1_high;
/* MSRC001_1036 IBS Op Data 2 Register */
unsigned int ibs_op_data2_low;
unsigned int ibs_op_data2_high;
/* MSRC001_1037 IBS Op Data 3 Register */
unsigned int ibs_op_data3_low;
unsigned int ibs_op_data3_high;
/* MSRC001_1038 IBS DC Linear Address */
unsigned int ibs_op_ldst_linaddr_low;
unsigned int ibs_op_ldst_linaddr_high;
/* MSRC001_1039 IBS DC Physical Address */
unsigned int ibs_op_phys_addr_low;
unsigned int ibs_op_phys_addr_high;
/* MSRC001_103B IBS Branch Target Address */
unsigned long ibs_op_brtgt_addr;
};
/**
* Handle an IBS fetch sample escape code sequence. An IBS fetch sample
* is represented as an escape code sequence. (See the comment for the
* function code_ibs_op_sample() for the sequence of entries in the event
* buffer.) When this function is called, the ESCAPE_CODE and IBS_FETCH_CODE
* have already been removed from the event buffer. Thus, 7 more event buffer
* entries are needed in order to process a complete IBS fetch sample.
*/
extern void code_ibs_fetch_sample(struct transient * trans);
/**
* Handle an IBS op sample escape code sequence. An IBS op sample
* is represented as an escape code sequence:
*
* IBS fetch IBS op
* --------------- ----------------
* ESCAPE_CODE ESCAPE_CODE
* IBS_FETCH_CODE IBS_OP_CODE
* Offset Offset
* IbsFetchLinAd low IbsOpRip low <-- Logical (virtual) RIP
* IbsFetchLinAd high IbsOpRip high <-- Logical (virtual) RIP
* IbsFetchCtl low IbsOpData low
* IbsFetchCtl high IbsOpData high
* IbsFetchPhysAd low IbsOpData2 low
* IbsFetchPhysAd high IbsOpData2 high
* IbsOpData3 low
* IbsOpData3 high
* IbsDcLinAd low
* IbsDcLinAd high
* IbsDcPhysAd low
* IbsDcPhysAd high
*
* When this function is called, the ESCAPE_CODE and IBS_OP_CODE have
* already been removed from the event buffer. Thus, 13 more event buffer
* entries are needed to process a complete IBS op sample.
*
* The IbsFetchLinAd and IbsOpRip are the linear (virtual) addresses
* that were generated by the IBS hardware. These addresses are mapped
* into the offset.
*/
extern void code_ibs_op_sample(struct transient * trans);
/** Log the specified IBS derived event. */
extern void opd_log_ibs_event(unsigned int event, struct transient * trans);
/** Log the specified IBS cycle count. */
extern void opd_log_ibs_count(unsigned int event, struct transient * trans, unsigned int count);
#endif /*OPD_IBS_H*/