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 * (C) Copyright 2020 Hewlett Packard Enterprise Development LP 7 * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. 8 */ 9 10 /* 11 * Cross Partition (XP) uv-based functions. 12 * 13 * Architecture specific implementation of common functions. 14 * 15 */ 16 17 #include <linux/device.h> 18 #include <asm/uv/uv_hub.h> 19 #if defined CONFIG_X86_64 20 #include <asm/uv/bios.h> 21 #elif defined CONFIG_IA64_SGI_UV 22 #include <asm/sn/sn_sal.h> 23 #endif 24 #include "../sgi-gru/grukservices.h" 25 #include "xp.h" 26 27 /* 28 * Convert a virtual memory address to a physical memory address. 29 */ 30 static unsigned long 31 xp_pa_uv(void *addr) 32 { 33 return uv_gpa(addr); 34 } 35 36 /* 37 * Convert a global physical to socket physical address. 38 */ 39 static unsigned long 40 xp_socket_pa_uv(unsigned long gpa) 41 { 42 return uv_gpa_to_soc_phys_ram(gpa); 43 } 44 45 static enum xp_retval 46 xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa, 47 size_t len) 48 { 49 int ret; 50 unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa)); 51 52 BUG_ON(!uv_gpa_in_mmr_space(src_gpa)); 53 BUG_ON(len != 8); 54 55 ret = gru_read_gpa(dst_va, src_gpa); 56 if (ret == 0) 57 return xpSuccess; 58 59 dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 60 "len=%ld\n", dst_gpa, src_gpa, len); 61 return xpGruCopyError; 62 } 63 64 65 static enum xp_retval 66 xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa, 67 size_t len) 68 { 69 int ret; 70 71 if (uv_gpa_in_mmr_space(src_gpa)) 72 return xp_remote_mmr_read(dst_gpa, src_gpa, len); 73 74 ret = gru_copy_gpa(dst_gpa, src_gpa, len); 75 if (ret == 0) 76 return xpSuccess; 77 78 dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 79 "len=%ld\n", dst_gpa, src_gpa, len); 80 return xpGruCopyError; 81 } 82 83 static int 84 xp_cpu_to_nasid_uv(int cpuid) 85 { 86 /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */ 87 return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); 88 } 89 90 static enum xp_retval 91 xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) 92 { 93 int ret; 94 95 #if defined CONFIG_X86_64 96 ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); 97 if (ret != BIOS_STATUS_SUCCESS) { 98 dev_err(xp, "uv_bios_change_memprotect(,, " 99 "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); 100 return xpBiosError; 101 } 102 103 #elif defined CONFIG_IA64_SGI_UV 104 u64 nasid_array; 105 106 ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, 107 &nasid_array); 108 if (ret != 0) { 109 dev_err(xp, "sn_change_memprotect(,, " 110 "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); 111 return xpSalError; 112 } 113 #else 114 #error not a supported configuration 115 #endif 116 return xpSuccess; 117 } 118 119 static enum xp_retval 120 xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) 121 { 122 int ret; 123 124 #if defined CONFIG_X86_64 125 ret = uv_bios_change_memprotect(phys_addr, size, 126 UV_MEMPROT_RESTRICT_ACCESS); 127 if (ret != BIOS_STATUS_SUCCESS) { 128 dev_err(xp, "uv_bios_change_memprotect(,, " 129 "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); 130 return xpBiosError; 131 } 132 133 #elif defined CONFIG_IA64_SGI_UV 134 u64 nasid_array; 135 136 ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, 137 &nasid_array); 138 if (ret != 0) { 139 dev_err(xp, "sn_change_memprotect(,, " 140 "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); 141 return xpSalError; 142 } 143 #else 144 #error not a supported configuration 145 #endif 146 return xpSuccess; 147 } 148 149 enum xp_retval 150 xp_init_uv(void) 151 { 152 WARN_ON(!is_uv_system()); 153 if (!is_uv_system()) 154 return xpUnsupported; 155 156 xp_max_npartitions = XP_MAX_NPARTITIONS_UV; 157 #ifdef CONFIG_X86 158 xp_partition_id = sn_partition_id; 159 xp_region_size = sn_region_size; 160 #endif 161 xp_pa = xp_pa_uv; 162 xp_socket_pa = xp_socket_pa_uv; 163 xp_remote_memcpy = xp_remote_memcpy_uv; 164 xp_cpu_to_nasid = xp_cpu_to_nasid_uv; 165 xp_expand_memprotect = xp_expand_memprotect_uv; 166 xp_restrict_memprotect = xp_restrict_memprotect_uv; 167 168 return xpSuccess; 169 } 170 171 void 172 xp_exit_uv(void) 173 { 174 WARN_ON(!is_uv_system()); 175 } 176