diff options
author | Russ Anderson <rja@sgi.com> | 2008-07-09 16:27:19 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 08:35:14 -0400 |
commit | 7019cc2dd6fafcdc6b104005482dc910dcdbb797 (patch) | |
tree | 0f8e67c0b5146543d407dc9f07ace6aeb4b0bd12 /arch | |
parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) |
x86 BIOS interface for RTC on SGI UV
Real-time code needs to know the number of cycles per second
on SGI UV. The information is provided via a run time BIOS
call. This patch provides the linux side of that interface.
This is the first of several run time BIOS calls to be defined
in uv/bios.h and bios_uv.c.
Note that BIOS_CALL() is just a stub for now. The bios
side is being worked on.
Signed-off-by: Russ Anderson <rja@sgi.com>
Cc: Jack Steiner <steiner@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/bios_uv.c | 48 | ||||
-rw-r--r-- | arch/x86/kernel/genx2apic_uv_x.c | 23 |
3 files changed, 72 insertions, 0 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index da140611bb57..b78a17b12810 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -102,6 +102,7 @@ obj-$(CONFIG_OLPC) += olpc.o | |||
102 | # 64 bit specific files | 102 | # 64 bit specific files |
103 | ifeq ($(CONFIG_X86_64),y) | 103 | ifeq ($(CONFIG_X86_64),y) |
104 | obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o | 104 | obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o |
105 | obj-y += bios_uv.o | ||
105 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o | 106 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o |
106 | obj-$(CONFIG_AUDIT) += audit_64.o | 107 | obj-$(CONFIG_AUDIT) += audit_64.o |
107 | 108 | ||
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c new file mode 100644 index 000000000000..c639bd55391c --- /dev/null +++ b/arch/x86/kernel/bios_uv.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * BIOS run time interface routines. | ||
3 | * | ||
4 | * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/uv/bios.h> | ||
22 | |||
23 | const char * | ||
24 | x86_bios_strerror(long status) | ||
25 | { | ||
26 | const char *str; | ||
27 | switch (status) { | ||
28 | case 0: str = "Call completed without error"; break; | ||
29 | case -1: str = "Not implemented"; break; | ||
30 | case -2: str = "Invalid argument"; break; | ||
31 | case -3: str = "Call completed with error"; break; | ||
32 | default: str = "Unknown BIOS status code"; break; | ||
33 | } | ||
34 | return str; | ||
35 | } | ||
36 | |||
37 | long | ||
38 | x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second, | ||
39 | unsigned long *drift_info) | ||
40 | { | ||
41 | struct uv_bios_retval isrv; | ||
42 | |||
43 | BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0); | ||
44 | *ticks_per_second = isrv.v0; | ||
45 | *drift_info = isrv.v1; | ||
46 | return isrv.status; | ||
47 | } | ||
48 | EXPORT_SYMBOL_GPL(x86_bios_freq_base); | ||
diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 711f11c30b06..3c3929340692 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
25 | #include <asm/uv/uv_mmrs.h> | 25 | #include <asm/uv/uv_mmrs.h> |
26 | #include <asm/uv/uv_hub.h> | 26 | #include <asm/uv/uv_hub.h> |
27 | #include <asm/uv/bios.h> | ||
27 | 28 | ||
28 | DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); | 29 | DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); |
29 | EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); | 30 | EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); |
@@ -40,6 +41,9 @@ EXPORT_SYMBOL_GPL(uv_cpu_to_blade); | |||
40 | short uv_possible_blades; | 41 | short uv_possible_blades; |
41 | EXPORT_SYMBOL_GPL(uv_possible_blades); | 42 | EXPORT_SYMBOL_GPL(uv_possible_blades); |
42 | 43 | ||
44 | unsigned long sn_rtc_cycles_per_second; | ||
45 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); | ||
46 | |||
43 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ | 47 | /* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ |
44 | 48 | ||
45 | static cpumask_t uv_target_cpus(void) | 49 | static cpumask_t uv_target_cpus(void) |
@@ -272,6 +276,23 @@ static __init void map_mmioh_high(int max_pnode) | |||
272 | map_high("MMIOH", mmioh.s.base, shift, map_uc); | 276 | map_high("MMIOH", mmioh.s.base, shift, map_uc); |
273 | } | 277 | } |
274 | 278 | ||
279 | static __init void uv_rtc_init(void) | ||
280 | { | ||
281 | long status, ticks_per_sec, drift; | ||
282 | |||
283 | status = | ||
284 | x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, | ||
285 | &drift); | ||
286 | if (status != 0 || ticks_per_sec < 100000) { | ||
287 | printk(KERN_WARNING | ||
288 | "unable to determine platform RTC clock frequency, " | ||
289 | "guessing.\n"); | ||
290 | /* BIOS gives wrong value for clock freq. so guess */ | ||
291 | sn_rtc_cycles_per_second = 1000000000000UL / 30000UL; | ||
292 | } else | ||
293 | sn_rtc_cycles_per_second = ticks_per_sec; | ||
294 | } | ||
295 | |||
275 | static __init void uv_system_init(void) | 296 | static __init void uv_system_init(void) |
276 | { | 297 | { |
277 | union uvh_si_addr_map_config_u m_n_config; | 298 | union uvh_si_addr_map_config_u m_n_config; |
@@ -326,6 +347,8 @@ static __init void uv_system_init(void) | |||
326 | gnode_upper = (((unsigned long)node_id.s.node_id) & | 347 | gnode_upper = (((unsigned long)node_id.s.node_id) & |
327 | ~((1 << n_val) - 1)) << m_val; | 348 | ~((1 << n_val) - 1)) << m_val; |
328 | 349 | ||
350 | uv_rtc_init(); | ||
351 | |||
329 | for_each_present_cpu(cpu) { | 352 | for_each_present_cpu(cpu) { |
330 | nid = cpu_to_node(cpu); | 353 | nid = cpu_to_node(cpu); |
331 | pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); | 354 | pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu)); |