diff options
author | Zachary Amsden <zach@vmware.com> | 2007-02-13 07:26:21 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-02-13 07:26:21 -0500 |
commit | bbab4f3bb7f528d2b8ccb5de9ae5f6ff3fb29684 (patch) | |
tree | 141d035b9d79711e6679fadc31c9583f908dfedb /include | |
parent | 7ce0bcfd1667736f1293cff845139bbee53186de (diff) |
[PATCH] i386: vMI timer patches
VMI timer code. It works by taking over the local APIC clock when APIC is
configured, which requires a couple hooks into the APIC code. The backend
timer code could be commonized into the timer infrastructure, but there are
some pieces missing (stolen time, in particular), and the exact semantics of
when to do accounting for NO_IDLE need to be shared between different
hypervisors as well. So for now, VMI timer is a separate module.
[Adrian Bunk: cleanups]
Subject: VMI timer patches
Signed-off-by: Zachary Amsden <zach@vmware.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Andi Kleen <ak@suse.de>
Cc: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-i386/apic.h | 2 | ||||
-rw-r--r-- | include/asm-i386/paravirt.h | 12 | ||||
-rw-r--r-- | include/asm-i386/time.h | 1 | ||||
-rw-r--r-- | include/asm-i386/timer.h | 2 | ||||
-rw-r--r-- | include/asm-i386/vmi_time.h | 103 |
5 files changed, 120 insertions, 0 deletions
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index 41a44319905f..3a61206fd108 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h | |||
@@ -43,6 +43,8 @@ extern void generic_apic_probe(void); | |||
43 | #define apic_write native_apic_write | 43 | #define apic_write native_apic_write |
44 | #define apic_write_atomic native_apic_write_atomic | 44 | #define apic_write_atomic native_apic_write_atomic |
45 | #define apic_read native_apic_read | 45 | #define apic_read native_apic_read |
46 | #define setup_boot_clock setup_boot_APIC_clock | ||
47 | #define setup_secondary_clock setup_secondary_APIC_clock | ||
46 | #endif | 48 | #endif |
47 | 49 | ||
48 | static __inline fastcall void native_apic_write(unsigned long reg, | 50 | static __inline fastcall void native_apic_write(unsigned long reg, |
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index 6ccf36499b2a..12ef95924da6 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h | |||
@@ -121,6 +121,8 @@ struct paravirt_ops | |||
121 | void (fastcall *apic_write)(unsigned long reg, unsigned long v); | 121 | void (fastcall *apic_write)(unsigned long reg, unsigned long v); |
122 | void (fastcall *apic_write_atomic)(unsigned long reg, unsigned long v); | 122 | void (fastcall *apic_write_atomic)(unsigned long reg, unsigned long v); |
123 | unsigned long (fastcall *apic_read)(unsigned long reg); | 123 | unsigned long (fastcall *apic_read)(unsigned long reg); |
124 | void (*setup_boot_clock)(void); | ||
125 | void (*setup_secondary_clock)(void); | ||
124 | #endif | 126 | #endif |
125 | 127 | ||
126 | void (fastcall *flush_tlb_user)(void); | 128 | void (fastcall *flush_tlb_user)(void); |
@@ -323,6 +325,16 @@ static inline unsigned long apic_read(unsigned long reg) | |||
323 | { | 325 | { |
324 | return paravirt_ops.apic_read(reg); | 326 | return paravirt_ops.apic_read(reg); |
325 | } | 327 | } |
328 | |||
329 | static inline void setup_boot_clock(void) | ||
330 | { | ||
331 | paravirt_ops.setup_boot_clock(); | ||
332 | } | ||
333 | |||
334 | static inline void setup_secondary_clock(void) | ||
335 | { | ||
336 | paravirt_ops.setup_secondary_clock(); | ||
337 | } | ||
326 | #endif | 338 | #endif |
327 | 339 | ||
328 | #ifdef CONFIG_SMP | 340 | #ifdef CONFIG_SMP |
diff --git a/include/asm-i386/time.h b/include/asm-i386/time.h index ea8065af825a..571b4294dc2e 100644 --- a/include/asm-i386/time.h +++ b/include/asm-i386/time.h | |||
@@ -30,6 +30,7 @@ static inline int native_set_wallclock(unsigned long nowtime) | |||
30 | 30 | ||
31 | #ifdef CONFIG_PARAVIRT | 31 | #ifdef CONFIG_PARAVIRT |
32 | #include <asm/paravirt.h> | 32 | #include <asm/paravirt.h> |
33 | extern unsigned long long native_sched_clock(void); | ||
33 | #else /* !CONFIG_PARAVIRT */ | 34 | #else /* !CONFIG_PARAVIRT */ |
34 | 35 | ||
35 | #define get_wallclock() native_get_wallclock() | 36 | #define get_wallclock() native_get_wallclock() |
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h index 1ee64e34cd35..4752c3a6a708 100644 --- a/include/asm-i386/timer.h +++ b/include/asm-i386/timer.h | |||
@@ -9,6 +9,8 @@ void setup_pit_timer(void); | |||
9 | extern int pit_latch_buggy; | 9 | extern int pit_latch_buggy; |
10 | extern int timer_ack; | 10 | extern int timer_ack; |
11 | extern int no_timer_check; | 11 | extern int no_timer_check; |
12 | extern unsigned long long (*custom_sched_clock)(void); | ||
13 | extern int no_sync_cmos_clock; | ||
12 | extern int recalibrate_cpu_khz(void); | 14 | extern int recalibrate_cpu_khz(void); |
13 | 15 | ||
14 | #endif | 16 | #endif |
diff --git a/include/asm-i386/vmi_time.h b/include/asm-i386/vmi_time.h new file mode 100644 index 000000000000..c12931211007 --- /dev/null +++ b/include/asm-i386/vmi_time.h | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * VMI Time wrappers | ||
3 | * | ||
4 | * Copyright (C) 2006, VMware, Inc. | ||
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, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
14 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
15 | * details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | * | ||
21 | * Send feedback to dhecht@vmware.com | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef __VMI_TIME_H | ||
26 | #define __VMI_TIME_H | ||
27 | |||
28 | /* | ||
29 | * Raw VMI call indices for timer functions | ||
30 | */ | ||
31 | #define VMI_CALL_GetCycleFrequency 66 | ||
32 | #define VMI_CALL_GetCycleCounter 67 | ||
33 | #define VMI_CALL_SetAlarm 68 | ||
34 | #define VMI_CALL_CancelAlarm 69 | ||
35 | #define VMI_CALL_GetWallclockTime 70 | ||
36 | #define VMI_CALL_WallclockUpdated 71 | ||
37 | |||
38 | /* Cached VMI timer operations */ | ||
39 | extern struct vmi_timer_ops { | ||
40 | u64 (*get_cycle_frequency)(void); | ||
41 | u64 (*get_cycle_counter)(int); | ||
42 | u64 (*get_wallclock)(void); | ||
43 | int (*wallclock_updated)(void); | ||
44 | void (*set_alarm)(u32 flags, u64 expiry, u64 period); | ||
45 | void (*cancel_alarm)(u32 flags); | ||
46 | } vmi_timer_ops; | ||
47 | |||
48 | /* Prototypes */ | ||
49 | extern void __init vmi_time_init(void); | ||
50 | extern unsigned long vmi_get_wallclock(void); | ||
51 | extern int vmi_set_wallclock(unsigned long now); | ||
52 | extern unsigned long long vmi_sched_clock(void); | ||
53 | |||
54 | #ifdef CONFIG_X86_LOCAL_APIC | ||
55 | extern void __init vmi_timer_setup_boot_alarm(void); | ||
56 | extern void __init vmi_timer_setup_secondary_alarm(void); | ||
57 | extern void apic_vmi_timer_interrupt(void); | ||
58 | #endif | ||
59 | |||
60 | #ifdef CONFIG_NO_IDLE_HZ | ||
61 | extern int vmi_stop_hz_timer(void); | ||
62 | extern void vmi_account_time_restart_hz_timer(void); | ||
63 | #endif | ||
64 | |||
65 | /* | ||
66 | * When run under a hypervisor, a vcpu is always in one of three states: | ||
67 | * running, halted, or ready. The vcpu is in the 'running' state if it | ||
68 | * is executing. When the vcpu executes the halt interface, the vcpu | ||
69 | * enters the 'halted' state and remains halted until there is some work | ||
70 | * pending for the vcpu (e.g. an alarm expires, host I/O completes on | ||
71 | * behalf of virtual I/O). At this point, the vcpu enters the 'ready' | ||
72 | * state (waiting for the hypervisor to reschedule it). Finally, at any | ||
73 | * time when the vcpu is not in the 'running' state nor the 'halted' | ||
74 | * state, it is in the 'ready' state. | ||
75 | * | ||
76 | * Real time is advances while the vcpu is 'running', 'ready', or | ||
77 | * 'halted'. Stolen time is the time in which the vcpu is in the | ||
78 | * 'ready' state. Available time is the remaining time -- the vcpu is | ||
79 | * either 'running' or 'halted'. | ||
80 | * | ||
81 | * All three views of time are accessible through the VMI cycle | ||
82 | * counters. | ||
83 | */ | ||
84 | |||
85 | /* The cycle counters. */ | ||
86 | #define VMI_CYCLES_REAL 0 | ||
87 | #define VMI_CYCLES_AVAILABLE 1 | ||
88 | #define VMI_CYCLES_STOLEN 2 | ||
89 | |||
90 | /* The alarm interface 'flags' bits */ | ||
91 | #define VMI_ALARM_COUNTERS 2 | ||
92 | |||
93 | #define VMI_ALARM_COUNTER_MASK 0x000000ff | ||
94 | |||
95 | #define VMI_ALARM_WIRED_IRQ0 0x00000000 | ||
96 | #define VMI_ALARM_WIRED_LVTT 0x00010000 | ||
97 | |||
98 | #define VMI_ALARM_IS_ONESHOT 0x00000000 | ||
99 | #define VMI_ALARM_IS_PERIODIC 0x00000100 | ||
100 | |||
101 | #define CONFIG_VMI_ALARM_HZ 100 | ||
102 | |||
103 | #endif | ||