ARMテクニカルリファレンスマニュアルに記載されてるレジスタ設定の読み方

# 知りたいこと
例えば
[c0, MPU Type Register](https://developer.arm.com/documentation/ddi0460/c/System-Control/Register-descriptions/c0--MPU-Type-Register?lang=en)
にある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/cd835881-c5dc-9d5f-3ac0-9c3d308bc876.png)
は、どのような意味で、コード上ではどう書けばよいか？

※リファレンスマニュアルは[Cortex-R5 and Cortex-R5F Technical Reference Manual](https://developer.arm.com/documentation/ddi0460/c/System-Control/Register-descriptions/c0--MPU-Type-Register)を参考にしている
※[コプロセッサ](https://www.aps-web.jp/academy/ca/229/)の説明とかぶるのだが、自分用の調査方法メモとして残しておく

#MRC
##Syntax
[MRC, MRC2, MRRC and MRRC2](https://developer.arm.com/documentation/dui0204/j/arm-and-thumb-instructions/coprocessor-instructions/mrc--mrc2--mrrc-and-mrrc2)
から
> op1{cond} coproc, #opcode1, Rt, CRn, CRm{, #opcode2}

上記の例であれば

- op1 : MRC ※MRCは**M**ove to ARM **R**egister or Registers from **C**oprocessor
- coproc : p15  (コプロセッサの番号をpnで指定。今回はCP15)
- \#opecode1 : 3bitのコプロセッサ命令
- \<Rd> : リードした結果の変数を設定するとこ
- CRn : コプロセッサのレジスタ
- CRm : コプロセッサのレジスタ
- \#opecode2 : オプションの3bitのコプロセッサ命令

## 各引数詳しく
### coproc
CP15とは？
CPとはCoProcessorのことでARMが提供する拡張機能のこと。
ARM11のマニュアルにしかなったので引用すると [About the coprocessor interface](https://developer.arm.com/documentation/ddi0301/h/coprocessor-interface/about-the-coprocessor-interface?lang=en)
> AMRでは0-15の16個のcoprocessorをサポートしている。以下の番号は予約されている
　CP10 : VFP control
　CP11 : VFP control
　CP14 : Debug and ETM control
　CP15 : System control
CP0-9, CP12, CP13はユーザー自身の外部コプロセッサとして使用できる

なので、CP15は`システムコントロールのコプロセッサ`となる。

[About system control](https://developer.arm.com/documentation/ddi0460/c/System-Control/About-system-control?lang=en)
を読むと、
>システム制御コプロセッサ(CP15)は、プロセッサに実装されている機能のステータス情報の制御、ステータスの提供をするもの。
システムの主な機能としては
　- システム全体の制御と設定
　- キャッシュの設定と管理
　- Memory Protection Unit(MPU)の設定と管理
　- システムパフォーマンスのモニタリング

となる。

### opecode1, opecode2, CRn, CRm
[Register Allocation](https://developer.arm.com/documentation/ddi0460/c/System-Control/Register-descriptions/Register-allocation)
を読むとわかる

ex.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/523748ac-5404-3de6-a9bc-0ff0fe52ec2f.png)

### 実装例
ZYNQのR5で実装
funcでDRegionを読む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/ac2d647b-9eb7-996f-18eb-0898c804ac84.png)


```c:
#define BIT_MASK_00 (0x00000000)
#define BIT_MASK_01 (0x00000001)
#define BIT_MASK_02 (0x00000003)
#define BIT_MASK_03 (0x00000007)
#define BIT_MASK_04 (0x0000000F)
#define BIT_MASK_05 (0x0000001F)
#define BIT_MASK_06 (0x0000003F)
#define BIT_MASK_07 (0x0000007F)
#define BIT_MASK_08 (0x000000FF)
static int BIT_MASK[] = {
    BIT_MASK_00,
    BIT_MASK_01,
    BIT_MASK_02,
    BIT_MASK_03,
    BIT_MASK_04,
    BIT_MASK_05,
    BIT_MASK_06,
    BIT_MASK_07,
    BIT_MASK_08,
};
int read_bits(const int val, const int left, const int right)
{
    return (val >> right) & BIT_MASK[left-right];
}

volatile inline static unsigned long __attribute__((always_inline))
int func(void) {
    uint32_t reg;
    asm volatile ("MRC p15, 0, %0, c0, c0, 4": "=r" (reg));
    printf( "%d:DRegion:%d\r\n", reg, read_bits(reg,15,8));

}

int main( void )
{
    printf( "\r\n");
    func();
```

出力は

```console
4096:DRegion:16
```

※インラインアセンブラに関しては
　https://qiita.com/azuki_bar/items/1dd0a57a292ac1a074e4
　に少し説明書いてある