uboot啓動流程詳解(3)-cpu_init_cp15

1、代碼及註釋

說明:
  1、關於p15協處理及其指令的介紹請看《ARM協處理器介紹 》
  2、關於mmu的詳細介紹請查看《 MMU內存管理單元介紹 》
  3、如果想要詳細閱讀以下代碼,需要查閱arm的參考手冊《ARM_Architecture_Reference_Manual_ARMv7-AR.pdf》

/*************************************************************************
 *
 * cpu_init_cp15
 *
 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
 * CONFIG_SYS_ICACHE_OFF is defined.
 *
 *************************************************************************/
ENTRY(cpu_init_cp15)
    /*
     * Invalidate L1 I/D
     */
    mov r0, #0          @ set up for MCR
    mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs  /*禁止從TLB中取地址描述符,也就是禁止虛擬地址到物理地址的轉換,因爲剛開始操作的都是物理寄存器!*/
    mcr p15, 0, r0, c7, c5, 0   @ invalidate icache /*關閉指令cache*/
    mcr p15, 0, r0, c7, c5, 6   @ invalidate BP array /*關閉分支預測*/
    mcr     p15, 0, r0, c7, c10, 4  @ DSB /*多核cpu之間進行數據同步*/
    mcr     p15, 0, r0, c7, c5, 4   @ ISB /*進行指令同步,放棄流水線中已經取到的指令,重新取指令*/

    /*
     * disable MMU stuff and caches
     */
      /*******************************************************
      *1、爲什麼要關閉mmu?
      *因爲MMU是把虛擬地址轉化爲物理地址得作用
      *而我們現在是要設置控制寄存器,而控制寄存器本來就是實地址(物理地址),
      *再使能MMU,不就是多此一舉了嗎?
      ********************************************************/

     /******************************************************************
     *2、爲什麼要關閉cache?
     *catch和MMU是通過CP15管理的,剛上電的時候,CPU還不能管理他們。
        *所以上電的時候MMU必須關閉,指令cache可關閉,可不關閉,但數據cache一定要關閉
        *否則可能導致剛開始的代碼裏面,去取數據的時候,從catch裏面取,
        *而這時候RAM中數據還沒有cache過來,導致數據預取異常
     *******************************************************************/
    mrc p15, 0, r0, c1, c0, 0
    bic r0, r0, #0x00002000 @ clear bits 13 (--V-) /*設置成正常異常模式,即異常向量表的基地址爲0x00000000*/
    bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) /*關閉指令cache,關閉指令對齊檢測,關閉mmu*/
    orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align /*使能對齊檢測*/
    orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB /*使能分支預測*/
#ifdef CONFIG_SYS_ICACHE_OFF
    bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
    orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache /*時能指令cache*/
#endif
    mcr p15, 0, r0, c1, c0, 0

#ifdef CONFIG_ARM_ERRATA_716044
    mrc p15, 0, r0, c1, c0, 0   @ read system control register
    orr r0, r0, #1 << 11    @ set bit #11
    mcr p15, 0, r0, c1, c0, 0   @ write system control register
#endif

#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
    mrc p15, 0, r0, c15, c0, 1  @ read diagnostic register
    orr r0, r0, #1 << 4     @ set bit #4
    mcr p15, 0, r0, c15, c0, 1  @ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_743622
    mrc p15, 0, r0, c15, c0, 1  @ read diagnostic register
    orr r0, r0, #1 << 6     @ set bit #6
    mcr p15, 0, r0, c15, c0, 1  @ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_751472
    mrc p15, 0, r0, c15, c0, 1  @ read diagnostic register
    orr r0, r0, #1 << 11    @ set bit #11
    mcr p15, 0, r0, c15, c0, 1  @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_761320
    mrc p15, 0, r0, c15, c0, 1  @ read diagnostic register
    orr r0, r0, #1 << 21    @ set bit #21
    mcr p15, 0, r0, c15, c0, 1  @ write diagnostic register
#endif

    mov pc, lr          @ back to my caller /*程序返回*/
ENDPROC(cpu_init_cp15)
發佈了57 篇原創文章 · 獲贊 80 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章