#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
}