OCTEON startup analysis

主要说一下OCTEON的启动过程,在Cavium提供的SDK中有可用的u-boot,需要针对自己的的板子来简单的改写了,但是不只是移植还看了下启动的原理,研究了MIPS架构上的一些东西。

 
 
  1. .globl _start
  2. .text
  3. _start:
  4. RVECENT(reset,0) /* U-boot entry point */
  5. /* The above jump instruction/nop are considered part of the
  6. * bootloader_header_t structure but are not changed when the header is
  7. * updated.
  8. */
  9. /* Leave room for bootloader_header_t header at start of binary. This
  10. * header is used to identify the board the bootloader is for, what
  11. * address it is linked at, failsafe/normal, etc. It also contains a
  12. * CRC of the entire image.
  13. */
  14. .org 0x200
  15. XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */
  16. ......
  17. XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */
  18. ......
  19. XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */
  20. ......
  21. XVECENT(romExcHandle,0x380) /* bfc00380: R4000 general vector */
  22. ......
  23. XVECENT(romExcHandle,0x400) /* bfc00400: */
  24. ......
  25. RVECENT(debugHandler,0x480) /* bfc00480: Debug vector*/
  26. ......
  27. RVECENT(romReserved,159)
  28. /* Reserve extra space so that when we use the boot bus local memory
  29. * segment to remap the debug exception vector we don't overwrite
  30. * anything useful
  31. */
  32. .align 8
  33. .globl asm_reset
  34. asm_reset:
  35. reset:
  36. nop
  37. mfc0 k0, COP0_STATUS_REG
  38. ori k0, 0x00E0 /* enable 64 bit mode for CSR access */
  39. mtc0 k0, COP0_STATUS_REG
  40. /* Check what core we are - if core 0, branch to init tlb
  41. * loop in flash. Otherwise, look up address of init tlb
  42. * loop that was saved in the boot vector block.
  43. */
  44. mfc0 a0, COP0_EBASE_REG
  45. andi a0, 0xFF /* get core */
  46. beqz a0, InitTLBStart_local
  47. nop
  48. break

如果是core0的话,进入到InitTLBStart_local进行TLB的设置

 
 
  1. .globl InitTLBStart
  2. InitTLBStart:
  3. InitTLBStart_local:
  4. /* If we don't have working memory yet configure a bunch of
  5. * scratch memory, and set the stack pointer to the top
  6. * of it. This allows us to go to C code without having
  7. * memory set up
  8. *
  9. * Warning: do not change SCRATCH_STACK_LINES as this can impact the
  10. * transition from start.S to crti.asm. crti requires 590 bytes of
  11. * stack space.
  12. */
  13. #define SCRATCH_STACK_LINES 0x36 /* MAX is 0x36 */
  14. dmfc0 v0, COP0_CVMMEMCTL_REG
  15. dsrl v0, 9
  16. dsll v0, 9
  17. /* setup SCRATCH_STACK_LINES scratch lines of scratch */
  18. ori v0, 0x100 | SCRATCH_STACK_LINES
  19. dmtc0 v0, COP0_CVMMEMCTL_REG
  20. /* set stack to top of scratch memory */
  21. li sp, 0xffff8000 + (SCRATCH_STACK_LINES * 128)
  22. /* Clear scratch for CN63XX pass 2.0 errata Core-15169*/
  23. li t0, 0xffff8000
  24. clear_scratch:
  25. sd zero, 0(t0)
  26. addi t0, 8
  27. bne t0, sp, clear_scratch
  28. nop

针对core0的TLB设置,方便core0从flash里面取bootloader的代码以启动其他的core。

 
 
  1. /* This code run on all cores - core 0 from flash,
  2. * the rest from DRAM. When booting from PCI, non-zero cores
  3. * come directly here from the boot vector - no earlier code in this
  4. * file is executed.
  5. */
  6. /* Some generic initialization is done here as well, as we need this
  7. * done on all cores even when booting from PCI
  8. */
  9. /* Clear watch registers. */
  10. mtc0 zero, CP0_WATCHLO
  11. mtc0 zero, CP0_WATCHHI
  12. /* STATUS register */
  13. mfc0 k0, CP0_STATUS
  14. li k1, ~ST0_IE
  15. and k0, k1
  16. mtc0 k0, CP0_STATUS
  17. /* CAUSE register */
  18. mtc0 zero, CP0_CAUSE
  19. /* Init Timer */
  20. dmtc0 zero, CP0_COUNT
  21. dmtc0 zero, CP0_COMPARE
  22. mfc0 a5, COP0_STATUS_REG
  23. li v0,0xE0 /* enable 64 bit mode for CSR access */
  24. or v0, v0, a5
  25. mtc0 v0, COP0_STATUS_REG
  26. dli v0, 1 << 29 /* Enable large physical address support in TLB */
  27. mtc0 v0, COP0_PAGEGRAIN_REG
  28. InitTLB:
  29. dmtc0 zero, COP0_ENTRYLO0_REG
  30. dmtc0 zero, COP0_ENTRYLO1_REG
  31. mtc0 zero, COP0_PAGEMASK_REG
  32. dmtc0 zero, COP0_CONTEXT_REG
  33. /* Use an offset into kseg0 so we won't conflict with Mips1 legacy
  34. * TLB clearing */
  35. dli v0, 0xFFFFFFFF90000000
  36. mfc0 a0, COP0_CONFIG1_REG
  37. srl a0, a0, 25
  38. /* Check if config4 reg present */
  39. mfc0 a1, COP0_CONFIG3_REG
  40. bbit0 a1, 31, 2f
  41. and a0, a0, 0x3F /* a0 now has the max mmu entry index */
  42. mfc0 a1, COP0_CONFIG4_REG
  43. bbit0 a1, 14, 2f /* check config4[MMUExtDef] */
  44. nop
  45. /* append config4[MMUSizeExt] to most significant bit of
  46. * config1[MMUSize-1] */
  47. ins a0, a1, 6, 8
  48. and a0, a0, 0x3fff /* a0 now includes max entries for cn6xxx */
  49. 2:
  50. dmtc0 zero, COP0_XCONTEXT_REG
  51. mtc0 zero, COP0_WIRED_REG

其他的core都在loop中

 
 
  1. InitTLBloop:
  2. /* Work around TLBx parity error on some CN6XXX devices. */
  3. .balign 64,0,48
  4. dmtc0 v0, COP0_ENTRYHI_REG
  5. nop
  6. nop
  7. nop
  8. tlbp
  9. nop
  10. nop
  11. nop
  12. nop
  13. nop
  14. nop
  15. mfc0 v1, COP0_INDEX_REG
  16. daddiu v0, v0, 1<<13
  17. bgez v1, InitTLBloop
  18. nop
  19. /* Work around TLBx parity error on some CN6XXX devices. */
  20. .balign 64,0,48
  21. nop
  22. mtc0 a0, COP0_INDEX_REG
  23. nop
  24. nop
  25. tlbwi
  26. nop
  27. nop
  28. nop
  29. nop
  30. nop
  31. nop
  32. nop
  33. nop
  34. bne a0, zero, InitTLBloop
  35. addiu a0, -1
  36. #ifdef ENABLE_BOARD_DEBUG
  37. /* Set GPIO output bits */
  38. dli a4, OCTEON_GPIO_TX_SET
  39. li a5, 0x7e
  40. sll a5, 8
  41. sd a5, 0(a4)
  42. #endif
  43. mthi zero
  44. mtlo zero
  45. /* Set up status register */
  46. mfc0 v0, COP0_STATUS_REG
  47. li a4, 1 << 28 /* enable cop0 access */
  48. or v0, a4
  49. li a4, 1 << 30 /* enable cop2 access */
  50. or v0, a4
  51. /* Must leave BEV set here, as DRAM is not configured for core 0.
  52. * Also, BEV must be 1 later on when the exception base address is set.*/
  53. li a4, ~0xff00 /* mask all interrupts */
  54. and v0, a4
  55. li a4, ~0xff
  56. and v0, a4
  57. /* Clear NMI (used to start cores other than core 0) */
  58. li a4, ~(1 << 19)
  59. and v0, a4
  60. ori v0, 0xE5 /* enable 64 bit, disable interrupts */
  61. mtc0 v0, COP0_STATUS_REG
  62. dli v0,0xC000000F /* enable all readhw locations */
  63. mtc0 v0, COP0_HWRENA_REG
  64. dmfc0 v0, COP0_CVMCTL_REG
  65. mfc0 a4, COP0_PROC_ID_REG
  66. li a5, 0x000d0000 /* Octeon pass1 chip id */
  67. bne a4, a5, skip_icachetch_disable
  68. nop
  69. /* disable icache prefectch - errata core 8 (pass1 only) */
  70. ori v0, 1<<13
  71. skip_icachetch_disable:
  72. ori v0, 1<<14 /* enable fixup of unaligned mem access */
  73. dmtc0 v0, COP0_CVMCTL_REG
  74. /* Setup scratch memory. This is also done in
  75. * cvmx_user_app_init, and this code will be removed
  76. * from the bootloader in the near future.
  77. */
  78. dmfc0 v0, COP0_CVMMEMCTL_REG
  79. mfc0 a4, COP0_PROC_ID_REG
  80. li a5, 0x000d9000 /* Octeon pass1 chip id */
  81. bgt a5, a4, 71f
  82. nop
  83. ori a6, a5, 8 /* Octeon cn63xx pass2 chip id */
  84. bge a4, a6, 71f
  85. nop
  86. li a6, 4
  87. ins v0, a6, 11, 4 /* Set WBTHRESH=4 as per Core-14752 errata */
  88. 71:
  89. dmtc0 v0, COP0_CVMMEMCTL_REG
  90. /* clear these to avoid immediate interrupt in noperf mode */
  91. dmtc0 zero, COP0_COMPARE_REG /* clear timer interrupt */
  92. dmtc0 zero, COP0_COUNT_REG /* clear timer interrupt */
  93. dmtc0 zero, COP0_PERF_CNT0_REG/* clear perfCnt0 */
  94. dmtc0 zero, COP0_PERF_CNT1_REG/* clear perfCnt1 */
  95. /* Set up TLB mappings for u-boot code in flash. */

里面一个设置

 
 
  1. ins v0, a6, 11, 4 /* Set WBTHRESH=4 as per Core-14752 errata

这个是63XX的一个BUG workaround,看来这个问题在6系列的OCTEON II CPU存在已久,有设置成10的,但是以前都是设置成4。这个值确实能够影响到write buffer,但是确实不能了解到Cavium的write buffer的实现细节,这个值是怎么影响到系统的就不得而知。大概看了下文档上的介绍,只能知道个所以然。

 
 
  1. /* Start of GP hack. This needs to be done once properly for all code.
  2. * old relocation hacks need to be removed.
  3. */
  4. /* Branch and link to get current PC in ra */
  5. bal 2f
  6. nop
  7. /* This contains the linked address of the GOT */
  8. .word _GLOBAL_OFFSET_TABLE_
  9. /* The ra register now contains the runtime address of the above
  10. * memory location */
  11. /* This contains the link time address of the previous word, */
  12. .word . - 4
  13. 2:
  14. move gp, ra /* Move current PC into gp register */
  15. lw a5, 0(ra) /* Load linked address of the GOT into a5 */
  16. lw a6, 4(ra) /* Load the link time address of the GOT
  17. * storage location into a6
  18. */
  19. sub a5, a6 /* Subtract a6 from t1. */
  20. /* a5 now contains the difference between the link-time GOT table
  21. * address and the link time expected PC
  22. */
  23. /* Add this difference to the current PC (copied into gp above) so
  24. * that gp now has the current runtime GOT table address
  25. */
  26. daddu gp, a5 # calculate current location of offset table
  27. /* End of GP hack. */

relocation在bootloader里面有点难度



本文地址:http://www.tech4cloud.com/2012/09/01/octeon-startup


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值