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_PMU_DisableClockDivider

int SOLID_PMU_DisableClockDivider(void)

サイクルカウンタのクロックディバイダを無効にする(M)(S)

64bitカウンタが有効な場合は Cycle Counter Clock Dividerは無効になります。 基本的には AArch32 アーキテクチャの CPU のみで有効な API です

戻り値:

SOLID_PMU_EnableMultiMode

int SOLID_PMU_EnableMultiMode(void)

サイクルカウンタを含む複数カウンタでの同時計測モードに設定する(S)

戻り値:

SOLID_PMU_DisableMultiMode

int SOLID_PMU_DisableMultiMode(void)

サイクルカウンタを含む複数カウンタでの同時計測モードを終了する(S)

戻り値:

SOLID_PMU_SetEventMulti

int SOLID_PMU_SetEventMulti(uint32_t counter_mask, uint32_t *event)

指定の複数のカウンタに対してPMUイベントを設定する(M)

設定したいカウンタ番号をビットマスクで設定し、 設定したい個数分の配列としてイベントを渡します

パラメータ:
  • counter_mask -- 設定したいカウンタ番号のビットマスク

  • event -- 設定したいPMUイベントの配列へのポインタ

戻り値:

SOLID_PMU_ClearEventMulti

int SOLID_PMU_ClearEventMulti(uint32_t counter_mask)

指定の複数のカウンタの PMUイベントを初期化する。(M)

初期化したいカウンタ番号をビットマスクで設定します

パラメータ:
  • counter_mask -- 初期化したいカウンタ番号のビットマスク

戻り値:

SOLID_PMU_ClearAllEventMulti

int SOLID_PMU_ClearAllEventMulti(void)

全てのカウンタの PMUイベントを初期化する(M)

戻り値:

SOLID_PMU_StartMulti

int SOLID_PMU_StartMulti(void)

複数カウンタでの計測を開始する(M)

戻り値:

SOLID_PMU_StopMulti

int SOLID_PMU_StopMulti(void)

複数カウンタでの計測を終了(M)

戻り値:

SOLID_PMU_GetCounterMulti

int SOLID_PMU_GetCounterMulti(uint32_t counter_mask, uint64_t *count)

指定の複数のカウンタ値を取得する(M)

取得したいカウンタ番号をビットマスクで設定し、 取得したい個数分の配列を用意します

パラメータ:
  • counter_mask -- 設定したいカウンタ番号のビットマスク

  • count -- カウンタ値を格納する配列へのポインタ

戻り値:

SOLID_PMU_GetCycleCounter

int SOLID_PMU_GetCycleCounter(uint64_t *count)

サイクルカウンタ値を取得する(M)(S)

パラメータ:
  • count -- カウンタ値を格納する変数のポインタ

戻り値:

SOLID_PMU_ClearCycleCounter

int SOLID_PMU_ClearCycleCounter(void)

サイクルカウンタの値を初期化する(M)(S)

戻り値:

SOLID_PMU_SetEvent

int SOLID_PMU_SetEvent(int number, uint32_t event)

指定のカウンタのイベントを設定する(S)

パラメータ:
  • number -- 設定したいカウンタ番号

  • event -- 設定した PMU イベント番号

戻り値:

SOLID_PMU_ClearEvent

int SOLID_PMU_ClearEvent(int number)

指定のカウンタのイベントを初期化する(S)

パラメータ:
  • number -- 初期化したいカウンタ番号

戻り値:

SOLID_PMU_StartCounter

int SOLID_PMU_StartCounter(int number)

指定のカウンタの計測を開始する(S)

パラメータ:
  • number -- 計測を開始したいカウンタ番号

戻り値:

SOLID_PMU_StopCounter

int SOLID_PMU_StopCounter(int number)

指定のカウンタの計測を停止する(S)

パラメータ:
  • number -- 計測を停止したいカウンタ番号

戻り値:

SOLID_PMU_GetCounter

int SOLID_PMU_GetCounter(int number, uint64_t *val)

指定のカウンタの値を取得する(S)

パラメータ:
  • number -- 値を取得したいカウンタ番号

  • val -- 値を受け取る変数へのポインタ

戻り値:

SOLID_PMU_ClearCounter

int SOLID_PMU_ClearCounter(int number)

指定のカウンタの値を初期化する(S)

パラメータ:
  • number -- 値を初期化したいカウンタ番号

戻り値:

SOLID_PMU_StartCycleCounter

int SOLID_PMU_StartCycleCounter(void)

サイクルカウンタを開始する(S)

戻り値:

SOLID_PMU_StopCycleCounter

int SOLID_PMU_StopCycleCounter(void)

サイクルカウンタを停止する(S)

戻り値: