diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
commit | 7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch) | |
tree | e730a4565e0318140d2fbd2f0415d18a339d7336 /arch/x86/kernel/bios_uv.c | |
parent | 41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) |
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'arch/x86/kernel/bios_uv.c')
-rw-r--r-- | arch/x86/kernel/bios_uv.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c new file mode 100644 index 000000000000..f0dfe6f17e7e --- /dev/null +++ b/arch/x86/kernel/bios_uv.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * BIOS run time interface routines. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. | ||
19 | * Copyright (c) Russ Anderson | ||
20 | */ | ||
21 | |||
22 | #include <linux/efi.h> | ||
23 | #include <asm/efi.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <asm/uv/bios.h> | ||
26 | #include <asm/uv/uv_hub.h> | ||
27 | |||
28 | struct uv_systab uv_systab; | ||
29 | |||
30 | s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5) | ||
31 | { | ||
32 | struct uv_systab *tab = &uv_systab; | ||
33 | |||
34 | if (!tab->function) | ||
35 | /* | ||
36 | * BIOS does not support UV systab | ||
37 | */ | ||
38 | return BIOS_STATUS_UNIMPLEMENTED; | ||
39 | |||
40 | return efi_call6((void *)__va(tab->function), | ||
41 | (u64)which, a1, a2, a3, a4, a5); | ||
42 | } | ||
43 | |||
44 | s64 uv_bios_call_irqsave(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, | ||
45 | u64 a4, u64 a5) | ||
46 | { | ||
47 | unsigned long bios_flags; | ||
48 | s64 ret; | ||
49 | |||
50 | local_irq_save(bios_flags); | ||
51 | ret = uv_bios_call(which, a1, a2, a3, a4, a5); | ||
52 | local_irq_restore(bios_flags); | ||
53 | |||
54 | return ret; | ||
55 | } | ||
56 | |||
57 | s64 uv_bios_call_reentrant(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, | ||
58 | u64 a4, u64 a5) | ||
59 | { | ||
60 | s64 ret; | ||
61 | |||
62 | preempt_disable(); | ||
63 | ret = uv_bios_call(which, a1, a2, a3, a4, a5); | ||
64 | preempt_enable(); | ||
65 | |||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | |||
70 | long sn_partition_id; | ||
71 | EXPORT_SYMBOL_GPL(sn_partition_id); | ||
72 | long uv_coherency_id; | ||
73 | EXPORT_SYMBOL_GPL(uv_coherency_id); | ||
74 | long uv_region_size; | ||
75 | EXPORT_SYMBOL_GPL(uv_region_size); | ||
76 | int uv_type; | ||
77 | |||
78 | |||
79 | s64 uv_bios_get_sn_info(int fc, int *uvtype, long *partid, long *coher, | ||
80 | long *region) | ||
81 | { | ||
82 | s64 ret; | ||
83 | u64 v0, v1; | ||
84 | union partition_info_u part; | ||
85 | |||
86 | ret = uv_bios_call_irqsave(UV_BIOS_GET_SN_INFO, fc, | ||
87 | (u64)(&v0), (u64)(&v1), 0, 0); | ||
88 | if (ret != BIOS_STATUS_SUCCESS) | ||
89 | return ret; | ||
90 | |||
91 | part.val = v0; | ||
92 | if (uvtype) | ||
93 | *uvtype = part.hub_version; | ||
94 | if (partid) | ||
95 | *partid = part.partition_id; | ||
96 | if (coher) | ||
97 | *coher = part.coherence_id; | ||
98 | if (region) | ||
99 | *region = part.region_size; | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | |||
104 | s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second) | ||
105 | { | ||
106 | return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type, | ||
107 | (u64)ticks_per_second, 0, 0, 0); | ||
108 | } | ||
109 | EXPORT_SYMBOL_GPL(uv_bios_freq_base); | ||
110 | |||
111 | |||
112 | #ifdef CONFIG_EFI | ||
113 | void uv_bios_init(void) | ||
114 | { | ||
115 | struct uv_systab *tab; | ||
116 | |||
117 | if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) || | ||
118 | (efi.uv_systab == (unsigned long)NULL)) { | ||
119 | printk(KERN_CRIT "No EFI UV System Table.\n"); | ||
120 | uv_systab.function = (unsigned long)NULL; | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | tab = (struct uv_systab *)ioremap(efi.uv_systab, | ||
125 | sizeof(struct uv_systab)); | ||
126 | if (strncmp(tab->signature, "UVST", 4) != 0) | ||
127 | printk(KERN_ERR "bad signature in UV system table!"); | ||
128 | |||
129 | /* | ||
130 | * Copy table to permanent spot for later use. | ||
131 | */ | ||
132 | memcpy(&uv_systab, tab, sizeof(struct uv_systab)); | ||
133 | iounmap(tab); | ||
134 | |||
135 | printk(KERN_INFO "EFI UV System Table Revision %d\n", tab->revision); | ||
136 | } | ||
137 | #else /* !CONFIG_EFI */ | ||
138 | |||
139 | void uv_bios_init(void) { } | ||
140 | #endif | ||
141 | |||