diff options
author | Allen Martin <amartin@nvidia.com> | 2012-12-19 13:02:36 -0800 |
---|---|---|
committer | Allen Martin <amartin@nvidia.com> | 2012-12-19 13:02:36 -0800 |
commit | a098cf41fdb2a6607c675f7fe4f3164617c9367e (patch) | |
tree | b37acb36f65909e6f74cc537d73efd883a1485a6 /arch/x86/cpu/interrupts.c | |
parent | b8a7c467960ffb4d5a5e1eef5f7783fb6f594542 (diff) | |
parent | 095728803eedfce850a2f85828f79500cb09979e (diff) |
Merge remote-tracking branch 'u-boot/master' into u-boot-arm-merged
Conflicts:
README
arch/arm/cpu/armv7/exynos/clock.c
board/samsung/universal_c210/universal.c
drivers/misc/Makefile
drivers/power/power_fsl.c
include/configs/mx35pdk.h
include/configs/mx53loco.h
include/configs/seaboard.h
Diffstat (limited to 'arch/x86/cpu/interrupts.c')
-rw-r--r-- | arch/x86/cpu/interrupts.c | 99 |
1 files changed, 33 insertions, 66 deletions
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index 43ec3f8b08..dd30a05a9d 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -28,10 +28,14 @@ */ #include <common.h> +#include <asm/cache.h> +#include <asm/control_regs.h> #include <asm/interrupt.h> #include <asm/io.h> #include <asm/processor-flags.h> #include <linux/compiler.h> +#include <asm/msr.h> +#include <asm/u-boot-x86.h> #define DECLARE_INTERRUPT(x) \ ".globl irq_"#x"\n" \ @@ -41,72 +45,6 @@ "pushl $"#x"\n" \ "jmp irq_common_entry\n" -/* - * Volatile isn't enough to prevent the compiler from reordering the - * read/write functions for the control registers and messing everything up. - * A memory clobber would solve the problem, but would prevent reordering of - * all loads stores around it, which can hurt performance. Solution is to - * use a variable and mimic reads and writes to it to enforce serialisation - */ -static unsigned long __force_order; - -static inline unsigned long read_cr0(void) -{ - unsigned long val; - asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order)); - return val; -} - -static inline unsigned long read_cr2(void) -{ - unsigned long val; - asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order)); - return val; -} - -static inline unsigned long read_cr3(void) -{ - unsigned long val; - asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order)); - return val; -} - -static inline unsigned long read_cr4(void) -{ - unsigned long val; - asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order)); - return val; -} - -static inline unsigned long get_debugreg(int regno) -{ - unsigned long val = 0; /* Damn you, gcc! */ - - switch (regno) { - case 0: - asm("mov %%db0, %0" : "=r" (val)); - break; - case 1: - asm("mov %%db1, %0" : "=r" (val)); - break; - case 2: - asm("mov %%db2, %0" : "=r" (val)); - break; - case 3: - asm("mov %%db3, %0" : "=r" (val)); - break; - case 6: - asm("mov %%db6, %0" : "=r" (val)); - break; - case 7: - asm("mov %%db7, %0" : "=r" (val)); - break; - default: - val = 0; - } - return val; -} - void dump_regs(struct irq_regs *regs) { unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; @@ -679,3 +617,32 @@ 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) +{ + static u64 tick_base; + u64 now_tick = rdtsc(); + + if (!tick_base) + tick_base = now_tick; + + return now_tick - tick_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 |