aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-06-29 17:12:12 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-06-29 17:12:12 +0000
commit79e1decf57682817f32e869dbff61606e6eac981 (patch)
treecc3f25846847611b08cf1399b05f0e52e5e61568
parent3cd648a5b1f3fbd64e1102c8d24580c4e6f9ffb8 (diff)
downloadxen-79e1decf57682817f32e869dbff61606e6eac981.tar.gz
xen-79e1decf57682817f32e869dbff61606e6eac981.tar.bz2
xen-79e1decf57682817f32e869dbff61606e6eac981.zip
bitkeeper revision 1.1770 (42c2d66cG6YTU0WhG1b97E-InSNWWA)
Ensure global variables required by get_s_time() are initialised before first use. Rejuggle bootstrap code slightly. Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/arch/x86/nmi.c16
-rw-r--r--xen/arch/x86/setup.c15
-rw-r--r--xen/arch/x86/time.c10
3 files changed, 33 insertions, 8 deletions
diff --git a/xen/arch/x86/nmi.c b/xen/arch/x86/nmi.c
index 0e03b6a674..a0b11f9e1f 100644
--- a/xen/arch/x86/nmi.c
+++ b/xen/arch/x86/nmi.c
@@ -240,7 +240,6 @@ void __pminit setup_apic_nmi_watchdog(void)
}
init_ac_timer(&nmi_timer[cpu], nmi_timer_fn, NULL, cpu);
- nmi_timer_fn(NULL);
nmi_pm_init();
}
@@ -257,18 +256,33 @@ static unsigned int watchdog_on;
void watchdog_disable(void)
{
unsigned long flags;
+
spin_lock_irqsave(&watchdog_lock, flags);
+
if ( watchdog_disable_count++ == 0 )
watchdog_on = 0;
+
spin_unlock_irqrestore(&watchdog_lock, flags);
}
void watchdog_enable(void)
{
+ unsigned int cpu;
unsigned long flags;
+
spin_lock_irqsave(&watchdog_lock, flags);
+
if ( --watchdog_disable_count == 0 )
+ {
watchdog_on = 1;
+ /*
+ * Ensure periodic heartbeats are active. We cannot do this earlier
+ * during setup because the timer infrastructure is not available.
+ */
+ for_each_online_cpu ( cpu )
+ set_ac_timer(&nmi_timer[cpu], NOW());
+ }
+
spin_unlock_irqrestore(&watchdog_lock, flags);
}
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 1fb131b2c8..e74adf86e8 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -75,7 +75,7 @@ unsigned long xenheap_phys_start, xenheap_phys_end;
extern void arch_init_memory(void);
extern void init_IRQ(void);
extern void trap_init(void);
-extern void time_init(void);
+extern void early_time_init(void);
extern void ac_timer_init(void);
extern void initialize_keytable(void);
extern void early_cpu_init(void);
@@ -184,7 +184,7 @@ static void __init start_of_day(void)
ac_timer_init();
- time_init();
+ early_time_init();
arch_init_memory();
@@ -205,14 +205,19 @@ static void __init start_of_day(void)
for_each_cpu ( i )
cpu_set(i, cpu_present_map);
- /* Sanity: We ought to be taking interrupts by now. */
- local_irq_enable();
+ /*
+ * Initialise higher-level timer functions. We do this fairly late
+ * (post-SMP) because the time bases and scale factors need to be updated
+ * regularly, and SMP initialisation can cause a long delay with
+ * interrupts not yet enabled.
+ */
+ init_xen_time();
initialize_keytable();
serial_init_postirq();
- init_xen_time();
+ BUG_ON(!local_irq_is_enabled());
for_each_present_cpu ( i )
{
diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c
index acc5979c2b..5cd738bcde 100644
--- a/xen/arch/x86/time.c
+++ b/xen/arch/x86/time.c
@@ -239,6 +239,8 @@ static inline u64 get_time_delta(void)
u32 low;
u64 delta, tsc;
+ ASSERT(st_scale_f || st_scale_i);
+
rdtscll(tsc);
low = (u32)(tsc >> rdtsc_bitshift);
delta_tsc = (s32)(low - shifted_tsc_irq);
@@ -349,13 +351,17 @@ int __init init_xen_time()
st_scale_f = scale & 0xffffffff;
st_scale_i = scale >> 32;
+ local_irq_disable();
+
/* System time ticks from zero. */
rdtscll(full_tsc_irq);
stime_irq = (s_time_t)0;
shifted_tsc_irq = (u32)(full_tsc_irq >> rdtsc_bitshift);
/* Wallclock time starts as the initial RTC time. */
- wc_sec = get_cmos_time();
+ wc_sec = get_cmos_time();
+
+ local_irq_enable();
printk("Time init:\n");
printk(".... cpu_freq: %08X:%08X\n", (u32)(cpu_freq>>32),(u32)cpu_freq);
@@ -367,7 +373,7 @@ int __init init_xen_time()
/* Early init function. */
-void __init time_init(void)
+void __init early_time_init(void)
{
unsigned long ticks_per_frac = calibrate_tsc();