cvmx-boot-vector.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2004-2017 Cavium, Inc.
  7. */
  8. /*
  9. We install this program at the bootvector:
  10. ------------------------------------
  11. .set noreorder
  12. .set nomacro
  13. .set noat
  14. reset_vector:
  15. dmtc0 $k0, $31, 0 # Save $k0 to DESAVE
  16. dmtc0 $k1, $31, 3 # Save $k1 to KScratch2
  17. mfc0 $k0, $12, 0 # Status
  18. mfc0 $k1, $15, 1 # Ebase
  19. ori $k0, 0x84 # Enable 64-bit addressing, set
  20. # ERL (should already be set)
  21. andi $k1, 0x3ff # mask out core ID
  22. mtc0 $k0, $12, 0 # Status
  23. sll $k1, 5
  24. lui $k0, 0xbfc0
  25. cache 17, 0($0) # Core-14345, clear L1 Dcache virtual
  26. # tags if the core hit an NMI
  27. ld $k0, 0x78($k0) # k0 <- (bfc00078) pointer to the reset vector
  28. synci 0($0) # Invalidate ICache to get coherent
  29. # view of target code.
  30. daddu $k0, $k0, $k1
  31. nop
  32. ld $k0, 0($k0) # k0 <- core specific target address
  33. dmfc0 $k1, $31, 3 # Restore $k1 from KScratch2
  34. beqz $k0, wait_loop # Spin in wait loop
  35. nop
  36. jr $k0
  37. nop
  38. nop # NOPs needed here to fill delay slots
  39. nop # on endian reversal of previous instructions
  40. wait_loop:
  41. wait
  42. nop
  43. b wait_loop
  44. nop
  45. nop
  46. nop
  47. ------------------------------------
  48. 0000000000000000 <reset_vector>:
  49. 0: 40baf800 dmtc0 k0,c0_desave
  50. 4: 40bbf803 dmtc0 k1,c0_kscratch2
  51. 8: 401a6000 mfc0 k0,c0_status
  52. c: 401b7801 mfc0 k1,c0_ebase
  53. 10: 375a0084 ori k0,k0,0x84
  54. 14: 337b03ff andi k1,k1,0x3ff
  55. 18: 409a6000 mtc0 k0,c0_status
  56. 1c: 001bd940 sll k1,k1,0x5
  57. 20: 3c1abfc0 lui k0,0xbfc0
  58. 24: bc110000 cache 0x11,0(zero)
  59. 28: df5a0078 ld k0,120(k0)
  60. 2c: 041f0000 synci 0(zero)
  61. 30: 035bd02d daddu k0,k0,k1
  62. 34: 00000000 nop
  63. 38: df5a0000 ld k0,0(k0)
  64. 3c: 403bf803 dmfc0 k1,c0_kscratch2
  65. 40: 13400005 beqz k0,58 <wait_loop>
  66. 44: 00000000 nop
  67. 48: 03400008 jr k0
  68. 4c: 00000000 nop
  69. 50: 00000000 nop
  70. 54: 00000000 nop
  71. 0000000000000058 <wait_loop>:
  72. 58: 42000020 wait
  73. 5c: 00000000 nop
  74. 60: 1000fffd b 58 <wait_loop>
  75. 64: 00000000 nop
  76. 68: 00000000 nop
  77. 6c: 00000000 nop
  78. */
  79. #include <asm/octeon/cvmx-boot-vector.h>
  80. static unsigned long long _cvmx_bootvector_data[16] = {
  81. 0x40baf80040bbf803ull, /* patch low order 8-bits if no KScratch*/
  82. 0x401a6000401b7801ull,
  83. 0x375a0084337b03ffull,
  84. 0x409a6000001bd940ull,
  85. 0x3c1abfc0bc110000ull,
  86. 0xdf5a0078041f0000ull,
  87. 0x035bd02d00000000ull,
  88. 0xdf5a0000403bf803ull, /* patch low order 8-bits if no KScratch*/
  89. 0x1340000500000000ull,
  90. 0x0340000800000000ull,
  91. 0x0000000000000000ull,
  92. 0x4200002000000000ull,
  93. 0x1000fffd00000000ull,
  94. 0x0000000000000000ull,
  95. OCTEON_BOOT_MOVEABLE_MAGIC1,
  96. 0 /* To be filled in with address of vector block*/
  97. };
  98. /* 2^10 CPUs */
  99. #define VECTOR_TABLE_SIZE (1024 * sizeof(struct cvmx_boot_vector_element))
  100. static void cvmx_boot_vector_init(void *mem)
  101. {
  102. uint64_t kseg0_mem;
  103. int i;
  104. memset(mem, 0, VECTOR_TABLE_SIZE);
  105. kseg0_mem = cvmx_ptr_to_phys(mem) | 0x8000000000000000ull;
  106. for (i = 0; i < 15; i++) {
  107. uint64_t v = _cvmx_bootvector_data[i];
  108. if (OCTEON_IS_OCTEON1PLUS() && (i == 0 || i == 7))
  109. v &= 0xffffffff00000000ull; /* KScratch not availble. */
  110. cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8);
  111. cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, v);
  112. }
  113. cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, 15 * 8);
  114. cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, kseg0_mem);
  115. cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000);
  116. }
  117. /**
  118. * Get a pointer to the per-core table of reset vector pointers
  119. *
  120. */
  121. struct cvmx_boot_vector_element *cvmx_boot_vector_get(void)
  122. {
  123. struct cvmx_boot_vector_element *ret;
  124. ret = cvmx_bootmem_alloc_named_range_once(VECTOR_TABLE_SIZE, 0,
  125. (1ull << 32) - 1, 8, "__boot_vector1__", cvmx_boot_vector_init);
  126. return ret;
  127. }
  128. EXPORT_SYMBOL(cvmx_boot_vector_get);