Re: PROBLEM: Can't boot a (HZ = 1000) kernel using an AMD Phenom-IIprocessor
From: Andreas Herrmann
Date: Fri Feb 20 2009 - 06:54:45 EST
On Thu, Feb 19, 2009 at 10:54:19AM -0500, Mark Hounschell wrote:
> Borislav Petkov wrote:
> > On Thu, Feb 19, 2009 at 10:16:40AM -0500, Mark Hounschell wrote:
> >> Andreas Herrmann wrote:
> >>> Hi Mark,
> >>>
> >>> Can you please provide us output of lspci -vvxxx.
> >>> (Please run this as root.)
> >>>
>
> Attached...
>
>
> >>> Furthermore you can try booting your 1000HZ kernel
> >>> with following kernel command lines:
> >>>
Thanks for trying this out.
But nothing suspicious found. I.e. timer/hpet interrupt is enabled
and its routing seems to be ok.
Here's one more check that's worth trying: In one of your logs I've
seen that HPET id reports 3 timers but later on 4 timers were detected
for HPET.
To check what's going on I'd like to see the HPET configuration in the
course of booting your system. Please apply attached patch and boot
with hpet=debug -- both with 250HZ and with 1000HZ -- and provide dmesg
output.
Regards,
Andreas
--
Operating | Advanced Micro Devices GmbH
System | Karl-Hammerschmidt-Str. 34, 85609 Dornach b. München, Germany
Research | Geschäftsführer: Jochen Polster, Thomas M. McCoy, Giuliano Meroni
Center | Sitz: Dornach, Gemeinde Aschheim, Landkreis München
(OSRC) | Registergericht München, HRB Nr. 43632
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 388254f..2a389d9 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -80,6 +80,7 @@ static inline void hpet_clear_mapping(void)
*/
static int boot_hpet_disable;
int hpet_force_user;
+static int hpet_debug;
static int __init hpet_setup(char *str)
{
@@ -88,6 +89,8 @@ static int __init hpet_setup(char *str)
boot_hpet_disable = 1;
if (!strncmp("force", str, 5))
hpet_force_user = 1;
+ if (!strncmp("debug", str, 5))
+ hpet_debug = 1;
}
return 1;
}
@@ -119,6 +122,42 @@ int is_hpet_enabled(void)
}
EXPORT_SYMBOL_GPL(is_hpet_enabled);
+static void _hpet_print_config(const char *function, int line)
+{
+ u32 l, h;
+ printk(KERN_DEBUG "hpet: %s(%d):\n", function, line);
+ l = hpet_readl(HPET_ID); h = hpet_readl(HPET_PERIOD);
+ printk(KERN_DEBUG "hpet: ID: %x, PERIOD: %x\n", l, h);
+ l = hpet_readl(HPET_CFG); h = hpet_readl(HPET_STATUS);
+ printk(KERN_DEBUG "hpet: CFG: %x, STATUS: %x\n", l, h);
+ l = hpet_readl(HPET_COUNTER); h = hpet_readl(HPET_COUNTER+4);
+ printk(KERN_DEBUG "hpet: COUNTER_l: %x, COUNTER_h: %x\n", l, h);
+ l = hpet_readl(HPET_T0_CFG); h = hpet_readl(HPET_T0_CFG+4);
+ printk(KERN_DEBUG "hpet: T0_CFG_l: %x, T0_CFG_h: %x\n", l, h);
+ l = hpet_readl(HPET_T0_CMP); h = hpet_readl(HPET_T0_CMP+4);
+ printk(KERN_DEBUG "hpet: T0_CMP_l: %x, T0_CMP_h: %x\n", l, h);
+ l = hpet_readl(HPET_T0_ROUTE); h = hpet_readl(HPET_T0_ROUTE+4);
+ printk(KERN_DEBUG "hpet: T0_ROUTE_l: %x, T0_ROUTE_h: %x\n", l, h);
+ l = hpet_readl(HPET_T1_CFG); h = hpet_readl(HPET_T1_CFG+4);
+ printk(KERN_DEBUG "hpet: T1_CFG_l: %x, T1_CFG_h: %x\n", l, h);
+ l = hpet_readl(HPET_T1_CMP); h = hpet_readl(HPET_T1_CMP+4);
+ printk(KERN_DEBUG "hpet: T1_CMP_l: %x, T1_CMP_h: %x\n", l, h);
+ l = hpet_readl(HPET_T1_ROUTE); h = hpet_readl(HPET_T1_ROUTE+4);
+ printk(KERN_DEBUG "hpet: T1_ROUTE_l: %x, T1_ROUTE_h: %x\n", l, h);
+ l = hpet_readl(HPET_T2_CFG); h = hpet_readl(HPET_T2_CFG+4);
+ printk(KERN_DEBUG "hpet: T2_CFG_l: %x, T2_CFG_h: %x\n", l, h);
+ l = hpet_readl(HPET_T2_CMP); h = hpet_readl(HPET_T2_CMP+4);
+ printk(KERN_DEBUG "hpet: T2_CMP_l: %x, T2_CMP_h: %x\n", l, h);
+ l = hpet_readl(HPET_T2_ROUTE); h = hpet_readl(HPET_T2_ROUTE+4);
+ printk(KERN_DEBUG "hpet: T2_ROUTE_l: %x, T2_ROUTE_h: %x\n", l, h);
+}
+
+#define hpet_print_config() \
+do { \
+ if (hpet_debug) \
+ _hpet_print_config(__FUNCTION__, __LINE__); \
+} while (0)
+
/*
* When the hpet driver (/dev/hpet) is enabled, we need to reserve
* timer 0 and timer 1 in case of RTC emulation.
@@ -264,6 +303,7 @@ static void hpet_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
+ hpet_print_config();
delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
delta >>= evt->shift;
now = hpet_readl(HPET_COUNTER);
@@ -280,6 +320,8 @@ static void hpet_set_mode(enum clock_event_mode mode,
hpet_writel(cmp, HPET_Tn_CMP(timer));
udelay(1);
hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
+ WARN_ON(cmp <= hpet_readl(HPET_COUNTER));
+ hpet_print_config();
break;
case CLOCK_EVT_MODE_ONESHOT:
@@ -524,6 +566,7 @@ static void hpet_msi_capability_lookup(unsigned int start_timer)
num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
num_timers++; /* Value read out starts from 0 */
+ hpet_print_config();
hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL);
if (!hpet_devs)
@@ -791,6 +834,7 @@ int __init hpet_enable(void)
* information and the number of channels
*/
id = hpet_readl(HPET_ID);
+ hpet_print_config();
#ifdef CONFIG_HPET_EMULATE_RTC
/*
@@ -843,6 +887,7 @@ static __init int hpet_late_init(void)
return -ENODEV;
hpet_reserve_platform_timers(hpet_readl(HPET_ID));
+ hpet_print_config();
for_each_online_cpu(cpu) {
hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);