0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/device.h>
0018 #include <asm/uv/uv_hub.h>
0019 #if defined CONFIG_X86_64
0020 #include <asm/uv/bios.h>
0021 #elif defined CONFIG_IA64_SGI_UV
0022 #include <asm/sn/sn_sal.h>
0023 #endif
0024 #include "../sgi-gru/grukservices.h"
0025 #include "xp.h"
0026
0027
0028
0029
0030 static unsigned long
0031 xp_pa_uv(void *addr)
0032 {
0033 return uv_gpa(addr);
0034 }
0035
0036
0037
0038
0039 static unsigned long
0040 xp_socket_pa_uv(unsigned long gpa)
0041 {
0042 return uv_gpa_to_soc_phys_ram(gpa);
0043 }
0044
0045 static enum xp_retval
0046 xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
0047 size_t len)
0048 {
0049 int ret;
0050 unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
0051
0052 BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
0053 BUG_ON(len != 8);
0054
0055 ret = gru_read_gpa(dst_va, src_gpa);
0056 if (ret == 0)
0057 return xpSuccess;
0058
0059 dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
0060 "len=%ld\n", dst_gpa, src_gpa, len);
0061 return xpGruCopyError;
0062 }
0063
0064
0065 static enum xp_retval
0066 xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
0067 size_t len)
0068 {
0069 int ret;
0070
0071 if (uv_gpa_in_mmr_space(src_gpa))
0072 return xp_remote_mmr_read(dst_gpa, src_gpa, len);
0073
0074 ret = gru_copy_gpa(dst_gpa, src_gpa, len);
0075 if (ret == 0)
0076 return xpSuccess;
0077
0078 dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
0079 "len=%ld\n", dst_gpa, src_gpa, len);
0080 return xpGruCopyError;
0081 }
0082
0083 static int
0084 xp_cpu_to_nasid_uv(int cpuid)
0085 {
0086
0087 return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
0088 }
0089
0090 static enum xp_retval
0091 xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
0092 {
0093 int ret;
0094
0095 #if defined CONFIG_X86_64
0096 ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
0097 if (ret != BIOS_STATUS_SUCCESS) {
0098 dev_err(xp, "uv_bios_change_memprotect(,, "
0099 "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
0100 return xpBiosError;
0101 }
0102
0103 #elif defined CONFIG_IA64_SGI_UV
0104 u64 nasid_array;
0105
0106 ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
0107 &nasid_array);
0108 if (ret != 0) {
0109 dev_err(xp, "sn_change_memprotect(,, "
0110 "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
0111 return xpSalError;
0112 }
0113 #else
0114 #error not a supported configuration
0115 #endif
0116 return xpSuccess;
0117 }
0118
0119 static enum xp_retval
0120 xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
0121 {
0122 int ret;
0123
0124 #if defined CONFIG_X86_64
0125 ret = uv_bios_change_memprotect(phys_addr, size,
0126 UV_MEMPROT_RESTRICT_ACCESS);
0127 if (ret != BIOS_STATUS_SUCCESS) {
0128 dev_err(xp, "uv_bios_change_memprotect(,, "
0129 "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
0130 return xpBiosError;
0131 }
0132
0133 #elif defined CONFIG_IA64_SGI_UV
0134 u64 nasid_array;
0135
0136 ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
0137 &nasid_array);
0138 if (ret != 0) {
0139 dev_err(xp, "sn_change_memprotect(,, "
0140 "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
0141 return xpSalError;
0142 }
0143 #else
0144 #error not a supported configuration
0145 #endif
0146 return xpSuccess;
0147 }
0148
0149 enum xp_retval
0150 xp_init_uv(void)
0151 {
0152 WARN_ON(!is_uv_system());
0153 if (!is_uv_system())
0154 return xpUnsupported;
0155
0156 xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
0157 #ifdef CONFIG_X86
0158 xp_partition_id = sn_partition_id;
0159 xp_region_size = sn_region_size;
0160 #endif
0161 xp_pa = xp_pa_uv;
0162 xp_socket_pa = xp_socket_pa_uv;
0163 xp_remote_memcpy = xp_remote_memcpy_uv;
0164 xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
0165 xp_expand_memprotect = xp_expand_memprotect_uv;
0166 xp_restrict_memprotect = xp_restrict_memprotect_uv;
0167
0168 return xpSuccess;
0169 }
0170
0171 void
0172 xp_exit_uv(void)
0173 {
0174 WARN_ON(!is_uv_system());
0175 }