diff options
author | Dean Nelson <dcn@sgi.com> | 2008-07-30 01:34:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-30 12:41:49 -0400 |
commit | 94bd2708d4a95d7da5a1c7c28a063eccd127fb69 (patch) | |
tree | bcc65d3966e240017f8fb355114ec07c906b0b63 /drivers/misc/sgi-xp/xpc_sn2.c | |
parent | 908787db9b95f548270af18d83d62b9d2020ca10 (diff) |
sgi-xp: prepare xpc_rsvd_page to work on either sn2 or uv hardware
Prepare XPC's reserved page header to work for either sn2 or uv.
Signed-off-by: Dean Nelson <dcn@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_sn2.c')
-rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c new file mode 100644 index 000000000000..5a37348715c7 --- /dev/null +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |||
@@ -0,0 +1,111 @@ | |||
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 Communication (XPC) sn2-based functions. | ||
11 | * | ||
12 | * Architecture specific implementation of common functions. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <asm/uncached.h> | ||
18 | #include <asm/sn/sn_sal.h> | ||
19 | #include "xpc.h" | ||
20 | |||
21 | struct xpc_vars *xpc_vars; | ||
22 | struct xpc_vars_part *xpc_vars_part; | ||
23 | |||
24 | static enum xp_retval | ||
25 | xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp) | ||
26 | { | ||
27 | AMO_t *amos_page; | ||
28 | u64 nasid_array = 0; | ||
29 | int i; | ||
30 | int ret; | ||
31 | |||
32 | xpc_vars = XPC_RP_VARS(rp); | ||
33 | |||
34 | rp->sn.vars_pa = __pa(xpc_vars); | ||
35 | |||
36 | xpc_vars_part = XPC_RP_VARS_PART(rp); | ||
37 | |||
38 | /* | ||
39 | * Before clearing xpc_vars, see if a page of AMOs had been previously | ||
40 | * allocated. If not we'll need to allocate one and set permissions | ||
41 | * so that cross-partition AMOs are allowed. | ||
42 | * | ||
43 | * The allocated AMO page needs MCA reporting to remain disabled after | ||
44 | * XPC has unloaded. To make this work, we keep a copy of the pointer | ||
45 | * to this page (i.e., amos_page) in the struct xpc_vars structure, | ||
46 | * which is pointed to by the reserved page, and re-use that saved copy | ||
47 | * on subsequent loads of XPC. This AMO page is never freed, and its | ||
48 | * memory protections are never restricted. | ||
49 | */ | ||
50 | amos_page = xpc_vars->amos_page; | ||
51 | if (amos_page == NULL) { | ||
52 | amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0, 1)); | ||
53 | if (amos_page == NULL) { | ||
54 | dev_err(xpc_part, "can't allocate page of AMOs\n"); | ||
55 | return xpNoMemory; | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * Open up AMO-R/W to cpu. This is done for Shub 1.1 systems | ||
60 | * when xpc_allow_IPI_ops() is called via xpc_hb_init(). | ||
61 | */ | ||
62 | if (!enable_shub_wars_1_1()) { | ||
63 | ret = sn_change_memprotect(ia64_tpa((u64)amos_page), | ||
64 | PAGE_SIZE, | ||
65 | SN_MEMPROT_ACCESS_CLASS_1, | ||
66 | &nasid_array); | ||
67 | if (ret != 0) { | ||
68 | dev_err(xpc_part, "can't change memory " | ||
69 | "protections\n"); | ||
70 | uncached_free_page(__IA64_UNCACHED_OFFSET | | ||
71 | TO_PHYS((u64)amos_page), 1); | ||
72 | return xpSalError; | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /* clear xpc_vars */ | ||
78 | memset(xpc_vars, 0, sizeof(struct xpc_vars)); | ||
79 | |||
80 | xpc_vars->version = XPC_V_VERSION; | ||
81 | xpc_vars->act_nasid = cpuid_to_nasid(0); | ||
82 | xpc_vars->act_phys_cpuid = cpu_physical_id(0); | ||
83 | xpc_vars->vars_part_pa = __pa(xpc_vars_part); | ||
84 | xpc_vars->amos_page_pa = ia64_tpa((u64)amos_page); | ||
85 | xpc_vars->amos_page = amos_page; /* save for next load of XPC */ | ||
86 | |||
87 | /* clear xpc_vars_part */ | ||
88 | memset((u64 *)xpc_vars_part, 0, sizeof(struct xpc_vars_part) * | ||
89 | xp_max_npartitions); | ||
90 | |||
91 | /* initialize the activate IRQ related AMO variables */ | ||
92 | for (i = 0; i < xp_nasid_mask_words; i++) | ||
93 | (void)xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); | ||
94 | |||
95 | /* initialize the engaged remote partitions related AMO variables */ | ||
96 | (void)xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); | ||
97 | (void)xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO); | ||
98 | |||
99 | return xpSuccess; | ||
100 | } | ||
101 | |||
102 | void | ||
103 | xpc_init_sn2(void) | ||
104 | { | ||
105 | xpc_rsvd_page_init = xpc_rsvd_page_init_sn2; | ||
106 | } | ||
107 | |||
108 | void | ||
109 | xpc_exit_sn2(void) | ||
110 | { | ||
111 | } | ||