- Moved hlt() to it's own header.
[coreboot.git] / src / mainboard / amd / solo / auto.c
index 33dea8e80d243f3b42eb511895a7a6d1eebde1b4..3a80e4c1bdd7087f0b9dca99dbfc4d16da0d5922 100644 (file)
 #define ASSEMBLY 1
 #include <stdint.h>
 #include <device/pci_def.h>
-#include "arch/romcc_io.h"
+#include <arch/io.h>
+#include <device/pnp.h>
+#include <arch/romcc_io.h>
+#include <arch/smp/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
 #include "pc80/serial.c"
 #include "arch/i386/lib/console.c"
 #include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/early_ht.c"
+#include "northbridge/amd/amdk8/incoherent_ht.c"
 #include "southbridge/amd/amd8111/amd8111_early_smbus.c"
-#include "northbridge/amd/amdk8/raminit.c"
-#include "northbridge/amd/amdk8/coherent_ht.c"
-#include "sdram/generic_sdram.c"
+#include "northbridge/amd/amdk8/raminit.h"
+#include "cpu/k8/apic_timer.c"
+#include "lib/delay.c"
+#include "cpu/p6/boot_cpu.c"
+#include "northbridge/amd/amdk8/reset_test.c"
+#include "debug.c"
+#include "northbridge/amd/amdk8/cpu_rev.c"
+#include "superio/NSC/pc87360/pc87360_early_serial.c"
 
-static int boot_cpu(void)
+#define SIO_BASE 0x2e
+
+static void hard_reset(void)
 {
-       volatile unsigned long *local_apic;
-       unsigned long apic_id;
-       int bsp;
-       msr_t msr;
-       msr = rdmsr(0x1b);
-       bsp = !!(msr.lo & (1 << 8));
-       if (bsp) {
-               print_debug("Bootstrap cpu\r\n");
-       }
+       set_bios_reset();
 
-       return bsp;
+       /* enable cf9 */
+       pci_write_config8(PCI_DEV(0, 0x05, 3), 0x41, 0xf1);
+       /* reset */
+       outb(0x0e, 0x0cf9);
 }
 
-static int cpu_init_detected(void)
+static void soft_reset(void)
 {
-       unsigned long dcl;
-       int cpu_init;
-
-       unsigned long htic;
-
-       htic = pci_read_config32(PCI_DEV(0, 0x18, 0), HT_INIT_CONTROL);
-#if 0
-       print_debug("htic: ");
-       print_debug_hex32(htic);
-       print_debug("\r\n");
+       set_bios_reset();
+       pci_write_config8(PCI_DEV(0, 0x05, 0), 0x47, 1);
+}
 
-       if (!(htic & HTIC_ColdR_Detect)) {
-               print_debug("Cold Reset.\r\n");
-       }
-       if ((htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect)) {
-               print_debug("BIOS generated Reset.\r\n");
-       }
-       if (htic & HTIC_INIT_Detect) {
-               print_debug("Init event.\r\n");
+static void memreset_setup(void)
+{
+       if (is_cpu_pre_c0()) {
+               /* Set the memreset low */
+               outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 28);
+               /* Ensure the BIOS has control of the memory lines */
+               outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 29);
        }
-#endif
-       cpu_init = (htic & HTIC_INIT_Detect);
-       if (cpu_init) {
-               print_debug("CPU INIT Detected.\r\n");
+       else {
+               /* Ensure the CPU has controll of the memory lines */
+               outb((0 << 7)|(0 << 6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 29);
        }
-       return cpu_init;
 }
 
-
-static void print_pci_devices(void)
+static void memreset(int controllers, const struct mem_controller *ctrl)
 {
-       device_t dev;
-       for(dev = PCI_DEV(0, 0, 0); 
-               dev <= PCI_DEV(0, 0x1f, 0x7); 
-               dev += PCI_DEV(0,0,1)) {
-               uint32_t id;
-               id = pci_read_config32(dev, PCI_VENDOR_ID);
-               if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
-                       (((id >> 16) & 0xffff) == 0xffff) ||
-                       (((id >> 16) & 0xffff) == 0x0000)) {
-                       continue;
-               }
-               print_debug("PCI: 00:");
-               print_debug_hex8(dev >> 11);
-               print_debug_char('.');
-               print_debug_hex8((dev >> 8) & 7);
-               print_debug("\r\n");
+       if (is_cpu_pre_c0()) {
+               udelay(800);
+               /* Set memreset_high */
+               outb((0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 28);
+               udelay(90);
        }
 }
 
+static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes)
+{
+       /* since the AMD Solo is a UP only machine, we can 
+        * always return the default row entry value
+        */
+       return 0x00010101; /* default row entry */
+}
 
-static void dump_spd_registers(void)
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
 {
-       unsigned device;
-       device = SMBUS_MEM_DEVICE_START;
-       print_debug("\r\n");
-       while(device <= SMBUS_MEM_DEVICE_END) {
-               int i;
-               print_debug("dimm: "); 
-               print_debug_hex8(device); 
-               for(i = 0; i < 256; i++) {
-                       int status;
-                       unsigned char byte;
-                       if ((i & 0xf) == 0) {
-                               print_debug("\r\n");
-                               print_debug_hex8(i);
-                               print_debug(": ");
-                       }
-                       status = smbus_read_byte(device, i);
-                       if (status < 0) {
-                               print_debug("bad device\r\n");
-                               break;
-                       }
-                       byte = status & 0xff;
-                       print_debug_hex8(byte);
-                       print_debug_char(' ');
-               }
-               device += SMBUS_MEM_DEVICE_INC;
-               print_debug("\r\n");
-       }
+       /* nothing to do */
 }
 
+static inline int spd_read_byte(unsigned device, unsigned address)
+{
+       return smbus_read_byte(device, address);
+}
 
 
+#include "northbridge/amd/amdk8/raminit.c"
+#include "northbridge/amd/amdk8/coherent_ht.c"
+#include "sdram/generic_sdram.c"
 
 static void main(void)
 {
+       static const struct mem_controller cpu[] = {
+               {
+                       .node_id = 0,
+                       .f0 = PCI_DEV(0, 0x18, 0),
+                       .f1 = PCI_DEV(0, 0x18, 1),
+                       .f2 = PCI_DEV(0, 0x18, 2),
+                       .f3 = PCI_DEV(0, 0x18, 3),
+                       .channel0 = { (0xa<<3)|0, (0xa<<3)|1, 0, 0 },
+                       .channel1 = { 0, 0, 0, 0 },
+               }
+       };
+       int needs_reset;
+       enable_lapic();
+       init_timer();
+       if (cpu_init_detected()) {
+               asm("jmp __cpu_reset");
+       }
+       enable_lapic();
+       init_timer();
+       distinguish_cpu_resets();
+       if (!boot_cpu()) {
+               print_err("This LinuxBIOS image is built for UP only.\n");
+               stop_this_cpu();
+       }
+       pc87360_enable_serial(SIO_BASE, TTYS0_BASE);
        uart_init();
        console_init();
-       if (boot_cpu() && !cpu_init_detected()) {
-               setup_coherent_ht_domain();
-               enumerate_ht_chain();
-               print_pci_devices();
-               enable_smbus();
-               sdram_initialize();
+       setup_default_resource_map();
+       needs_reset = setup_coherent_ht_domain();
+       needs_reset = ht_setup_chain(PCI_DEV(0, 0x18, 0), 0x80);
+       if (needs_reset) {
+               print_info("ht reset -");
+               soft_reset();
+       }
+#if 0
+       print_pci_devices();
+#endif
+       enable_smbus();
+#if 0
+       dump_spd_registers(&cpu[0]);
+#endif
+       memreset_setup();
+       sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
 
-               dump_spd_registers();
 #if 0
-               ram_fill(  0x00100000, 0x00180000);
-               ram_verify(0x00100000, 0x00180000);
+       dump_pci_devices();
 #endif
-#ifdef MEMORY_1024MB
-               ram_fill(  0x00000000, 0x00001000);
-               ram_verify(0x00000000, 0x00001000);
+#if 0
+       dump_pci_device(PCI_DEV(0, 0x18, 2));
 #endif
-#ifdef MEMROY_512MB
-               ram_fill(  0x00000000, 0x01ffffff);
-               ram_verify(0x00000000, 0x01ffffff);
+
+       /* Check all of memory */
+#if 0
+       msr_t msr;
+       msr = rdmsr(TOP_MEM);
+       print_debug("TOP_MEM: ");
+       print_debug_hex32(msr.hi);
+       print_debug_hex32(msr.lo);
+       print_debug("\r\n");
+#endif
+#if 0
+       ram_check(0x00000000, msr.lo);
 #endif
+#if 0
+       static const struct {
+               unsigned long lo, hi;
+       } check_addrs[] = {
+               /* Check 16MB of memory @ 0*/
+               { 0x00000000, 0x01000000 },
+       };
+       int i;
+       for(i = 0; i < sizeof(check_addrs)/sizeof(check_addrs[0]); i++) {
+               ram_check(check_addrs[i].lo, check_addrs[i].hi);
        }
+#endif
 }