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
6 * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
10 * Cross Partition Communication (XPC) sn2-based functions.
12 * Architecture specific implementation of common functions.
16 #include <linux/kernel.h>
17 #include <asm/uncached.h>
18 #include <asm/sn/sn_sal.h>
21 struct xpc_vars *xpc_vars;
22 struct xpc_vars_part *xpc_vars_part;
25 xpc_rsvd_page_init_sn2(struct xpc_rsvd_page *rp)
32 xpc_vars = XPC_RP_VARS(rp);
34 rp->sn.vars_pa = __pa(xpc_vars);
36 xpc_vars_part = XPC_RP_VARS_PART(rp);
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.
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.
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");
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().
62 if (!enable_shub_wars_1_1()) {
63 ret = sn_change_memprotect(ia64_tpa((u64)amos_page),
65 SN_MEMPROT_ACCESS_CLASS_1,
68 dev_err(xpc_part, "can't change memory "
70 uncached_free_page(__IA64_UNCACHED_OFFSET |
71 TO_PHYS((u64)amos_page), 1);
78 memset(xpc_vars, 0, sizeof(struct xpc_vars));
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 */
87 /* clear xpc_vars_part */
88 memset((u64 *)xpc_vars_part, 0, sizeof(struct xpc_vars_part) *
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);
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);
105 xpc_rsvd_page_init = xpc_rsvd_page_init_sn2;