xref: /openbmc/linux/drivers/misc/sgi-xp/xp_uv.c (revision 6c1c325de908cbc444cf284f59c3a892161012e9)
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