1bc63d387SDean Nelson /* 2bc63d387SDean Nelson * This file is subject to the terms and conditions of the GNU General Public 3bc63d387SDean Nelson * License. See the file "COPYING" in the main directory of this archive 4bc63d387SDean Nelson * for more details. 5bc63d387SDean Nelson * 6bc63d387SDean Nelson * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. 7bc63d387SDean Nelson */ 8bc63d387SDean Nelson 9bc63d387SDean Nelson /* 10bc63d387SDean Nelson * Cross Partition (XP) uv-based functions. 11bc63d387SDean Nelson * 12bc63d387SDean Nelson * Architecture specific implementation of common functions. 13bc63d387SDean Nelson * 14bc63d387SDean Nelson */ 15bc63d387SDean Nelson 16a812dcc3SDean Nelson #include <linux/device.h> 17a812dcc3SDean Nelson #include <asm/uv/uv_hub.h> 18*6c1c325dSDean Nelson #if defined CONFIG_X86_64 19*6c1c325dSDean Nelson #include <asm/uv/bios.h> 20*6c1c325dSDean Nelson #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 21*6c1c325dSDean Nelson #include <asm/sn/sn_sal.h> 22*6c1c325dSDean Nelson #endif 23a812dcc3SDean Nelson #include "../sgi-gru/grukservices.h" 24bc63d387SDean Nelson #include "xp.h" 25bc63d387SDean Nelson 26a812dcc3SDean Nelson /* 27a812dcc3SDean Nelson * Convert a virtual memory address to a physical memory address. 28a812dcc3SDean Nelson */ 29a812dcc3SDean Nelson static unsigned long 30a812dcc3SDean Nelson xp_pa_uv(void *addr) 31908787dbSDean Nelson { 32a812dcc3SDean Nelson return uv_gpa(addr); 33a812dcc3SDean Nelson } 34a812dcc3SDean Nelson 35a812dcc3SDean Nelson static enum xp_retval 36a812dcc3SDean Nelson xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa, 37a812dcc3SDean Nelson size_t len) 38a812dcc3SDean Nelson { 39a812dcc3SDean Nelson int ret; 40a812dcc3SDean Nelson 41a812dcc3SDean Nelson ret = gru_copy_gpa(dst_gpa, src_gpa, len); 42a812dcc3SDean Nelson if (ret == 0) 43a812dcc3SDean Nelson return xpSuccess; 44a812dcc3SDean Nelson 45a812dcc3SDean Nelson dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 46a812dcc3SDean Nelson "len=%ld\n", dst_gpa, src_gpa, len); 47a812dcc3SDean Nelson return xpGruCopyError; 48908787dbSDean Nelson } 49908787dbSDean Nelson 505b8669dfSDean Nelson static int 515b8669dfSDean Nelson xp_cpu_to_nasid_uv(int cpuid) 525b8669dfSDean Nelson { 535b8669dfSDean Nelson /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */ 545b8669dfSDean Nelson return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); 555b8669dfSDean Nelson } 565b8669dfSDean Nelson 57*6c1c325dSDean Nelson static enum xp_retval 58*6c1c325dSDean Nelson xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) 59*6c1c325dSDean Nelson { 60*6c1c325dSDean Nelson int ret; 61*6c1c325dSDean Nelson 62*6c1c325dSDean Nelson #if defined CONFIG_X86_64 63*6c1c325dSDean Nelson ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); 64*6c1c325dSDean Nelson if (ret != BIOS_STATUS_SUCCESS) { 65*6c1c325dSDean Nelson dev_err(xp, "uv_bios_change_memprotect(,, " 66*6c1c325dSDean Nelson "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); 67*6c1c325dSDean Nelson return xpBiosError; 68*6c1c325dSDean Nelson } 69*6c1c325dSDean Nelson 70*6c1c325dSDean Nelson #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 71*6c1c325dSDean Nelson u64 nasid_array; 72*6c1c325dSDean Nelson 73*6c1c325dSDean Nelson ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, 74*6c1c325dSDean Nelson &nasid_array); 75*6c1c325dSDean Nelson if (ret != 0) { 76*6c1c325dSDean Nelson dev_err(xp, "sn_change_memprotect(,, " 77*6c1c325dSDean Nelson "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); 78*6c1c325dSDean Nelson return xpSalError; 79*6c1c325dSDean Nelson } 80*6c1c325dSDean Nelson #else 81*6c1c325dSDean Nelson #error not a supported configuration 82*6c1c325dSDean Nelson #endif 83*6c1c325dSDean Nelson return xpSuccess; 84*6c1c325dSDean Nelson } 85*6c1c325dSDean Nelson 86*6c1c325dSDean Nelson static enum xp_retval 87*6c1c325dSDean Nelson xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) 88*6c1c325dSDean Nelson { 89*6c1c325dSDean Nelson int ret; 90*6c1c325dSDean Nelson 91*6c1c325dSDean Nelson #if defined CONFIG_X86_64 92*6c1c325dSDean Nelson ret = uv_bios_change_memprotect(phys_addr, size, 93*6c1c325dSDean Nelson UV_MEMPROT_RESTRICT_ACCESS); 94*6c1c325dSDean Nelson if (ret != BIOS_STATUS_SUCCESS) { 95*6c1c325dSDean Nelson dev_err(xp, "uv_bios_change_memprotect(,, " 96*6c1c325dSDean Nelson "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); 97*6c1c325dSDean Nelson return xpBiosError; 98*6c1c325dSDean Nelson } 99*6c1c325dSDean Nelson 100*6c1c325dSDean Nelson #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 101*6c1c325dSDean Nelson u64 nasid_array; 102*6c1c325dSDean Nelson 103*6c1c325dSDean Nelson ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, 104*6c1c325dSDean Nelson &nasid_array); 105*6c1c325dSDean Nelson if (ret != 0) { 106*6c1c325dSDean Nelson dev_err(xp, "sn_change_memprotect(,, " 107*6c1c325dSDean Nelson "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); 108*6c1c325dSDean Nelson return xpSalError; 109*6c1c325dSDean Nelson } 110*6c1c325dSDean Nelson #else 111*6c1c325dSDean Nelson #error not a supported configuration 112*6c1c325dSDean Nelson #endif 113*6c1c325dSDean Nelson return xpSuccess; 114*6c1c325dSDean Nelson } 115*6c1c325dSDean Nelson 116bc63d387SDean Nelson enum xp_retval 117bc63d387SDean Nelson xp_init_uv(void) 118bc63d387SDean Nelson { 119bc63d387SDean Nelson BUG_ON(!is_uv()); 120bc63d387SDean Nelson 121bc63d387SDean Nelson xp_max_npartitions = XP_MAX_NPARTITIONS_UV; 1225b8669dfSDean Nelson xp_partition_id = 0; /* !!! not correct value */ 1235b8669dfSDean Nelson xp_region_size = 0; /* !!! not correct value */ 124908787dbSDean Nelson 125a812dcc3SDean Nelson xp_pa = xp_pa_uv; 126908787dbSDean Nelson xp_remote_memcpy = xp_remote_memcpy_uv; 1275b8669dfSDean Nelson xp_cpu_to_nasid = xp_cpu_to_nasid_uv; 128*6c1c325dSDean Nelson xp_expand_memprotect = xp_expand_memprotect_uv; 129*6c1c325dSDean Nelson xp_restrict_memprotect = xp_restrict_memprotect_uv; 130908787dbSDean Nelson 131908787dbSDean Nelson return xpSuccess; 132bc63d387SDean Nelson } 133bc63d387SDean Nelson 134bc63d387SDean Nelson void 135bc63d387SDean Nelson xp_exit_uv(void) 136bc63d387SDean Nelson { 137bc63d387SDean Nelson BUG_ON(!is_uv()); 138bc63d387SDean Nelson } 139