From 095593c0301399ae834050e2008862451a72b8b0 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Sun, 2 Dec 2012 04:49:50 +0000 Subject: x86: Add basic cache operations Add functions to enable/disable the data cache. Signed-off-by: Stefan Reinauer Signed-off-by: Simon Glass --- arch/x86/cpu/interrupts.c | 68 ++--------------------------------------------- 1 file changed, 2 insertions(+), 66 deletions(-) (limited to 'arch/x86/cpu/interrupts.c') diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index 43ec3f8b0..e7887152f 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -28,6 +28,8 @@ */ #include +#include +#include #include #include #include @@ -41,72 +43,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; -- cgit v1.2.3-70-g09d2 From 7c71034d3ca2f4bd01812e94e813d35a78a27e34 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Mon, 3 Dec 2012 13:59:20 +0000 Subject: x86: Provide tick counter and frequency reference for Intel core architecture Some u-boot modules rely on availability of get_ticks() and get_tbclk() functions, reporting a free running clock and its frequency respectively. Traditionally these functions return number and frequency of timer interrupts. Intel's core architecture processors however are known to run the rdtsc instruction at a constant rate of the so called 'Max Non Turbo ratio' times the external clock frequency which is 100MHz. This is just as good for the timer tick functions in question. Signed-off-by: Vadim Bendebury Signed-off-by: Simon Glass --- arch/x86/cpu/interrupts.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'arch/x86/cpu/interrupts.c') diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index e7887152f..dd30a05a9 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #define DECLARE_INTERRUPT(x) \ ".globl irq_"#x"\n" \ @@ -615,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 -- cgit v1.2.3-70-g09d2