PMU インタフェース API
Cortex-A CPUに搭載されているPMUに簡単にアクセスするための API です。
ソリューションプロパティ
PMUインタフェース APIを使用するには、ソリューションプロパティで "SOLID_USE_PMU" を "1" に設定してください。
サポートする PMU イベント
サポートされているPMUイベントはSoCの実装によって異なることがありますので、 詳細はSoCのマニュアル、または、各 Cortex-A 実装のTRM (Technical Reference Manual)を 参照してください。
PMUイベントのうちの代表的なものは、solid_pmu.h
から include している pmu_events.h
内で
定義されている以下のものがあります。
#define SW_INCR 0x00
#define L1I_CACHE_REFILL 0x01
#define L1I_TLB_REFILL 0x02
#define L1D_CACHE_REFILL 0x03
#define L1D_CACHE 0x04
#define L1D_TLB_REFILL 0x05
#define EXC_LOAD 0x06
#define LD_RETIRED 0x06
#define EXC_STORE 0x07
#define ST_RETIRED 0x07
#define INST_RETIRED 0x08
#define EXC_TAKEN 0x09
#define EXC_RETURN 0x0A
#define CID_WRITE_RETIRED 0x0B
#define EXC_PC 0x0C
#define PC_WRITE_RETIRED 0x0C
#define EXC_IMBR 0x0D
#define BR_IMMED_RETIRED 0x0D
#define EXC_PROCRTN 0x0E
#define BR_RETURN_RETIRED 0x0E
#define EXC_UNALIGN 0x0F
#define UNALIGNED_LDST_RETIRED 0x0F
#define BR_MIS_PRED 0x10
#define CPU_CYCLES 0x11
#define BR_PRED 0x12
#define MEM_ACCESS 0x13
#define L1I_CACHE 0x14
#define L1D_CACHE_WB 0x15
#define L2D_CACHE 0x16
#define L2D_CACHE_REFILL 0x17
#define L2D_CACHE_WB 0x18
#define BUS_ACCESS 0x19
#define MEMORY_ERROR 0x1A
#define INST_SPEC 0x1B
#define TTBR_WRITE_RETIRED 0x1C
#define BUS_CYCLES 0x1D
#define CHAIN 0x1E
#define L1D_CACHE_ALLOCATE 0x1F
#define L2D_CACHE_ALLOCATE 0x20
#define BR_RETIRED 0x21
#define BR_MIS_PRED_RETIRED 0x22
#define STALL_FRONTEND 0x23
#define STALL_BACKEND 0x24
#define L1D_TLB 0x25
#define L1I_TLB 0x26
#define L2I_CACHE 0x27
#define L2I_CACHE_REFILL 0x28
#define L3D_CACHE_ALLOCATE 0x29
#define L3D_CACHE_REFILL 0x2A
#define L3D_CACHE 0x2B
#define L3D_CACHE_WB 0x2C
#define L2D_TLB_REFILL 0x2D
#define L2I_TLB_REFILL 0x2E
#define L2D_TLB 0x2F
#define L2I_TLB 0x30
#define L1D_CACHE_LD 0x40
#define L1D_CACHE_ST 0x41
#define L1D_CACHE_REFILL_LD 0x42
#define L1D_CACHE_REFILL_ST 0x43
#define L1D_CACHE_WB_VICTIM 0x46
#define L1D_CACHE_WB_CLEAN 0x47
#define L1D_CACHE_INVAL 0x48
#define L1D_TLB_REFILL_LD 0x4C
#define L1D_TLB_REFILL_ST 0x4D
#define L2D_CACHE_LD 0x50
#define L2D_CACHE_ST 0x51
#define L2D_CACHE_REFILL_LD 0x52
#define L2D_CACHE_REFILL_ST 0x53
#define L2D_CACHE_WB_VICTIM 0x56
#define L2D_CACHE_WB_CLEAN 0x57
#define L2D_CACHE_INVAL 0x58
#define BUS_ACCESS_LD 0x60
#define BUS_ACCESS_ST 0x61
#define BUS_ACCESS_SHARED 0x62
#define BUS_ACCESS_NOT_SHARED 0x63
#define BUS_ACCESS_NORMAL 0x64
#define BUS_ACCESS_PERIPH 0x65
#define MEM_ACCESS_LD 0x66
#define MEM_ACCESS_ST 0x67
#define UNALIGNED_LD_SPEC 0x68
#define UNALIGNED_ST_SPEC 0x69
#define UNALIGNED_LDST_SPEC 0x6A
#define LDREX_SPEC 0x6C
#define STREX_PASS_SPEC 0x6D
#define STREX_FAIL_SPEC 0x6E
#define LD_SPEC 0x70
#define ST_SPEC 0x71
#define LDST_SPEC 0x72
#define DP_SPEC 0x73
#define ASE_SPEC 0x74
#define VFP_SPEC 0x75
#define PC_WRITE_SPEC 0x76
#define BR_IMMED_SPEC 0x78
#define BR_RETURN_SPEC 0x79
#define BR_INDIRECT_SPEC 0x7A
#define ISB_SPEC 0x7C
#define DSB_SPEC 0x7D
#define DMB_SPEC 0x7E
#define EXC_IRQ 0x86
#define EXC_FIQ 0x87
API
これらの API は、APIを呼び出したCPUコアの PMU に対しての操作になります。
APIを使用するコードでは solid_pmu.h
をインクルードしてください。
#include "solid_pmu.h"
PMU機能の初期状態は、シングルカウンタ計測モードです。以下の定義中、(S)はシングルカウンタ計測モードで利用可能、(M)は複数カウンタ同時計測モードで利用可能です 通常のカウンタ読み出しは、どちらのモードでもカウンタ停止状態で読み出します。
サイクルカウンタ読み出しは、計測中でも読み出し可能です。
SOLID_PMU_GetCounterNums
-
int SOLID_PMU_GetCounterNums(void)
CPUが持っているPMUカウンタレジスタの数を取得する(M)(S)
- 戻り値
PMUカウンタレジスタの数
SOLID_PMU_EnableClockDivider
-
int SOLID_PMU_EnableClockDivider(void)
サイクルカウンタのクロックディバイダを有効にする(M)(S)
64bitカウンタが有効な場合は Cycle Counter Clock Dividerは無効になります。 基本的には AArch32 アーキテクチャの CPU のみで有効な API です
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_NOTSUPPORTED
: サポートされないAPI
SOLID_PMU_DisableClockDivider
-
int SOLID_PMU_DisableClockDivider(void)
サイクルカウンタのクロックディバイダを無効にする(M)(S)
64bitカウンタが有効な場合は Cycle Counter Clock Dividerは無効になります。 基本的には AArch32 アーキテクチャの CPU のみで有効な API です
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_NOTSUPPORTED
: サポートされないAPI
SOLID_PMU_EnableMultiMode
-
int SOLID_PMU_EnableMultiMode(void)
サイクルカウンタを含む複数カウンタでの同時計測モードに設定する(S)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 既に同期計測モードに設定されているSOLID_ERR_BUSY
: 使用可能なカウンタが残っていない
SOLID_PMU_DisableMultiMode
-
int SOLID_PMU_DisableMultiMode(void)
サイクルカウンタを含む複数カウンタでの同時計測モードを終了する(S)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていない
SOLID_PMU_SetEventMulti
-
int SOLID_PMU_SetEventMulti(uint32_t counter_mask, uint32_t *event)
指定の複数のカウンタに対してPMUイベントを設定する(M)
設定したいカウンタ番号をビットマスクで設定し、 設定したい個数分の配列としてイベントを渡します
- パラメータ
counter_mask -- 設定したいカウンタ番号のビットマスク
event -- 設定したいPMUイベントの配列へのポインタ
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていない
SOLID_PMU_ClearEventMulti
-
int SOLID_PMU_ClearEventMulti(uint32_t counter_mask)
指定の複数のカウンタの PMUイベントを初期化する。(M)
初期化したいカウンタ番号をビットマスクで設定します
- パラメータ
counter_mask -- 初期化したいカウンタ番号のビットマスク
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていないSOLID_ERR_OUTOFBOUND
: カウンタ数の上限を越えたマスクが指定されています
SOLID_PMU_ClearAllEventMulti
-
int SOLID_PMU_ClearAllEventMulti(void)
全てのカウンタの PMUイベントを初期化する(M)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていない
SOLID_PMU_StartMulti
-
int SOLID_PMU_StartMulti(void)
複数カウンタでの計測を開始する(M)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていない
SOLID_PMU_StopMulti
-
int SOLID_PMU_StopMulti(void)
複数カウンタでの計測を終了(M)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_NOTUSED
: 同期計測モードを実行中ではないSOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていない
SOLID_PMU_GetCounterMulti
-
int SOLID_PMU_GetCounterMulti(uint32_t counter_mask, uint64_t *count)
指定の複数のカウンタ値を取得する(M)
取得したいカウンタ番号をビットマスクで設定し、 取得したい個数分の配列を用意します
- パラメータ
counter_mask -- 設定したいカウンタ番号のビットマスク
count -- カウンタ値を格納する配列へのポインタ
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: 同期計測モードに設定されていない
SOLID_PMU_GetCycleCounter
-
int SOLID_PMU_GetCycleCounter(uint64_t *count)
サイクルカウンタ値を取得する(M)(S)
- パラメータ
count -- カウンタ値を格納する変数のポインタ
- 戻り値
SOLID_ERR_OK
: 正常終了
SOLID_PMU_ClearCycleCounter
-
int SOLID_PMU_ClearCycleCounter(void)
サイクルカウンタの値を初期化する(M)(S)
- 戻り値
SOLID_ERR_OK
: 正常終了
SOLID_PMU_SetEvent
-
int SOLID_PMU_SetEvent(int number, uint32_t event)
指定のカウンタのイベントを設定する(S)
- パラメータ
number -- 設定したいカウンタ番号
event -- 設定した PMU イベント番号
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではない
SOLID_PMU_ClearEvent
-
int SOLID_PMU_ClearEvent(int number)
指定のカウンタのイベントを初期化する(S)
- パラメータ
number -- 初期化したいカウンタ番号
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_OUTOFBOUND
: カウンタ数の上限を越えた指定SOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではないSOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_NOTUSED
: 初期化されていないカウンタ番号が指定された
SOLID_PMU_StartCounter
-
int SOLID_PMU_StartCounter(int number)
指定のカウンタの計測を開始する(S)
- パラメータ
number -- 計測を開始したいカウンタ番号
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_OUTOFBOUND
: カウンタ数の上限を越えた指定SOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではないSOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_NOTUSED
: 初期化されていないカウンタ番号が指定された
SOLID_PMU_StopCounter
-
int SOLID_PMU_StopCounter(int number)
指定のカウンタの計測を停止する(S)
- パラメータ
number -- 計測を停止したいカウンタ番号
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_OUTOFBOUND
: カウンタ数の上限を越えた指定SOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではないSOLID_ERR_NOTUSED
: 計測中ではないカウンタ番号が指定された
SOLID_PMU_GetCounter
-
int SOLID_PMU_GetCounter(int number, uint64_t *val)
指定のカウンタの値を取得する(S)
- パラメータ
number -- 値を取得したいカウンタ番号
val -- 値を受け取る変数へのポインタ
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_OUTOFBOUND
: カウンタ数の上限を越えた指定SOLID_ERR_BUSY
: 計測実行中SOLID_ERR_NOTUSED
: 使用中ではないカウンタが指定されたSOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではない
SOLID_PMU_ClearCounter
-
int SOLID_PMU_ClearCounter(int number)
指定のカウンタの値を初期化する(S)
- パラメータ
number -- 値を初期化したいカウンタ番号
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_OUTOFBOUND
: カウンタ数の上限を越えた指定SOLID_ERR_BUSY
: 計測実行中SOLID_ERR_NOTUSED
: 使用中ではないカウンタが指定されたSOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではない
SOLID_PMU_StartCycleCounter
-
int SOLID_PMU_StartCycleCounter(void)
サイクルカウンタを開始する(S)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_ALREADYUSED
: 計測実行中SOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではない
SOLID_PMU_StopCycleCounter
-
int SOLID_PMU_StopCycleCounter(void)
サイクルカウンタを停止する(S)
- 戻り値
SOLID_ERR_OK
: 正常終了SOLID_ERR_NOTUSED
: 使用中ではないSOLID_ERR_BADSEQUENCE
: シングルカウンタ計測モードではない