X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Finclude%2Fcpu%2Fx86%2Fcache.h;h=c2de073a521972a6f2edde3a46452a7e3599d5e1;hb=5ff7c13e858a31addf1558731a12cf6c753b576d;hp=858637cf2bd27d6580fdce0f45f9177496bc1e4e;hpb=fdddce3b926b5ad1d27f807feaeb318471a543ab;p=coreboot.git diff --git a/src/include/cpu/x86/cache.h b/src/include/cpu/x86/cache.h index 858637cf2..c2de073a5 100644 --- a/src/include/cpu/x86/cache.h +++ b/src/include/cpu/x86/cache.h @@ -20,20 +20,17 @@ #ifndef CPU_X86_CACHE #define CPU_X86_CACHE -/* the memory clobber prevents the GCC from reordering the read/write order - of CR0 */ - +/* + * Need two versions because ROMCC chokes on certain clobbers: + * cache.h:29.71: cache.h:60.24: earlymtrr.c:117.23: romstage.c:144.33: + * 0x1559920 asm Internal compiler error: lhs 1 regcm == 0 */ #if defined(__GNUC__) -/* -Need this because ROMCC fails here with: - -cache.h:29.71: cache.h:60.24: earlymtrr.c:117.23: romstage.c:144.33: -0x1559920 asm Internal compiler error: lhs 1 regcm == 0 -*/ - +/* The memory clobber prevents the GCC from reordering the read/write order + * of CR0 + */ static inline unsigned long read_cr0(void) { unsigned long cr0; @@ -46,6 +43,11 @@ static inline void write_cr0(unsigned long cr0) asm volatile ("movl %0, %%cr0" : : "r" (cr0) : "memory"); } +static inline void wbinvd(void) +{ + asm volatile ("wbinvd" ::: "memory"); +} + #else static inline unsigned long read_cr0(void) @@ -60,20 +62,29 @@ static inline void write_cr0(unsigned long cr0) asm volatile ("movl %0, %%cr0" : : "r" (cr0)); } -#endif +static inline void wbinvd(void) +{ + asm volatile ("wbinvd"); +} +#endif static inline void invd(void) { asm volatile("invd" ::: "memory"); } -static inline void wbinvd(void) -{ - asm volatile ("wbinvd" ::: "memory"); -} - -static inline void enable_cache(void) +/* The following functions require the always_inline due to AMD + * function STOP_CAR_AND_CPU that disables cache as + * ram, the cache as ram stack can no longer be used. Called + * functions must be inlined to avoid stack usage. Also, the + * compiler must keep local variables register based and not + * allocated them from the stack. With gcc 4.5.0, some functions + * declared as inline are not being inlined. This patch forces + * these functions to always be inlined by adding the qualifier + * __attribute__((always_inline)) to their declaration. + */ +static inline __attribute__((always_inline)) void enable_cache(void) { unsigned long cr0; cr0 = read_cr0(); @@ -81,7 +92,7 @@ static inline void enable_cache(void) write_cr0(cr0); } -static inline void disable_cache(void) +static inline __attribute__((always_inline)) void disable_cache(void) { /* Disable and write back the cache */ unsigned long cr0;