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 /* 10 * Cross Partition (XP) uv-based functions. 11 * 12 * Architecture specific implementation of common functions. 13 * 14 */ 15 16 #include <linux/device.h> 17 #include <asm/uv/uv_hub.h> 18 #if defined CONFIG_X86_64 19 #include <asm/uv/bios.h> 20 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 21 #include <asm/sn/sn_sal.h> 22 #endif 23 #include "../sgi-gru/grukservices.h" 24 #include "xp.h" 25 26 /* 27 * Convert a virtual memory address to a physical memory address. 28 */ 29 static unsigned long 30 xp_pa_uv(void *addr) 31 { 32 return uv_gpa(addr); 33 } 34 35 static enum xp_retval 36 xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa, 37 size_t len) 38 { 39 int ret; 40 41 ret = gru_copy_gpa(dst_gpa, src_gpa, len); 42 if (ret == 0) 43 return xpSuccess; 44 45 dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 46 "len=%ld\n", dst_gpa, src_gpa, len); 47 return xpGruCopyError; 48 } 49 50 static int 51 xp_cpu_to_nasid_uv(int cpuid) 52 { 53 /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */ 54 return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); 55 } 56 57 static enum xp_retval 58 xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) 59 { 60 int ret; 61 62 #if defined CONFIG_X86_64 63 ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); 64 if (ret != BIOS_STATUS_SUCCESS) { 65 dev_err(xp, "uv_bios_change_memprotect(,, " 66 "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); 67 return xpBiosError; 68 } 69 70 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 71 u64 nasid_array; 72 73 ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, 74 &nasid_array); 75 if (ret != 0) { 76 dev_err(xp, "sn_change_memprotect(,, " 77 "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); 78 return xpSalError; 79 } 80 #else 81 #error not a supported configuration 82 #endif 83 return xpSuccess; 84 } 85 86 static enum xp_retval 87 xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) 88 { 89 int ret; 90 91 #if defined CONFIG_X86_64 92 ret = uv_bios_change_memprotect(phys_addr, size, 93 UV_MEMPROT_RESTRICT_ACCESS); 94 if (ret != BIOS_STATUS_SUCCESS) { 95 dev_err(xp, "uv_bios_change_memprotect(,, " 96 "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); 97 return xpBiosError; 98 } 99 100 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 101 u64 nasid_array; 102 103 ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, 104 &nasid_array); 105 if (ret != 0) { 106 dev_err(xp, "sn_change_memprotect(,, " 107 "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); 108 return xpSalError; 109 } 110 #else 111 #error not a supported configuration 112 #endif 113 return xpSuccess; 114 } 115 116 enum xp_retval 117 xp_init_uv(void) 118 { 119 BUG_ON(!is_uv()); 120 121 xp_max_npartitions = XP_MAX_NPARTITIONS_UV; 122 xp_partition_id = sn_partition_id; 123 xp_region_size = sn_region_size; 124 125 xp_pa = xp_pa_uv; 126 xp_remote_memcpy = xp_remote_memcpy_uv; 127 xp_cpu_to_nasid = xp_cpu_to_nasid_uv; 128 xp_expand_memprotect = xp_expand_memprotect_uv; 129 xp_restrict_memprotect = xp_restrict_memprotect_uv; 130 131 return xpSuccess; 132 } 133 134 void 135 xp_exit_uv(void) 136 { 137 BUG_ON(!is_uv()); 138 } 139