kernel-entry-init.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. # Write the cavium control register
  64. dmtc0 v0, CP0_CVMCTL_REG
  65. sync
  66. # Flush dcache after config change
  67. cache 9, 0($0)
  68. # Get my core id
  69. rdhwr v0, $0
  70. # Jump the master to kernel_entry
  71. bne a2, zero, octeon_main_processor
  72. nop
  73. #ifdef CONFIG_SMP
  74. #
  75. # All cores other than the master need to wait here for SMP bootstrap
  76. # to begin
  77. #
  78. # This is the variable where the next core to boot os stored
  79. PTR_LA t0, octeon_processor_boot
  80. octeon_spin_wait_boot:
  81. # Get the core id of the next to be booted
  82. LONG_L t1, (t0)
  83. # Keep looping if it isn't me
  84. bne t1, v0, octeon_spin_wait_boot
  85. nop
  86. # Get my GP from the global variable
  87. PTR_LA t0, octeon_processor_gp
  88. LONG_L gp, (t0)
  89. # Get my SP from the global variable
  90. PTR_LA t0, octeon_processor_sp
  91. LONG_L sp, (t0)
  92. # Set the SP global variable to zero so the master knows we've started
  93. LONG_S zero, (t0)
  94. #ifdef __OCTEON__
  95. syncw
  96. syncw
  97. #else
  98. sync
  99. #endif
  100. # Jump to the normal Linux SMP entry point
  101. j smp_bootstrap
  102. nop
  103. #else /* CONFIG_SMP */
  104. #
  105. # Someone tried to boot SMP with a non SMP kernel. All extra cores
  106. # will halt here.
  107. #
  108. octeon_wait_forever:
  109. wait
  110. b octeon_wait_forever
  111. nop
  112. #endif /* CONFIG_SMP */
  113. octeon_main_processor:
  114. .set pop
  115. .endm
  116. /*
  117. * Do SMP slave processor setup necessary before we can savely execute C code.
  118. */
  119. .macro smp_slave_setup
  120. .endm
  121. #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */