xp_sn2.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. * Wrapper for bte_copy().
  77. *
  78. * dst_pa - physical address of the destination of the transfer.
  79. * src_pa - physical address of the source of the transfer.
  80. * len - number of bytes to transfer from source to destination.
  81. *
  82. * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
  83. */
  84. static enum xp_retval
  85. xp_remote_memcpy_sn2(unsigned long dst_pa, const unsigned long src_pa,
  86. size_t len)
  87. {
  88. bte_result_t ret;
  89. ret = bte_copy(src_pa, dst_pa, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
  90. if (ret == BTE_SUCCESS)
  91. return xpSuccess;
  92. if (is_shub2()) {
  93. dev_err(xp, "bte_copy() on shub2 failed, error=0x%x dst_pa="
  94. "0x%016lx src_pa=0x%016lx len=%ld\\n", ret, dst_pa,
  95. src_pa, len);
  96. } else {
  97. dev_err(xp, "bte_copy() failed, error=%d dst_pa=0x%016lx "
  98. "src_pa=0x%016lx len=%ld\\n", ret, dst_pa, src_pa, len);
  99. }
  100. return xpBteCopyError;
  101. }
  102. static int
  103. xp_cpu_to_nasid_sn2(int cpuid)
  104. {
  105. return cpuid_to_nasid(cpuid);
  106. }
  107. static enum xp_retval
  108. xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
  109. {
  110. u64 nasid_array = 0;
  111. int ret;
  112. ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
  113. &nasid_array);
  114. if (ret != 0) {
  115. dev_err(xp, "sn_change_memprotect(,, "
  116. "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
  117. return xpSalError;
  118. }
  119. return xpSuccess;
  120. }
  121. static enum xp_retval
  122. xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
  123. {
  124. u64 nasid_array = 0;
  125. int ret;
  126. ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
  127. &nasid_array);
  128. if (ret != 0) {
  129. dev_err(xp, "sn_change_memprotect(,, "
  130. "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
  131. return xpSalError;
  132. }
  133. return xpSuccess;
  134. }
  135. enum xp_retval
  136. xp_init_sn2(void)
  137. {
  138. BUG_ON(!is_shub());
  139. xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
  140. xp_partition_id = sn_partition_id;
  141. xp_region_size = sn_region_size;
  142. xp_pa = xp_pa_sn2;
  143. xp_remote_memcpy = xp_remote_memcpy_sn2;
  144. xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
  145. xp_expand_memprotect = xp_expand_memprotect_sn2;
  146. xp_restrict_memprotect = xp_restrict_memprotect_sn2;
  147. return xp_register_nofault_code_sn2();
  148. }
  149. void
  150. xp_exit_sn2(void)
  151. {
  152. BUG_ON(!is_shub());
  153. xp_unregister_nofault_code_sn2();
  154. }