Rework boolean expression (DeMorgan and all) for
[coreboot.git] / src / mainboard / supermicro / h8dme / romstage.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 #include "southbridge/nvidia/mcp55/mcp55_enable_rom.c"
197 #include "northbridge/amd/amdk8/early_ht.c"
198
199 static void sio_setup(void)
200 {
201
202         u32 value;
203         uint32_t dword;
204         uint8_t byte;
205
206         enable_smbus();
207 //      smbusx_write_byte(1, (0x58>>1), 0, 0x80); /* select bank0 */
208         smbusx_write_byte(1, (0x58 >> 1), 0xb1, 0xff);  /* set FAN ctrl to DC mode */
209
210         byte = pci_read_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b);
211         byte |= 0x20;
212         pci_write_config8(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0x7b, byte);
213
214         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0);
215         dword |= (1 << 0);
216         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa0, dword);
217
218         dword = pci_read_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4);
219         dword |= (1 << 16);
220         pci_write_config32(PCI_DEV(0, MCP55_DEVN_BASE + 1, 0), 0xa4, dword);
221
222 }
223
224 /* We have no idea where the SMBUS switch is. This doesn't do anything ATM. */
225 #define RC0 (2<<8)
226 #define RC1 (1<<8)
227
228 #if CONFIG_USE_FAILOVER_IMAGE==0
229
230 void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
231 {
232 /* The SPD is being read from the CPU1 (marked CPU2 on the board) and we
233    don't know how to switch the SMBus to decode the CPU0 SPDs. So, The
234    memory on each CPU must be an exact match.
235  */
236         static const uint16_t spd_addr[] = {
237                 RC0 | (0xa << 3) | 0, RC0 | (0xa << 3) | 2,
238                     RC0 | (0xa << 3) | 4, RC0 | (0xa << 3) | 6,
239                 RC0 | (0xa << 3) | 1, RC0 | (0xa << 3) | 3,
240                     RC0 | (0xa << 3) | 5, RC0 | (0xa << 3) | 7,
241 #if CONFIG_MAX_PHYSICAL_CPUS > 1
242                 RC1 | (0xa << 3) | 0, RC1 | (0xa << 3) | 2,
243                     RC1 | (0xa << 3) | 4, RC1 | (0xa << 3) | 6,
244                 RC1 | (0xa << 3) | 1, RC1 | (0xa << 3) | 3,
245                     RC1 | (0xa << 3) | 5, RC1 | (0xa << 3) | 7,
246 #endif
247         };
248
249         struct sys_info *sysinfo =
250             (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE);
251
252         int needs_reset = 0;
253         unsigned bsp_apicid = 0;
254
255         if (!cpu_init_detectedx && boot_cpu()) {
256                 /* Nothing special needs to be done to find bus 0 */
257                 /* Allow the HT devices to be found */
258
259                 enumerate_ht_chain();
260
261                 sio_setup();
262
263                 /* Setup the mcp55 */
264                 mcp55_enable_rom();
265         }
266
267         if (bist == 0) {
268                 bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);
269         }
270
271         pnp_enter_ext_func_mode(SERIAL_DEV);
272         pnp_write_config(SERIAL_DEV, 0x24, 0x84 | (1 << 6));
273         w83627hf_enable_dev(SERIAL_DEV, CONFIG_TTYS0_BASE);
274         pnp_exit_ext_func_mode(SERIAL_DEV);
275
276         uart_init();
277         console_init();
278
279         /* Halt if there was a built in self test failure */
280         report_bist_failure(bist);
281
282         print_debug("*sysinfo range: [");
283         print_debug_hex32(sysinfo);
284         print_debug(",");
285         print_debug_hex32((unsigned long)sysinfo + sizeof(struct sys_info));
286         print_debug(")\r\n");
287
288         setup_mb_resource_map();
289
290         print_debug("bsp_apicid=");
291         print_debug_hex8(bsp_apicid);
292         print_debug("\r\n");
293
294 #if CONFIG_MEM_TRAIN_SEQ == 1
295         set_sysinfo_in_ram(0);  // in BSP so could hold all ap until sysinfo is in ram
296 #endif
297 /*      dump_smbus_registers(); */
298         setup_coherent_ht_domain();     // routing table and start other core0
299
300         wait_all_core0_started();
301 #if CONFIG_LOGICAL_CPUS==1
302         // It is said that we should start core1 after all core0 launched
303         /* becase optimize_link_coherent_ht is moved out from setup_coherent_ht_domain,
304          * So here need to make sure last core0 is started, esp for two way system,
305          * (there may be apic id conflicts in that case)
306          */
307         start_other_cores();
308         wait_all_other_cores_started(bsp_apicid);
309 #endif
310
311         /* it will set up chains and store link pair for optimization later */
312         ht_setup_chains_x(sysinfo);     // it will init sblnk and sbbusn, nodes, sbdn
313
314 #if K8_SET_FIDVID == 1
315
316         {
317                 msr_t msr;
318                 msr = rdmsr(0xc0010042);
319                 print_debug("begin msr fid, vid ");
320                 print_debug_hex32(msr.hi);
321                 print_debug_hex32(msr.lo);
322                 print_debug("\r\n");
323
324         }
325
326         enable_fid_change();
327
328         enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
329
330         init_fidvid_bsp(bsp_apicid);
331
332         // show final fid and vid
333         {
334                 msr_t msr;
335                 msr = rdmsr(0xc0010042);
336                 print_debug("end   msr fid, vid ");
337                 print_debug_hex32(msr.hi);
338                 print_debug_hex32(msr.lo);
339                 print_debug("\r\n");
340
341         }
342 #endif
343
344 #if 1
345         needs_reset |= optimize_link_coherent_ht();
346         needs_reset |= optimize_link_incoherent_ht(sysinfo);
347         needs_reset |= mcp55_early_setup_x();
348
349         // fidvid change will issue one LDTSTOP and the HT change will be effective too
350         if (needs_reset) {
351                 print_info("ht reset -\r\n");
352                 soft_reset();
353         }
354 #endif
355         allow_all_aps_stop(bsp_apicid);
356
357         //It's the time to set ctrl in sysinfo now;
358         fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
359
360         enable_smbus();         /* enable in sio_setup */
361
362         memreset_setup();
363
364         //do we need apci timer, tsc...., only debug need it for better output
365         /* all ap stopped? */
366 //        init_timer(); // Need to use TMICT to synconize FID/VID
367
368         sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
369
370         post_cache_as_ram();    // bsp swtich stack to ram and copy sysinfo ram now
371
372 }
373
374 #endif