x86: uv: xpc needs to provide an abstraction for uv_gpa
[linux-2.6.git] / drivers / misc / sgi-xp / xp_uv.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
7  */
8
9 /*
10  * Cross Partition (XP) uv-based functions.
11  *
12  *      Architecture specific implementation of common functions.
13  *
14  */
15
16 #include <linux/device.h>
17 #include <asm/uv/uv_hub.h>
18 #if defined CONFIG_X86_64
19 #include <asm/uv/bios.h>
20 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
21 #include <asm/sn/sn_sal.h>
22 #endif
23 #include "../sgi-gru/grukservices.h"
24 #include "xp.h"
25
26 /*
27  * Convert a virtual memory address to a physical memory address.
28  */
29 static unsigned long
30 xp_pa_uv(void *addr)
31 {
32         return uv_gpa(addr);
33 }
34
35 /*
36  * Convert a global physical to socket physical address.
37  */
38 static unsigned long
39 xp_socket_pa_uv(unsigned long gpa)
40 {
41         return uv_gpa_to_soc_phys_ram(gpa);
42 }
43
44 static enum xp_retval
45 xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
46                     size_t len)
47 {
48         int ret;
49
50         ret = gru_copy_gpa(dst_gpa, src_gpa, len);
51         if (ret == 0)
52                 return xpSuccess;
53
54         dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
55                 "len=%ld\n", dst_gpa, src_gpa, len);
56         return xpGruCopyError;
57 }
58
59 static int
60 xp_cpu_to_nasid_uv(int cpuid)
61 {
62         /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
63         return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
64 }
65
66 static enum xp_retval
67 xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
68 {
69         int ret;
70
71 #if defined CONFIG_X86_64
72         ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
73         if (ret != BIOS_STATUS_SUCCESS) {
74                 dev_err(xp, "uv_bios_change_memprotect(,, "
75                         "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
76                 return xpBiosError;
77         }
78
79 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
80         u64 nasid_array;
81
82         ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
83                                    &nasid_array);
84         if (ret != 0) {
85                 dev_err(xp, "sn_change_memprotect(,, "
86                         "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
87                 return xpSalError;
88         }
89 #else
90         #error not a supported configuration
91 #endif
92         return xpSuccess;
93 }
94
95 static enum xp_retval
96 xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
97 {
98         int ret;
99
100 #if defined CONFIG_X86_64
101         ret = uv_bios_change_memprotect(phys_addr, size,
102                                         UV_MEMPROT_RESTRICT_ACCESS);
103         if (ret != BIOS_STATUS_SUCCESS) {
104                 dev_err(xp, "uv_bios_change_memprotect(,, "
105                         "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
106                 return xpBiosError;
107         }
108
109 #elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
110         u64 nasid_array;
111
112         ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
113                                    &nasid_array);
114         if (ret != 0) {
115                 dev_err(xp, "sn_change_memprotect(,, "
116                         "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
117                 return xpSalError;
118         }
119 #else
120         #error not a supported configuration
121 #endif
122         return xpSuccess;
123 }
124
125 enum xp_retval
126 xp_init_uv(void)
127 {
128         BUG_ON(!is_uv());
129
130         xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
131         xp_partition_id = sn_partition_id;
132         xp_region_size = sn_region_size;
133
134         xp_pa = xp_pa_uv;
135         xp_socket_pa = xp_socket_pa_uv;
136         xp_remote_memcpy = xp_remote_memcpy_uv;
137         xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
138         xp_expand_memprotect = xp_expand_memprotect_uv;
139         xp_restrict_memprotect = xp_restrict_memprotect_uv;
140
141         return xpSuccess;
142 }
143
144 void
145 xp_exit_uv(void)
146 {
147         BUG_ON(!is_uv());
148 }