1 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ids.h>
10 #include <cpu/amd/gx2def.h>
11 #include <cpu/x86/msr.h>
12 #include <cpu/x86/cache.h>
19 msr.whatever |= ID_CONFIG_SERIAL_SET;
26 msr = rdmsr(MC_GLD_MSR_PM);
34 * Bugtool #465 and #609
36 * There is also fix code in cache and PCI functions. This bug is very is pervasive.
38 static void pcideadlock(void)
42 /* forces serialization of all load misses. Setting this bit prevents the
43 * DM pipe from backing up if a read request has to be held up waiting
44 * for PCI writes to complete.
46 msr = rdmsr(CPU_DM_CONFIG0);
47 msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
48 msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
49 msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
50 wrmsr(CPU_DM_CONFIG0, msr);
52 /* interlock instruction fetches to WS regions with data accesses.
53 * This prevents an instruction fetch from going out to PCI if the
54 * data side is about to make a request.
56 msr = rdmsr(CPU_IM_CONFIG);
57 msr.lo |= IM_CONFIG_LOWER_QWT_SET;
58 wrmsr(CPU_IM_CONFIG, msr);
60 /* write serialize memory hole to PCI. Need to unWS when something is
61 * shadowed regardless of cachablility.
65 wrmsr( CPU_RCONF_A0_BF, msr);
66 wrmsr( CPU_RCONF_C0_DF, msr);
67 wrmsr( CPU_RCONF_E0_FF, msr);
74 * Fix CPUID instructions for < 3.0 CPUs
76 static void bug784(void)
79 //static char *name = "Geode by NSC";
81 /* we'll do this the stupid way, for now, but that's the string they want. NO ONE KNOWS why you
82 * would do this -- the OS can figure this type of stuff out!
96 /* More CPUID to match AMD better. #792*/
103 /* cpubug 1398: enable MC if we KNOW we have DDR*/
107 * ClearQuest #IAENG1398
108 * The MC can not be enabled with SDR memory but can for DDR. Enable for
109 * DDR here if the setup token is "Default"
110 * Add this back to core by default once 2.0 CPUs are not supported.
112 static void eng1398(void)
116 msr = rdmsr(MSR_GLCP+0x17);
117 if ((msr.lo & 0xff) <= CPU_REV_2_0) {
118 msr = rdmsr(GLCP_SYS_RSTPLL);
119 if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT))
123 /* no CMOS/NVRAM to check, so enable MC Clock Gating */
124 msr = rdmsr(MC_GLD_MSR_PM);
125 msr.lo |= 3; /* enable MC clock gating.*/
126 wrmsr(MC_GLD_MSR_PM, msr);
131 * Clear Quest IAENG00002900, VSS 118.150
133 * BTB issue causes blue screen in windows, but the fix is required
134 * for all operating systems.
136 static void eng2900(void)
140 printk(BIOS_DEBUG, "CPU_BUG:%s\n", __func__);
141 /* Clear bit 43, disables the sysenter/sysexit in CPUID3 */
143 msr.hi &= 0xFFFFF7FF;
146 /* change this value to zero if you need to disable this BTB SWAPSiF. */
149 /* Disable enable_actions in DIAGCTL while setting up GLCP */
152 wrmsr(MSR_GLCP + 0x005f, msr);
154 /* Changing DBGCLKCTL register to GeodeLink */
157 wrmsr(MSR_GLCP + 0x0016, msr);
161 wrmsr(MSR_GLCP + 0x0016, msr);
163 /* The code below sets up the CPU to stall for 4 GeodeLink
164 * clocks when CPU is snooped. Because setting XSTATE to 0
165 * overrides any other XSTATE action, the code will always
166 * stall for 4 GeodeLink clocks after a snoop request goes
167 * away even if it occured a clock or two later than a
168 * different snoop; the stall signal will never 'glitch high'
169 * for only one or two CPU clocks with this code.
172 /* Send mb0 port 3 requests to upper GeodeLink diag bits
176 wrmsr(MSR_GLIU0 + 0x2005, msr);
178 /* set5m watches request ready from mb0 to CPU (snoop) */
181 wrmsr(MSR_GLCP + 0x0045, msr);
183 /* SET4M will be high when state is idle (XSTATE=11) */
186 wrmsr(MSR_GLCP + 0x0044, msr);
188 /* SET5n to watch for processor stalled state */
191 wrmsr(MSR_GLCP + 0x004D, msr);
193 /* Writing action number 13: XSTATE=0 to occur when CPU is
194 snooped unless we're stalled */
197 wrmsr(MSR_GLCP + 0x0075, msr);
199 /* Writing action number 11: inc XSTATE every GeodeLink clock
203 wrmsr(MSR_GLCP + 0x0073, msr);
205 /* Writing action number 5: STALL_CPU_PIPE when exitting idle
206 state or not in idle state */
209 wrmsr(MSR_GLCP + 0x006D, msr);
211 /* Writing DIAGCTL Register to enable the stall action and to
212 let set5m watch the upper GeodeLink diag bits. */
215 wrmsr(MSR_GLCP + 0x005f, msr);
219 static void bug118253(void)
221 /* GLPCI PIO Post Control shouldn't be enabled */
224 msr = rdmsr(GLPCI_SPARE);
225 msr.lo &= ~GLPCI_SPARE_LOWER_PPC_SET;
226 wrmsr(GLPCI_SPARE, msr);
229 static void bug118339(void)
231 /* per AMD, do this always */
235 /* Disable enable_actions in DIAGCTL while setting up GLCP */
236 wrmsr(MSR_GLCP + 0x005f, msr);
238 /* SET2M fires if VG pri is odd (3, not 2) and Ystate=0 */
239 msrnum = MSR_GLCP + 0x042;
240 /* msr.hi = 2d6b8000h */;
245 /* SET3M fires if MBUS changed and VG pri is odd */
246 msrnum = MSR_GLCP + 0x043;
251 /* Put VG request data on lower diag bus */
252 msrnum = MSR_GLIU0 + 0x2005;
257 /* Increment Y state if SET3M if true */
258 msrnum = MSR_GLCP + 0x074;
263 /* Set up MBUS action to PRI=3 read of MBIU */
264 msrnum = MSR_GLCP + 0x020;
269 /* Trigger MBUS action if VG=pri3 and Y=0, this blocks most PCI */
270 msrnum = MSR_GLCP + 0x071;
275 /* Writing DIAGCTL */
276 msrnum = MSR_GLCP + 0x005f;
281 /* Code to enable FS2 even when BTB and VGTEAR SWAPSiFs are enabled
282 * As per Todd Roberts in PBz1094 and PBz1095
283 * Moved from CPUREG to CPUBUG per Tom Sylla
285 msrnum = 0x04C000042; /* GLCP SETMCTL Register */
287 msr.hi |= 8; /* Bit 35 = MCP_IN */
293 /* DisableMemoryReorder
296 * The MC reordered transactions incorrectly and breaks coherency.
297 * Disable reording and take a potential performance hit.
298 * This is safe to do here and not in MC init since there is nothing
299 * to maintain coherency with and the cache is not enabled yet.
301 static void disablememoryreadorder(void)
305 msr = rdmsr(MC_CF8F_DATA);
306 msr.hi |= CF8F_UPPER_REORDER_DIS_SET;
307 wrmsr(MC_CF8F_DATA, msr);
315 msr = rdmsr(GLCP_CHIP_REVID);
319 printk(BIOS_ERR, "%s: rev < 0x20! bailing!\n", __func__);
322 printk(BIOS_DEBUG, "Doing cpubug fixes for rev 0x%x\n", rev);
328 /* cs 5530 bug; ignore
342 printk(BIOS_ERR, "unknown rev %x, bailing\n", rev);
347 disablememoryreadorder();
348 printk(BIOS_DEBUG, "Done cpubug fixes \n");