2 * This file is part of the coreboot project.
4 * Copyright (C) 2007 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
21 static inline void _WRMSR(u32 addr, u32 lo, u32 hi)
26 :"c"(addr),"a"(lo), "d" (hi)
31 static inline void _RDMSR(u32 addr, u32 *lo, u32 *hi)
35 :"=a"(*lo), "=d" (*hi)
41 static inline void _RDTSC(u32 *lo, u32 *hi)
45 : "=a" (*lo), "=d"(*hi)
50 static inline void _cpu_id(u32 addr, u32 *val)
63 static inline u32 bsr(u32 x)
80 static inline u32 bsf(u32 x)
95 #define _MFENCE asm volatile ( "mfence")
97 #define _SFENCE asm volatile ( "sfence" )
99 /* prevent speculative execution of following instructions */
100 #define _EXECFENCE asm volatile ("outb %al, $0xed")
102 static inline u32 read_cr4(void)
105 __asm__ volatile ("movl %%cr4, %0" : "=r" (cr4));
110 static inline void write_cr4(u32 cr4)
112 __asm__ volatile ("movl %0, %%cr4" : : "r" (cr4));
116 u32 SetUpperFSbase(u32 addr_hi);
119 static void proc_CLFLUSH(u32 addr_hi)
121 SetUpperFSbase(addr_hi);
124 /* clflush fs:[eax] */
125 "outb %%al, $0xed\n\t" /* _EXECFENCE */
126 "clflush %%fs:(%0)\n\t"
133 static void WriteLNTestPattern(u32 addr_lo, u8 *buf_a, u32 line_num)
136 /*prevent speculative execution of following instructions*/
137 /* FIXME: needed ? */
138 "outb %%al, $0xed\n\t" /* _EXECFENCE */
140 "movdqa (%3), %%xmm0\n\t"
141 "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
147 :: "a" (addr_lo), "d" (16), "c" (line_num * 4), "b"(buf_a)
153 u32 read32_fs(u32 addr_lo)
157 "outb %%al, $0xed\n\t" /* _EXECFENCE */
158 "movl %%fs:(%1), %0\n\t"
159 :"=b"(value): "a" (addr_lo)
165 u8 read8_fs(u32 addr_lo)
169 "outb %%al, $0xed\n\t" /* _EXECFENCE */
170 "movb %%fs:(%1), %b0\n\t"
172 :"=b"(byte): "a" (addr_lo)
178 static void FlushDQSTestPattern_L9(u32 addr_lo)
181 "outb %%al, $0xed\n\t" /* _EXECFENCE */
182 "clflush %%fs:-128(%%ecx)\n\t"
183 "clflush %%fs:-64(%%ecx)\n\t"
184 "clflush %%fs:(%%ecx)\n\t"
185 "clflush %%fs:64(%%ecx)\n\t"
187 "clflush %%fs:-128(%%eax)\n\t"
188 "clflush %%fs:-64(%%eax)\n\t"
189 "clflush %%fs:(%%eax)\n\t"
190 "clflush %%fs:64(%%eax)\n\t"
192 "clflush %%fs:-128(%%ebx)\n\t"
194 :: "b" (addr_lo+128+8*64), "c"(addr_lo+128),
195 "a"(addr_lo+128+4*64)
201 static __attribute__((noinline)) void FlushDQSTestPattern_L18(u32 addr_lo)
204 "outb %%al, $0xed\n\t" /* _EXECFENCE */
205 "clflush %%fs:-128(%%eax)\n\t"
206 "clflush %%fs:-64(%%eax)\n\t"
207 "clflush %%fs:(%%eax)\n\t"
208 "clflush %%fs:64(%%eax)\n\t"
210 "clflush %%fs:-128(%%edi)\n\t"
211 "clflush %%fs:-64(%%edi)\n\t"
212 "clflush %%fs:(%%edi)\n\t"
213 "clflush %%fs:64(%%edi)\n\t"
215 "clflush %%fs:-128(%%ebx)\n\t"
216 "clflush %%fs:-64(%%ebx)\n\t"
217 "clflush %%fs:(%%ebx)\n\t"
218 "clflush %%fs:64(%%ebx)\n\t"
220 "clflush %%fs:-128(%%ecx)\n\t"
221 "clflush %%fs:-64(%%ecx)\n\t"
222 "clflush %%fs:(%%ecx)\n\t"
223 "clflush %%fs:64(%%ecx)\n\t"
225 "clflush %%fs:-128(%%edx)\n\t"
226 "clflush %%fs:-64(%%edx)\n\t"
228 :: "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
229 "d" (addr_lo +128+16*64), "a"(addr_lo+128),
230 "D"(addr_lo+128+4*64)
235 static void ReadL18TestPattern(u32 addr_lo)
237 // set fs and use fs prefix to access the mem
239 "outb %%al, $0xed\n\t" /* _EXECFENCE */
240 "movl %%fs:-128(%%esi), %%eax\n\t" //TestAddr cache line
241 "movl %%fs:-64(%%esi), %%eax\n\t" //+1
242 "movl %%fs:(%%esi), %%eax\n\t" //+2
243 "movl %%fs:64(%%esi), %%eax\n\t" //+3
245 "movl %%fs:-128(%%edi), %%eax\n\t" //+4
246 "movl %%fs:-64(%%edi), %%eax\n\t" //+5
247 "movl %%fs:(%%edi), %%eax\n\t" //+6
248 "movl %%fs:64(%%edi), %%eax\n\t" //+7
250 "movl %%fs:-128(%%ebx), %%eax\n\t" //+8
251 "movl %%fs:-64(%%ebx), %%eax\n\t" //+9
252 "movl %%fs:(%%ebx), %%eax\n\t" //+10
253 "movl %%fs:64(%%ebx), %%eax\n\t" //+11
255 "movl %%fs:-128(%%ecx), %%eax\n\t" //+12
256 "movl %%fs:-64(%%ecx), %%eax\n\t" //+13
257 "movl %%fs:(%%ecx), %%eax\n\t" //+14
258 "movl %%fs:64(%%ecx), %%eax\n\t" //+15
260 "movl %%fs:-128(%%edx), %%eax\n\t" //+16
261 "movl %%fs:-64(%%edx), %%eax\n\t" //+17
264 :: "a"(0), "b" (addr_lo+128+8*64), "c" (addr_lo+128+12*64),
265 "d" (addr_lo +128+16*64), "S"(addr_lo+128),
266 "D"(addr_lo+128+4*64)
272 static void ReadL9TestPattern(u32 addr_lo)
275 // set fs and use fs prefix to access the mem
277 "outb %%al, $0xed\n\t" /* _EXECFENCE */
279 "movl %%fs:-128(%%ecx), %%eax\n\t" //TestAddr cache line
280 "movl %%fs:-64(%%ecx), %%eax\n\t" //+1
281 "movl %%fs:(%%ecx), %%eax\n\t" //+2
282 "movl %%fs:64(%%ecx), %%eax\n\t" //+3
284 "movl %%fs:-128(%%edx), %%eax\n\t" //+4
285 "movl %%fs:-64(%%edx), %%eax\n\t" //+5
286 "movl %%fs:(%%edx), %%eax\n\t" //+6
287 "movl %%fs:64(%%edx), %%eax\n\t" //+7
289 "movl %%fs:-128(%%ebx), %%eax\n\t" //+8
292 :: "a"(0), "b" (addr_lo+128+8*64), "c"(addr_lo+128),
293 "d"(addr_lo+128+4*64)
299 static void ReadMaxRdLat1CLTestPattern_D(u32 addr)
301 SetUpperFSbase(addr);
304 "outb %%al, $0xed\n\t" /* _EXECFENCE */
305 "movl %%fs:-128(%%esi), %%eax\n\t" //TestAddr cache line
306 "movl %%fs:-64(%%esi), %%eax\n\t" //+1
307 "movl %%fs:(%%esi), %%eax\n\t" //+2
309 :: "a"(0), "S"((addr<<8)+128)
315 void WriteMaxRdLat1CLTestPattern_D(u32 buf, u32 addr)
317 SetUpperFSbase(addr);
320 "outb %%al, $0xed\n\t" /* _EXECFENCE */
322 "movdqa (%3), %%xmm0\n\t"
323 "movntdq %%xmm0, %%fs:(%0)\n\t" /* xmm0 is 128 bit */
329 :: "a" (addr<<8), "d" (16), "c" (3 * 4), "b"(buf)
334 static void FlushMaxRdLatTestPattern_D(u32 addr)
336 /* Flush a pattern of 72 bit times (per DQ) from cache.
337 * This procedure is used to ensure cache miss on the next read training.
340 SetUpperFSbase(addr);
343 "outb %%al, $0xed\n\t" /* _EXECFENCE */
344 "clflush %%fs:-128(%%esi)\n\t" //TestAddr cache line
345 "clflush %%fs:-64(%%esi)\n\t" //+1
346 "clflush %%fs:(%%esi)\n\t" //+2
349 :: "S"((addr<<8)+128)
354 u32 stream_to_int(u8 *p)
362 for(i=3; i>=0; i--) {
372 void oemSet_NB32(u32 addr, u32 val, u8 *valid)
377 u32 oemGet_NB32(u32 addr, u8 *valid)
384 u8 oemNodePresent_D(u8 Node, u8 *ret)