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 * SGI UV Core Functions
8 * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
11 #include <linux/acpi.h>
12 #include <linux/efi.h>
13 #include <linux/module.h>
14 #include <linux/percpu.h>
15 #include <asm/uv/uv.h>
16 #include <asm/uv/uv_mmrs.h>
17 #include <asm/uv/uv_hub.h>
20 EXPORT_SYMBOL_GPL(ia64_is_uv
);
22 DEFINE_PER_CPU(struct uv_hub_info_s
, __uv_hub_info
);
23 EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info
);
26 unsigned long redirect
;
30 #define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT
32 static __initdata
struct redir_addr redir_addrs
[] = {
33 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR
, UVH_SI_ALIAS0_OVERLAY_CONFIG
},
34 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR
, UVH_SI_ALIAS1_OVERLAY_CONFIG
},
35 {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR
, UVH_SI_ALIAS2_OVERLAY_CONFIG
},
38 static __init
void get_lowmem_redirect(unsigned long *base
, unsigned long *size
)
40 union uvh_si_alias0_overlay_config_u alias
;
41 union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect
;
44 for (i
= 0; i
< ARRAY_SIZE(redir_addrs
); i
++) {
45 alias
.v
= uv_read_local_mmr(redir_addrs
[i
].alias
);
46 if (alias
.s
.base
== 0) {
47 *size
= (1UL << alias
.s
.m_alias
);
48 redirect
.v
= uv_read_local_mmr(redir_addrs
[i
].redirect
);
49 *base
= (unsigned long)redirect
.s
.dest_base
<< DEST_SHIFT
;
56 void __init
uv_probe_system_type(void)
58 struct acpi_table_rsdp
*rsdp
;
59 struct acpi_table_xsdt
*xsdt
;
61 if (efi
.acpi20
== EFI_INVALID_TABLE_ADDR
) {
62 pr_err("ACPI 2.0 RSDP not found.\n");
66 rsdp
= (struct acpi_table_rsdp
*)__va(efi
.acpi20
);
67 if (strncmp(rsdp
->signature
, ACPI_SIG_RSDP
, sizeof(ACPI_SIG_RSDP
) - 1)) {
68 pr_err("ACPI 2.0 RSDP signature incorrect.\n");
72 xsdt
= (struct acpi_table_xsdt
*)__va(rsdp
->xsdt_physical_address
);
73 if (strncmp(xsdt
->header
.signature
, ACPI_SIG_XSDT
,
74 sizeof(ACPI_SIG_XSDT
) - 1)) {
75 pr_err("ACPI 2.0 XSDT signature incorrect.\n");
79 if (!strcmp(xsdt
->header
.oem_id
, "SGI") &&
80 !strcmp(xsdt
->header
.oem_table_id
+ 4, "UV"))
84 void __init
uv_setup(char **cmdline_p
)
86 union uvh_si_addr_map_config_u m_n_config
;
87 union uvh_node_id_u node_id
;
88 unsigned long gnode_upper
;
89 int nid
, cpu
, m_val
, n_val
;
90 unsigned long mmr_base
, lowmem_redir_base
, lowmem_redir_size
;
92 get_lowmem_redirect(&lowmem_redir_base
, &lowmem_redir_size
);
93 node_id
.v
= uv_read_local_mmr(UVH_NODE_ID
);
94 m_n_config
.v
= uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG
);
95 mmr_base
= uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR
) &
98 m_val
= m_n_config
.s
.m_skt
;
99 n_val
= m_n_config
.s
.n_skt
;
100 printk(KERN_DEBUG
"UV: global MMR base 0x%lx\n", mmr_base
);
102 gnode_upper
= (((unsigned long)node_id
.s
.node_id
) &
103 ~((1 << n_val
) - 1)) << m_val
;
105 for_each_present_cpu(cpu
) {
106 nid
= cpu_to_node(cpu
);
107 uv_cpu_hub_info(cpu
)->lowmem_remap_base
= lowmem_redir_base
;
108 uv_cpu_hub_info(cpu
)->lowmem_remap_top
=
109 lowmem_redir_base
+ lowmem_redir_size
;
110 uv_cpu_hub_info(cpu
)->m_val
= m_val
;
111 uv_cpu_hub_info(cpu
)->n_val
= n_val
;
112 uv_cpu_hub_info(cpu
)->pnode_mask
= (1 << n_val
) -1;
113 uv_cpu_hub_info(cpu
)->gpa_mask
= (1 << (m_val
+ n_val
)) - 1;
114 uv_cpu_hub_info(cpu
)->gnode_upper
= gnode_upper
;
115 uv_cpu_hub_info(cpu
)->global_mmr_base
= mmr_base
;
116 uv_cpu_hub_info(cpu
)->coherency_domain_number
= 0;/* ZZZ */
117 printk(KERN_DEBUG
"UV cpu %d, nid %d\n", cpu
, nid
);