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> 186c1c325dSDean Nelson #if defined CONFIG_X86_64 196c1c325dSDean Nelson #include <asm/uv/bios.h> 206c1c325dSDean Nelson #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 216c1c325dSDean Nelson #include <asm/sn/sn_sal.h> 226c1c325dSDean 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 35*68212893SRobin Holt /* 36*68212893SRobin Holt * Convert a global physical to socket physical address. 37*68212893SRobin Holt */ 38*68212893SRobin Holt static unsigned long 39*68212893SRobin Holt xp_socket_pa_uv(unsigned long gpa) 40*68212893SRobin Holt { 41*68212893SRobin Holt return uv_gpa_to_soc_phys_ram(gpa); 42*68212893SRobin Holt } 43*68212893SRobin Holt 44a812dcc3SDean Nelson static enum xp_retval 45a812dcc3SDean Nelson xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa, 46a812dcc3SDean Nelson size_t len) 47a812dcc3SDean Nelson { 48a812dcc3SDean Nelson int ret; 49a812dcc3SDean Nelson 50a812dcc3SDean Nelson ret = gru_copy_gpa(dst_gpa, src_gpa, len); 51a812dcc3SDean Nelson if (ret == 0) 52a812dcc3SDean Nelson return xpSuccess; 53a812dcc3SDean Nelson 54a812dcc3SDean Nelson dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 55a812dcc3SDean Nelson "len=%ld\n", dst_gpa, src_gpa, len); 56a812dcc3SDean Nelson return xpGruCopyError; 57908787dbSDean Nelson } 58908787dbSDean Nelson 595b8669dfSDean Nelson static int 605b8669dfSDean Nelson xp_cpu_to_nasid_uv(int cpuid) 615b8669dfSDean Nelson { 625b8669dfSDean Nelson /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */ 635b8669dfSDean Nelson return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); 645b8669dfSDean Nelson } 655b8669dfSDean Nelson 666c1c325dSDean Nelson static enum xp_retval 676c1c325dSDean Nelson xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) 686c1c325dSDean Nelson { 696c1c325dSDean Nelson int ret; 706c1c325dSDean Nelson 716c1c325dSDean Nelson #if defined CONFIG_X86_64 726c1c325dSDean Nelson ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); 736c1c325dSDean Nelson if (ret != BIOS_STATUS_SUCCESS) { 746c1c325dSDean Nelson dev_err(xp, "uv_bios_change_memprotect(,, " 756c1c325dSDean Nelson "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); 766c1c325dSDean Nelson return xpBiosError; 776c1c325dSDean Nelson } 786c1c325dSDean Nelson 796c1c325dSDean Nelson #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 806c1c325dSDean Nelson u64 nasid_array; 816c1c325dSDean Nelson 826c1c325dSDean Nelson ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, 836c1c325dSDean Nelson &nasid_array); 846c1c325dSDean Nelson if (ret != 0) { 856c1c325dSDean Nelson dev_err(xp, "sn_change_memprotect(,, " 866c1c325dSDean Nelson "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); 876c1c325dSDean Nelson return xpSalError; 886c1c325dSDean Nelson } 896c1c325dSDean Nelson #else 906c1c325dSDean Nelson #error not a supported configuration 916c1c325dSDean Nelson #endif 926c1c325dSDean Nelson return xpSuccess; 936c1c325dSDean Nelson } 946c1c325dSDean Nelson 956c1c325dSDean Nelson static enum xp_retval 966c1c325dSDean Nelson xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) 976c1c325dSDean Nelson { 986c1c325dSDean Nelson int ret; 996c1c325dSDean Nelson 1006c1c325dSDean Nelson #if defined CONFIG_X86_64 1016c1c325dSDean Nelson ret = uv_bios_change_memprotect(phys_addr, size, 1026c1c325dSDean Nelson UV_MEMPROT_RESTRICT_ACCESS); 1036c1c325dSDean Nelson if (ret != BIOS_STATUS_SUCCESS) { 1046c1c325dSDean Nelson dev_err(xp, "uv_bios_change_memprotect(,, " 1056c1c325dSDean Nelson "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); 1066c1c325dSDean Nelson return xpBiosError; 1076c1c325dSDean Nelson } 1086c1c325dSDean Nelson 1096c1c325dSDean Nelson #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 1106c1c325dSDean Nelson u64 nasid_array; 1116c1c325dSDean Nelson 1126c1c325dSDean Nelson ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, 1136c1c325dSDean Nelson &nasid_array); 1146c1c325dSDean Nelson if (ret != 0) { 1156c1c325dSDean Nelson dev_err(xp, "sn_change_memprotect(,, " 1166c1c325dSDean Nelson "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); 1176c1c325dSDean Nelson return xpSalError; 1186c1c325dSDean Nelson } 1196c1c325dSDean Nelson #else 1206c1c325dSDean Nelson #error not a supported configuration 1216c1c325dSDean Nelson #endif 1226c1c325dSDean Nelson return xpSuccess; 1236c1c325dSDean Nelson } 1246c1c325dSDean Nelson 125bc63d387SDean Nelson enum xp_retval 126bc63d387SDean Nelson xp_init_uv(void) 127bc63d387SDean Nelson { 128bc63d387SDean Nelson BUG_ON(!is_uv()); 129bc63d387SDean Nelson 130bc63d387SDean Nelson xp_max_npartitions = XP_MAX_NPARTITIONS_UV; 13131de5eceSDean Nelson xp_partition_id = sn_partition_id; 13231de5eceSDean Nelson xp_region_size = sn_region_size; 133908787dbSDean Nelson 134a812dcc3SDean Nelson xp_pa = xp_pa_uv; 135*68212893SRobin Holt xp_socket_pa = xp_socket_pa_uv; 136908787dbSDean Nelson xp_remote_memcpy = xp_remote_memcpy_uv; 1375b8669dfSDean Nelson xp_cpu_to_nasid = xp_cpu_to_nasid_uv; 1386c1c325dSDean Nelson xp_expand_memprotect = xp_expand_memprotect_uv; 1396c1c325dSDean Nelson xp_restrict_memprotect = xp_restrict_memprotect_uv; 140908787dbSDean Nelson 141908787dbSDean Nelson return xpSuccess; 142bc63d387SDean Nelson } 143bc63d387SDean Nelson 144bc63d387SDean Nelson void 145bc63d387SDean Nelson xp_exit_uv(void) 146bc63d387SDean Nelson { 147bc63d387SDean Nelson BUG_ON(!is_uv()); 148bc63d387SDean Nelson } 149