rpi_start.Sを読む (第5回)
2013/11/09(土) 27:22 NetBSD はてブ情報 はてブに登録 はてブ数

MMU_INITマクロの続編です。前回だいぶ解明したおかげで残りは順調に進みそうです。

二つ目のMMU_INITマクロを読み解きましょう。
    314 	MMU_INIT(KERNEL_BASE, 0x0,
    315 	    (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1),
    316 	    L1_S_PROTO | L1_S_AP_KRW  | L1_S_B | L1_S_C)
三つめまでの引数は先ほどのほぼ同様ですね。KERNEL_BASEもわかっているので問題ありません。
最後の引数も新しいのはL1_S_B, L1_S_Cの二つです。
おなじみ、pte.hで定義されています。先ほどのL1_S_IMPの上にいました。
  /* L1 Section Descriptor */
  #define L1_S_B          0x00000004      /* bufferable Section */
  #define L1_S_C          0x00000008      /* cacheable Section */
  #define L1_S_IMP        0x00000010      /* implementation defined */
ですから、L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C = 0x0012 | 0x0400 | 0x0004 | 0x0008 = 0x041Eです。

ということで、
    314 	MMU_INIT(KERNEL_BASE, 0x0,
    315 	    (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1),
    316 	    L1_S_PROTO | L1_S_AP_KRW  | L1_S_B | L1_S_C)
というMMU_INITは
  va = 0xC0000000;
  pa = 0x0;
  n_sec = 0x643033;
  attr = 0x041E;
と表現できることがわかります。

さて、最後のMMU_INITマクロです。
コメントによると16MBのペリフェラルのマップとのこと。メモリマップI/Oされた周辺機器に関するエントリのようですね。
    318 	/* Map the 16MB of peripherals */
    319 	MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE,
    320 	    (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1),
    321 	    L1_S_PROTO | L1_S_AP_KRW)
これは、四つ目の引数が一つ目のMMU_INITマクロと同じですから最初の三つの引数が読み解ければよいですね。

まずは、RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASEです。

これは、arch/evbarm/rpi/rpi.hにある
  #define    RPI_KERNEL_IO_VBASE        BCM2835_PERIPHERALS_VBASE
  #define    RPI_KERNEL_IO_PBASE        BCM2835_PERIPHERALS_BASE
  
  #define    RPI_KERNEL_IO_VSIZE        BCM2835_PERIPHERALS_SIZE
からのarch/arm/broadcom/bcm2835reg.hにおいて定義されています。
  #define    BCM2835_PERIPHERALS_BASE    0x20000000
  #define    BCM2835_PERIPHERALS_SIZE    0x01000000    /* 16MBytes */
  
  #define BCM2835_IOPHYSTOVIRT(a) \
      ((0xf0000000 | (((a) & 0xf0000000) >> 4)) + ((a) & ~0xf0000000))
  
  #define    BCM2835_PERIPHERALS_VBASE \
      BCM2835_IOPHYSTOVIRT(BCM2835_PERIPHERALS_BASE)
RPI_KERNEL_IO_PBASEはそのままBCM2835_PERIPHERALS_BASEですから0x20000000になります。

RPI_KERNEL_IO_VBASEはBCM2835_IOPHYSTOVIRTというマクロを経由しますが、計算するとRPI_KERNEL_IO_VBASE = 0xF2000000になります。

三つ目のMMU_INITマクロである
    318 	/* Map the 16MB of peripherals */
    319 	MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE,
    320 	    (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1),
    321 	    L1_S_PROTO | L1_S_AP_KRW)
については次のように表現できます。
  va = 0xF2000000
  pa = 0x20000000
  n_sec = 0x01000000 + 0x00100000 - 1 = 0x010FFFFF
  attr = 0x0412
最後のMMU_INITマクロは、
    323 	/* end of table */
    324 	MMU_INIT(0, 0, 0, 0)
ということで、テーブルの最後にすべてを0にしたものです。テーブルの最後を示す、番兵の役目ということでしょうか。

番兵を除く、MMU_INITマクロを表にしてみましょう。
vapansecattr
0x00x00x6430330x412
0xC00000000x00x6430330x041E
0xF20000000x200000000x010FFFFF0x0412

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0807/tb/