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. # Disable unaligned load/store support but leave HW fixup enabled
  35. # Needed for octeon specific memcpy
  36. or v0, v0, 0x5001
  37. xor v0, v0, 0x1001
  38. # Read the processor ID register
  39. mfc0 v1, CP0_PRID_REG
  40. # Disable instruction prefetching (Octeon Pass1 errata)
  41. or v0, v0, 0x2000
  42. # Skip reenable of prefetching for Octeon Pass1
  43. beq v1, CP0_PRID_OCTEON_PASS1, skip
  44. nop
  45. # Reenable instruction prefetching, not on Pass1
  46. xor v0, v0, 0x2000
  47. # Strip off pass number off of processor id
  48. srl v1, 8
  49. sll v1, 8
  50. # CN30XX needs some extra stuff turned off for better performance
  51. bne v1, CP0_PRID_OCTEON_CN30XX, skip
  52. nop
  53. # CN30XX Use random Icache replacement
  54. or v0, v0, 0x400
  55. # CN30XX Disable instruction prefetching
  56. or v0, v0, 0x2000
  57. skip:
  58. # First clear off CvmCtl[IPPCI] bit and move the performance
  59. # counters interrupt to IRQ 6
  60. li v1, ~(7 << 7)
  61. and v0, v0, v1
  62. ori v0, v0, (6 << 7)
  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 */