72d5809ea429e0d6aa003c879c8f130c5417c72b
[coreboot.git] / src / mainboard / supermicro / h8dme / cache_as_ram_auto.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  */
18
19 #define ASSEMBLY 1
20 #define __PRE_RAM__
21
22 #define RAMINIT_SYSINFO 1
23
24 #define K8_ALLOCATE_IO_RANGE 1
25
26 #define QRANK_DIMM_SUPPORT 1
27
28 #if CONFIG_LOGICAL_CPUS==1
29 #define SET_NB_CFG_54 1
30 #endif
31
32 // used by init_cpus and fidvid
33 #define K8_SET_FIDVID 1
34 //if we want to wait for core1 done before DQS training, set it to 0
35 #define K8_SET_FIDVID_CORE0_ONLY 1
36
37 #if CONFIG_K8_REV_F_SUPPORT == 1
38 #define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0
39 #endif
40
41 #include <stdint.h>
42 #include <string.h>
43 #include <device/pci_def.h>
44 #include <device/pci_ids.h>
45 #include <arch/io.h>
46 #include <device/pnp_def.h>
47 #include <arch/romcc_io.h>
48 #include <cpu/x86/lapic.h>
49 #include "option_table.h"
50 #include "pc80/mc146818rtc_early.c"
51
52 // for enable the FAN
53 #include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
54
55 #if CONFIG_USE_FAILOVER_IMAGE==0
56 #include "pc80/serial.c"
57 #include "arch/i386/lib/console.c"
58 #include "lib/ramtest.c"
59
60 #include <cpu/amd/model_fxx_rev.h>
61
62 // #include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
63 #include "northbridge/amd/amdk8/raminit.h"
64 #include "cpu/amd/model_fxx/apic_timer.c"
65 #include "lib/delay.c"
66
67 #endif
68
69 #include "cpu/x86/lapic/boot_cpu.c"
70 #include "northbridge/amd/amdk8/reset_test.c"
71 #include "superio/winbond/w83627hf/w83627hf_early_serial.c"
72 #include "superio/winbond/w83627hf/w83627hf_early_init.c"
73
74 #if CONFIG_USE_FAILOVER_IMAGE==0
75
76 #include "cpu/x86/bist.h"
77
78 #include "northbridge/amd/amdk8/debug.c"
79
80 #include "cpu/amd/mtrr/amd_earlymtrr.c"
81
82 #include "northbridge/amd/amdk8/setup_resource_map.c"
83
84 #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
85
86 #include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
87
88 static void memreset_setup(void)
89 {
90 }
91
92 static void memreset(int controllers, const struct mem_controller *ctrl)
93 {
94 }
95
96 static int smbus_send_byte_one(unsigned device, unsigned char val)
97 {
98         return do_smbus_send_byte(SMBUS1_IO_BASE, device, val);
99 }
100
101 static void dump_smbus_registers(void)
102 {
103         u32 device;
104
105         print_debug("\r\n");
106         for (device = 1; device < 0x80; device++) {
107                 int j;
108                 if (smbus_read_byte(device, 0) < 0)
109                         continue;
110                 printk_debug("smbus: %02x", device);
111                 for (j = 0; j < 256; j++) {
112                         int status;
113                         unsigned char byte;
114                         status = smbus_read_byte(device, j);
115                         if (status < 0) {
116                                 break;
117                         }
118                         if ((j & 0xf) == 0) {
119                                 printk_debug("\r\n%02x: ", j);
120                         }
121                         byte = status & 0xff;
122                         printk_debug("%02x ", byte);
123                 }
124                 print_debug("\r\n");
125         }
126 }
127
128 static inline void activate_spd_rom(const struct mem_controller *ctrl)
129 {
130 /* We don't do any switching yet.
131 #define SMBUS_SWITCH1 0x48
132 #define SMBUS_SWITCH2 0x49
133         unsigned device=(ctrl->channel0[0])>>8;
134         smbus_send_byte(SMBUS_SWITCH1, device);
135         smbus_send_byte(SMBUS_SWITCH2, (device >> 4) & 0x0f);
136 */
137         /* nothing to do */
138 }
139
140 /*
141 static inline void change_i2c_mux(unsigned device)
142 {
143 #define SMBUS_SWITCH1 0x48
144 #define SMBUS_SWITHC2 0x49
145         smbus_send_byte(SMBUS_SWITCH1, device & 0x0f);
146         smbus_send_byte_one(SMBUS_SWITCH2, (device >> 4) & 0x0f);
147         int ret;
148         print_debug("change_i2c_mux i="); print_debug_hex8(device); print_debug("\r\n");
149         dump_smbus_registers();
150         ret = smbus_send_byte(SMBUS_SWITCH1, device);
151         print_debug("change_i2c_mux ret="); print_debug_hex32(ret); print_debug("\r\n");
152         dump_smbus_registers();
153         ret = smbus_send_byte_one(SMBUS_SWITCH2, device);
154         print_debug("change_i2c_mux ret="); print_debug_hex32(ret); print_debug("\r\n");
155         dump_smbus_registers();
156 }
157 */
158
159 static inline int spd_read_byte(unsigned device, unsigned address)
160 {
161         return smbus_read_byte(device, address);
162 }
163
164 #include "northbridge/amd/amdk8/amdk8_f.h"
165 #include "northbridge/amd/amdk8/coherent_ht.c"
166
167 #include "northbridge/amd/amdk8/incoherent_ht.c"
168
169 #include "northbridge/amd/amdk8/raminit_f.c"
170
171 #include "lib/generic_sdram.c"
172
173 #include "resourcemap.c"
174
175 #include "cpu/amd/dualcore/dualcore.c"
176
177 #define MCP55_NUM 1
178 #define MCP55_USE_NIC 1
179 #define MCP55_USE_AZA 1
180
181 #define MCP55_PCI_E_X_0 4
182
183 #include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
184 #include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
185
186 #include "cpu/amd/car/copy_and_run.c"
187
188 #include "cpu/amd/car/post_cache_as_ram.c"
189
190 #include "cpu/amd/model_fxx/init_cpus.c"
191
192 #include "cpu/amd/model_fxx/fidvid.c"
193
194 #endif
195
196 #if ((CONFIG_HAVE_FAILOVER_BOOT==1) && (CONFIG_USE_FAILOVER_IMAGE == 1)) || ((CONFIG_HAVE_FAILOVER_BOOT==0) && (CONFIG_USE_FALLBACK_IMAGE == 1))
197
198 #include "southbridge/nvidia/mcp55/mcp55_enable_rom.c"
199 #include "northbridge/amd/amdk8/early_ht.c"
200
201 static void sio_setup(void)
202 {
203
204         u32 value;
205         uint32_t dword;
206         uint8_t byte;
207
208         enable_smbus();
209 //      smbusx_write_byte(1, (0x58>>1), 0, 0x80); /* select bank0 */
210         smbusx_write_byte(1, (0x58 >> 1), 0xb1, 0xff);  /* set FAN ctrl to DC mode */
211
212         byte = pci_read_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b);
213         byte |= 0x20;
214         pci_write_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b, byte);
215
216         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0);
217         dword |= (1 << 0);
218         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0, dword);
219
220         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4);
221         dword |= (1 << 16);
222         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4, dword);
223
224 }
225
226 void failover_process(unsigned long bist, unsigned long cpu_init_detectedx)
227 {
228         u32 last_boot_normal_x = last_boot_normal();
229
230         /* Is this a cpu only reset? or Is this a secondary cpu? */
231         if ((cpu_init_detectedx) || (!boot_cpu())) {
232                 if (last_boot_normal_x) {
233                         goto normal_image;
234                 } else {
235                         goto fallback_image;
236                 }
237         }
238
239         /* Nothing special needs to be done to find bus 0 */
240         /* Allow the HT devices to be found */
241
242         enumerate_ht_chain();
243
244         sio_setup();
245
246         /* Setup the mcp55 */
247         mcp55_enable_rom();
248
249         /* Is this a deliberate reset by the bios */
250         if (bios_reset_detected() && last_boot_normal_x) {
251                 goto normal_image;
252         }
253         /* This is the primary cpu how should I boot? */
254         else if (do_normal_boot()) {
255                 goto normal_image;
256         } else {
257                 goto fallback_image;
258         }
259 normal_image:
260         __asm__ volatile ("jmp __normal_image": /* outputs */
261                           :"a" (bist), "b"(cpu_init_detectedx)  /* inputs */
262             );
263
264       fallback_image:
265 #if CONFIG_HAVE_FAILOVER_BOOT==1
266         __asm__ volatile ("jmp __fallback_image":       /* outputs */
267                           :"a" (bist), "b"(cpu_init_detectedx)  /* inputs */
268             )
269 #endif
270         ;
271 }
272 #endif
273 void real_main(unsigned long bist, unsigned long cpu_init_detectedx);
274
275 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
276 {
277 #if CONFIG_HAVE_FAILOVER_BOOT==1
278 #if CONFIG_USE_FAILOVER_IMAGE==1
279         failover_process(bist, cpu_init_detectedx);
280 #else
281         real_main(bist, cpu_init_detectedx);
282 #endif
283 #else
284 #if CONFIG_USE_FALLBACK_IMAGE == 1
285         failover_process(bist, cpu_init_detectedx);
286 #endif
287         real_main(bist, cpu_init_detectedx);
288 #endif
289 }
290
291 /* We have no idea where the SMBUS switch is. This doesn't do anything ATM. */
292 #define RC0 (2<<8)
293 #define RC1 (1<<8)
294
295 #if CONFIG_USE_FAILOVER_IMAGE==0
296
297 void real_main(unsigned long bist, unsigned long cpu_init_detectedx)
298 {
299 /* The SPD is being read from the CPU1 (marked CPU2 on the board) and we
300    don't know how to switch the SMBus to decode the CPU0 SPDs. So, The
301    memory on each CPU must be an exact match.
302  */
303         static const uint16_t spd_addr[] = {
304                 RC0 | (0xa << 3) | 0, RC0 | (0xa << 3) | 2,
305                     RC0 | (0xa << 3) | 4, RC0 | (0xa << 3) | 6,
306                 RC0 | (0xa << 3) | 1, RC0 | (0xa << 3) | 3,
307                     RC0 | (0xa << 3) | 5, RC0 | (0xa << 3) | 7,
308 #if CONFIG_MAX_PHYSICAL_CPUS > 1
309                 RC1 | (0xa << 3) | 0, RC1 | (0xa << 3) | 2,
310                     RC1 | (0xa << 3) | 4, RC1 | (0xa << 3) | 6,
311                 RC1 | (0xa << 3) | 1, RC1 | (0xa << 3) | 3,
312                     RC1 | (0xa << 3) | 5, RC1 | (0xa << 3) | 7,
313 #endif
314         };
315
316         struct sys_info *sysinfo =
317             (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
318
319         int needs_reset = 0;
320         unsigned bsp_apicid = 0;
321
322         if (bist == 0) {
323                 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
324         }
325
326         pnp_enter_ext_func_mode(SERIAL_DEV);
327         pnp_write_config(SERIAL_DEV, 0x24, 0x84 | (1 << 6));
328         w83627hf_enable_dev(SERIAL_DEV, CONFIG_TTYS0_BASE);
329         pnp_exit_ext_func_mode(SERIAL_DEV);
330
331         uart_init();
332         console_init();
333
334         /* Halt if there was a built in self test failure */
335         report_bist_failure(bist);
336
337         print_debug("*sysinfo range: [");
338         print_debug_hex32(sysinfo);
339         print_debug(",");
340         print_debug_hex32((unsigned long)sysinfo + sizeof(struct sys_info));
341         print_debug(")\r\n");
342
343         setup_mb_resource_map();
344
345         print_debug("bsp_apicid=");
346         print_debug_hex8(bsp_apicid);
347         print_debug("\r\n");
348
349 #if CONFIG_MEM_TRAIN_SEQ == 1
350         set_sysinfo_in_ram(0);  // in BSP so could hold all ap until sysinfo is in ram
351 #endif
352 /*      dump_smbus_registers(); */
353         setup_coherent_ht_domain();     // routing table and start other core0
354
355         wait_all_core0_started();
356 #if CONFIG_LOGICAL_CPUS==1
357         // It is said that we should start core1 after all core0 launched
358         /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain,
359          * So here need to make sure last core0 is started, esp for two way system,
360          * (there may be apic id conflicts in that case)
361          */
362         start_other_cores();
363         wait_all_other_cores_started(bsp_apicid);
364 #endif
365
366         /* it will set up chains and store link pair for optimization later */
367         ht_setup_chains_x(sysinfo);     // it will init sblnk and sbbusn, nodes, sbdn
368
369 #if K8_SET_FIDVID == 1
370
371         {
372                 msr_t msr;
373                 msr = rdmsr(0xc0010042);
374                 print_debug("begin msr fid, vid ");
375                 print_debug_hex32(msr.hi);
376                 print_debug_hex32(msr.lo);
377                 print_debug("\r\n");
378
379         }
380
381         enable_fid_change();
382
383         enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
384
385         init_fidvid_bsp(bsp_apicid);
386
387         // show final fid and vid
388         {
389                 msr_t msr;
390                 msr = rdmsr(0xc0010042);
391                 print_debug("end   msr fid, vid ");
392                 print_debug_hex32(msr.hi);
393                 print_debug_hex32(msr.lo);
394                 print_debug("\r\n");
395
396         }
397 #endif
398
399 #if 1
400         needs_reset |= optimize_link_coherent_ht();
401         needs_reset |= optimize_link_incoherent_ht(sysinfo);
402         needs_reset |= mcp55_early_setup_x();
403
404         // fidvid change will issue one LDTSTOP and the HT change will be effective too
405         if (needs_reset) {
406                 print_info("ht reset -\r\n");
407                 soft_reset();
408         }
409 #endif
410         allow_all_aps_stop(bsp_apicid);
411
412         //It's the time to set ctrl in sysinfo now;
413         fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
414
415         enable_smbus();         /* enable in sio_setup */
416
417         memreset_setup();
418
419         //do we need apci timer, tsc...., only debug need it for better output
420         /* all ap stopped? */
421 //        init_timer(); // Need to use TMICT to synconize FID/VID
422
423         sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
424
425         post_cache_as_ram();    // bsp swtich stack to ram and copy sysinfo ram now
426
427 }
428
429 #endif