xp_sn2.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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) 2008 Silicon Graphics, Inc. All Rights Reserved.
  7. */
  8. /*
  9. * Cross Partition (XP) sn2-based functions.
  10. *
  11. * Architecture specific implementation of common functions.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/device.h>
  15. #include <asm/sn/bte.h>
  16. #include <asm/sn/sn_sal.h>
  17. #include "xp.h"
  18. /*
  19. * The export of xp_nofault_PIOR needs to happen here since it is defined
  20. * in drivers/misc/sgi-xp/xp_nofault.S. The target of the nofault read is
  21. * defined here.
  22. */
  23. EXPORT_SYMBOL_GPL(xp_nofault_PIOR);
  24. u64 xp_nofault_PIOR_target;
  25. EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target);
  26. /*
  27. * Register a nofault code region which performs a cross-partition PIO read.
  28. * If the PIO read times out, the MCA handler will consume the error and
  29. * return to a kernel-provided instruction to indicate an error. This PIO read
  30. * exists because it is guaranteed to timeout if the destination is down
  31. * (amo operations do not timeout on at least some CPUs on Shubs <= v1.2,
  32. * which unfortunately we have to work around).
  33. */
  34. static enum xp_retval
  35. xp_register_nofault_code_sn2(void)
  36. {
  37. int ret;
  38. u64 func_addr;
  39. u64 err_func_addr;
  40. func_addr = *(u64 *)xp_nofault_PIOR;
  41. err_func_addr = *(u64 *)xp_error_PIOR;
  42. ret = sn_register_nofault_code(func_addr, err_func_addr, err_func_addr,
  43. 1, 1);
  44. if (ret != 0) {
  45. dev_err(xp, "can't register nofault code, error=%d\n", ret);
  46. return xpSalError;
  47. }
  48. /*
  49. * Setup the nofault PIO read target. (There is no special reason why
  50. * SH_IPI_ACCESS was selected.)
  51. */
  52. if (is_shub1())
  53. xp_nofault_PIOR_target = SH1_IPI_ACCESS;
  54. else if (is_shub2())
  55. xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
  56. return xpSuccess;
  57. }
  58. static void
  59. xp_unregister_nofault_code_sn2(void)
  60. {
  61. u64 func_addr = *(u64 *)xp_nofault_PIOR;
  62. u64 err_func_addr = *(u64 *)xp_error_PIOR;
  63. /* unregister the PIO read nofault code region */
  64. (void)sn_register_nofault_code(func_addr, err_func_addr,
  65. err_func_addr, 1, 0);
  66. }
  67. /*
  68. * Convert a virtual memory address to a physical memory address.
  69. */
  70. static unsigned long
  71. xp_pa_sn2(void *addr)
  72. {
  73. return __pa(addr);
  74. }
  75. /*
  76. * Convert a global physical to a socket physical address.
  77. */
  78. static unsigned long
  79. xp_socket_pa_sn2(unsigned long gpa)
  80. {
  81. return gpa;
  82. }
  83. /*
  84. * Wrapper for bte_copy().
  85. *
  86. * dst_pa - physical address of the destination of the transfer.
  87. * src_pa - physical address of the source of the transfer.
  88. * len - number of bytes to transfer from source to destination.
  89. *
  90. * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
  91. */
  92. static enum xp_retval
  93. xp_remote_memcpy_sn2(unsigned long dst_pa, const unsigned long src_pa,
  94. size_t len)
  95. {
  96. bte_result_t ret;
  97. ret = bte_copy(src_pa, dst_pa, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
  98. if (ret == BTE_SUCCESS)
  99. return xpSuccess;
  100. if (is_shub2()) {
  101. dev_err(xp, "bte_copy() on shub2 failed, error=0x%x dst_pa="
  102. "0x%016lx src_pa=0x%016lx len=%ld\\n", ret, dst_pa,
  103. src_pa, len);
  104. } else {
  105. dev_err(xp, "bte_copy() failed, error=%d dst_pa=0x%016lx "
  106. "src_pa=0x%016lx len=%ld\\n", ret, dst_pa, src_pa, len);
  107. }
  108. return xpBteCopyError;
  109. }
  110. static int
  111. xp_cpu_to_nasid_sn2(int cpuid)
  112. {
  113. return cpuid_to_nasid(cpuid);
  114. }
  115. static enum xp_retval
  116. xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
  117. {
  118. u64 nasid_array = 0;
  119. int ret;
  120. ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
  121. &nasid_array);
  122. if (ret != 0) {
  123. dev_err(xp, "sn_change_memprotect(,, "
  124. "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
  125. return xpSalError;
  126. }
  127. return xpSuccess;
  128. }
  129. static enum xp_retval
  130. xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
  131. {
  132. u64 nasid_array = 0;
  133. int ret;
  134. ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
  135. &nasid_array);
  136. if (ret != 0) {
  137. dev_err(xp, "sn_change_memprotect(,, "
  138. "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
  139. return xpSalError;
  140. }
  141. return xpSuccess;
  142. }
  143. enum xp_retval
  144. xp_init_sn2(void)
  145. {
  146. BUG_ON(!is_shub());
  147. xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
  148. xp_partition_id = sn_partition_id;
  149. xp_region_size = sn_region_size;
  150. xp_pa = xp_pa_sn2;
  151. xp_socket_pa = xp_socket_pa_sn2;
  152. xp_remote_memcpy = xp_remote_memcpy_sn2;
  153. xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
  154. xp_expand_memprotect = xp_expand_memprotect_sn2;
  155. xp_restrict_memprotect = xp_restrict_memprotect_sn2;
  156. return xp_register_nofault_code_sn2();
  157. }
  158. void
  159. xp_exit_sn2(void)
  160. {
  161. BUG_ON(!is_shub());
  162. xp_unregister_nofault_code_sn2();
  163. }