1bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson/* 2bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * This file is subject to the terms and conditions of the GNU General Public 3bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * License. See the file "COPYING" in the main directory of this archive 4bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * for more details. 5bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * 6bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. 7bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson */ 8bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson 9bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson/* 10bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * Cross Partition (XP) uv-based functions. 11bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * 12bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * Architecture specific implementation of common functions. 13bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson * 14bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson */ 15bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson 16a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson#include <linux/device.h> 17a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson#include <asm/uv/uv_hub.h> 186c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#if defined CONFIG_X86_64 196c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#include <asm/uv/bios.h> 206c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 216c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#include <asm/sn/sn_sal.h> 226c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#endif 23a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson#include "../sgi-gru/grukservices.h" 24bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson#include "xp.h" 25bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson 26a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson/* 27a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson * Convert a virtual memory address to a physical memory address. 28a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson */ 29a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelsonstatic unsigned long 30a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelsonxp_pa_uv(void *addr) 31a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson{ 32a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson return uv_gpa(addr); 33a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson} 34a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson 35682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt/* 36682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt * Convert a global physical to socket physical address. 37682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt */ 38682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holtstatic unsigned long 39682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holtxp_socket_pa_uv(unsigned long gpa) 40682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt{ 41682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt return uv_gpa_to_soc_phys_ram(gpa); 42682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt} 43682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt 44908787db9b95f548270af18d83d62b9d2020ca10Dean Nelsonstatic enum xp_retval 45c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holtxp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa, 46c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt size_t len) 47c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt{ 48c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt int ret; 49c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa)); 50c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 51c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt BUG_ON(!uv_gpa_in_mmr_space(src_gpa)); 52c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt BUG_ON(len != 8); 53c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 54c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt ret = gru_read_gpa(dst_va, src_gpa); 55c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt if (ret == 0) 56c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt return xpSuccess; 57c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 58c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 59c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt "len=%ld\n", dst_gpa, src_gpa, len); 60c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt return xpGruCopyError; 61c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt} 62c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 63c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 64c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holtstatic enum xp_retval 65a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelsonxp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa, 66a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson size_t len) 67908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson{ 68a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson int ret; 69a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson 70c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt if (uv_gpa_in_mmr_space(src_gpa)) 71c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt return xp_remote_mmr_read(dst_gpa, src_gpa, len); 72c2c9f115741453715d6b4da1cd2de65af8c7ad86Robin Holt 73a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson ret = gru_copy_gpa(dst_gpa, src_gpa, len); 74a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson if (ret == 0) 75a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson return xpSuccess; 76a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson 77a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx " 78a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson "len=%ld\n", dst_gpa, src_gpa, len); 79a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson return xpGruCopyError; 80908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson} 81908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson 825b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonstatic int 835b8669dfd110a62a74eea525a009342f73987ea0Dean Nelsonxp_cpu_to_nasid_uv(int cpuid) 845b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson{ 855b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */ 865b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid)); 875b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson} 885b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson 896c1c325de908cbc444cf284f59c3a892161012e9Dean Nelsonstatic enum xp_retval 906c1c325de908cbc444cf284f59c3a892161012e9Dean Nelsonxp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size) 916c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson{ 926c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson int ret; 936c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 946c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#if defined CONFIG_X86_64 956c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW); 966c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson if (ret != BIOS_STATUS_SUCCESS) { 976c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson dev_err(xp, "uv_bios_change_memprotect(,, " 986c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret); 996c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson return xpBiosError; 1006c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson } 1016c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 1026c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 1036c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson u64 nasid_array; 1046c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 1056c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1, 1066c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson &nasid_array); 1076c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson if (ret != 0) { 1086c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson dev_err(xp, "sn_change_memprotect(,, " 1096c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret); 1106c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson return xpSalError; 1116c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson } 1126c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#else 1136c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson #error not a supported configuration 1146c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#endif 1156c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson return xpSuccess; 1166c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson} 1176c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 1186c1c325de908cbc444cf284f59c3a892161012e9Dean Nelsonstatic enum xp_retval 1196c1c325de908cbc444cf284f59c3a892161012e9Dean Nelsonxp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size) 1206c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson{ 1216c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson int ret; 1226c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 1236c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#if defined CONFIG_X86_64 1246c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson ret = uv_bios_change_memprotect(phys_addr, size, 1256c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson UV_MEMPROT_RESTRICT_ACCESS); 1266c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson if (ret != BIOS_STATUS_SUCCESS) { 1276c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson dev_err(xp, "uv_bios_change_memprotect(,, " 1286c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret); 1296c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson return xpBiosError; 1306c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson } 1316c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 1326c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV 1336c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson u64 nasid_array; 1346c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 1356c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0, 1366c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson &nasid_array); 1376c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson if (ret != 0) { 1386c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson dev_err(xp, "sn_change_memprotect(,, " 1396c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret); 1406c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson return xpSalError; 1416c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson } 1426c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#else 1436c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson #error not a supported configuration 1446c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson#endif 1456c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson return xpSuccess; 1466c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson} 1476c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson 148bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelsonenum xp_retval 149bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelsonxp_init_uv(void) 150bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson{ 151bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson BUG_ON(!is_uv()); 152bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson 153bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson xp_max_npartitions = XP_MAX_NPARTITIONS_UV; 15431de5ece351a218a35b9bf83ab05a14373261bb6Dean Nelson xp_partition_id = sn_partition_id; 15531de5ece351a218a35b9bf83ab05a14373261bb6Dean Nelson xp_region_size = sn_region_size; 156908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson 157a812dcc3a298eef650c381e094e2cf41a4ecc9adDean Nelson xp_pa = xp_pa_uv; 158682128939f546e3a9cdd9fef392b932dd9c41a65Robin Holt xp_socket_pa = xp_socket_pa_uv; 159908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson xp_remote_memcpy = xp_remote_memcpy_uv; 1605b8669dfd110a62a74eea525a009342f73987ea0Dean Nelson xp_cpu_to_nasid = xp_cpu_to_nasid_uv; 1616c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson xp_expand_memprotect = xp_expand_memprotect_uv; 1626c1c325de908cbc444cf284f59c3a892161012e9Dean Nelson xp_restrict_memprotect = xp_restrict_memprotect_uv; 163908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson 164908787db9b95f548270af18d83d62b9d2020ca10Dean Nelson return xpSuccess; 165bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson} 166bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson 167bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelsonvoid 168bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelsonxp_exit_uv(void) 169bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson{ 170bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson BUG_ON(!is_uv()); 171bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3Dean Nelson} 172