Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * (C) Copyright 2020 Hewlett Packard Enterprise Development LP
0007  * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
0008  */
0009 
0010 /*
0011  * Cross Partition (XP) uv-based functions.
0012  *
0013  *      Architecture specific implementation of common functions.
0014  *
0015  */
0016 
0017 #include <linux/device.h>
0018 #include <asm/uv/uv_hub.h>
0019 #if defined CONFIG_X86_64
0020 #include <asm/uv/bios.h>
0021 #elif defined CONFIG_IA64_SGI_UV
0022 #include <asm/sn/sn_sal.h>
0023 #endif
0024 #include "../sgi-gru/grukservices.h"
0025 #include "xp.h"
0026 
0027 /*
0028  * Convert a virtual memory address to a physical memory address.
0029  */
0030 static unsigned long
0031 xp_pa_uv(void *addr)
0032 {
0033     return uv_gpa(addr);
0034 }
0035 
0036 /*
0037  * Convert a global physical to socket physical address.
0038  */
0039 static unsigned long
0040 xp_socket_pa_uv(unsigned long gpa)
0041 {
0042     return uv_gpa_to_soc_phys_ram(gpa);
0043 }
0044 
0045 static enum xp_retval
0046 xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
0047            size_t len)
0048 {
0049     int ret;
0050     unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
0051 
0052     BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
0053     BUG_ON(len != 8);
0054 
0055     ret = gru_read_gpa(dst_va, src_gpa);
0056     if (ret == 0)
0057         return xpSuccess;
0058 
0059     dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
0060         "len=%ld\n", dst_gpa, src_gpa, len);
0061     return xpGruCopyError;
0062 }
0063 
0064 
0065 static enum xp_retval
0066 xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
0067             size_t len)
0068 {
0069     int ret;
0070 
0071     if (uv_gpa_in_mmr_space(src_gpa))
0072         return xp_remote_mmr_read(dst_gpa, src_gpa, len);
0073 
0074     ret = gru_copy_gpa(dst_gpa, src_gpa, len);
0075     if (ret == 0)
0076         return xpSuccess;
0077 
0078     dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
0079         "len=%ld\n", dst_gpa, src_gpa, len);
0080     return xpGruCopyError;
0081 }
0082 
0083 static int
0084 xp_cpu_to_nasid_uv(int cpuid)
0085 {
0086     /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
0087     return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
0088 }
0089 
0090 static enum xp_retval
0091 xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
0092 {
0093     int ret;
0094 
0095 #if defined CONFIG_X86_64
0096     ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
0097     if (ret != BIOS_STATUS_SUCCESS) {
0098         dev_err(xp, "uv_bios_change_memprotect(,, "
0099             "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
0100         return xpBiosError;
0101     }
0102 
0103 #elif defined CONFIG_IA64_SGI_UV
0104     u64 nasid_array;
0105 
0106     ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
0107                    &nasid_array);
0108     if (ret != 0) {
0109         dev_err(xp, "sn_change_memprotect(,, "
0110             "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
0111         return xpSalError;
0112     }
0113 #else
0114     #error not a supported configuration
0115 #endif
0116     return xpSuccess;
0117 }
0118 
0119 static enum xp_retval
0120 xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
0121 {
0122     int ret;
0123 
0124 #if defined CONFIG_X86_64
0125     ret = uv_bios_change_memprotect(phys_addr, size,
0126                     UV_MEMPROT_RESTRICT_ACCESS);
0127     if (ret != BIOS_STATUS_SUCCESS) {
0128         dev_err(xp, "uv_bios_change_memprotect(,, "
0129             "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
0130         return xpBiosError;
0131     }
0132 
0133 #elif defined CONFIG_IA64_SGI_UV
0134     u64 nasid_array;
0135 
0136     ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
0137                    &nasid_array);
0138     if (ret != 0) {
0139         dev_err(xp, "sn_change_memprotect(,, "
0140             "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
0141         return xpSalError;
0142     }
0143 #else
0144     #error not a supported configuration
0145 #endif
0146     return xpSuccess;
0147 }
0148 
0149 enum xp_retval
0150 xp_init_uv(void)
0151 {
0152     WARN_ON(!is_uv_system());
0153     if (!is_uv_system())
0154         return xpUnsupported;
0155 
0156     xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
0157 #ifdef CONFIG_X86
0158     xp_partition_id = sn_partition_id;
0159     xp_region_size = sn_region_size;
0160 #endif
0161     xp_pa = xp_pa_uv;
0162     xp_socket_pa = xp_socket_pa_uv;
0163     xp_remote_memcpy = xp_remote_memcpy_uv;
0164     xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
0165     xp_expand_memprotect = xp_expand_memprotect_uv;
0166     xp_restrict_memprotect = xp_restrict_memprotect_uv;
0167 
0168     return xpSuccess;
0169 }
0170 
0171 void
0172 xp_exit_uv(void)
0173 {
0174     WARN_ON(!is_uv_system());
0175 }