[U-Boot] [PATCH v2 10/33] x86: Tidy up timer code for Intel core architecture

Bin Meng bmeng.cn at gmail.com
Wed Nov 12 02:26:12 CET 2014


Hi Simon,

On Wed, Nov 12, 2014 at 12:12 AM, Simon Glass <sjg at chromium.org> wrote:
> Hi Bin,
>
> On 11 November 2014 03:05, Bin Meng <bmeng.cn at gmail.com> wrote:
>> Hi Simon,
>>
>> On Tue, Nov 11, 2014 at 9:00 AM, Simon Glass <sjg at chromium.org> wrote:
>>> We can use an MSR to obtain the time base. Add this back in and consolidate
>>> the code.
>>>
>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>> ---
>>>
>>> Changes in v2:
>>> - Add new patch to tidy up timer code for Intel core architecture
>>>
>>>  arch/x86/cpu/interrupts.c | 28 ----------------------------
>>>  arch/x86/lib/tsc_timer.c  | 16 +++++++++++++++-
>>>  2 files changed, 15 insertions(+), 29 deletions(-)
>>>
>>> diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
>>> index 51e2c59..4822c11 100644
>>> --- a/arch/x86/cpu/interrupts.c
>>> +++ b/arch/x86/cpu/interrupts.c
>>> @@ -603,31 +603,3 @@ asm(".globl irq_common_entry\n" \
>>>         DECLARE_INTERRUPT(253) \
>>>         DECLARE_INTERRUPT(254) \
>>>         DECLARE_INTERRUPT(255));
>>> -
>>> -#if defined(CONFIG_INTEL_CORE_ARCH)
>>> -/*
>>> - * Get the number of CPU time counter ticks since it was read first time after
>>> - * restart. This yields a free running counter guaranteed to take almost 6
>>> - * years to wrap around even at 100GHz clock rate.
>>> - */
>>> -u64 get_ticks(void)
>>> -{
>>> -       u64 now_tick = rdtsc();
>>> -
>>> -       if (!gd->arch.tsc_base)
>>> -               gd->arch.tsc_base = now_tick;
>>> -
>>> -       return now_tick - gd->arch.tsc_base;
>>> -}
>>> -
>>> -#define PLATFORM_INFO_MSR 0xce
>>> -
>>> -unsigned long get_tbclk(void)
>>> -{
>>> -       u32 ratio;
>>> -       u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
>>> -
>>> -       ratio = (platform_info >> 8) & 0xff;
>>> -       return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */
>>> -}
>>> -#endif
>>> diff --git a/arch/x86/lib/tsc_timer.c b/arch/x86/lib/tsc_timer.c
>>> index f091c91..3936b36 100644
>>> --- a/arch/x86/lib/tsc_timer.c
>>> +++ b/arch/x86/lib/tsc_timer.c
>>> @@ -180,6 +180,20 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp,
>>>         return count > 5;
>>>  }
>>>
>>> +#define PLATFORM_INFO_MSR 0xce
>>> +
>>> +/* Get the speed of the TSC timer in MHz */
>>> +unsigned __attribute__((no_instrument_function))
>>> +               long get_tbclk_mhz_from_msr(void)
>>> +{
>>> +       u32 ratio;
>>> +       u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
>>> +
>>> +       /* 100MHz times Max Non Turbo ratio */
>>> +       ratio = (platform_info >> 8) & 0xff;
>>> +       return 100 * ratio;
>>> +}
>>> +
>>>  /*
>>>   * How many MSB values do we want to see? We aim for
>>>   * a maximum error rate of 500ppm (in practice the
>>> @@ -302,7 +316,7 @@ unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void)
>>>
>>>         fast_calibrate = quick_pit_calibrate();
>>>         if (!fast_calibrate)
>>> -               panic("TSC frequency is ZERO");
>>> +               fast_calibrate = get_tbclk_mhz_from_msr();
>>>
>>>         gd->arch.tsc_mhz = fast_calibrate;
>>>         return fast_calibrate;
>>> --
>>
>> Adding MSR calibration back for Intel CORE this way is inconsistent
>> with the code logic. Can you please try adding the family number and
>> model number in the freq_desc_tables[]?
>
> Yes, but I was hoping for something automatic rather than a list of
> exceptions. What is the guaranteed way to do this calibration?

I am not considering this as an exception. The Linux codes explicitly
mentions that the MSR calibration is only used on Atom processors.
What I am proposing here is that since the CORE architecture also has
the MSR_PLATFORM_INFO and the TSC running frequency can be easily
retrieved from that, we can add such capability into the MSR
calibration routine to handle the non-Atom architectures. Note on
Linux, when quick_pit_calibrate() fails, Linux falls back to use a
slow PIT calibration and HPET/PMTIMER as the calibration source. I
originally did not pull these stuff into the U-Boot, and thought the
quick_pit_calibrate() is enough on all platforms. If you think
updating freq_desc_tables[] is not feasible, or we need keep U-Boot
consistent with the Linux implementation, feel free to bring the slow
PIT calibration and HPET/PMTIMER into U-Boot.

Regards,
Bin


More information about the U-Boot mailing list