kernel-entry-init.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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) 2005-2008 Cavium Networks, Inc
  7. */
  8. #ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
  9. #define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
  10. #define CP0_CYCLE_COUNTER $9, 6
  11. #define CP0_CVMCTL_REG $9, 7
  12. #define CP0_CVMMEMCTL_REG $11,7
  13. #define CP0_PRID_REG $15, 0
  14. #define CP0_PRID_OCTEON_PASS1 0x000d0000
  15. #define CP0_PRID_OCTEON_CN30XX 0x000d0200
  16. .macro kernel_entry_setup
  17. # Registers set by bootloader:
  18. # (only 32 bits set by bootloader, all addresses are physical
  19. # addresses, and need to have the appropriate memory region set
  20. # by the kernel
  21. # a0 = argc
  22. # a1 = argv (kseg0 compat addr)
  23. # a2 = 1 if init core, zero otherwise
  24. # a3 = address of boot descriptor block
  25. .set push
  26. .set arch=octeon
  27. # Read the cavium mem control register
  28. dmfc0 v0, CP0_CVMMEMCTL_REG
  29. # Clear the lower 6 bits, the CVMSEG size
  30. dins v0, $0, 0, 6
  31. ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
  32. dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register
  33. dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register
  34. #ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
  35. # Disable unaligned load/store support but leave HW fixup enabled
  36. or v0, v0, 0x5001
  37. xor v0, v0, 0x1001
  38. #else
  39. # Disable unaligned load/store and HW fixup support
  40. or v0, v0, 0x5001
  41. xor v0, v0, 0x5001
  42. #endif
  43. # Read the processor ID register
  44. mfc0 v1, CP0_PRID_REG
  45. # Disable instruction prefetching (Octeon Pass1 errata)
  46. or v0, v0, 0x2000
  47. # Skip reenable of prefetching for Octeon Pass1
  48. beq v1, CP0_PRID_OCTEON_PASS1, skip
  49. nop
  50. # Reenable instruction prefetching, not on Pass1
  51. xor v0, v0, 0x2000
  52. # Strip off pass number off of processor id
  53. srl v1, 8
  54. sll v1, 8
  55. # CN30XX needs some extra stuff turned off for better performance
  56. bne v1, CP0_PRID_OCTEON_CN30XX, skip
  57. nop
  58. # CN30XX Use random Icache replacement
  59. or v0, v0, 0x400
  60. # CN30XX Disable instruction prefetching
  61. or v0, v0, 0x2000
  62. skip:
  63. # First clear off CvmCtl[IPPCI] bit and move the performance
  64. # counters interrupt to IRQ 6
  65. li v1, ~(7 << 7)
  66. and v0, v0, v1
  67. ori v0, v0, (6 << 7)
  68. # Write the cavium control register
  69. dmtc0 v0, CP0_CVMCTL_REG
  70. sync
  71. # Flush dcache after config change
  72. cache 9, 0($0)
  73. # Get my core id
  74. rdhwr v0, $0
  75. # Jump the master to kernel_entry
  76. bne a2, zero, octeon_main_processor
  77. nop
  78. #ifdef CONFIG_SMP
  79. #
  80. # All cores other than the master need to wait here for SMP bootstrap
  81. # to begin
  82. #
  83. # This is the variable where the next core to boot os stored
  84. PTR_LA t0, octeon_processor_boot
  85. octeon_spin_wait_boot:
  86. # Get the core id of the next to be booted
  87. LONG_L t1, (t0)
  88. # Keep looping if it isn't me
  89. bne t1, v0, octeon_spin_wait_boot
  90. nop
  91. # Get my GP from the global variable
  92. PTR_LA t0, octeon_processor_gp
  93. LONG_L gp, (t0)
  94. # Get my SP from the global variable
  95. PTR_LA t0, octeon_processor_sp
  96. LONG_L sp, (t0)
  97. # Set the SP global variable to zero so the master knows we've started
  98. LONG_S zero, (t0)
  99. #ifdef __OCTEON__
  100. syncw
  101. syncw
  102. #else
  103. sync
  104. #endif
  105. # Jump to the normal Linux SMP entry point
  106. j smp_bootstrap
  107. nop
  108. #else /* CONFIG_SMP */
  109. #
  110. # Someone tried to boot SMP with a non SMP kernel. All extra cores
  111. # will halt here.
  112. #
  113. octeon_wait_forever:
  114. wait
  115. b octeon_wait_forever
  116. nop
  117. #endif /* CONFIG_SMP */
  118. octeon_main_processor:
  119. .set pop
  120. .endm
  121. /*
  122. * Do SMP slave processor setup necessary before we can savely execute C code.
  123. */
  124. .macro smp_slave_setup
  125. .endm
  126. #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */