2 * This file is part of the coreboot project.
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 static inline void _WRMSR(u32 addr, u32 lo, u32 hi)
25 :"c"(addr),"a"(lo), "d" (hi)
29 static inline void _RDMSR(u32 addr, u32 *lo, u32 *hi)
33 :"=a"(*lo), "=d" (*hi)
38 static inline void _RDTSC(u32 *lo, u32 *hi)
42 : "=a" (*lo), "=d"(*hi)
46 static inline void _cpu_id(u32 addr, u32 *val)
89 #define _MFENCE asm volatile ( "mfence")
91 #define _SFENCE asm volatile ( "sfence" )
93 /* prevent speculative execution of following instructions */
94 #define _EXECFENCE asm volatile ("outb %al, $0xed")
96 static inline u32 read_cr4(void)
99 __asm__ volatile ("movl %%cr4, %0" : "=r" (cr4));
103 static inline void write_cr4(u32 cr4)
105 __asm__ volatile ("movl %0, %%cr4" : : "r" (cr4));
108 u32 SetUpperFSbase(u32 addr_hi);
110 static void proc_CLFLUSH(u32 addr_hi)
112 SetUpperFSbase(addr_hi);
115 /* clflush fs:[eax] */
116 "outb %%al, $0xed\n\t" /* _EXECFENCE */
117 "clflush %%fs:(%0)\n\t"
124 static void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num)
127 /*prevent speculative execution of following instructions*/
128 /* FIXME: needed ? */
129 "outb %%al, $0xed\n\t" /* _EXECFENCE */
131 "movdqa (%3), %%xmm0\n\t"
132 "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
138 :: "a" (addr_lo), "d" (16), "c" (line_num * 4), "b"(buf_a)
143 static u32 read32_fs(u32 addr_lo)
147 "outb %%al, $0xed\n\t" /* _EXECFENCE */
148 "movl %%fs:(%1), %0\n\t"
149 :"=b"(value): "a" (addr_lo)
155 static u8 read8_fs(u32 addr_lo)
159 "outb %%al, $0xed\n\t" /* _EXECFENCE */
160 "movb %%fs:(%1), %b0\n\t"
162 :"=b"(byte): "a" (addr_lo)
168 static void FlushDQSTestPattern_L9(u32 addr_lo)
171 "outb %%al, $0xed\n\t" /* _EXECFENCE */
172 "clflush %%fs:-128(%%ecx)\n\t"
173 "clflush %%fs:-64(%%ecx)\n\t"
174 "clflush %%fs:(%%ecx)\n\t"
175 "clflush %%fs:64(%%ecx)\n\t"
177 "clflush %%fs:-128(%%eax)\n\t"
178 "clflush %%fs:-64(%%eax)\n\t"
179 "clflush %%fs:(%%eax)\n\t"
180 "clflush %%fs:64(%%eax)\n\t"
182 "clflush %%fs:-128(%%ebx)\n\t"
184 :: "b" (addr_lo+128+8*64), "c"(addr_lo+128),
185 "a"(addr_lo+128+4*64)
190 static __attribute__((noinline)) void FlushDQSTestPattern_L18(u32 addr_lo)
193 "outb %%al, $0xed\n\t" /* _EXECFENCE */
194 "clflush %%fs:-128(%%eax)\n\t"
195 "clflush %%fs:-64(%%eax)\n\t"
196 "clflush %%fs:(%%eax)\n\t"
197 "clflush %%fs:64(%%eax)\n\t"
199 "clflush %%fs:-128(%%edi)\n\t"
200 "clflush %%fs:-64(%%edi)\n\t"
201 "clflush %%fs:(%%edi)\n\t"
202 "clflush %%fs:64(%%edi)\n\t"
204 "clflush %%fs:-128(%%ebx)\n\t"
205 "clflush %%fs:-64(%%ebx)\n\t"
206 "clflush %%fs:(%%ebx)\n\t"
207 "clflush %%fs:64(%%ebx)\n\t"
209 "clflush %%fs:-128(%%ecx)\n\t"
210 "clflush %%fs:-64(%%ecx)\n\t"
211 "clflush %%fs:(%%ecx)\n\t"
212 "clflush %%fs:64(%%ecx)\n\t"
214 "clflush %%fs:-128(%%edx)\n\t"
215 "clflush %%fs:-64(%%edx)\n\t"
217 :: "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
218 "d" (addr_lo +128+16*64), "a"(addr_lo+128),
219 "D"(addr_lo+128+4*64)
223 static void ReadL18TestPattern(u32 addr_lo)
225 /* set fs and use fs prefix to access the mem */
227 "outb %%al, $0xed\n\t" /* _EXECFENCE */
228 "movl %%fs:-128(%%esi), %%eax\n\t" /* TestAddr cache line */
229 "movl %%fs:-64(%%esi), %%eax\n\t" /* +1 */
230 "movl %%fs:(%%esi), %%eax\n\t" /* +2 */
231 "movl %%fs:64(%%esi), %%eax\n\t" /* +3 */
233 "movl %%fs:-128(%%edi), %%eax\n\t" /* +4 */
234 "movl %%fs:-64(%%edi), %%eax\n\t" /* +5 */
235 "movl %%fs:(%%edi), %%eax\n\t" /* +6 */
236 "movl %%fs:64(%%edi), %%eax\n\t" /* +7 */
238 "movl %%fs:-128(%%ebx), %%eax\n\t" /* +8 */
239 "movl %%fs:-64(%%ebx), %%eax\n\t" /* +9 */
240 "movl %%fs:(%%ebx), %%eax\n\t" /* +10 */
241 "movl %%fs:64(%%ebx), %%eax\n\t" /* +11 */
243 "movl %%fs:-128(%%ecx), %%eax\n\t" /* +12 */
244 "movl %%fs:-64(%%ecx), %%eax\n\t" /* +13 */
245 "movl %%fs:(%%ecx), %%eax\n\t" /* +14 */
246 "movl %%fs:64(%%ecx), %%eax\n\t" /* +15 */
248 "movl %%fs:-128(%%edx), %%eax\n\t" /* +16 */
249 "movl %%fs:-64(%%edx), %%eax\n\t" /* +17 */
252 :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
253 "d" (addr_lo +128+16*64), "S"(addr_lo+128),
254 "D"(addr_lo+128+4*64)
259 static void ReadL9TestPattern(u32 addr_lo)
262 /* set fs and use fs prefix to access the mem */
264 "outb %%al, $0xed\n\t" /* _EXECFENCE */
266 "movl %%fs:-128(%%ecx), %%eax\n\t" /* TestAddr cache line */
267 "movl %%fs:-64(%%ecx), %%eax\n\t" /* +1 */
268 "movl %%fs:(%%ecx), %%eax\n\t" /* +2 */
269 "movl %%fs:64(%%ecx), %%eax\n\t" /* +3 */
271 "movl %%fs:-128(%%edx), %%eax\n\t" /* +4 */
272 "movl %%fs:-64(%%edx), %%eax\n\t" /* +5 */
273 "movl %%fs:(%%edx), %%eax\n\t" /* +6 */
274 "movl %%fs:64(%%edx), %%eax\n\t" /* +7 */
276 "movl %%fs:-128(%%ebx), %%eax\n\t" /* +8 */
279 :: "a"(0), "b" (addr_lo+128+8*64), "c"(addr_lo+128),
280 "d"(addr_lo+128+4*64)
285 static void ReadMaxRdLat1CLTestPattern_D(u32 addr)
287 SetUpperFSbase(addr);
290 "outb %%al, $0xed\n\t" /* _EXECFENCE */
291 "movl %%fs:-128(%%esi), %%eax\n\t" /* TestAddr cache line */
292 "movl %%fs:-64(%%esi), %%eax\n\t" /* +1 */
293 "movl %%fs:(%%esi), %%eax\n\t" /* +2 */
295 :: "a"(0), "S"((addr<<8)+128)
300 static void WriteMaxRdLat1CLTestPattern_D(u32 buf, u32 addr)
302 SetUpperFSbase(addr);
305 "outb %%al, $0xed\n\t" /* _EXECFENCE */
307 "movdqa (%3), %%xmm0\n\t"
308 "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
314 :: "a" (addr<<8), "d" (16), "c" (3 * 4), "b"(buf)
318 static void FlushMaxRdLatTestPattern_D(u32 addr)
320 /* Flush a pattern of 72 bit times (per DQ) from cache.
321 * This procedure is used to ensure cache miss on the next read training.
324 SetUpperFSbase(addr);
327 "outb %%al, $0xed\n\t" /* _EXECFENCE */
328 "clflush %%fs:-128(%%esi)\n\t" /* TestAddr cache line */
329 "clflush %%fs:-64(%%esi)\n\t" /* +1 */
330 "clflush %%fs:(%%esi)\n\t" /* +2 */
333 :: "S"((addr<<8)+128)
337 static u32 stream_to_int(u8 *p)
345 for(i=3; i>=0; i--) {
355 static void oemSet_NB32(u32 addr, u32 val, u8 *valid)
359 static u32 oemGet_NB32(u32 addr, u8 *valid)
366 static u8 oemNodePresent_D(u8 Node, u8 *ret)