e8bc195307ecf52aee2f696b7225ae16c657c5ca
[coreboot.git] / src / include / cpu / x86 / msr.h
1 #ifndef CPU_X86_MSR_H
2 #define CPU_X86_MSR_H
3
4 #if defined(__ROMCC__)
5
6 typedef __builtin_msr_t msr_t;
7
8 static msr_t rdmsr(unsigned long index)
9 {
10         return __builtin_rdmsr(index);
11 }
12
13 static void wrmsr(unsigned long index, msr_t msr)
14 {
15         __builtin_wrmsr(index, msr.lo, msr.hi);
16 }
17
18 #else
19
20 typedef struct msr_struct
21 {
22         unsigned lo;
23         unsigned hi;
24 } msr_t;
25
26 typedef struct msrinit_struct 
27 {
28         unsigned index;
29         msr_t msr;
30 } msrinit_t;
31
32 /* The following functions require the always_inline due to AMD
33  * function STOP_CAR_AND_CPU that disables cache as
34  * ram, the cache as ram stack can no longer be used. Called
35  * functions must be inlined to avoid stack usage. Also, the
36  * compiler must keep local variables register based and not
37  * allocated them from the stack. With gcc 4.5.0, some functions
38  * declared as inline are not being inlined. This patch forces
39  * these functions to always be inlined by adding the qualifier
40  * __attribute__((always_inline)) to their declaration.
41  */
42 static inline __attribute__((always_inline)) msr_t rdmsr(unsigned index)
43 {
44         msr_t result;
45         __asm__ __volatile__ (
46                 "rdmsr"
47                 : "=a" (result.lo), "=d" (result.hi)
48                 : "c" (index)
49                 );
50         return result;
51 }
52
53 static inline __attribute__((always_inline)) void wrmsr(unsigned index, msr_t msr)
54 {
55         __asm__ __volatile__ (
56                 "wrmsr"
57                 : /* No outputs */
58                 : "c" (index), "a" (msr.lo), "d" (msr.hi)
59                 );
60 }
61
62 #endif /* __ROMCC__ */
63
64 #endif /* CPU_X86_MSR_H */