Skip to content

Commit 7019cc2

Browse files
Russ AndersonIngo Molnar
authored andcommitted
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>
1 parent 5b664cb commit 7019cc2

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

arch/x86/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ obj-$(CONFIG_OLPC) += olpc.o
102102
# 64 bit specific files
103103
ifeq ($(CONFIG_X86_64),y)
104104
obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
105+
obj-y += bios_uv.o
105106
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
106107
obj-$(CONFIG_AUDIT) += audit_64.o
107108

arch/x86/kernel/bios_uv.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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);

arch/x86/kernel/genx2apic_uv_x.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <asm/pgtable.h>
2525
#include <asm/uv/uv_mmrs.h>
2626
#include <asm/uv/uv_hub.h>
27+
#include <asm/uv/bios.h>
2728

2829
DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
2930
EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
@@ -40,6 +41,9 @@ EXPORT_SYMBOL_GPL(uv_cpu_to_blade);
4041
short uv_possible_blades;
4142
EXPORT_SYMBOL_GPL(uv_possible_blades);
4243

44+
unsigned long sn_rtc_cycles_per_second;
45+
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
46+
4347
/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */
4448

4549
static cpumask_t uv_target_cpus(void)
@@ -272,6 +276,23 @@ static __init void map_mmioh_high(int max_pnode)
272276
map_high("MMIOH", mmioh.s.base, shift, map_uc);
273277
}
274278

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+
275296
static __init void uv_system_init(void)
276297
{
277298
union uvh_si_addr_map_config_u m_n_config;
@@ -326,6 +347,8 @@ static __init void uv_system_init(void)
326347
gnode_upper = (((unsigned long)node_id.s.node_id) &
327348
~((1 << n_val) - 1)) << m_val;
328349

350+
uv_rtc_init();
351+
329352
for_each_present_cpu(cpu) {
330353
nid = cpu_to_node(cpu);
331354
pnode = uv_apicid_to_pnode(per_cpu(x86_cpu_to_apicid, cpu));

include/asm-x86/uv/bios.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#ifndef _ASM_X86_BIOS_H
2+
#define _ASM_X86_BIOS_H
3+
4+
/*
5+
* BIOS layer definitions.
6+
*
7+
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
8+
*
9+
* This program is free software; you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation; either version 2 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program; if not, write to the Free Software
21+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22+
*/
23+
24+
#include <linux/rtc.h>
25+
26+
#define BIOS_FREQ_BASE 0x01000001
27+
28+
enum {
29+
BIOS_FREQ_BASE_PLATFORM = 0,
30+
BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
31+
BIOS_FREQ_BASE_REALTIME_CLOCK = 2
32+
};
33+
34+
# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7) \
35+
do { \
36+
/* XXX - the real call goes here */ \
37+
result.status = BIOS_STATUS_UNIMPLEMENTED; \
38+
isrv.v0 = 0; \
39+
isrv.v1 = 0; \
40+
} while (0)
41+
42+
enum {
43+
BIOS_STATUS_SUCCESS = 0,
44+
BIOS_STATUS_UNIMPLEMENTED = -1,
45+
BIOS_STATUS_EINVAL = -2,
46+
BIOS_STATUS_ERROR = -3
47+
};
48+
49+
struct uv_bios_retval {
50+
/*
51+
* A zero status value indicates call completed without error.
52+
* A negative status value indicates reason of call failure.
53+
* A positive status value indicates success but an
54+
* informational value should be printed (e.g., "reboot for
55+
* change to take effect").
56+
*/
57+
s64 status;
58+
u64 v0;
59+
u64 v1;
60+
u64 v2;
61+
};
62+
63+
extern long
64+
x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
65+
unsigned long *drift_info);
66+
extern const char *x86_bios_strerror(long status);
67+
68+
#endif /* _ASM_X86_BIOS_H */

0 commit comments

Comments
 (0)