3 #include <device/pci_def.h>
4 #include "arch/romcc_io.h"
5 #include "pc80/serial.c"
6 #include "arch/i386/lib/console.c"
7 #include "ram/ramtest.c"
8 #include "northbridge/amd/amdk8/early_ht.c"
9 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
10 #include "northbridge/amd/amdk8/raminit.h"
12 #warning "FIXME move these delay functions somewhere more appropriate"
13 #warning "FIXME use the apic timer instead it needs no calibration on an Opteron it runs at 200Mhz"
14 static void print_clock_multiplier(void)
17 print_debug("clock multipler: 0x");
18 msr = rdmsr(0xc0010042);
19 print_debug_hex32(msr.lo & 0x3f);
21 print_debug_hex32(((msr.lo & 0x3f) + 8) * 100);
22 print_debug("Mhz\r\n");
25 static unsigned usecs_to_ticks(unsigned usecs)
27 #warning "FIXME make usecs_to_ticks work properly"
31 // This can only be done if cpuid says fid changing is supported
32 // I need to look up the base frequency another way for other
33 // cpus. Is it worth dedicating a global register to this?
34 // Are the PET timers useable for this purpose?
37 msr = rdmsr(0xc0010042);
38 return ((msr.lo & 0x3f) + 8) * 100 *usecs;
42 static void init_apic_timer(void)
44 volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
46 // Set the apic timer to no interrupts and periodic mode
47 apic_reg[0x320 >> 2] = (1 << 17)|(1<< 16)|(0 << 12)|(0 << 0);
48 // Set the divider to 1, no divider
49 apic_reg[0x3e0 >> 2] = (1 << 3) | 3;
50 // Set the initial counter to 0xffffffff
51 apic_reg[0x380 >> 2] = 0xffffffff;
54 static void udelay(unsigned usecs)
57 uint32_t start, ticks;
59 // Calculate the number of ticks to run for
60 ticks = usecs_to_ticks(usecs);
61 // Find the current time
66 } while((tsc.lo - start) < ticks);
68 volatile uint32_t *apic_reg = (volatile uint32_t *)0xfee00000;
69 uint32_t start, value, ticks;
70 // Calculate the number of ticks to run for
72 start = apic_reg[0x390 >> 2];
74 value = apic_reg[0x390 >> 2];
75 } while((start - value) < ticks);
79 static void mdelay(unsigned msecs)
82 for(i = 0; i < msecs; i++) {
87 static void delay(unsigned secs)
90 for(i = 0; i < secs; i++) {
95 static void memreset_setup(const struct mem_controller *ctrl)
97 // Set the memreset low
98 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
99 // Ensure the BIOS has control of the memory lines
100 outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
101 print_debug("memreset lo\r\n");
104 static void memreset(const struct mem_controller *ctrl)
108 outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
109 print_debug("memreset hi\r\n");
114 #include "northbridge/amd/amdk8/raminit.c"
115 #include "northbridge/amd/amdk8/coherent_ht.c"
116 #include "sdram/generic_sdram.c"
119 #define HT_INIT_CONTROL 0x6c
121 #define HTIC_ColdR_Detect (1<<4)
122 #define HTIC_BIOSR_Detect (1<<5)
123 #define HTIC_INIT_Detect (1<<6)
125 #define APIC_DEFAULT_BASE 0xfee00000
127 #define APIC_ID 0x020
129 static int boot_cpu(void)
131 volatile unsigned long *local_apic;
132 unsigned long apic_id;
137 bsp = !!(msr.lo & (1 << 8));
138 apicEn = !!(msr.lo & (1<<11));
140 print_debug("apic enabled\r\n");
145 apic_id = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
146 print_debug("apic_id: ");
147 print_debug_hex32(apic_id>>24);
151 print_debug("Bootstrap cpu\r\n");
153 print_debug("Application processor\r\n");
154 // asm("hlt"); // move to end before halt should notify BSP
155 // if you start AP in coherent.c you can just stop it here
161 static int cpu_init_detected(void)
168 htic = pci_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL);
170 print_debug("htic: ");
171 print_debug_hex32(htic);
174 if (!(htic & HTIC_ColdR_Detect)) {
175 print_debug("Cold Reset.\r\n");
177 if ((htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect)) {
178 print_debug("BIOS generated Reset.\r\n");
180 if (htic & HTIC_INIT_Detect) {
181 print_debug("Init event.\r\n");
184 cpu_init = (htic & HTIC_INIT_Detect);
186 print_debug("CPU INIT Detected.\r\n");
191 static void print_debug_pci_dev(unsigned dev)
193 print_debug("PCI: ");
194 print_debug_hex8((dev >> 16) & 0xff);
195 print_debug_char(':');
196 print_debug_hex8((dev >> 11) & 0x1f);
197 print_debug_char('.');
198 print_debug_hex8((dev >> 8) & 7);
202 static void print_pci_devices(void)
205 for(dev = PCI_DEV(0, 0, 0);
206 dev <= PCI_DEV(0, 0x1f, 0x7);
207 dev += PCI_DEV(0,0,1)) {
209 id = pci_read_config32(dev, PCI_VENDOR_ID);
210 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
211 (((id >> 16) & 0xffff) == 0xffff) ||
212 (((id >> 16) & 0xffff) == 0x0000)) {
215 print_debug_pci_dev(dev);
221 static void dump_pci_device(unsigned dev)
224 print_debug_pci_dev(dev);
227 for(i = 0; i <= 255; i++) {
229 if ((i & 0x0f) == 0) {
231 print_debug_char(':');
233 val = pci_read_config8(dev, i);
234 print_debug_char(' ');
235 print_debug_hex8(val);
236 if ((i & 0x0f) == 0x0f) {
241 static void dump_pci_devices(void)
244 for(dev = PCI_DEV(0, 0, 0);
245 dev <= PCI_DEV(0, 0x1f, 0x7);
246 dev += PCI_DEV(0,0,1)) {
248 id = pci_read_config32(dev, PCI_VENDOR_ID);
249 if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
250 (((id >> 16) & 0xffff) == 0xffff) ||
251 (((id >> 16) & 0xffff) == 0x0000)) {
254 dump_pci_device(dev);
260 static void dump_spd_registers(const struct mem_controller *ctrl)
264 for(i = 0; i < 4; i++) {
266 device = ctrl->channel0[i];
269 print_debug("dimm: ");
272 print_debug_hex8(device);
273 for(j = 0; j < 256; j++) {
276 if ((j & 0xf) == 0) {
281 status = smbus_read_byte(device, j);
283 print_debug("bad device\r\n");
287 byte = status & 0xff;
288 print_debug_hex8(byte);
289 print_debug_char(' ');
293 device = ctrl->channel1[i];
296 print_debug("dimm: ");
299 print_debug_hex8(device);
300 for(j = 0; j < 256; j++) {
303 if ((j & 0xf) == 0) {
308 status = smbus_read_byte(device, j);
311 print_debug("bad device\r\n");
314 byte = status & 0xff;
315 print_debug_hex8(byte);
316 print_debug_char(' ');
327 static void main(void)
329 static const struct mem_controller cpu0 = {
330 .f0 = PCI_DEV(0, 0x18, 0),
331 .f1 = PCI_DEV(0, 0x18, 1),
332 .f2 = PCI_DEV(0, 0x18, 2),
333 .f3 = PCI_DEV(0, 0x18, 3),
334 .channel0 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 },
335 .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 },
337 static const struct mem_controller cpu1 = {
338 .f0 = PCI_DEV(0, 0x19, 0),
339 .f1 = PCI_DEV(0, 0x19, 1),
340 .f2 = PCI_DEV(0, 0x19, 2),
341 .f3 = PCI_DEV(0, 0x19, 3),
342 .channel0 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 },
343 .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 },
349 // dev = PCI_ADDR(0, 0x19, 0, 0x6C) & ~0xff;
350 // where = PCI_ADDR(0, 0x19, 0, 0x6C) & 0xff;
357 if (boot_cpu() && !cpu_init_detected()) {
358 setup_default_resource_map();
359 setup_coherent_ht_domain();
360 enumerate_ht_chain();
361 // print_pci_devices();
363 // sdram_initialize();
364 // dump_spd_registers(&cpu0);
365 sdram_initialize(&cpu0);
366 // dump_spd_registers(&cpu1);
367 // sdram_initialize(&cpu1);
369 // dump_pci_device(PCI_DEV(0, 0x18, 2));
371 ram_fill( 0x00100000, 0x00180000);
372 ram_verify(0x00100000, 0x00180000);
374 //#ifdef MEMORY_1024MB
375 // ram_fill( 0x00000000, 0x00001000);
376 // ram_verify(0x00000000, 0x00001000);
378 //#ifdef MEMROY_512MB
379 // ram_fill( 0x00000000, 0x01ffffff);
380 // ram_verify(0x00000000, 0x01ffffff);
382 /* Check the first 512M */
384 msr = rdmsr(TOP_MEM);
385 print_debug("TOP_MEM: ");
386 print_debug_hex32(msr.hi);
387 print_debug_hex32(msr.lo);
389 ram_check(0x00000000, msr.lo);
392 reg = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
393 print_debug("bootstrap cpu apic_id: ");
394 print_debug_hex32(reg>>24);
399 reg = pci_read_config32(PCI_DEV(0, 0x19, 0), 0x6C);
402 pci_write_config32(PCI_DEV(0, 0x19, 0), 0x6C, reg); //start AP
404 reg = pci_read_config32(PCI_DEV(0, 0x19, 0), 0x6C);
405 if((reg & (1<<4))==0) break; // wait until AP stop
408 pci_write_config32(PCI_DEV(0, 0x19, 0), 0x6C, reg);
412 // Need to init second cpu's APIC id
415 // apic_write(APIC_ID,(1<<24));
416 reg = *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID));
417 /* print_debug("applicaton cpu apic_id: ");
418 print_debug_hex32(reg>>24);
420 if((reg>>24)==7){ // FIXME: Need to read NodeID at first.
421 *((volatile unsigned long *)(APIC_DEFAULT_BASE+APIC_ID))=1<<24;
424 // before hlt clear the ColdResetbit
426 //notify BSP that AP is stopped
427 reg = pci_read_config32(PCI_DEV(0, 0x19, 0), 0x6C);
429 pci_write_config32(PCI_DEV(0, 0x19, 0), 0x6C, reg);