aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdk8/raminit_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/amd/amdk8/raminit_test.c')
-rw-r--r--src/northbridge/amd/amdk8/raminit_test.c442
1 files changed, 442 insertions, 0 deletions
diff --git a/src/northbridge/amd/amdk8/raminit_test.c b/src/northbridge/amd/amdk8/raminit_test.c
new file mode 100644
index 0000000000..8e323ea859
--- /dev/null
+++ b/src/northbridge/amd/amdk8/raminit_test.c
@@ -0,0 +1,442 @@
+#include <unistd.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <setjmp.h>
+#include <device/pci_def.h>
+#include "amdk8.h"
+
+jmp_buf end_buf;
+
+static int is_cpu_pre_c0(void)
+{
+ return 0;
+}
+
+#define PCI_ADDR(BUS, DEV, FN, WHERE) ( \
+ (((BUS) & 0xFF) << 16) | \
+ (((DEV) & 0x1f) << 11) | \
+ (((FN) & 0x07) << 8) | \
+ ((WHERE) & 0xFF))
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFF) << 16) | \
+ (((DEV) & 0x1f) << 11) | \
+ (((FN) & 0x7) << 8))
+
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+ ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+
+typedef unsigned device_t;
+
+unsigned char pci_register[256*5*3*256];
+
+static uint8_t pci_read_config8(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = dev | where;
+ return pci_register[addr];
+}
+
+static uint16_t pci_read_config16(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = dev | where;
+ return pci_register[addr] | (pci_register[addr + 1] << 8);
+}
+
+static uint32_t pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ uint32_t value;
+ addr = dev | where;
+ value = pci_register[addr] |
+ (pci_register[addr + 1] << 8) |
+ (pci_register[addr + 2] << 16) |
+ (pci_register[addr + 3] << 24);
+
+#if 0
+ print_debug("pcir32(");
+ print_debug_hex32(addr);
+ print_debug("):");
+ print_debug_hex32(value);
+ print_debug("\n");
+#endif
+ return value;
+
+}
+
+static void pci_write_config8(device_t dev, unsigned where, uint8_t value)
+{
+ unsigned addr;
+ addr = dev | where;
+ pci_register[addr] = value;
+}
+
+static void pci_write_config16(device_t dev, unsigned where, uint16_t value)
+{
+ unsigned addr;
+ addr = dev | where;
+ pci_register[addr] = value & 0xff;
+ pci_register[addr + 1] = (value >> 8) & 0xff;
+}
+
+static void pci_write_config32(device_t dev, unsigned where, uint32_t value)
+{
+ unsigned addr;
+ addr = dev | where;
+ pci_register[addr] = value & 0xff;
+ pci_register[addr + 1] = (value >> 8) & 0xff;
+ pci_register[addr + 2] = (value >> 16) & 0xff;
+ pci_register[addr + 3] = (value >> 24) & 0xff;
+
+#if 0
+ print_debug("pciw32(");
+ print_debug_hex32(addr);
+ print_debug(", ");
+ print_debug_hex32(value);
+ print_debug(")\n");
+#endif
+}
+
+#define PCI_DEV_INVALID (0xffffffffU)
+static device_t pci_locate_device(unsigned pci_id, device_t dev)
+{
+ for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
+ unsigned int id;
+ id = pci_read_config32(dev, 0);
+ if (id == pci_id) {
+ return dev;
+ }
+ }
+ return PCI_DEV_INVALID;
+}
+
+
+
+
+static void uart_tx_byte(unsigned char data)
+{
+ write(STDOUT_FILENO, &data, 1);
+}
+static void hlt(void)
+{
+ longjmp(end_buf, 2);
+}
+#include "../../../arch/i386/lib/console.c"
+
+unsigned long log2(unsigned long x)
+{
+ // assume 8 bits per byte.
+ unsigned long i = 1 << (sizeof(x)*8 - 1);
+ unsigned long pow = sizeof(x) * 8 - 1;
+
+ if (! x) {
+ static const char errmsg[] = " called with invalid parameter of 0\n";
+ write(STDERR_FILENO, __func__, sizeof(__func__) - 1);
+ write(STDERR_FILENO, errmsg, sizeof(errmsg) - 1);
+ hlt();
+ }
+ for(; i > x; i >>= 1, pow--)
+ ;
+
+ return pow;
+}
+
+typedef struct msr_struct
+{
+ unsigned lo;
+ unsigned hi;
+} msr_t;
+
+static inline msr_t rdmsr(unsigned index)
+{
+ msr_t result;
+ result.lo = 0;
+ result.hi = 0;
+ return result;
+}
+
+static inline void wrmsr(unsigned index, msr_t msr)
+{
+}
+
+#include "raminit.h"
+
+#define SIO_BASE 0x2e
+
+static void hard_reset(void)
+{
+ /* FIXME implement the hard reset case... */
+ longjmp(end_buf, 3);
+}
+
+static void memreset_setup(void)
+{
+ /* Nothing to do */
+}
+
+static void memreset(int controllers, const struct mem_controller *ctrl)
+{
+ /* Nothing to do */
+}
+
+static inline void activate_spd_rom(const struct mem_controller *ctrl)
+{
+ /* nothing to do */
+}
+
+
+static uint8_t spd_mt4lsdt464a[256] =
+{
+ 0x80, 0x08, 0x04, 0x0C, 0x08, 0x01, 0x40, 0x00, 0x01, 0x70,
+ 0x54, 0x00, 0x80, 0x10, 0x00, 0x01, 0x8F, 0x04, 0x06, 0x01,
+ 0x01, 0x00, 0x0E, 0x75, 0x54, 0x00, 0x00, 0x0F, 0x0E, 0x0F,
+
+ 0x25, 0x08, 0x15, 0x08, 0x15, 0x08, 0x00, 0x12, 0x01, 0x4E,
+ 0x9C, 0xE4, 0xB7, 0x46, 0x2C, 0xFF, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x00,
+};
+
+static uint8_t spd_micron_512MB_DDR333[256] =
+{
+ 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x02, 0x48, 0x00, 0x04, 0x60,
+ 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
+ 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
+ 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x48, 0x30, 0x28, 0x50, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x6f, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x01, 0x33, 0x36, 0x56, 0x44, 0x44, 0x46, 0x31,
+ 0x32, 0x38, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43,
+ 0x33, 0x03, 0x00, 0x03, 0x23, 0x17, 0x07, 0x5a, 0xb2, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+static uint8_t spd_micron_256MB_DDR333[256] =
+{
+ 0x80, 0x08, 0x07, 0x0d, 0x0b, 0x01, 0x48, 0x00, 0x04, 0x60,
+ 0x70, 0x02, 0x82, 0x04, 0x04, 0x01, 0x0e, 0x04, 0x0c, 0x01,
+ 0x02, 0x26, 0xc0, 0x75, 0x70, 0x00, 0x00, 0x48, 0x30, 0x48,
+ 0x2a, 0x80, 0x80, 0x80, 0x45, 0x45, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x48, 0x30, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0x01, 0x31, 0x38, 0x56, 0x44, 0x44, 0x46, 0x36,
+ 0x34, 0x37, 0x32, 0x47, 0x2d, 0x33, 0x33, 0x35, 0x43, 0x31,
+ 0x20, 0x01, 0x00, 0x03, 0x19, 0x17, 0x05, 0xb2, 0xf4, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+#define MAX_DIMMS 16
+static uint8_t spd_data[MAX_DIMMS*256];
+
+static unsigned spd_count, spd_fail_count;
+static int spd_read_byte(unsigned device, unsigned address)
+{
+ int result;
+ spd_count++;
+ if ((device < 0x50) || (device >= (0x50 +MAX_DIMMS))) {
+ result = -1;
+ }
+ else {
+ device -= 0x50;
+
+ if (address > 256) {
+ result = -1;
+ }
+ else if (spd_data[(device << 8) | 2] != 7) {
+ result = -1;
+ }
+ else {
+ result = spd_data[(device << 8) | address];
+ }
+ }
+#if 0
+ print_debug("spd_read_byte(");
+ print_debug_hex32(device);
+ print_debug(", ");
+ print_debug_hex32(address);
+ print_debug(") -> ");
+ print_debug_hex32(result);
+ print_debug("\n");
+#endif
+ if (spd_count >= spd_fail_count) {
+ result = -1;
+ }
+ return result;
+}
+
+/* no specific code here. this should go away completely */
+static void coherent_ht_mainboard(unsigned cpus)
+{
+}
+
+#include "raminit.c"
+#include "../../../sdram/generic_sdram.c"
+
+#define FIRST_CPU 1
+#define SECOND_CPU 1
+#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU)
+static void raminit_main(void)
+{
+ /*
+ * GPIO28 of 8111 will control H0_MEMRESET_L
+ * GPIO29 of 8111 will control H1_MEMRESET_L
+ */
+ static const struct mem_controller cpu[] = {
+#if FIRST_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 = { 0x50+0, 0x50+2, 0x50+4, 0x50+6 },
+ .channel1 = { 0x50+1, 0x50+3, 0x50+5, 0x50+7 },
+ },
+#endif
+#if SECOND_CPU
+ {
+ .node_id = 1,
+ .f0 = PCI_DEV(0, 0x19, 0),
+ .f1 = PCI_DEV(0, 0x19, 1),
+ .f2 = PCI_DEV(0, 0x19, 2),
+ .f3 = PCI_DEV(0, 0x19, 3),
+ .channel0 = { 0x50+8, 0x50+10, 0x50+12, 0x50+14 },
+ .channel1 = { 0x50+9, 0x50+11, 0x50+13, 0x50+15 },
+ },
+#endif
+ };
+ console_init();
+ memreset_setup();
+ sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
+
+}
+
+static void reset_tests(void)
+{
+ /* Clear the results of any previous tests */
+ memset(pci_register, 0, sizeof(pci_register));
+ memset(spd_data, 0, sizeof(spd_data));
+ spd_count = 0;
+ spd_fail_count = UINT_MAX;
+
+ pci_write_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP,
+ NBCAP_128Bit |
+ NBCAP_MP| NBCAP_BIG_MP |
+ /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
+ (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
+ NBCAP_MEMCTRL);
+
+ pci_write_config32(PCI_DEV(0, 0x19, 3), NORTHBRIDGE_CAP,
+ NBCAP_128Bit |
+ NBCAP_MP| NBCAP_BIG_MP |
+ /* NBCAP_ECC | NBCAP_CHIPKILL_ECC | */
+ (NBCAP_MEMCLK_200MHZ << NBCAP_MEMCLK_SHIFT) |
+ NBCAP_MEMCTRL);
+
+#if 0
+ pci_read_config32(PCI_DEV(0, 0x18, 3), NORTHBRIDGE_CAP);
+#endif
+}
+
+static void test1(void)
+{
+ reset_tests();
+
+ memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
+ memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
+#if 0
+ memcpy(&spd_data[2*256], spd_micron_512MB_DDR333, 256);
+ memcpy(&spd_data[3*256], spd_micron_512MB_DDR333, 256);
+
+ memcpy(&spd_data[8*256], spd_micron_512MB_DDR333, 256);
+ memcpy(&spd_data[9*256], spd_micron_512MB_DDR333, 256);
+ memcpy(&spd_data[10*256], spd_micron_512MB_DDR333, 256);
+ memcpy(&spd_data[11*256], spd_micron_512MB_DDR333, 256);
+#endif
+
+ raminit_main();
+
+#if 0
+ print_debug("spd_count: ");
+ print_debug_hex32(spd_count);
+ print_debug("\r\n");
+#endif
+
+}
+
+
+static void do_test2(int i)
+{
+ jmp_buf tmp_buf;
+ memcpy(&tmp_buf, &end_buf, sizeof(end_buf));
+ if (setjmp(end_buf) != 0) {
+ goto done;
+ }
+ reset_tests();
+ spd_fail_count = i;
+
+ print_debug("\r\nSPD will fail after: ");
+ print_debug_hex32(spd_fail_count);
+ print_debug(" accesses.\r\n");
+
+ memcpy(&spd_data[0*256], spd_micron_512MB_DDR333, 256);
+ memcpy(&spd_data[1*256], spd_micron_512MB_DDR333, 256);
+
+ raminit_main();
+
+ done:
+ memcpy(&end_buf, &tmp_buf, sizeof(end_buf));
+}
+
+static void test2(void)
+{
+ int i;
+ for(i = 0; i < 0x48; i++) {
+ do_test2(i);
+ }
+
+}
+
+int main(int argc, char **argv)
+{
+ if (setjmp(end_buf) != 0) {
+ return -1;
+ }
+ test1();
+ test2();
+ return 0;
+}