diff options
Diffstat (limited to 'src')
303 files changed, 30195 insertions, 1910 deletions
diff --git a/src/config/Options.lb b/src/config/Options.lb index 92104a0451..13a531b478 100644 --- a/src/config/Options.lb +++ b/src/config/Options.lb @@ -576,6 +576,42 @@ define AUTOBOOT_CMDLINE comment "Default command line when autobooting" end +define USE_WATCHDOG_ON_BOOT + default 0 + export always + comment "Use the watchdog on booting" +end + +############################################### +# Plugin Device support options +############################################### + +define CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT + default 1 + export always + comment "Enable support for plugin Hypertransport busses" +end +define CONFIG_AGP_PLUGIN_SUPPORT + default 1 + export always + comment "Enable support for plugin AGP busses" +end +define CONFIG_CARDBUS_PLUGIN_SUPPORT + default 1 + export always + comment "Enable support cardbus plugin cards" +end +define CONFIG_PCIX_PLUGIN_SUPPORT + default 1 + export always + comment "Enable support for plugin PCI-X busses" +end +define CONFIG_PCIEXP_PLUGIN_SUPPORT + default 1 + export always + comment "Enable support for plugin PCI-E busses" +end + ############################################### # IRQ options ############################################### @@ -709,21 +745,6 @@ define HAVE_HARD_RESET export used comment "Have hard reset" end -define HARD_RESET_BUS - default 1 - export always - comment "Bus number of southbridge device doing reset" -end -define HARD_RESET_DEVICE - default 5 - export always - comment "Device number of southbridge device doing reset" -end -define HARD_RESET_FUNCTION - default 0 - export always - comment "Function number of southbridge device doing reset" -end define MEMORY_HOLE default none export used diff --git a/src/cpu/amd/car/cache_as_ram_post.c b/src/cpu/amd/car/cache_as_ram_post.c index 66ca9fdf96..6a129b258a 100644 --- a/src/cpu/amd/car/cache_as_ram_post.c +++ b/src/cpu/amd/car/cache_as_ram_post.c @@ -1,4 +1,5 @@ /* by yhlu 6.2005 */ +/* be warned, this file will be used other cores and core0/node0 */ __asm__ volatile ( /* FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that. diff --git a/src/cpu/amd/model_fxx/model_fxx_init.c b/src/cpu/amd/model_fxx/model_fxx_init.c index b75025b4c8..3c526e78ca 100644 --- a/src/cpu/amd/model_fxx/model_fxx_init.c +++ b/src/cpu/amd/model_fxx/model_fxx_init.c @@ -192,6 +192,7 @@ static void init_ecc_memory(unsigned node_id) /* If ecc support is not enabled don't touch memory */ dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW); if (!(dcl & DCL_DimmEccEn)) { + printk_debug("ECC Disabled\n"); return; } @@ -226,7 +227,9 @@ static void init_ecc_memory(unsigned node_id) disable_lapic(); /* Walk through 2M chunks and zero them */ - for(basek = begink; basek < endk; basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) { + for(basek = begink; basek < endk; + basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) + { unsigned long limitk; unsigned long size; void *addr; @@ -255,12 +258,13 @@ static void init_ecc_memory(unsigned node_id) } size = (limitk - basek) << 10; addr = map_2M_page(basek >> 11); - addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10)); if (addr == MAPPING_ERROR) { + printk_err("Cannot map page: %x\n", basek >> 11); continue; } /* clear memory 2M (limitk - basek) */ + addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10)); clear_memory(addr, size); } /* Restore the normal state */ @@ -319,19 +323,16 @@ static inline void k8_errata(void) } wrmsr(NB_CFG_MSR, msr); } -// AMD_D0_SUPPORT + + /* Erratum 97 ... */ if (!is_cpu_pre_c0() && is_cpu_pre_d0()) { - /* D0 later don't need it */ - /* Erratum 97 ... */ msr = rdmsr_amd(DC_CFG_MSR); msr.lo |= 1 << 3; wrmsr_amd(DC_CFG_MSR, msr); - } - -//AMD_D0_SUPPORT - if(is_cpu_pre_d0()) { - /*D0 later don't need it */ - /* Erratum 94 ... */ + } + + /* Erratum 94 ... */ + if (is_cpu_pre_d0()) { msr = rdmsr_amd(IC_CFG_MSR); msr.lo |= 1 << 11; wrmsr_amd(IC_CFG_MSR, msr); @@ -339,37 +340,51 @@ static inline void k8_errata(void) /* Erratum 91 prefetch miss is handled in the kernel */ -//AMD_D0_SUPPORT + /* Erratum 106 ... */ + msr = rdmsr_amd(LS_CFG_MSR); + msr.lo |= 1 << 25; + wrmsr_amd(LS_CFG_MSR, msr); + + /* Erratum 107 ... */ + msr = rdmsr_amd(BU_CFG_MSR); + msr.hi |= 1 << (43 - 32); + wrmsr_amd(BU_CFG_MSR, msr); + if(is_cpu_d0()) { /* Erratum 110 ...*/ msr = rdmsr_amd(CPU_ID_HYPER_EXT_FEATURES); msr.hi |=1; wrmsr_amd(CPU_ID_HYPER_EXT_FEATURES, msr); - } + } -//AMD_E0_SUPPORT - if(!is_cpu_pre_e0()) { - /* Erratum 110 ...*/ + if (!is_cpu_pre_e0()) { + /* Erratum 110 ... */ msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR); msr.hi |=1; wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr); } + + /* Erratum 122 */ + msr = rdmsr(HWCR_MSR); + msr.lo |= 1 << 6; + wrmsr(HWCR_MSR, msr); + } void model_fxx_init(device_t dev) { unsigned long i; msr_t msr; -#if CONFIG_LOGICAL_CPUS==1 +#if CONFIG_LOGICAL_CPUS struct node_core_id id; - unsigned siblings; + unsigned siblings; id.coreid=0; #else unsigned nodeid; #endif /* Turn on caching if we haven't already */ - x86_enable_cache(); + x86_enable_cache(); amd_setup_mtrrs(); x86_mtrr_check(); @@ -386,11 +401,12 @@ void model_fxx_init(device_t dev) enable_cache(); -#if CONFIG_LOGICAL_CPUS==1 -//AMD_DUAL_CORE_SUPPORT + /* Enable the local cpu apics */ + setup_lapic(); + +#if CONFIG_LOGICAL_CPUS == 1 siblings = cpuid_ecx(0x80000008) & 0xff; -// id = get_node_core_id((!is_cpu_pre_e0())? read_nb_cfg_54():0); id = get_node_core_id(read_nb_cfg_54()); // pre e0 nb_cfg_54 can not be set if(siblings>0) { @@ -407,24 +423,24 @@ void model_fxx_init(device_t dev) wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr); } + /* Is this a bad location? In particular can another node prefecth * data from this node before we have initialized it? */ - if(id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core0 + if (id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core 0 #else - /* For now there is a 1-1 mapping between node_id and cpu_id */ - nodeid = lapicid() & 0x7; + /* Is this a bad location? In particular can another node prefecth + * data from this node before we have initialized it? + */ + nodeid = lapicid() & 0xf; init_ecc_memory(nodeid); #endif - - /* Enable the local cpu apics */ - setup_lapic(); #if CONFIG_LOGICAL_CPUS==1 -//AMD_DUAL_CORE_SUPPORT /* Start up my cpu siblings */ // if(id.coreid==0) amd_sibling_init(dev); // Don't need core1 is already be put in the CPU BUS in bus_cpu_scan #endif + } static struct device_operations cpu_dev_ops = { diff --git a/src/cpu/amd/model_fxx/model_fxx_msr.h b/src/cpu/amd/model_fxx/model_fxx_msr.h index c8d57bee1a..b4795cbbb2 100644 --- a/src/cpu/amd/model_fxx/model_fxx_msr.h +++ b/src/cpu/amd/model_fxx/model_fxx_msr.h @@ -3,6 +3,7 @@ #define HWCR_MSR 0xC0010015 #define NB_CFG_MSR 0xC001001f +#define LS_CFG_MSR 0xC0011020 #define IC_CFG_MSR 0xC0011021 #define DC_CFG_MSR 0xC0011022 #define BU_CFG_MSR 0xC0011023 diff --git a/src/cpu/amd/mtrr/amd_mtrr.c b/src/cpu/amd/mtrr/amd_mtrr.c index de4ed988c2..e57bb3bec7 100644 --- a/src/cpu/amd/mtrr/amd_mtrr.c +++ b/src/cpu/amd/mtrr/amd_mtrr.c @@ -96,26 +96,32 @@ static void set_fixed_mtrr_resource(void *gp, struct device *dev, struct resourc return; } printk_debug("Setting fixed MTRRs(%d-%d) Type: WB, RdMEM, WrMEM\n", - start_mtrr, last_mtrr); + start_mtrr, last_mtrr); set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM); } +extern void enable_fixed_mtrr(void); + void amd_setup_mtrrs(void) { + unsigned long address_bits; struct mem_state state; unsigned long i; msr_t msr; + /* Enable the access to AMD RdDram and WrDram extension bits */ + disable_cache(); msr = rdmsr(SYSCFG_MSR); msr.lo |= SYSCFG_MSR_MtrrFixDramModEn; wrmsr(SYSCFG_MSR, msr); + enable_cache(); printk_debug("\n"); /* Initialized the fixed_mtrrs to uncached */ printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n", - 0, NUM_FIXED_RANGES); + 0, NUM_FIXED_RANGES); set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE); /* Except for the PCI MMIO hole just before 4GB there are no @@ -127,6 +133,7 @@ void amd_setup_mtrrs(void) IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, set_fixed_mtrr_resource, &state); printk_debug("DONE fixed MTRRs\n"); + if (state.mmio_basek > state.tomk) { state.mmio_basek = state.tomk; } @@ -164,10 +171,17 @@ void amd_setup_mtrrs(void) msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn; wrmsr(SYSCFG_MSR, msr); + enable_fixed_mtrr(); + enable_cache(); + /* FIXME we should probably query the cpu for this + * but so far this is all any recent AMD cpu has supported. + */ + address_bits = 40; + /* Now that I have mapped what is memory and what is not * Setup the mtrrs so we can cache the memory. */ - x86_setup_mtrrs(); + x86_setup_var_mtrrs(address_bits); } diff --git a/src/cpu/intel/model_f0x/model_f0x_init.c b/src/cpu/intel/model_f0x/model_f0x_init.c index 55504a1049..474d025799 100644 --- a/src/cpu/intel/model_f0x/model_f0x_init.c +++ b/src/cpu/intel/model_f0x/model_f0x_init.c @@ -30,7 +30,7 @@ static void model_f0x_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(); + x86_setup_mtrrs(36); x86_mtrr_check(); /* Update the microcode */ diff --git a/src/cpu/intel/model_f1x/model_f1x_init.c b/src/cpu/intel/model_f1x/model_f1x_init.c index 53cee4fe68..42dff1e276 100644 --- a/src/cpu/intel/model_f1x/model_f1x_init.c +++ b/src/cpu/intel/model_f1x/model_f1x_init.c @@ -30,7 +30,7 @@ static void model_f1x_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(); + x86_setup_mtrrs(36); x86_mtrr_check(); /* Update the microcode */ diff --git a/src/cpu/intel/model_f2x/model_f2x_init.c b/src/cpu/intel/model_f2x/model_f2x_init.c index 4f69d81d2a..f019ea4473 100644 --- a/src/cpu/intel/model_f2x/model_f2x_init.c +++ b/src/cpu/intel/model_f2x/model_f2x_init.c @@ -34,7 +34,7 @@ static void model_f2x_init(device_t cpu) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(); + x86_setup_mtrrs(36); x86_mtrr_check(); /* Update the microcode */ diff --git a/src/cpu/intel/model_f3x/model_f3x_init.c b/src/cpu/intel/model_f3x/model_f3x_init.c index a89e7d1782..20b8518c7c 100644 --- a/src/cpu/intel/model_f3x/model_f3x_init.c +++ b/src/cpu/intel/model_f3x/model_f3x_init.c @@ -31,7 +31,7 @@ static void model_f3x_init(device_t cpu) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(); + x86_setup_mtrrs(36); x86_mtrr_check(); /* Update the microcode */ diff --git a/src/cpu/intel/model_f4x/Config.lb b/src/cpu/intel/model_f4x/Config.lb new file mode 100644 index 0000000000..66f6ceb00f --- /dev/null +++ b/src/cpu/intel/model_f4x/Config.lb @@ -0,0 +1,12 @@ +uses HAVE_MOVNTI +default HAVE_MOVNTI=1 +dir /cpu/x86/tsc +dir /cpu/x86/mtrr +dir /cpu/x86/fpu +dir /cpu/x86/mmx +dir /cpu/x86/sse +dir /cpu/x86/lapic +dir /cpu/x86/cache +dir /cpu/intel/microcode +dir /cpu/intel/hyperthreading +driver model_f4x_init.o diff --git a/src/cpu/intel/model_f4x/microcode_MBDF410D.h b/src/cpu/intel/model_f4x/microcode_MBDF410D.h new file mode 100644 index 0000000000..9266ce5c34 --- /dev/null +++ b/src/cpu/intel/model_f4x/microcode_MBDF410D.h @@ -0,0 +1,1024 @@ +0x00000001, /* Header Version */
+0x0000000d, /* Patch ID */
+0x11032004, /* DATE */
+0x00000f41, /* CPUID */
+0xa3430d74, /* Checksum */
+0x00000001, /* Loader Version */
+0x000000bd, /* Platform ID */
+0x00000fd0, /* Data size */
+0x00001000, /* Total size */
+0x00000000, /* reserved */
+0x00000000, /* reserved */
+0x00000000, /* reserved */
+0x23869663,
+0x00e8d132,
+0xc1efa329,
+0x20662968,
+0xb833cad6,
+0x78012780,
+0x0971cf44,
+0xda1410ae,
+0xece61219,
+0x5ec0a10c,
+0x5a1c529c,
+0x9b5e4fac,
+0x35fee068,
+0x24bb3539,
+0xa6c23421,
+0x0309a01d,
+0x80331c7b,
+0x960d5da2,
+0x56d31115,
+0xdaadb98b,
+0x8d5c0ca8,
+0xc1fc4f86,
+0xef6ee956,
+0x512c9483,
+0x08a9c125,
+0x03b95162,
+0x6499668c,
+0x25e15127,
+0xfb4f0f0b,
+0x10d1b2c3,
+0x542be728,
+0xa0f11cc9,
+0xa5bc6bd2,
+0xf3b7cc86,
+0xe4a91466,
+0x41eceee1,
+0x5beb249b,
+0x6ab82791,
+0x2c5a86ac,
+0x90c2865d,
+0x4702c4a5,
+0xbddad5f1,
+0xb2e224fb,
+0x0ffb50d3,
+0x13c6933c,
+0xc573b9df,
+0x908510f6,
+0xca6f3a9e,
+0x2049f489,
+0xe20b8848,
+0xfd659d6e,
+0xc9afd397,
+0x1432aa70,
+0x62c3e20c,
+0xee6dda59,
+0xe8601135,
+0xa9e30f8e,
+0x691b59e5,
+0x0446816b,
+0xd63a3f0c,
+0x5d1b9d99,
+0xfe8d9637,
+0xee61a0a4,
+0xeeae5aa0,
+0x709d78e6,
+0x5468e7fb,
+0x7e0f2dc3,
+0x632591e1,
+0x990864bb,
+0x413a220b,
+0x5285bdcd,
+0xb7323fa6,
+0xfe0098ce,
+0xd05d24b2,
+0x51ee2e1e,
+0x0078c207,
+0x9d1e1514,
+0x1be23c59,
+0xa80398e4,
+0xe0fa94c8,
+0x2b2f841e,
+0x21144f67,
+0x0a6a1413,
+0xfa30499a,
+0xba49558e,
+0x1607d767,
+0xebd70987,
+0x00cb016d,
+0xac1de18a,
+0xfcde8566,
+0x23f51d05,
+0xb7368509,
+0x9b1947fd,
+0x0d0d3c22,
+0xfbeab67d,
+0xfc963120,
+0x0aeae56b,
+0x0dbe2aeb,
+0x6d4ba825,
+0xab4b8dae,
+0x23bbe7a0,
+0x53d38f2e,
+0x6ee7bed3,
+0x39869966,
+0x8e36076d,
+0x410dca57,
+0x133c4861,
+0xcc2920d0,
+0xb1cfc172,
+0xd3c2e94b,
+0x8cdb7550,
+0xcb14be86,
+0x1c72bb42,
+0x469a6066,
+0x912f65eb,
+0x173ac7b9,
+0xfa02afca,
+0x23fc44f2,
+0xbbf0c89f,
+0xa018ba5f,
+0x950654d1,
+0x1b6d7652,
+0xb2a04767,
+0x86630316,
+0xff3fd7b3,
+0x9c9b3aba,
+0xb7d6115b,
+0x7c7a354c,
+0x1761b195,
+0xc54b49dd,
+0x2e0f5f20,
+0xaf1e90b2,
+0x07056032,
+0x46ccdd94,
+0xcc751ec5,
+0x4774af8a,
+0x24a3dba1,
+0xa388bccc,
+0xacd1c25a,
+0x4ee406c1,
+0x9861931a,
+0x5bae36e2,
+0xafc6e087,
+0x8d36cd1b,
+0x25f894d1,
+0xd749fdaa,
+0x3cef917d,
+0xb85440c2,
+0x4d22a2bf,
+0x19703ee4,
+0xa5fd9e1e,
+0x76062779,
+0x14031f62,
+0x6e309271,
+0x55476f65,
+0xb4fd2411,
+0x554882db,
+0xee9d4d38,
+0x57faf730,
+0x730e0285,
+0xb882d382,
+0xc156852d,
+0xf2db8f7a,
+0xea52f3e4,
+0x323430d1,
+0x51ea5fe9,
+0x0929d601,
+0x8e6740cf,
+0x69c456e1,
+0xd9e2f5c1,
+0x0124bf3b,
+0x0220f415,
+0xfbe91365,
+0x2bc82d06,
+0x0a31f25c,
+0xbeaf32af,
+0x3c2175b7,
+0xe8f67a0e,
+0x177bb8fa,
+0x33b86eb3,
+0x3ba0e579,
+0x368fc48b,
+0xe6665da8,
+0x688bfd43,
+0x48448000,
+0xc5c99d34,
+0xab99cfeb,
+0x1ce9c58d,
+0x773ae448,
+0x3534d849,
+0x6d86470f,
+0x306db8d0,
+0x550c15ff,
+0x7a2c439a,
+0xe6f1b78f,
+0x0bf4cdd7,
+0xfbcab3d7,
+0x402e87ec,
+0xf4ee5874,
+0xc03c70d9,
+0x3b9ed9e6,
+0x04ef67e0,
+0xd04ae924,
+0xf6845607,
+0x5e58c954,
+0xc2fdf283,
+0xc558ae4e,
+0x8300ece1,
+0x7bbaea80,
+0xc5d0b0f1,
+0xfc9e8004,
+0xfcea494a,
+0x04f4eb47,
+0x129f505d,
+0xccbae019,
+0x59c0616f,
+0xaaba53a8,
+0x19d8a002,
+0x361fb171,
+0x00c4aee2,
+0x6bb0dfb0,
+0xc03d6b9a,
+0xabaed6fb,
+0xa23c48fe,
+0x50866e98,
+0xbb499854,
+0xb5730aad,
+0xbe89d93c,
+0xe6d35886,
+0x7ae05c20,
+0xc2708cbd,
+0xf8f18059,
+0xf492c48e,
+0x14121e3d,
+0x9e9dc5a7,
+0xafa3ef3a,
+0x17535114,
+0x08296547,
+0xe1ab5d3c,
+0x2e51d954,
+0x0e6953db,
+0xde0ea136,
+0xd1f37944,
+0x3074f7ed,
+0x3b196093,
+0x0efb3b56,
+0x3b904c2c,
+0xcef179ee,
+0xc854e7f5,
+0x48aa28ce,
+0x1c0cb17e,
+0xae4236b2,
+0x87c5dc18,
+0x7832ec05,
+0xc4212949,
+0xca5a40d2,
+0x8e8f431d,
+0x328df52b,
+0xe4dd2524,
+0x7b8ae78a,
+0x17ba24a3,
+0x25eb59d5,
+0x1a341b63,
+0x45f1e3f2,
+0x0e2d9cf8,
+0xa66c17e8,
+0x515bc934,
+0xfea866d3,
+0xd149deac,
+0x740a7cf5,
+0x2f47375b,
+0xa5fdd0c4,
+0xd8965720,
+0x4ecefd2f,
+0x1916443a,
+0x984995a9,
+0x7b919733,
+0x80f02747,
+0x30fe0d17,
+0x65a68843,
+0xdb0931ad,
+0x0929b113,
+0x1bd4cc0c,
+0x7b2f63fd,
+0x6238656c,
+0x8a1badab,
+0x6565a869,
+0xca48cce2,
+0x7ff6bdc3,
+0x772305d4,
+0x376639d3,
+0x56ed9f11,
+0x75e17cef,
+0x7dffbcf4,
+0xfbafb077,
+0x932aed24,
+0x8b04ebf4,
+0x768ac85f,
+0xb54a99f9,
+0xd4fdf692,
+0x43b09d0a,
+0x32d81423,
+0xcb2a74e6,
+0x59f40d29,
+0x6392b933,
+0x7a3bc72c,
+0xfa647af0,
+0x2c28e15f,
+0xa724e1b0,
+0x6174f8f6,
+0x651672ab,
+0xd8eb376a,
+0x61d18571,
+0xa9bab242,
+0x2ba20ac2,
+0x332c20a9,
+0x21e71331,
+0x7ba9dbe4,
+0x1e61e44d,
+0x07ee9579,
+0xd1846f7a,
+0xca29125b,
+0x11958b89,
+0xb6fe5a2b,
+0x249991b4,
+0x5f28c005,
+0x0b909d87,
+0x673159ab,
+0xf25d3b1a,
+0x2a7f0d31,
+0x2e741145,
+0x60c1525d,
+0x7a2996a7,
+0x5051ead4,
+0xb9473e57,
+0x7c5f9d0e,
+0x51584719,
+0xa25c2246,
+0xceec4103,
+0x813e68be,
+0xabf2eed8,
+0x4fb4988f,
+0x678fba46,
+0x801b82e1,
+0x7fc428dc,
+0xa30bf423,
+0xd1dc03db,
+0x65d1f1fb,
+0xfea39d25,
+0x7b8cfad4,
+0x7eda42af,
+0x4c7cb670,
+0x1ac54e69,
+0x6ecd00ae,
+0x2ff34b4e,
+0x0f7c1999,
+0x14713cb0,
+0x3942aea8,
+0x07832b5c,
+0x5cd3fa0c,
+0x918b4916,
+0xe9420e66,
+0x8bd0f43c,
+0x28e79a91,
+0x999c89a3,
+0x59da832c,
+0x3dd8cb18,
+0x67deb7fe,
+0xa4f503bb,
+0x77f8114f,
+0xe732a72b,
+0x7e8b8835,
+0x10192856,
+0x54da048f,
+0x8ea0f6cd,
+0x722ba57f,
+0x133ad6fc,
+0x7d486fb3,
+0x27764f83,
+0x8c0dff5f,
+0x9f137e77,
+0x5d6b4057,
+0xeef4eee0,
+0xb0e0e900,
+0xf37b72f1,
+0xec1b84f5,
+0x0a454136,
+0xc23a91a3,
+0x0ab3bae8,
+0x715496f9,
+0xc1082181,
+0xccf9217f,
+0x5213635d,
+0x2e29ab5b,
+0xb4574eef,
+0x2bc2fea8,
+0x1ee67ef8,
+0xd567c2b8,
+0xfc19ef2c,
+0xe19af740,
+0x28a28944,
+0x836be662,
+0xb0080f12,
+0xd6f61914,
+0x33c85c03,
+0x326e680f,
+0x87b45aa5,
+0xad7c015b,
+0x63e312a9,
+0x65fb08cf,
+0x5fca6d27,
+0x7b57bef5,
+0x466fa276,
+0x56c21f72,
+0x38fb8f1d,
+0xc1966d08,
+0x15d4c28b,
+0xeec1eade,
+0x905f5218,
+0x5be29b59,
+0xb64aa150,
+0xc8994548,
+0xe4bfb038,
+0xd63e54cf,
+0x98469c03,
+0xb28e3b7b,
+0xf852cae3,
+0xc76b8b09,
+0x16810021,
+0x8ea0bfec,
+0xdfc083e5,
+0x884c8453,
+0x908a80f2,
+0xb6d91870,
+0x56ad6422,
+0x05174668,
+0x380d8035,
+0xeef37603,
+0x38ff195e,
+0x44898288,
+0xb300620f,
+0xa814ec47,
+0xa58d3007,
+0x7d4536f5,
+0x2dfc2f4d,
+0xfa2ae308,
+0x24d4799f,
+0x1423df15,
+0x82dc572b,
+0xa3141ca3,
+0xa1210bb1,
+0xb7eecdc4,
+0x5d9ac524,
+0xb8f4b3fb,
+0x6cd8f8a8,
+0x0e745c45,
+0xb0041dbe,
+0x6ee22101,
+0xc9fb746b,
+0x69909b4d,
+0x9e63a31c,
+0xbc627065,
+0x6b24225b,
+0x1d2b80b1,
+0x4c08e46b,
+0x1f78a68c,
+0x75bc0a34,
+0x74d23ab8,
+0xb16d2786,
+0xfbb6fa5f,
+0xc9bbf303,
+0x69ebae66,
+0xcfa4bf29,
+0xaa69d19e,
+0x5d965c81,
+0x7cebac23,
+0x030b7aca,
+0x7983efba,
+0x03babdb7,
+0xd9d7a8bb,
+0xa939d7e1,
+0x6913d42f,
+0xfce3f3b5,
+0xb9d2a26b,
+0x32e614b2,
+0xbbb00851,
+0x4313ca42,
+0xe17a6d39,
+0x5b9f0631,
+0x90569ece,
+0xf980f983,
+0x13eb7233,
+0xc8da9166,
+0x60dbe5fc,
+0x4621997a,
+0xccd2a527,
+0x061180aa,
+0xa92467da,
+0x3dc79eef,
+0x39f31e91,
+0x9e45191c,
+0x7dcba672,
+0xfc23a8b8,
+0x1a773f6a,
+0x6fc6fa46,
+0x46b50e14,
+0x514bd261,
+0xe6cc3574,
+0x5a88dea2,
+0x9121d758,
+0x7f39e3bf,
+0x9ab043b6,
+0xc1007d0c,
+0xc3c3ff8e,
+0x08411386,
+0x0bd529d7,
+0xcaa9a1d8,
+0x27b19be2,
+0x95703f7e,
+0x44ab493a,
+0xcf1fc404,
+0x3f34062d,
+0xa56d454b,
+0x9464f996,
+0x1346eadf,
+0xdd6e6895,
+0x27b5ba10,
+0xb84c1d0c,
+0x5fa57ca4,
+0xad052de8,
+0xf5b4a3ae,
+0x6a61144d,
+0x48c00092,
+0x4897fad0,
+0x90b7b116,
+0xcdf29b2c,
+0xa41aac9a,
+0x147d09f7,
+0xebf3615d,
+0xb3ddf0b0,
+0xc8edc675,
+0x43cbf71b,
+0xfa0a0b5c,
+0xe0b63692,
+0x6c5870a9,
+0xe0b37be9,
+0xb16acc39,
+0xc55aed8c,
+0xd34fb041,
+0x24735885,
+0x0fff6e94,
+0x834181e8,
+0x56671872,
+0xb3f2e29b,
+0xfa383cd3,
+0xe585e5b6,
+0xa40cb894,
+0x1fe8376a,
+0xf794c60a,
+0xa3efdb18,
+0x0df1f1b4,
+0x54230798,
+0xd2a8ba49,
+0x349ce466,
+0xcbff13b4,
+0x71a63418,
+0x728ae615,
+0xf7c4f811,
+0x0dd072d8,
+0x9aa6fac7,
+0xa44210d0,
+0x2a1a85bf,
+0x1e18a8c6,
+0xbe2bb680,
+0xfed00f0e,
+0x2acc1b4b,
+0x4f049f6f,
+0x6f5aeec1,
+0x2db8f7b4,
+0xd61041a2,
+0x5cc7c861,
+0xb6ed3676,
+0x02aef566,
+0x2b6d41c8,
+0xaba9296e,
+0xf7b032cd,
+0xc290e538,
+0x584ad0f9,
+0x95289bc7,
+0x49b428b8,
+0x84bb41d4,
+0xdf0fcf91,
+0x9bd712a9,
+0xc6f730e1,
+0xe28b78d4,
+0x45b0480d,
+0x29d344bf,
+0xcd0101bb,
+0x18561b59,
+0xcfa84f65,
+0x76e798eb,
+0xac73f8af,
+0x71fe2488,
+0x207dd75d,
+0x198130e5,
+0x3604d44d,
+0xd895dc9b,
+0xf55fe7e2,
+0x4fed2e51,
+0xf434e20a,
+0x7c3204e8,
+0x4d653a59,
+0x6652a556,
+0x8713f1e2,
+0xa69dea42,
+0x2fd0ee37,
+0xe7617993,
+0xc0791c80,
+0x57e14435,
+0x87fcad6e,
+0x96505f56,
+0x838e7a38,
+0x78b228ab,
+0x84411d16,
+0x0b4e1d87,
+0x21f17d96,
+0x72021b3c,
+0xe69f4784,
+0x324fb9b4,
+0x041c7459,
+0x500ffe39,
+0x6e561c0f,
+0xadaf6fd7,
+0x0c91509f,
+0x8be04594,
+0x6a5ead5a,
+0x313c9f9d,
+0xe4754919,
+0x63d7cebc,
+0x02d0ad32,
+0x2dc3cdb7,
+0xd9b2e421,
+0xa1ad018c,
+0xd954f545,
+0x9f3871b2,
+0xf8a9a4a9,
+0x4cdc558d,
+0x300c9685,
+0x639f4b78,
+0x2181680d,
+0xb96442d6,
+0x7821a1a2,
+0x174a9e5b,
+0x79320590,
+0xf580c60c,
+0xba8539ce,
+0x59905669,
+0xc6f39c94,
+0xb57cc9bf,
+0xc2f7ad76,
+0x8d9ebc2d,
+0x6c33e47f,
+0x29294c84,
+0x49a2bef6,
+0x8aa6f79b,
+0x809f0eb5,
+0x3691aa7f,
+0xcf4b0e8f,
+0xec44f802,
+0x16bf83a7,
+0x82c00d36,
+0xa99071b1,
+0xe3815c76,
+0xc0835331,
+0xc794c55f,
+0x041b44af,
+0x2fa75171,
+0x985bd852,
+0xc4391e66,
+0x7bf08eaf,
+0x2b826882,
+0xfb8834dc,
+0x9128681e,
+0x6a2cb9ef,
+0x6d1d20f9,
+0x9f90ee4d,
+0xc48c3ee3,
+0xdd063585,
+0x82454044,
+0xf7077f1a,
+0x47e6e556,
+0xd803f7dd,
+0x98f67f71,
+0x9089e4ac,
+0xe7f09610,
+0xa9e3f93b,
+0x420c1550,
+0xc01f7710,
+0x0905da5e,
+0x02d71f99,
+0xbf36b473,
+0x50a96e32,
+0x2dedb8b9,
+0x9e3051a2,
+0x84c023c4,
+0xd43073b1,
+0x74f23fbb,
+0xd42a4487,
+0x266dfc42,
+0x6be0acdf,
+0xa986294c,
+0x3ee65aa8,
+0x19c1cf4f,
+0x2fdf8308,
+0xa6a64910,
+0xc3fa82e8,
+0x2943c8b8,
+0xf1a60b7b,
+0x4cc9ea04,
+0x3cc95270,
+0x054a8d2b,
+0xae7a4525,
+0x2e2abb62,
+0x24b9522b,
+0xb95a6668,
+0xad8c237d,
+0x1ea73bf8,
+0xff33f0d6,
+0x772a16a3,
+0xfefabdc4,
+0xb181234c,
+0xab59fb47,
+0x96f2c987,
+0xff0d4f54,
+0x6e938aba,
+0x727e6266,
+0xea0d851f,
+0x2ced3474,
+0x8c2e7718,
+0xa576c375,
+0xc97addeb,
+0x2f46a635,
+0xdb669986,
+0xa4333f93,
+0x7042c2c6,
+0x419fda5f,
+0x95b8aa3f,
+0x6ad05dc8,
+0x8b90655a,
+0xd8c77947,
+0x20508480,
+0xfa3cdf6b,
+0xdbb44af2,
+0x235941d0,
+0x3154c107,
+0x566bc32a,
+0x426fb2cd,
+0xd2010afa,
+0xe2775abe,
+0x6f543a20,
+0x2c626450,
+0x34f193f4,
+0x37ac5908,
+0x58a7eca6,
+0xc4859881,
+0x183393ff,
+0xab9abed9,
+0xde947d21,
+0xffec2b7d,
+0xb21b8788,
+0xb527117f,
+0x199dffe5,
+0xd7ebe4e6,
+0xc89a72b0,
+0x91cc3042,
+0x91bd3463,
+0x736e6f4f,
+0x0cc208bc,
+0x029f21cb,
+0x3f204418,
+0x050db787,
+0x71b56562,
+0xaf07f08f,
+0xaca4701f,
+0x88d4f2f8,
+0xf98fe016,
+0xb47672c6,
+0xed601c94,
+0x285db8b8,
+0x28a81c19,
+0x9e2763ce,
+0xe39741c0,
+0xcd9fce6d,
+0xe9917796,
+0xfdd3ebaf,
+0x99dcb253,
+0xe9aa0db4,
+0x3a65c0b0,
+0xb39c61fb,
+0x1f413c5e,
+0x60576c8c,
+0x48d6df34,
+0x0cbca786,
+0x4caff4b7,
+0x8473e181,
+0x36eed747,
+0x82f486af,
+0x79f02eed,
+0xab6886ed,
+0x06aef911,
+0xad42a654,
+0x5471c813,
+0xc8bbe710,
+0xfc65fd97,
+0x60f467af,
+0xf56b71d8,
+0xc1d6f193,
+0x3a1c42bf,
+0x46ce3b78,
+0x39472626,
+0x04dc137e,
+0xb48dc9dd,
+0xdfd27741,
+0x4718e5a2,
+0x00ba4728,
+0x855b661f,
+0x6d98577f,
+0xc3b48131,
+0x2b0384c1,
+0x8af572fe,
+0x760aa4e3,
+0x2f5b53fb,
+0xb9234297,
+0x401b47f5,
+0x44237cc0,
+0x2f7205f4,
+0x19b63c6e,
+0x7c375e6b,
+0x152c42d8,
+0x603731c7,
+0xc67601fb,
+0xa5d4826c,
+0x9068966f,
+0x864fe2f9,
+0xb37311d9,
+0xe6e4a34a,
+0xd46ee161,
+0xecd76c4a,
+0x90d0328a,
+0x4865b540,
+0xd2e13982,
+0x7e3925f4,
+0xc850a518,
+0x63bffcce,
+0x7cdb918f,
+0xcd8786d3,
+0xcf83df01,
+0x27122e50,
+0x0f014b76,
+0xde1485d7,
+0xa6ff496f,
+0xed0812f7,
+0x34efe965,
+0x12a63465,
+0xb83d9f77,
+0x040efa2e,
+0x4ac576d1,
+0x185430dd,
+0xb4271745,
+0x9bb58be2,
+0x7f55d4bb,
+0xca7dae0b,
+0x0bfe5147,
+0x4a9ade45,
+0x20bdc545,
+0xdf66689d,
+0x22e29493,
+0x31763c1f,
+0x2d021cd2,
+0x06286428,
+0xc7bba5d4,
+0x6bc42a0e,
+0x1c987082,
+0xd6c6c2f9,
+0x2c1ecdd0,
+0x84946249,
+0x42c1c41b,
+0x6d949e60,
+0x9dbb1571,
+0xf6b1df68,
+0x0705ae1a,
+0xa1ec5add,
+0x7e94d7c8,
+0x7d4d451d,
+0xd53c13d4,
+0x0204877b,
+0x0f0e44e0,
+0xdf25570f,
+0xd2a9adaf,
+0x556aeacf,
+0x2f985a30,
+0x706c42c6,
+0x2d5a76a5,
+0xdc428213,
+0xdf2864a2,
+0x0f6788a9,
+0xc764d3a6,
+0x9211d0ca,
+0x59e3f5cc,
+0xd31fd5b6,
+0xfa8b535b,
+0x2cac74bb,
+0xc43f36b2,
+0xf83b5bac,
+0x96c255bf,
+0x45915993,
+0x657d751a,
+0x9b86b994,
+0xddab62fd,
+0x1b6ac108,
+0x559073c9,
+0xe60a0bda,
+0xd65df6de,
+0x41f7e5d4,
+0x825a5701,
+0x377307b6,
+0x08176ce6,
+0x7a8a2c4a,
+0xd7ecb869,
+0x02710179,
+0x75e7517c,
+0xdfaf2c82,
+0x67590275,
+0x6ad621af,
+0xaedaa35c,
+0xfa8fbee3,
+0x9e5dda5f,
+0x09f571fa,
+0xe358dbfe,
+0x1b3300f1,
+0x05567c6b,
+0x5a9d335f,
+0x215114f8,
+0xd5744f0a,
+0x78ecc142,
+0x9b5f60b8,
+0x30f8fed2,
+0x5c013696,
+0x675c84de,
+0xdb50bbcc,
+0x7c504a4e,
+0x3ffc5fda,
+0x24b2c30a,
+0xac00d64a,
+0x97832b52,
+0xb34d9975,
+0x93c6cb4e,
+0x471bfcae,
+0xaabbb6d8,
+0x0bc6a5e5,
+0x6875c630,
+0xf4cce30c,
+0xdab0d64b,
+0x29aba8b9,
+0xe34b3cde,
+0x8654e470,
+0x2c5041f7,
+0xdcf5eff9,
+0x26a88f84,
+0x9d374761,
+0xefa60ac4,
+0xdf0d0fd3,
+0x72e37e59,
+0xa76d26e1,
+0x3ffe2408,
+0x13ecf42d,
+0x46de7cba,
+0x43330219,
+0xc2536a31,
+0xa69c4729,
+0x114990f8,
+0x3f08ed00,
+0xeaa05cae,
+0x08f06e57,
+0x30f4a62f,
+0x963a7557,
+0x631fb75f,
+0x1344a74b,
+0x1e80cef5,
+0x8a4f86dd,
+0x0f7f1c62,
+0xfe9f5809,
+0x710d86de,
+0x8939283d,
+0x19403076,
+0x26ce286b,
+0x6baaf798,
+0xbc1d2808,
+0xea980728,
+0x72288979,
+0x7c92be68,
+0x0a7af91b,
+0x7bb8059b,
+0xe7eca99c,
+0xd3a8819f,
+0xb9182916,
+0x0c48ba1e,
+0xb6aaf63b,
+0x10a740a6,
+0x0aa2e4e7,
+0x0bf27e94,
+0x6d266f86,
diff --git a/src/cpu/intel/model_f4x/model_f4x_init.c b/src/cpu/intel/model_f4x/model_f4x_init.c new file mode 100644 index 0000000000..649638670d --- /dev/null +++ b/src/cpu/intel/model_f4x/model_f4x_init.c @@ -0,0 +1,58 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/device.h> +#include <device/pci.h> +#include <string.h> +#include <cpu/cpu.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/lapic.h> +#include <cpu/intel/microcode.h> +#include <cpu/intel/hyperthreading.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/mtrr.h> + +static uint32_t microcode_updates[] = { + /* WARNING - Intel has a new data structure that has variable length + * microcode update lengths. They are encoded in int 8 and 9. A + * dummy header of nulls must terminate the list. + */ + +#include "microcode_MBDF410D.h" + /* Dummy terminator */ + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, +}; + + +static void model_f4x_init(device_t cpu) +{ + /* Turn on caching if we haven't already */ + x86_enable_cache(); + x86_setup_mtrrs(36); + x86_mtrr_check(); + + /* Update the microcode */ + intel_update_microcode(microcode_updates); + + /* Enable the local cpu apics */ + setup_lapic(); + + /* Start up my cpu siblings */ + intel_sibling_init(cpu); +}; + +static struct device_operations cpu_dev_ops = { + .init = model_f4x_init, +}; +static struct cpu_device_id cpu_table[] = { + { X86_VENDOR_INTEL, 0x0f41 }, /* Xeon */ + { 0, 0 }, +}; + +static struct cpu_driver model_f4x __cpu_driver = { + .ops = &cpu_dev_ops, + .id_table = cpu_table, +}; diff --git a/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb b/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb index 0b794338a2..2637c86594 100644 --- a/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb +++ b/src/cpu/intel/socket_mPGA604_800Mhz/Config.lb @@ -1,3 +1,4 @@ config chip.h object socket_mPGA604_800Mhz.o dir /cpu/intel/model_f3x +dir /cpu/intel/model_f4x diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c index c435b2edd5..105f7c49df 100644 --- a/src/cpu/x86/mtrr/earlymtrr.c +++ b/src/cpu/x86/mtrr/earlymtrr.c @@ -37,8 +37,8 @@ static void disable_var_mtrr(unsigned reg) wrmsr(MTRRphysMask_MSR(reg), zero); } -static void set_var_mtrr(unsigned reg, unsigned base, unsigned size, - unsigned type) +static void set_var_mtrr( + unsigned reg, unsigned base, unsigned size, unsigned type) { /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */ @@ -76,7 +76,7 @@ static void do_early_mtrr_init(const unsigned long *mtrr_msrs) msr.lo = 0; msr.hi = 0; unsigned long msr_nr; - for (msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) { + for(msr_addr = mtrr_msrs; (msr_nr = *msr_addr); msr_addr++) { wrmsr(msr_nr, msr); } diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index 59f9ca1e91..1226713cf5 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -22,9 +22,14 @@ * * Reference: Intel Architecture Software Developer's Manual, Volume 3: System Programming */ + /* - 2005.1 yhlu add NC support to spare mtrrs for 64G memory stored + 2005.1 yhlu add NC support to spare mtrrs for 64G memory above installed + 2005.6 Eric add address bit in x86_setup_mtrrs + 2005.6 yhlu split x86_setup_var_mtrrs and x86_setup_fixed_mtrrs, + for AMD, it will not use x86_setup_fixed_mtrrs */ + #include <stddef.h> #include <console/console.h> #include <device/device.h> @@ -32,19 +37,6 @@ #include <cpu/x86/mtrr.h> #include <cpu/x86/cache.h> -#warning "FIXME I do not properly handle address more than 36 physical address bits" - -//#define k8 0 -#define k8 1 - -#if k8 -# define ADDRESS_BITS 40 -#else -# define ADDRESS_BITS 36 -#endif -#define ADDRESS_BITS_HIGH (ADDRESS_BITS - 32) -#define ADDRESS_MASK_HIGH ((1u << ADDRESS_BITS_HIGH) - 1) - static unsigned int mtrr_msr[] = { MTRRfix64K_00000_MSR, MTRRfix16K_80000_MSR, MTRRfix16K_A0000_MSR, MTRRfix4K_C0000_MSR, MTRRfix4K_C8000_MSR, MTRRfix4K_D0000_MSR, MTRRfix4K_D8000_MSR, @@ -52,7 +44,7 @@ static unsigned int mtrr_msr[] = { }; -static void enable_fixed_mtrr(void) +void enable_fixed_mtrr(void) { msr_t msr; @@ -71,21 +63,26 @@ static void enable_var_mtrr(void) } /* setting variable mtrr, comes from linux kernel source */ -static void set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type) +static void set_var_mtrr( + unsigned int reg, unsigned long basek, unsigned long sizek, + unsigned char type, unsigned address_bits) { msr_t base, mask; + unsigned address_mask_high; + + address_mask_high = ((1u << (address_bits - 32u)) - 1u); base.hi = basek >> 22; base.lo = basek << 10; - //printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH); + printk_spew("ADDRESS_MASK_HIGH=%#x\n", address_mask_high); if (sizek < 4*1024*1024) { - mask.hi = ADDRESS_MASK_HIGH; + mask.hi = address_mask_high; mask.lo = ~((sizek << 10) -1); } else { - mask.hi = ADDRESS_MASK_HIGH & (~((sizek >> 22) -1)); + mask.hi = address_mask_high & (~((sizek >> 22) -1)); mask.lo = 0; } @@ -219,7 +216,7 @@ static unsigned fixed_mtrr_index(unsigned long addrk) static unsigned int range_to_mtrr(unsigned int reg, unsigned long range_startk, unsigned long range_sizek, - unsigned long next_range_startk, unsigned char type) + unsigned long next_range_startk, unsigned char type, unsigned address_bits) { if (!range_sizek || (reg >= BIOS_MTRRS)) { return reg; @@ -235,11 +232,11 @@ static unsigned int range_to_mtrr(unsigned int reg, } sizek = 1 << align; printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type %s\n", - reg, range_startk >>10, sizek >> 10, - (type==MTRR_TYPE_UNCACHEABLE) ? "NC" : - ((type==MTRR_TYPE_WRBACK) ? "WB" : "Other") + reg, range_startk >>10, sizek >> 10, + (type==MTRR_TYPE_UNCACHEABLE)?"UC": + ((type==MTRR_TYPE_WRBACK)?"WB":"Other") ); - set_var_mtrr(reg++, range_startk, sizek, type); + set_var_mtrr(reg++, range_startk, sizek, type, address_bits); range_startk += sizek; range_sizek -= sizek; if (reg >= BIOS_MTRRS) @@ -279,6 +276,7 @@ struct var_mtrr_state { unsigned long range_startk, range_sizek; unsigned int reg; unsigned long hole_startk, hole_sizek; + unsigned address_bits; }; void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res) @@ -300,47 +298,68 @@ void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res) } /* Write the range mtrrs */ if (state->range_sizek != 0) { - if(state->hole_sizek == 0) { - // we need to put that on to hole. - unsigned long endk = basek + sizek; + if (state->hole_sizek == 0) { + /* We need to put that on to hole */ + unsigned long endk = basek + sizek; state->hole_startk = state->range_startk + state->range_sizek; - state->hole_sizek = basek - state->hole_startk; - state->range_sizek = endk - state->range_startk; + state->hole_sizek = basek - state->hole_startk; + state->range_sizek = endk - state->range_startk; return; } - state->reg = range_to_mtrr(state->reg, state->range_startk, state->range_sizek, basek, MTRR_TYPE_WRBACK); - state->reg = range_to_mtrr(state->reg, state->hole_startk, state->hole_sizek, basek, MTRR_TYPE_UNCACHEABLE); + state->reg = range_to_mtrr(state->reg, state->range_startk, + state->range_sizek, basek, MTRR_TYPE_WRBACK, state->address_bits); + state->reg = range_to_mtrr(state->reg, state->hole_startk, + state->hole_sizek, basek, MTRR_TYPE_UNCACHEABLE, state->address_bits); state->range_startk = 0; state->range_sizek = 0; state->hole_startk = 0; state->hole_sizek = 0; } - /* Allocate an msr */ + /* Allocate an msr */ + printk_spew(" Allocate an msr - basek = %d, sizek = %d,\n", basek, sizek); state->range_startk = basek; state->range_sizek = sizek; } -void x86_setup_mtrrs(void) +void x86_setup_fixed_mtrrs(void) +{ + /* Try this the simple way of incrementally adding together + * mtrrs. If this doesn't work out we can get smart again + * and clear out the mtrrs. + */ + struct var_mtrr_state var_state; + + printk_debug("\n"); + /* Initialized the fixed_mtrrs to uncached */ + printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n", + 0, NUM_FIXED_RANGES); + set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE); + + /* Now see which of the fixed mtrrs cover ram. + */ + search_global_resources( + IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, + set_fixed_mtrr_resource, NULL); + printk_debug("DONE fixed MTRRs\n"); + + /* enable fixed MTRR */ + printk_spew("call enable_fixed_mtrr()\n"); + enable_fixed_mtrr(); + +} +void x86_setup_var_mtrrs(unsigned address_bits) +/* this routine needs to know how many address bits a given processor + * supports. CPUs get grumpy when you set too many bits in + * their mtrr registers :( I would generically call cpuid here + * and find out how many physically supported but some cpus are + * buggy, and report more bits then they actually support. + */ { /* Try this the simple way of incrementally adding together * mtrrs. If this doesn't work out we can get smart again * and clear out the mtrrs. */ struct var_mtrr_state var_state; -#if !k8 - printk_debug("\n"); - /* Initialized the fixed_mtrrs to uncached */ - printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n", - 0, NUM_FIXED_RANGES); - set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHEABLE); - - /* Now see which of the fixed mtrrs cover ram. - */ - search_global_resources( - IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, - set_fixed_mtrr_resource, NULL); - printk_debug("DONE fixed MTRRs\n"); -#endif /* Cache as many memory areas as possible */ /* FIXME is there an algorithm for computing the optimal set of mtrrs? @@ -351,28 +370,35 @@ void x86_setup_mtrrs(void) var_state.hole_startk = 0; var_state.hole_sizek = 0; var_state.reg = 0; + var_state.address_bits = address_bits; search_global_resources( IORESOURCE_MEM | IORESOURCE_CACHEABLE, IORESOURCE_MEM | IORESOURCE_CACHEABLE, set_var_mtrr_resource, &var_state); /* Write the last range */ - var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk, var_state.range_sizek, 0, MTRR_TYPE_WRBACK); - var_state.reg = range_to_mtrr(var_state.reg, var_state.hole_startk, var_state.hole_sizek, 0, MTRR_TYPE_UNCACHEABLE); + var_state.reg = range_to_mtrr(var_state.reg, var_state.range_startk, + var_state.range_sizek, 0, MTRR_TYPE_WRBACK, var_state.address_bits); + var_state.reg = range_to_mtrr(var_state.reg, var_state.hole_startk, + var_state.hole_sizek, 0, MTRR_TYPE_UNCACHEABLE, var_state.address_bits); printk_debug("DONE variable MTRRs\n"); printk_debug("Clear out the extra MTRR's\n"); /* Clear out the extra MTRR's */ while(var_state.reg < MTRRS) { - set_var_mtrr(var_state.reg++, 0, 0, 0); + set_var_mtrr(var_state.reg++, 0, 0, 0, var_state.address_bits); } - /* enable fixed MTRR */ - printk_spew("call enable_fixed_mtrr()\n"); - enable_fixed_mtrr(); printk_spew("call enable_var_mtrr()\n"); enable_var_mtrr(); printk_spew("Leave %s\n", __FUNCTION__); post_code(0x6A); } +void x86_setup_mtrrs(unsigned address_bits) +{ + x86_setup_fixed_mtrrs(); + x86_setup_var_mtrrs(address_bits); +} + + int x86_mtrr_check(void) { /* Only Pentium Pro and later have MTRR */ diff --git a/src/devices/Config.lb b/src/devices/Config.lb index 8de8d4af32..6ba7472cc7 100644 --- a/src/devices/Config.lb +++ b/src/devices/Config.lb @@ -3,8 +3,12 @@ object device.o object root_device.o object device_util.o object pci_device.o -object pnp_device.o object hypertransport.o +object pcix_device.o +object pciexp_device.o +object agp_device.o +object cardbus_device.o +object pnp_device.o object pci_ops.o object smbus_ops.o diff --git a/src/devices/agp_device.c b/src/devices/agp_device.c new file mode 100644 index 0000000000..27ae36eefd --- /dev/null +++ b/src/devices/agp_device.c @@ -0,0 +1,54 @@ +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/agp.h> + +static void agp_tune_dev(device_t dev) +{ + unsigned cap; + cap = pci_find_capability(dev, PCI_CAP_ID_AGP); + if (!cap) { + return; + } + /* The OS is responsible for AGP tuning so do nothing here */ +} + +unsigned int agp_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max) +{ + device_t child; + max = pci_scan_bus(bus, min_devfn, max_devfn, max); + for(child = bus->children; child; child = child->sibling) { + if ( (child->path.u.pci.devfn < min_devfn) || + (child->path.u.pci.devfn > max_devfn)) + { + continue; + } + agp_tune_dev(child); + } + return max; +} + +unsigned int agp_scan_bridge(device_t dev, unsigned int max) +{ + return do_pci_scan_bridge(dev, max, agp_scan_bus); +} + +/** Default device operations for AGP bridges */ +static struct pci_operations agp_bus_ops_pci = { + .set_subsystem = 0, +}; + +struct device_operations default_agp_ops_bus = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = 0, + .scan_bus = agp_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, + .ops_pci = &agp_bus_ops_pci, +}; diff --git a/src/devices/device.c b/src/devices/device.c index d2c435fb72..303a669d9f 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -58,7 +58,7 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) spin_lock(&dev_lock); /* Find the last child of our parent */ - for (child = parent->children; child && child->sibling; ) { + for(child = parent->children; child && child->sibling; ) { child = child->sibling; } @@ -70,7 +70,7 @@ device_t alloc_dev(struct bus *parent, struct device_path *path) memcpy(&dev->path, path, sizeof(*path)); /* Initialize the back pointers in the link fields */ - for (link = 0; link < MAX_LINKS; link++) { + for(link = 0; link < MAX_LINKS; link++) { dev->link[link].dev = dev; dev->link[link].link = link; } @@ -119,10 +119,10 @@ static void read_resources(struct bus *bus) struct device *curdev; printk_spew("%s read_resources bus %d link: %d\n", - dev_path(bus->dev), bus->secondary, bus->link); + dev_path(bus->dev), bus->secondary, bus->link); /* Walk through all of the devices and find which resources they need. */ - for (curdev = bus->children; curdev; curdev = curdev->sibling) { + for(curdev = bus->children; curdev; curdev = curdev->sibling) { unsigned links; int i; if (curdev->have_resources) { @@ -140,7 +140,7 @@ static void read_resources(struct bus *bus) curdev->have_resources = 1; /* Read in subtractive resources behind the current device */ links = 0; - for (i = 0; i < curdev->resources; i++) { + for(i = 0; i < curdev->resources; i++) { struct resource *resource; unsigned link; resource = &curdev->resource[i]; @@ -149,18 +149,17 @@ static void read_resources(struct bus *bus) link = IOINDEX_SUBTRACTIVE_LINK(resource->index); if (link > MAX_LINKS) { printk_err("%s subtractive index on link: %d\n", - dev_path(curdev), link); + dev_path(curdev), link); continue; } if (!(links & (1 << link))) { links |= (1 << link); - read_resources(&curdev->link[resource->index]); - + read_resources(&curdev->link[link]); } } } printk_spew("%s read_resources bus %d link: %d done\n", - dev_path(bus->dev), bus->secondary, bus->link); + dev_path(bus->dev), bus->secondary, bus->link); } struct pick_largest_state { @@ -181,6 +180,7 @@ static void pick_largest_resource(void *gp, state->seen_last = 1; return; } + if (resource->flags & IORESOURCE_FIXED ) return; //skip it if (last && ( (last->align < resource->align) || ((last->align == resource->align) && @@ -191,9 +191,10 @@ static void pick_largest_resource(void *gp, return; } if (!state->result || - (state->result->align < resource->align) || - ((state->result->align == resource->align) && - (state->result->size < resource->size))) { + (state->result->align < resource->align) || + ((state->result->align == resource->align) && + (state->result->size < resource->size))) + { state->result_dev = dev; state->result = resource; } @@ -258,10 +259,10 @@ void compute_allocate_resource( base = bridge->base; printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d\n", - dev_path(bus->dev), - (bridge->flags & IORESOURCE_IO)? "io": - (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran); + dev_path(bus->dev), + (bridge->flags & IORESOURCE_IO)? "io": + (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran); /* We want different minimum alignments for different kinds of * resources. These minimums are not device type specific @@ -283,7 +284,7 @@ void compute_allocate_resource( /* Walk through all the devices on the current bus and * compute the addresses. */ - while ((dev = largest_resource(bus, &resource, type_mask, type))) { + while((dev = largest_resource(bus, &resource, type_mask, type))) { resource_t size; /* Do NOT I repeat do not ignore resources which have zero size. * If they need to be ignored dev->read_resources should not even @@ -301,9 +302,11 @@ void compute_allocate_resource( if (align < min_align) { align = min_align; } + if (resource->flags & IORESOURCE_FIXED) { continue; } + /* Propogate the resource limit to the bridge register */ if (bridge->limit > resource->limit) { bridge->limit = resource->limit; @@ -338,13 +341,14 @@ void compute_allocate_resource( resource->flags &= ~IORESOURCE_STORED; base += size; - printk_spew("%s %02x * [0x%08Lx - 0x%08Lx] %s\n", - dev_path(dev), - resource->index, - resource->base, - resource->base + resource->size - 1, - (resource->flags & IORESOURCE_IO)? "io": - (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem"); + printk_spew( + "%s %02x * [0x%08Lx - 0x%08Lx] %s\n", + dev_path(dev), + resource->index, + resource->base, + resource->base + resource->size - 1, + (resource->flags & IORESOURCE_IO)? "io": + (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem"); } } /* A pci bridge resource does not need to be a power @@ -356,15 +360,16 @@ void compute_allocate_resource( bridge->size = round(base, bridge->gran) - bridge->base; printk_spew("%s compute_allocate_%s: base: %08Lx size: %08Lx align: %d gran: %d done\n", - dev_path(bus->dev), - (bridge->flags & IORESOURCE_IO)? "io": - (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", - base, bridge->size, bridge->align, bridge->gran); + dev_path(bus->dev), + (bridge->flags & IORESOURCE_IO)? "io": + (bridge->flags & IORESOURCE_PREFETCH)? "prefmem" : "mem", + base, bridge->size, bridge->align, bridge->gran); } #if CONFIG_CONSOLE_VGA == 1 + device_t vga_pri = 0; static void allocate_vga_resource(void) { @@ -377,10 +382,11 @@ static void allocate_vga_resource(void) bus = 0; vga = 0; vga_onboard = 0; - for (dev = all_devices; dev; dev = dev->next) { + for(dev = all_devices; dev; dev = dev->next) { if (!dev->enabled) continue; if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) && - ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) { + ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) + { if (!vga) { if (dev->on_mainboard) { vga_onboard = dev; @@ -398,14 +404,15 @@ static void allocate_vga_resource(void) } if (vga) { - // vga is first add on card or the only onboard vga + /* vga is first add on card or the only onboard vga */ printk_debug("Allocating VGA resource %s\n", dev_path(vga)); + /* All legacy VGA cards have MEM & I/O space registers */ vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO); vga_pri = vga; bus = vga->bus; } /* Now walk up the bridges setting the VGA enable */ - while (bus) { + while(bus) { printk_debug("Setting PCI_BRIDGE_CTL_VGA for bridge %s\n", dev_path(bus->dev)); bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA; @@ -435,7 +442,7 @@ void assign_resources(struct bus *bus) printk_spew("%s assign_resources, bus %d link: %d\n", dev_path(bus->dev), bus->secondary, bus->link); - for (curdev = bus->children; curdev; curdev = curdev->sibling) { + for(curdev = bus->children; curdev; curdev = curdev->sibling) { if (!curdev->enabled || !curdev->resources) { continue; } @@ -480,6 +487,70 @@ void enable_resources(struct device *dev) dev->ops->enable_resources(dev); } +/** + * @brief Reset all of the devices a bus + * + * Reset all of the devices on a bus and clear the bus's reset_needed flag. + * + * @param bus pointer to the bus structure + * + * @return 1 if the bus was successfully reset, 0 otherwise. + * + */ +int reset_bus(struct bus *bus) +{ + device_t dev; + if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) + { + bus->dev->ops->reset_bus(bus); + bus->reset_needed = 0; + return 1; + } + return 0; +} + +/** + * @brief Scan for devices on a bus. + * + * If there are bridges on the bus, recursively scan the buses behind the bridges. + * If the setting up and tuning of the bus causes a reset to be required, + * reset the bus and scan it again. + * + * @param bus pointer to the bus device + * @param max current bus number + * + * @return The maximum bus number found, after scanning all subordinate busses + */ +unsigned int scan_bus(device_t bus, unsigned int max) +{ + unsigned int new_max; + int do_scan_bus; + if ( !bus || + !bus->enabled || + !bus->ops || + !bus->ops->scan_bus) + { + return max; + } + do_scan_bus = 1; + while(do_scan_bus) { + int link; + new_max = bus->ops->scan_bus(bus, max); + do_scan_bus = 0; + for(link = 0; link < bus->links; link++) { + if (bus->link[link].reset_needed) { + if (reset_bus(&bus->link[link])) { + do_scan_bus = 1; + } else { + bus->bus->reset_needed = 1; + } + } + } + } + return new_max; +} + + /** * @brief Determine the existence of devices and extend the device tree. * @@ -515,7 +586,7 @@ void dev_enumerate(void) printk_err("dev_root missing scan_bus operation"); return; } - subordinate = root->ops->scan_bus(root, 0); + subordinate = scan_bus(root, 0); printk_info("done\n"); } @@ -613,18 +684,19 @@ void dev_initialize(void) struct device *dev; printk_info("Initializing devices...\n"); - - for (dev = all_devices; dev; dev = dev->next) { - if (dev->enabled && !dev->initialized && - dev->ops && dev->ops->init) - { - if(dev->path.type == DEVICE_PATH_I2C) - printk_debug("smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link ); - printk_debug("%s init\n", dev_path(dev)); - dev->initialized = 1; - dev->ops->init(dev); - } - } + for(dev = all_devices; dev; dev = dev->next) { + if (dev->enabled && !dev->initialized && + dev->ops && dev->ops->init) + { + if (dev->path.type == DEVICE_PATH_I2C) { + printk_debug("smbus: %s[%d]->", + dev_path(dev->bus->dev), dev->bus->link); + } + printk_debug("%s init\n", dev_path(dev)); + dev->initialized = 1; + dev->ops->init(dev); + } + } printk_info("Devices initialized\n"); } diff --git a/src/devices/device_util.c b/src/devices/device_util.c index a19a878b47..fa2adaef4f 100644 --- a/src/devices/device_util.c +++ b/src/devices/device_util.c @@ -16,7 +16,7 @@ device_t find_dev_path(struct bus *parent, struct device_path *path) { device_t child; - for (child = parent->children; child; child = child->sibling) { + for(child = parent->children; child; child = child->sibling) { if (path_eq(path, &child->path)) { break; } @@ -178,6 +178,14 @@ const char *dev_path(device_t dev) return buffer; } +const char *bus_path(struct bus *bus) +{ + static char buffer[BUS_PATH_MAX]; + sprintf(buffer, "%s,%d", + dev_path(bus->dev), bus->link); + return buffer; +} + int path_eq(struct device_path *path1, struct device_path *path2) { int equal = 0; @@ -390,12 +398,30 @@ resource_t resource_max(struct resource *resource) } /** + * @brief return the resource type of a resource + * @param resource the resource type to decode. + */ +const char *resource_type(struct resource *resource) +{ + static char buffer[RESOURCE_TYPE_MAX]; + sprintf(buffer, "%s%s%s%s", + ((resource->flags & IORESOURCE_READONLY)? "ro": ""), + ((resource->flags & IORESOURCE_PREFETCH)? "pref":""), + ((resource->flags == 0)? "unused": + (resource->flags & IORESOURCE_IO)? "io": + (resource->flags & IORESOURCE_DRQ)? "drq": + (resource->flags & IORESOURCE_IRQ)? "irq": + (resource->flags & IORESOURCE_MEM)? "mem":"??????"), + ((resource->flags & IORESOURCE_PCI64)?"64":"")); + return buffer; +} + +/** * @brief print the resource that was just stored. * @param dev the device the stored resorce lives on * @param resource the resource that was just stored. */ -void report_resource_stored(device_t dev, struct resource *resource, - const char *comment) +void report_resource_stored(device_t dev, struct resource *resource, const char *comment) { if (resource->flags & IORESOURCE_STORED) { unsigned char buf[10]; @@ -407,18 +433,12 @@ void report_resource_stored(device_t dev, struct resource *resource, sprintf(buf, "bus %d ", dev->link[0].secondary); } printk_debug( - "%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s%s\n", + "%s %02x <- [0x%010Lx - 0x%010Lx] %s%s%s\n", dev_path(dev), resource->index, base, end, buf, - (resource->flags & IORESOURCE_PREFETCH) ? "pref" : "", - (resource->flags & IORESOURCE_IO)? "io": - (resource->flags & IORESOURCE_DRQ)? "drq": - (resource->flags & IORESOURCE_IRQ)? "irq": - (resource->flags & IORESOURCE_READONLY)? "rom": - (resource->flags & IORESOURCE_MEM)? "mem": - "????", + resource_type(resource), comment); } } @@ -473,3 +493,29 @@ void search_global_resources( } } } + +void dev_set_enabled(device_t dev, int enable) +{ + if (dev->enabled == enable) { + return; + } + dev->enabled = enable; + if (dev->ops && dev->ops->enable) { + dev->ops->enable(dev); + } + else if (dev->chip_ops && dev->chip_ops->enable_dev) { + dev->chip_ops->enable_dev(dev); + } +} + +void disable_children(struct bus *bus) +{ + device_t child; + for(child = bus->children; child; child = child->sibling) { + int link; + for(link = 0; link < child->links; link++) { + disable_children(&child->link[link]); + } + dev_set_enabled(child, 0); + } +} diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index 80c621ed79..a30c8f6a8d 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -9,7 +9,7 @@ #include <part/fallback_boot.h> #define OPT_HT_LINK 0 - + #if OPT_HT_LINK == 1 #include "../northbridge/amd/amdk8/cpu_rev.c" #endif @@ -19,17 +19,37 @@ static device_t ht_scan_get_devs(device_t *old_devices) device_t first, last; first = *old_devices; last = first; + /* Extract the chain of devices to (first through last) + * for the next hypertransport device. + */ while(last && last->sibling && (last->sibling->path.type == DEVICE_PATH_PCI) && - (last->sibling->path.u.pci.devfn > last->path.u.pci.devfn)) { + (last->sibling->path.u.pci.devfn > last->path.u.pci.devfn)) + { last = last->sibling; } if (first) { + device_t child; + /* Unlink the chain from the list of old devices */ *old_devices = last->sibling; last->sibling = 0; + + /* Now add the device to the list of devices on the bus. + */ + /* Find the last child of our parent */ + for(child = first->bus->children; child && child->sibling; ) { + child = child->sibling; + } + /* Place the chain on the list of children of their parent. */ + if (child) { + child->sibling = first; + } else { + first->bus->children = first; + } } return first; } + #if OPT_HT_LINK == 1 static unsigned ht_read_freq_cap(device_t dev, unsigned pos) { @@ -43,30 +63,37 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos) if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == PCI_DEVICE_ID_AMD_8131_PCIX)) { freq_cap &= ~(1 << HT_FREQ_800Mhz); - } else + } /* AMD 8151 Errata 23 */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == PCI_DEVICE_ID_AMD_8151_SYSCTRL)) { freq_cap &= ~(1 << HT_FREQ_800Mhz); - } else + } /* AMD K8 Unsupported 1Ghz? */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) { +#if K8_HT_FREQ_1G_SUPPORT == 1 if (is_cpu_pre_e0()) +#endif + { freq_cap &= ~(1 << HT_FREQ_1000Mhz); + } + } return freq_cap; } +#endif -struct prev_link { +struct ht_link { struct device *dev; unsigned pos; - unsigned char config_off, freq_off, freq_cap_off; + unsigned char ctrl_off, config_off, freq_off, freq_cap_off; }; -static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos) +static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos) { static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 }; static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 }; + struct ht_link cur[1]; unsigned present_width_cap, upstream_width_cap; unsigned present_freq_cap, upstream_freq_cap; unsigned ln_present_width_in, ln_upstream_width_in; @@ -78,13 +105,30 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos) /* Set the hypertransport link width and frequency */ reset_needed = 0; - linkb_to_host = (pci_read_config16(dev, pos + PCI_CAP_FLAGS) >> 10) & 1; - + /* See which side of the device our previous write to + * set the unitid came from. + */ + cur->dev = dev; + cur->pos = pos; + linkb_to_host = (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1; + if (!linkb_to_host) { + cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0; + cur->config_off = PCI_HT_CAP_SLAVE_WIDTH0; + cur->freq_off = PCI_HT_CAP_SLAVE_FREQ0; + cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0; + } + else { + cur->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1; + cur->config_off = PCI_HT_CAP_SLAVE_WIDTH1; + cur->freq_off = PCI_HT_CAP_SLAVE_FREQ1; + cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; + } +#if OPT_HT_LINK == 1 /* Read the capabilities */ - present_freq_cap = ht_read_freq_cap(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ_CAP1: PCI_HT_CAP_SLAVE_FREQ_CAP0)); + present_freq_cap = ht_read_freq_cap(cur->dev, cur->pos + cur->freq_cap_off); upstream_freq_cap = ht_read_freq_cap(prev->dev, prev->pos + prev->freq_cap_off); - present_width_cap = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0)); - upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off); + present_width_cap = pci_read_config8(cur->dev, cur->pos + cur->config_off); + upstream_width_cap = pci_read_config8(prev->dev, prev->pos + prev->config_off); /* Calculate the highest useable frequency */ freq = log2(present_freq_cap & upstream_freq_cap); @@ -107,87 +151,130 @@ static int ht_setup_link(struct prev_link *prev, device_t dev, unsigned pos) present_width |= pow2_to_link_width[ln_upstream_width_out]; /* Set the current device */ - old_freq = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0)); + old_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off); + old_freq &= 0x0f; if (freq != old_freq) { - pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_FREQ1:PCI_HT_CAP_SLAVE_FREQ0), freq); + unsigned new_freq; + pci_write_config8(cur->dev, cur->pos + cur->freq_off, freq); reset_needed = 1; printk_spew("HyperT FreqP old %x new %x\n",old_freq,freq); + new_freq = pci_read_config8(cur->dev, cur->pos + cur->freq_off); + new_freq &= 0x0f; + if (new_freq != freq) { + printk_err("%s Hypertransport frequency would not set wanted: %x got: %x\n", + dev_path(dev), freq, new_freq); + } } - old_width = pci_read_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1); + old_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1); if (present_width != old_width) { - pci_write_config8(dev, pos + (linkb_to_host ? PCI_HT_CAP_SLAVE_WIDTH1: PCI_HT_CAP_SLAVE_WIDTH0) + 1, present_width); + unsigned new_width; + pci_write_config8(cur->dev, cur->pos + cur->config_off + 1, + present_width); reset_needed = 1; printk_spew("HyperT widthP old %x new %x\n",old_width, present_width); + new_width = pci_read_config8(cur->dev, cur->pos + cur->config_off + 1); + if (new_width != present_width) { + printk_err("%s Hypertransport width would not set wanted: %x got: %x\n", + dev_path(dev), present_width, new_width); + } } /* Set the upstream device */ old_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off); old_freq &= 0x0f; if (freq != old_freq) { + unsigned new_freq; pci_write_config8(prev->dev, prev->pos + prev->freq_off, freq); reset_needed = 1; printk_spew("HyperT freqU old %x new %x\n", old_freq, freq); + new_freq = pci_read_config8(prev->dev, prev->pos + prev->freq_off); + new_freq &= 0x0f; + if (new_freq != freq) { + printk_err("%s Hypertransport frequency would not set wanted: %x got: %x\n", + dev_path(prev->dev), freq, new_freq); + } } old_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1); if (upstream_width != old_width) { + unsigned new_width; pci_write_config8(prev->dev, prev->pos + prev->config_off + 1, upstream_width); reset_needed = 1; printk_spew("HyperT widthU old %x new %x\n", old_width, upstream_width); + new_width = pci_read_config8(prev->dev, prev->pos + prev->config_off + 1); + if (new_width != upstream_width) { + printk_err("%s Hypertransport width would not set wanted: %x got: %x\n", + dev_path(prev->dev), upstream_width, new_width); + } } +#endif - /* Remember the current link as the previous link */ - prev->dev = dev; - prev->pos = pos; - if(linkb_to_host) { - prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0; - prev->freq_off = PCI_HT_CAP_SLAVE_FREQ0; - prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0; - } - else { - prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1; - prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1; - prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; - } + /* Remember the current link as the previous link, + * But look at the other offsets. + */ + prev->dev = cur->dev; + prev->pos = cur->pos; + if (cur->ctrl_off == PCI_HT_CAP_SLAVE_CTRL0) { + prev->ctrl_off = PCI_HT_CAP_SLAVE_CTRL1; + prev->config_off = PCI_HT_CAP_SLAVE_WIDTH1; + prev->freq_off = PCI_HT_CAP_SLAVE_FREQ1; + prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1; + } else { + prev->ctrl_off = PCI_HT_CAP_SLAVE_CTRL0; + prev->config_off = PCI_HT_CAP_SLAVE_WIDTH0; + prev->freq_off = PCI_HT_CAP_SLAVE_FREQ0; + prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0; + } return reset_needed; } -#endif static unsigned ht_lookup_slave_capability(struct device *dev) { unsigned pos; pos = 0; - switch(dev->hdr_type & 0x7f) { - case PCI_HEADER_TYPE_NORMAL: - case PCI_HEADER_TYPE_BRIDGE: - pos = PCI_CAPABILITY_LIST; - break; - } - if (pos > PCI_CAP_LIST_NEXT) { - pos = pci_read_config8(dev, pos); - } - while(pos != 0) { /* loop through the linked list */ - uint8_t cap; - cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID); - printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos); - if (cap == PCI_CAP_ID_HT) { + do { + pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos); + if (pos) { unsigned flags; flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); - printk_spew("flags: 0x%04x\n", (unsigned)flags); + printk_spew("flags: 0x%04x\n", flags); if ((flags >> 13) == 0) { - /* Entry is a Slave secondary, success...*/ + /* Entry is a Slave secondary, success... */ break; } } - pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT); - } + } while(pos); return pos; } static void ht_collapse_early_enumeration(struct bus *bus) { unsigned int devfn; + struct ht_link prev; + unsigned ctrl; + + /* Initialize the hypertransport enumeration state */ + prev.dev = bus->dev; + prev.pos = bus->cap; + prev.ctrl_off = PCI_HT_CAP_HOST_CTRL; + prev.config_off = PCI_HT_CAP_HOST_WIDTH; + prev.freq_off = PCI_HT_CAP_HOST_FREQ; + prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP; + + /* Wait until the link initialization is complete */ + do { + ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + /* Is this the end of the hypertransport chain */ + if (ctrl & (1 << 6)) { + return; + } + /* Has the link failed? */ + if (ctrl & (1 << 4)) { + return; + } + } while((ctrl & (1 << 5)) == 0); + /* Spin through the devices and collapse any early * hypertransport enumeration. @@ -200,21 +287,10 @@ static void ht_collapse_early_enumeration(struct bus *bus) dummy.path.type = DEVICE_PATH_PCI; dummy.path.u.pci.devfn = devfn; id = pci_read_config32(&dummy, PCI_VENDOR_ID); - if (id == 0xffffffff || id == 0x00000000 || - id == 0x0000ffff || id == 0xffff0000) { + if ( (id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000)) { continue; } - -#if 0 -#if CK804_DEVN_BASE==0 - //CK804 workaround: - // CK804 UnitID changes not use - if(id == 0x005e10de) { - break; - } -#endif -#endif - dummy.vendor = id & 0xffff; dummy.device = (id >> 16) & 0xffff; dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE); @@ -232,15 +308,13 @@ static void ht_collapse_early_enumeration(struct bus *bus) } } -unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) +unsigned int hypertransport_scan_chain(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max) { - unsigned next_unitid, last_unitid, previous_unitid; - device_t old_devices, dev, func, *chain_last; + unsigned next_unitid, last_unitid; + device_t old_devices, dev, func; unsigned min_unitid = 1; -#if OPT_HT_LINK == 1 - int reset_needed; - struct prev_link prev; -#endif + struct ht_link prev; /* Restore the hypertransport chain to it's unitialized state */ ht_collapse_early_enumeration(bus); @@ -248,71 +322,48 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) /* See which static device nodes I have */ old_devices = bus->children; bus->children = 0; - chain_last = &bus->children; /* Initialize the hypertransport enumeration state */ -#if OPT_HT_LINK == 1 - reset_needed = 0; prev.dev = bus->dev; prev.pos = bus->cap; + prev.ctrl_off = PCI_HT_CAP_HOST_CTRL; prev.config_off = PCI_HT_CAP_HOST_WIDTH; prev.freq_off = PCI_HT_CAP_HOST_FREQ; prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP; -#endif /* If present assign unitid to a hypertransport chain */ last_unitid = min_unitid -1; next_unitid = min_unitid; do { - uint32_t id, class; - uint8_t hdr_type; - unsigned pos; + uint8_t pos; uint16_t flags; unsigned count, static_count; + unsigned ctrl; - previous_unitid = last_unitid; last_unitid = next_unitid; - /* Get setup the device_structure */ + /* Wait until the link initialization is complete */ + do { + ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off); + /* Is this the end of the hypertransport chain? + * Has the link failed? + * If so further scanning is pointless. + */ + if (ctrl & ((1 << 6) | (1 << 4))) { + goto end_of_chain; + } + } while((ctrl & (1 << 5)) == 0); + + + /* Get and setup the device_structure */ dev = ht_scan_get_devs(&old_devices); - if (!dev) { - struct device dummy; - dummy.bus = bus; - dummy.path.type = DEVICE_PATH_PCI; - dummy.path.u.pci.devfn = 0; - id = pci_read_config32(&dummy, PCI_VENDOR_ID); - /* If the chain is fully enumerated quit */ - if (id == 0xffffffff || id == 0x00000000 || - id == 0x0000ffff || id == 0xffff0000) { - break; - } - dev = alloc_dev(bus, &dummy.path); - } - else { - /* Add this device to the pci bus chain */ - *chain_last = dev; - /* Run the magice enable sequence for the device */ - if (dev->chip_ops && dev->chip_ops->enable_dev) { - dev->chip_ops->enable_dev(dev); - } - /* Now read the vendor and device id */ - id = pci_read_config32(dev, PCI_VENDOR_ID); - - /* If the chain is fully enumerated quit */ - if (id == 0xffffffff || id == 0x00000000 || - id == 0x0000ffff || id == 0xffff0000) { - if (dev->enabled) { - printk_info("Disabling static device: %s\n", - dev_path(dev)); - dev->enabled = 0; - } - break; - } - } - /* Update the device chain tail */ - for(func = dev; func; func = func->sibling) { - chain_last = &func->sibling; + /* See if a device is present and setup the + * device structure. + */ + dev = pci_probe_dev(dev, bus, 0); + if (!dev || !dev->enabled) { + break; } /* Find the hypertransport link capability */ @@ -323,20 +374,29 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) break; } - /* Update the Unitid of the current device */ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); + + /* If the devices has a unitid set and is at devfn 0 we are done. + * This can happen with shadow hypertransport devices, + * or if we have reached the bottom of a + * hypertransport device chain. + */ + if (flags & 0x1f) { + break; + } + flags &= ~0x1f; /* mask out base Unit ID */ #if CK804_DEVN_BASE==0 - if(id == 0x005e10de) { - next_unitid = 0; - } - else { + if((dev->vendor == 0x10de) && (dev->device == 0x005e)) { + next_unitid = 0; + } + else { #endif - flags |= next_unitid & 0x1f; - pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); + flags |= next_unitid & 0x1f; + pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); #if CK804_DEVN_BASE==0 - } + } #endif /* Update the Unitd id in the device structure */ @@ -347,17 +407,6 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) - (dev->path.u.pci.devfn >> 3) + 1; } - /* Read the rest of the pci configuration information */ - hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); - class = pci_read_config32(dev, PCI_CLASS_REVISION); - - /* Store the interesting information in the device structure */ - dev->vendor = id & 0xffff; - dev->device = (id >> 16) & 0xffff; - dev->hdr_type = hdr_type; - /* class code, the upper 3 bytes of PCI_CLASS_REVISION */ - dev->class = class >> 8; - /* Compute the number of unitids consumed */ count = (flags >> 5) & 0x1f; /* get unit count */ printk_spew("%s count: %04x static_count: %04x\n", @@ -369,36 +418,83 @@ unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max) /* Update the Unitid of the next device */ next_unitid += count; -#if OPT_HT_LINK == 1 /* Setup the hypetransport link */ - reset_needed |= ht_setup_link(&prev, dev, pos); -#endif + bus->reset_needed |= ht_setup_link(&prev, dev, pos); printk_debug("%s [%04x/%04x] %s next_unitid: %04x\n", dev_path(dev), dev->vendor, dev->device, (dev->enabled? "enabled": "disabled"), next_unitid); + #if CK804_DEVN_BASE==0 - if(id == 0x005e10de) { - break; // CK804 can not change unitid, so it only can be alone in the link - } + if ((dev->vendor == 0x10de) && (dev->device == 0x005e)) { + break; // CK804 can not change unitid, so it only can be alone in the link + } #endif - } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); - + } while((last_unitid != next_unitid) && (next_unitid <= (max_devfn >> 3))); + end_of_chain: #if OPT_HT_LINK == 1 -#if HAVE_HARD_RESET == 1 - if(reset_needed) { + if(bus->reset_needed) { printk_info("HyperT reset needed\n"); - hard_reset(); } else { printk_debug("HyperT reset not needed\n"); } #endif -#endif if (next_unitid > 0x1f) { next_unitid = 0x1f; } - return pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max); + + /* Die if any leftover Static devices are are found. + * There's probably a problem in the Config.lb. + */ + if(old_devices) { + device_t left; + for(left = old_devices; left; left = left->sibling) { + printk_debug("%s\n", dev_path(left)); + } + die("Left over static devices. Check your Config.lb\n"); + } + + /* Now that nothing is overlapping it is safe to scan the + * children. + */ + max = pci_scan_bus(bus, 0x00, (next_unitid << 3)|7, max); + return max; +} + +/** + * @brief Scan a PCI bridge and the buses behind the bridge. + * + * Determine the existence of buses behind the bridge. Set up the bridge + * according to the result of the scan. + * + * This function is the default scan_bus() method for PCI bridge devices. + * + * @param dev pointer to the bridge device + * @param max the highest bus number assgined up to now + * + * @return The maximum bus number found, after scanning all subordinate busses + */ +unsigned int ht_scan_bridge(struct device *dev, unsigned int max) +{ + return do_pci_scan_bridge(dev, max, hypertransport_scan_chain); } + + +/** Default device operations for hypertransport bridges */ +static struct pci_operations ht_bus_ops_pci = { + .set_subsystem = 0, +}; + +struct device_operations default_ht_ops_bus = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = 0, + .scan_bus = ht_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, + .ops_pci = &ht_bus_ops_pci, +}; diff --git a/src/devices/pci_device.c b/src/devices/pci_device.c index 3f9a1cadae..f3f53f0688 100644 --- a/src/devices/pci_device.c +++ b/src/devices/pci_device.c @@ -21,8 +21,23 @@ #include <part/hard_reset.h> #include <part/fallback_boot.h> #include <delay.h> +#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1 +#include <device/hypertransport.h> +#endif +#if CONFIG_PCIX_PLUGIN_SUPPORT == 1 +#include <device/pcix.h> +#endif +#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1 +#include <device/pciexp.h> +#endif +#if CONFGI_AGP_PLUGIN_SUPPORT == 1 +#include <device/agp.h> +#endif +#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1 +#include <device/cardbus.h> +#endif -static uint8_t pci_moving_config8(struct device *dev, unsigned reg) +uint8_t pci_moving_config8(struct device *dev, unsigned reg) { uint8_t value, ones, zeroes; value = pci_read_config8(dev, reg); @@ -38,7 +53,7 @@ static uint8_t pci_moving_config8(struct device *dev, unsigned reg) return ones ^ zeroes; } -static uint16_t pci_moving_config16(struct device *dev, unsigned reg) +uint16_t pci_moving_config16(struct device *dev, unsigned reg) { uint16_t value, ones, zeroes; value = pci_read_config16(dev, reg); @@ -54,7 +69,7 @@ static uint16_t pci_moving_config16(struct device *dev, unsigned reg) return ones ^ zeroes; } -static uint32_t pci_moving_config32(struct device *dev, unsigned reg) +uint32_t pci_moving_config32(struct device *dev, unsigned reg) { uint32_t value, ones, zeroes; value = pci_read_config32(dev, reg); @@ -70,29 +85,53 @@ static uint32_t pci_moving_config32(struct device *dev, unsigned reg) return ones ^ zeroes; } -unsigned pci_find_capability(device_t dev, unsigned cap) +unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last) { unsigned pos; + unsigned status; + unsigned reps = 48; pos = 0; + status = pci_read_config16(dev, PCI_STATUS); + if (!(status & PCI_STATUS_CAP_LIST)) { + return 0; + } switch(dev->hdr_type & 0x7f) { case PCI_HEADER_TYPE_NORMAL: case PCI_HEADER_TYPE_BRIDGE: pos = PCI_CAPABILITY_LIST; break; + case PCI_HEADER_TYPE_CARDBUS: + pos = PCI_CB_CAPABILITY_LIST; + break; + default: + return 0; } - if (pos > PCI_CAP_LIST_NEXT) { - pos = pci_read_config8(dev, pos); - } - while (pos != 0) { /* loop through the linked list */ + pos = pci_read_config8(dev, pos); + while(reps-- && (pos >= 0x40)) { /* loop through the linked list */ int this_cap; + pos &= ~3; this_cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID); - if (this_cap == cap) { + printk_spew("Capability: 0x%02x @ 0x%02x\n", cap, pos); + if (this_cap == 0xff) { + break; + } + if (!last && (this_cap == cap)) { return pos; } + if (last == pos) { + last = 0; + } + pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT); } return 0; } +unsigned pci_find_capability(device_t dev, unsigned cap) +{ + return pci_find_next_capability(dev, cap, 0); + +} + /** Given a device and register, read the size of the BAR for that register. * @param dev Pointer to the device structure * @param resource Pointer to the resource structure @@ -118,7 +157,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) /* If it is a 64bit resource look at the high half as well */ if (((attr & PCI_BASE_ADDRESS_SPACE_IO) == 0) && - ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64)) + ((attr & PCI_BASE_ADDRESS_MEM_LIMIT_MASK) == PCI_BASE_ADDRESS_MEM_LIMIT_64)) { /* Find the high bits that move */ moving |= ((resource_t)pci_moving_config32(dev, index + 4)) << 32; @@ -134,7 +173,7 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) if (moving) { resource->size = 1; resource->align = resource->gran = 0; - while (!(moving & resource->size)) { + while(!(moving & resource->size)) { resource->size <<= 1; resource->align += 1; resource->gran += 1; @@ -154,17 +193,20 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) */ if (moving == 0) { if (value != 0) { - printk_debug("%s register %02x(%08x), read-only ignoring it\n", - dev_path(dev), index, value); + printk_debug( + "%s register %02x(%08x), read-only ignoring it\n", + dev_path(dev), index, value); } resource->flags = 0; - } else if (attr & PCI_BASE_ADDRESS_SPACE_IO) { + } + else if (attr & PCI_BASE_ADDRESS_SPACE_IO) { /* An I/O mapped base address */ attr &= PCI_BASE_ADDRESS_IO_ATTR_MASK; resource->flags |= IORESOURCE_IO; /* I don't want to deal with 32bit I/O resources */ resource->limit = 0xffff; - } else { + } + else { /* A Memory mapped base address */ attr &= PCI_BASE_ADDRESS_MEM_ATTR_MASK; resource->flags |= IORESOURCE_MEM; @@ -175,14 +217,17 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_32) { /* 32bit limit */ resource->limit = 0xffffffffUL; - } else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) { + } + else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_1M) { /* 1MB limit */ resource->limit = 0x000fffffUL; - } else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) { + } + else if (attr == PCI_BASE_ADDRESS_MEM_LIMIT_64) { /* 64bit limit */ resource->limit = 0xffffffffffffffffULL; resource->flags |= IORESOURCE_PCI64; - } else { + } + else { /* Invalid value */ resource->flags = 0; } @@ -194,18 +239,15 @@ struct resource *pci_get_resource(struct device *dev, unsigned long index) #if 0 if (resource->flags) { printk_debug("%s %02x ->", - dev_path(dev), resource->index); + dev_path(dev), resource->index); printk_debug(" value: 0x%08Lx zeroes: 0x%08Lx ones: 0x%08Lx attr: %08lx\n", - value, zeroes, ones, attr); + value, zeroes, ones, attr); printk_debug( - "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s%s\n ", + "%s %02x -> size: 0x%08Lx max: 0x%08Lx %s\n ", dev_path(dev), resource->index, resource->size, resource->limit, - (resource->flags == 0) ? "unused": - (resource->flags & IORESOURCE_IO)? "io": - (resource->flags & IORESOURCE_PREFETCH)? "prefmem": "mem", - (resource->flags & IORESOURCE_PCI64)?"64":""); + resource_type(resource)); } #endif @@ -272,32 +314,32 @@ static void pci_get_rom_resource(struct device *dev, unsigned long index) resource->flags |= IORESOURCE_MEM | IORESOURCE_READONLY | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; } + + compact_resources(dev); } /** Read the base address registers for a given device. * @param dev Pointer to the dev structure * @param howmany How many registers to read (6 for device, 2 for bridge) */ -static void pci_read_bases(struct device *dev, unsigned int howmany, unsigned long rom) +static void pci_read_bases(struct device *dev, unsigned int howmany) { unsigned long index; - for (index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) { + for(index = PCI_BASE_ADDRESS_0; (index < PCI_BASE_ADDRESS_0 + (howmany << 2)); ) { struct resource *resource; resource = pci_get_resource(dev, index); index += (resource->flags & IORESOURCE_PCI64)?8:4; } - if (rom) - pci_get_rom_resource(dev, rom); compact_resources(dev); } static void pci_set_resource(struct device *dev, struct resource *resource); -static void pci_record_bridge_resource( struct device *dev, resource_t moving, - unsigned index, unsigned long mask, - unsigned long type) +static void pci_record_bridge_resource( + struct device *dev, resource_t moving, + unsigned index, unsigned long mask, unsigned long type) { /* Initiliaze the constraints on the current bus */ struct resource *resource; @@ -346,8 +388,10 @@ static void pci_bridge_read_bases(struct device *dev) moving = moving_base & moving_limit; /* Initialize the io space constraints on the current bus */ - pci_record_bridge_resource(dev, moving, PCI_IO_BASE, - IORESOURCE_IO, IORESOURCE_IO); + pci_record_bridge_resource( + dev, moving, PCI_IO_BASE, + IORESOURCE_IO, IORESOURCE_IO); + /* See if the bridge prefmem resources are implemented */ moving_base = ((resource_t)pci_moving_config16(dev, PCI_PREF_MEMORY_BASE)) << 16; @@ -358,9 +402,11 @@ static void pci_bridge_read_bases(struct device *dev) moving = moving_base & moving_limit; /* Initiliaze the prefetchable memory constraints on the current bus */ - pci_record_bridge_resource(dev, moving, PCI_PREF_MEMORY_BASE, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM | IORESOURCE_PREFETCH); + pci_record_bridge_resource( + dev, moving, PCI_PREF_MEMORY_BASE, + IORESOURCE_MEM | IORESOURCE_PREFETCH, + IORESOURCE_MEM | IORESOURCE_PREFETCH); + /* See if the bridge mem resources are implemented */ moving_base = ((uint32_t)pci_moving_config16(dev, PCI_MEMORY_BASE)) << 16; @@ -369,26 +415,25 @@ static void pci_bridge_read_bases(struct device *dev) moving = moving_base & moving_limit; /* Initialize the memory resources on the current bus */ - pci_record_bridge_resource(dev, moving, PCI_MEMORY_BASE, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM); + pci_record_bridge_resource( + dev, moving, PCI_MEMORY_BASE, + IORESOURCE_MEM | IORESOURCE_PREFETCH, + IORESOURCE_MEM); compact_resources(dev); } void pci_dev_read_resources(struct device *dev) { - uint32_t addr; - - pci_read_bases(dev, 6, PCI_ROM_ADDRESS); + pci_read_bases(dev, 6); + pci_get_rom_resource(dev, PCI_ROM_ADDRESS); } void pci_bus_read_resources(struct device *dev) { - uint32_t addr; - pci_bridge_read_bases(dev); - pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); + pci_read_bases(dev, 2); + pci_get_rom_resource(dev, PCI_ROM_ADDRESS1); } static void pci_set_resource(struct device *dev, struct resource *resource) @@ -397,8 +442,10 @@ static void pci_set_resource(struct device *dev, struct resource *resource) /* Make certain the resource has actually been set */ if (!(resource->flags & IORESOURCE_ASSIGNED)) { - printk_err("ERROR: %s %02x not allocated\n", - dev_path(dev), resource->index); + printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n", + dev_path(dev), resource->index, + resource_type(resource), + resource->size); return; } @@ -497,10 +544,10 @@ void pci_dev_set_resources(struct device *dev) last = &dev->resource[dev->resources]; - for (resource = &dev->resource[0]; resource < last; resource++) { + for(resource = &dev->resource[0]; resource < last; resource++) { pci_set_resource(dev, resource); } - for (link = 0; link < dev->links; link++) { + for(link = 0; link < dev->links; link++) { struct bus *bus; bus = &dev->link[link]; if (bus->children) { @@ -551,14 +598,10 @@ void pci_dev_enable_resources(struct device *dev) void pci_bus_enable_resources(struct device *dev) { uint16_t ctrl; - -#if CONFIG_CONSOLE_VGA == 1 /* enable IO in command register if there is VGA card * connected with (even it does not claim IO resource) */ if (dev->link[0].bridge_ctrl & PCI_BRIDGE_CTL_VGA) dev->command |= PCI_COMMAND_IO; -#endif - ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL); ctrl |= dev->link[0].bridge_ctrl; ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */ @@ -570,15 +613,27 @@ void pci_bus_enable_resources(struct device *dev) enable_childrens_resources(dev); } +void pci_bus_reset(struct bus *bus) +{ + unsigned ctl; + ctl = pci_read_config16(bus->dev, PCI_BRIDGE_CONTROL); + ctl |= PCI_BRIDGE_CTL_BUS_RESET; + pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl); + mdelay(10); + ctl &= ~PCI_BRIDGE_CTL_BUS_RESET; + pci_write_config16(bus->dev, PCI_BRIDGE_CONTROL, ctl); + delay(1); +} + void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device) { pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, ((device & 0xffff) << 16) | (vendor & 0xffff)); } -#if CONFIG_PCI_ROM_RUN == 1 void pci_dev_init(struct device *dev) { +#if CONFIG_PCI_ROM_RUN == 1 struct rom_header *rom, *ram; rom = pci_rom_probe(dev); @@ -589,8 +644,8 @@ void pci_dev_init(struct device *dev) return; run_bios(dev, ram); -} #endif +} /** Default device operation for PCI devices */ static struct pci_operations pci_dev_ops_pci = { @@ -601,11 +656,7 @@ struct device_operations default_pci_ops_dev = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, -#if CONFIG_PCI_ROM_RUN == 1 .init = pci_dev_init, -#else - .init = 0, -#endif .scan_bus = 0, .enable = 0, .ops_pci = &pci_dev_ops_pci, @@ -623,10 +674,79 @@ struct device_operations default_pci_ops_bus = { .init = 0, .scan_bus = pci_scan_bridge, .enable = 0, + .reset_bus = pci_bus_reset, .ops_pci = &pci_bus_ops_pci, }; /** + * @brief Detect the type of downstream bridge + * + * This function is a heuristic to detect which type + * of bus is downstream of a pci to pci bridge. This + * functions by looking for various capability blocks + * to figure out the type of downstream bridge. PCI-X + * PCI-E, and Hypertransport all seem to have appropriate + * capabilities. + * + * When only a PCI-Express capability is found the type + * is examined to see which type of bridge we have. + * + * @param dev + * + * @return appropriate bridge operations + */ +static struct device_operations *get_pci_bridge_ops(device_t dev) +{ + unsigned pos; + +#if CONFIG_PCIX_PLUGIN_SUPPORT == 1 + pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); + if (pos) { + printk_debug("%s subbordinate bus PCI-X\n", dev_path(dev)); + return &default_pcix_ops_bus; + } +#endif +#if CONFIG_AGP_PLUGIN_SUPPORT == 1 + /* How do I detect an PCI to AGP bridge? */ +#endif +#if CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT == 1 + pos = 0; + while((pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos))) { + unsigned flags; + flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); + if ((flags >> 13) == 1) { + /* Host or Secondary Interface */ + printk_debug("%s subbordinate bus Hypertransport\n", + dev_path(dev)); + return &default_ht_ops_bus; + } + } +#endif +#if CONFIG_PCIEXP_PLUGIN_SUPPORT == 1 + pos = pci_find_capability(dev, PCI_CAP_ID_PCIE); + if (pos) { + unsigned flags; + flags = pci_read_config16(dev, pos + PCI_EXP_FLAGS); + switch((flags & PCI_EXP_FLAGS_TYPE) >> 4) { + case PCI_EXP_TYPE_ROOT_PORT: + case PCI_EXP_TYPE_UPSTREAM: + case PCI_EXP_TYPE_DOWNSTREAM: + printk_debug("%s subbordinate bus PCI Express\n", + dev_path(dev)); + return &default_pciexp_ops_bus; + case PCI_EXP_TYPE_PCI_BRIDGE: + printk_debug("%s subbordinate PCI\n", + dev_path(dev)); + return &default_pci_ops_bus; + default: + break; + } + } +#endif + return &default_pci_ops_bus; +} + +/** * @brief Set up PCI device operation * * @@ -644,12 +764,12 @@ static void set_pci_ops(struct device *dev) /* Look through the list of setup drivers and find one for * this pci device */ - for (driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) { + for(driver = &pci_drivers[0]; driver != &epci_drivers[0]; driver++) { if ((driver->vendor == dev->vendor) && - (driver->device == dev->device)) + (driver->device == dev->device)) { dev->ops = driver->ops; - printk_debug("%s [%04x/%04x] %sops\n", + printk_spew("%s [%04x/%04x] %sops\n", dev_path(dev), driver->vendor, driver->device, (driver->ops->scan_bus?"bus ":"")); @@ -667,8 +787,13 @@ static void set_pci_ops(struct device *dev) case PCI_HEADER_TYPE_BRIDGE: if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) goto bad; - dev->ops = &default_pci_ops_bus; + dev->ops = get_pci_bridge_ops(dev); break; +#if CONFIG_CARDBUS_PLUGIN_SUPPORT == 1 + case PCI_HEADER_TYPE_CARDBUS: + dev->ops = &default_cardbus_ops_bus; + break; +#endif default: bad: if (dev->enabled) { @@ -682,6 +807,8 @@ static void set_pci_ops(struct device *dev) return; } + + /** * @brief See if we have already allocated a device structure for a given devfn. * @@ -702,7 +829,7 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) for(; *list; list = &(*list)->sibling) { if ((*list)->path.type != DEVICE_PATH_PCI) { printk_err("child %s not a pci device\n", - dev_path(*list)); + dev_path(*list)); continue; } if ((*list)->path.u.pci.devfn == devfn) { @@ -713,15 +840,15 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) break; } } - /* Just like alloc_dev add the device to the list of device on the bus. - * When the list of devices was formed we removed all of the parents - * children, and now we are interleaving static and dynamic devices in + /* Just like alloc_dev add the device to the list of device on the bus. + * When the list of devices was formed we removed all of the parents + * children, and now we are interleaving static and dynamic devices in * order on the bus. */ if (dev) { device_t child; /* Find the last child of our parent */ - for (child = dev->bus->children; child && child->sibling; ) { + for(child = dev->bus->children; child && child->sibling; ) { child = child->sibling; } /* Place the device on the list of children of it's parent. */ @@ -738,9 +865,128 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) /** * @brief Scan a PCI bus. * + * Determine the existence of a given PCI device. + * + * @param bus pointer to the bus structure + * @param devfn to look at + * + * @return The device structure for hte device (if found) + * or the NULL if no device is found. + */ +device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn) +{ + uint32_t id, class; + uint8_t hdr_type; + + /* Detect if a device is present */ + if (!dev) { + struct device dummy; + dummy.bus = bus; + dummy.path.type = DEVICE_PATH_PCI; + dummy.path.u.pci.devfn = devfn; + id = pci_read_config32(&dummy, PCI_VENDOR_ID); + /* Have we found somthing? + * Some broken boards return 0 if a slot is empty. + */ + if ( (id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000)) + { + printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id); + return NULL; + } + dev = alloc_dev(bus, &dummy.path); + } + else { + /* Enable/disable the device. Once we have + * found the device specific operations this + * operations we will disable the device with + * those as well. + * + * This is geared toward devices that have subfunctions + * that do not show up by default. + * + * If a device is a stuff option on the motherboard + * it may be absent and enable_dev must cope. + * + */ + /* Run the magice enable sequence for the device */ + if (dev->chip_ops && dev->chip_ops->enable_dev) { + dev->chip_ops->enable_dev(dev); + } + /* Now read the vendor and device id */ + id = pci_read_config32(dev, PCI_VENDOR_ID); + + + /* If the device does not have a pci id disable it. + * Possibly this is because we have already disabled + * the device. But this also handles optional devices + * that may not always show up. + */ + /* If the chain is fully enumerated quit */ + if ( (id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000)) + { + if (dev->enabled) { + printk_info("Disabling static device: %s\n", + dev_path(dev)); + dev->enabled = 0; + } + return dev; + } + } + /* Read the rest of the pci configuration information */ + hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + class = pci_read_config32(dev, PCI_CLASS_REVISION); + + /* Store the interesting information in the device structure */ + dev->vendor = id & 0xffff; + dev->device = (id >> 16) & 0xffff; + dev->hdr_type = hdr_type; + /* class code, the upper 3 bytes of PCI_CLASS_REVISION */ + dev->class = class >> 8; + + + /* Architectural/System devices always need to + * be bus masters. + */ + if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) { + dev->command |= PCI_COMMAND_MASTER; + } + /* Look at the vendor and device id, or at least the + * header type and class and figure out which set of + * configuration methods to use. Unless we already + * have some pci ops. + */ + set_pci_ops(dev); + + /* Now run the magic enable/disable sequence for the device */ + if (dev->ops && dev->ops->enable) { + dev->ops->enable(dev); + } + + + /* Display the device and error if we don't have some pci operations + * for it. + */ + printk_debug("%s [%04x/%04x] %s%s\n", + dev_path(dev), + dev->vendor, dev->device, + dev->enabled?"enabled": "disabled", + dev->ops?"" : " No operations" + ); + + return dev; +} + +/** + * @brief Scan a PCI bus. + * * Determine the existence of devices and bridges on a PCI bus. If there are * bridges on the bus, recursively scan the buses behind the bridges. * + * This function is the default scan_bus() method for the root device + * 'dev_root'. + * * @param bus pointer to the bus structure * @param min_devfn minimum devfn to look at in the scan usually 0x00 * @param max_devfn maximum devfn to look at in the scan usually 0xff @@ -748,11 +994,11 @@ static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) * * @return The maximum bus number found, after scanning all subordinate busses */ -unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn, - unsigned int max) +unsigned int pci_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, + unsigned int max) { unsigned int devfn; - device_t dev; device_t old_devices; device_t child; @@ -762,141 +1008,49 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf bus->children = 0; post_code(0x24); - /* probe all devices/functions on this bus with some optimization for * non-existence and single funcion devices */ for (devfn = min_devfn; devfn <= max_devfn; devfn++) { - uint32_t id, class; - uint8_t hdr_type; + device_t dev; /* First thing setup the device structure */ dev = pci_scan_get_dev(&old_devices, devfn); - - /* Detect if a device is present */ - if (!dev) { - struct device dummy; - dummy.bus = bus; - dummy.path.type = DEVICE_PATH_PCI; - dummy.path.u.pci.devfn = devfn; - id = pci_read_config32(&dummy, PCI_VENDOR_ID); - /* some broken boards return 0 if a slot is empty: */ - if ((id == 0xffffffff) || (id == 0x00000000) || - (id == 0x0000ffff) || (id == 0xffff0000)) - { - printk_spew("PCI: devfn 0x%x, bad id 0x%x\n", devfn, id); - if (PCI_FUNC(devfn) == 0x00) { - /* if this is a function 0 device and - * it is not present, - * skip to next device - */ - devfn += 0x07; - } - /* This function in a multi function device is - * not present, skip to the next function. - */ - continue; - } - dev = alloc_dev(bus, &dummy.path); - } - else { - /* Enable/disable the device. Once we have - * found the device specific operations this - * operations we will disable the device with - * those as well. - * - * This is geared toward devices that have subfunctions - * that do not show up by default. - * - * If a device is a stuff option on the motherboard - * it may be absent and enable_dev must cope. - * - */ - if (dev->chip_ops && dev->chip_ops->enable_dev) - { - dev->chip_ops->enable_dev(dev); - } - /* Now read the vendor and device id */ - id = pci_read_config32(dev, PCI_VENDOR_ID); - - /* If the device does not have a pci id disable it. - * Possibly this is because we have already disabled - * the device. But this also handles optional devices - * that may not always show up. - */ - if (id == 0xffffffff || id == 0x00000000 || - id == 0x0000ffff || id == 0xffff0000) - { - if (dev->enabled) { - printk_info("Disabling static device: %s\n", - dev_path(dev)); - dev->enabled = 0; - } - continue; - } - } - /* Read the rest of the pci configuration information */ - hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); - class = pci_read_config32(dev, PCI_CLASS_REVISION); - - /* Store the interesting information in the device structure */ - dev->vendor = id & 0xffff; - dev->device = (id >> 16) & 0xffff; - dev->hdr_type = hdr_type; - /* class code, the upper 3 bytes of PCI_CLASS_REVISION */ - dev->class = class >> 8; - - /* Architectural/System devices always need to - * be bus masters. - */ - if ((dev->class >> 16) == PCI_BASE_CLASS_SYSTEM) { - dev->command |= PCI_COMMAND_MASTER; - } - /* Look at the vendor and device id, or at least the - * header type and class and figure out which set of - * configuration methods to use. Unless we already - * have some pci ops. + /* See if a device is present and setup the device + * structure. */ - set_pci_ops(dev); - /* Error if we don't have some pci operations for it */ - if (!dev->ops) { - printk_err("%s No device operations\n", - dev_path(dev)); - continue; - } + dev = pci_probe_dev(dev, bus, devfn); - /* Now run the magic enable/disable sequence for the device */ - if (dev->ops && dev->ops->enable) { - dev->ops->enable(dev); - } - - printk_debug("%s [%04x/%04x] %s\n", - dev_path(dev), - dev->vendor, dev->device, - dev->enabled?"enabled": "disabled"); - - if (PCI_FUNC(devfn) == 0x00 && (hdr_type & 0x80) != 0x80) { - /* if this is not a multi function device, - * don't waste time probing another function. - * Skip to next device. - */ + /* if this is not a multi function device, + * or the device is not present don't waste + * time probing another function. + * Skip to next device. + */ + if ((PCI_FUNC(devfn) == 0x00) && + (!dev || (dev->enabled && ((dev->hdr_type & 0x80) != 0x80)))) + { devfn += 0x07; } } post_code(0x25); + /* Die if any leftover Static devices are are found. + * There's probably a problem in the Config.lb. + */ + if(old_devices) { + device_t left; + for(left = old_devices; left; left = left->sibling) { + printk_debug("%s\n", dev_path(left)); + } + die("Left over static devices. Check your Config.lb\n"); + } + /* For all children that implement scan_bus (i.e. bridges) * scan the bus behind that child. */ - for (child = bus->children; child; child = child->sibling) { - if (!child->enabled || - !child->ops || - !child->ops->scan_bus) - { - continue; - } - max = child->ops->scan_bus(child, max); + for(child = bus->children; child; child = child->sibling) { + max = scan_bus(child, max); } /* @@ -911,6 +1065,7 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf return max; } + /** * @brief Scan a PCI bridge and the buses behind the bridge. * @@ -924,7 +1079,9 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devf * * @return The maximum bus number found, after scanning all subordinate busses */ -unsigned int pci_scan_bridge(struct device *dev, unsigned int max) +unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max, + unsigned int (*do_scan_bus)(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max)) { struct bus *bus; uint32_t buses; @@ -960,14 +1117,14 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) */ buses &= 0xff000000; buses |= (((unsigned int) (dev->bus->secondary) << 0) | - ((unsigned int) (bus->secondary) << 8) | - ((unsigned int) (bus->subordinate) << 16)); + ((unsigned int) (bus->secondary) << 8) | + ((unsigned int) (bus->subordinate) << 16)); pci_write_config32(dev, PCI_PRIMARY_BUS, buses); /* Now we can scan all subordinate buses * i.e. the bus behind the bridge. */ - max = pci_scan_bus(bus, 0x00, 0xff, max); + max = do_scan_bus(bus, 0x00, 0xff, max); /* We know the number of buses behind this bridge. Set the subordinate * bus number to its real value. @@ -977,11 +1134,29 @@ unsigned int pci_scan_bridge(struct device *dev, unsigned int max) ((unsigned int) (bus->subordinate) << 16); pci_write_config32(dev, PCI_PRIMARY_BUS, buses); pci_write_config16(dev, PCI_COMMAND, cr); - + printk_spew("%s returns max %d\n", __func__, max); return max; } +/** + * @brief Scan a PCI bridge and the buses behind the bridge. + * + * Determine the existence of buses behind the bridge. Set up the bridge + * according to the result of the scan. + * + * This function is the default scan_bus() method for PCI bridge devices. + * + * @param dev pointer to the bridge device + * @param max the highest bus number assgined up to now + * + * @return The maximum bus number found, after scanning all subordinate busses + */ +unsigned int pci_scan_bridge(struct device *dev, unsigned int max) +{ + return do_pci_scan_bridge(dev, max, pci_scan_bus); +} + /* Tell the EISA int controller this int must be level triggered THIS IS A KLUDGE -- sorry, this needs to get cleaned up. @@ -1026,7 +1201,8 @@ static void pci_level_irq(unsigned char intNum) -kevinh@ispiri.com */ -void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]) +void pci_assign_irqs(unsigned bus, unsigned slot, + const unsigned char pIntAtoD[4]) { unsigned functNum; device_t pdev; diff --git a/src/devices/pciexp_device.c b/src/devices/pciexp_device.c new file mode 100644 index 0000000000..5422a8eb18 --- /dev/null +++ b/src/devices/pciexp_device.c @@ -0,0 +1,60 @@ +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pciexp.h> + + +static void pciexp_tune_dev(device_t dev) +{ + unsigned cap; + + cap = pci_find_capability(dev, PCI_CAP_ID_PCIE); + if (!cap) { + /* error... */ + return; + } + printk_debug("PCIEXP: tunning %s\n", dev_path(dev)); +#warning "IMPLEMENT PCI EXPRESS TUNING" +} + +unsigned int pciexp_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, + unsigned int max) +{ + device_t child; + max = pci_scan_bus(bus, min_devfn, max_devfn, max); + for(child = bus->children; child; child = child->sibling) { + if ( (child->path.u.pci.devfn < min_devfn) || + (child->path.u.pci.devfn > max_devfn)) + { + continue; + } + pciexp_tune_dev(child); + } + return max; +} + + +unsigned int pciexp_scan_bridge(device_t dev, unsigned int max) +{ + return do_pci_scan_bridge(dev, max, pciexp_scan_bus); +} + +/** Default device operations for PCI Express bridges */ +static struct pci_operations pciexp_bus_ops_pci = { + .set_subsystem = 0, +}; + +struct device_operations default_pciexp_ops_bus = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = 0, + .scan_bus = pciexp_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, + .ops_pci = &pciexp_bus_ops_pci, +}; diff --git a/src/devices/pcix_device.c b/src/devices/pcix_device.c new file mode 100644 index 0000000000..8915e56a1b --- /dev/null +++ b/src/devices/pcix_device.c @@ -0,0 +1,140 @@ +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pcix.h> + + +static void pcix_tune_dev(device_t dev) +{ + unsigned cap; + unsigned status, orig_cmd, cmd; + unsigned max_read, max_tran; + + if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) { + return; + } + cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); + if (!cap) { + return; + } + printk_debug("%s PCI-X tuning\n", dev_path(dev)); + status = pci_read_config32(dev, cap + PCI_X_STATUS); + orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD); + + max_read = (status & PCI_X_STATUS_MAX_READ) >> 21; + max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23; + if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) { + cmd &= ~PCI_X_CMD_MAX_READ; + cmd |= max_read << 2; + } + if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) { + cmd &= ~PCI_X_CMD_MAX_SPLIT; + cmd |= max_tran << 4; + } + /* Don't attempt to handle PCI-X errors */ + cmd &= ~PCI_X_CMD_DPERR_E; + /* Enable Relaxed Ordering */ + cmd |= PCI_X_CMD_ERO; + if (orig_cmd != cmd) { + pci_write_config16(dev, cap + PCI_X_CMD, cmd); + } +} + +unsigned int pcix_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max) +{ + device_t child; + max = pci_scan_bus(bus, min_devfn, max_devfn, max); + for(child = bus->children; child; child = child->sibling) { + if ( (child->path.u.pci.devfn < min_devfn) || + (child->path.u.pci.devfn > max_devfn)) + { + continue; + } + pcix_tune_dev(child); + } + return max; +} + +const char *pcix_speed(unsigned sstatus) +{ + static const char conventional[] = "Conventional PCI"; + static const char pcix_66mhz[] = "66MHz PCI-X"; + static const char pcix_100mhz[] = "100MHz PCI-X"; + static const char pcix_133mhz[] = "133MHz PCI-X"; + static const char pcix_266mhz[] = "266MHz PCI-X"; + static const char pcix_533mhz[] = "533MHZ PCI-X"; + static const char unknown[] = "Unknown"; + + const char *result; + result = unknown; + switch(PCI_X_SSTATUS_MFREQ(sstatus)) { + case PCI_X_SSTATUS_CONVENTIONAL_PCI: + result = conventional; + break; + case PCI_X_SSTATUS_MODE1_66MHZ: + result = pcix_66mhz; + break; + case PCI_X_SSTATUS_MODE1_100MHZ: + result = pcix_100mhz; + break; + + case PCI_X_SSTATUS_MODE1_133MHZ: + result = pcix_133mhz; + break; + + case PCI_X_SSTATUS_MODE2_266MHZ_REF_66MHZ: + case PCI_X_SSTATUS_MODE2_266MHZ_REF_100MHZ: + case PCI_X_SSTATUS_MODE2_266MHZ_REF_133MHZ: + result = pcix_266mhz; + break; + + case PCI_X_SSTATUS_MODE2_533MHZ_REF_66MHZ: + case PCI_X_SSTATUS_MODE2_533MHZ_REF_100MHZ: + case PCI_X_SSTATUS_MODE2_533MHZ_REF_133MHZ: + result = pcix_533mhz; + break; + } + return result; +} + +unsigned int pcix_scan_bridge(device_t dev, unsigned int max) +{ + unsigned pos; + unsigned sstatus; + + /* Find the PCI-X capability */ + pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); + sstatus = pci_read_config16(dev, pos + PCI_X_SEC_STATUS); + + if (PCI_X_SSTATUS_MFREQ(sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) { + max = do_pci_scan_bridge(dev, max, pci_scan_bus); + } else { + max = do_pci_scan_bridge(dev, max, pcix_scan_bus); + } + + /* Print the PCI-X bus speed */ + printk_debug("PCI: %02x: %s\n", dev->link[0].secondary, pcix_speed(sstatus)); + + return max; +} + + +/** Default device operations for PCI-X bridges */ +static struct pci_operations pcix_bus_ops_pci = { + .set_subsystem = 0, +}; + +struct device_operations default_pcix_ops_bus = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = 0, + .scan_bus = pcix_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, + .ops_pci = &pcix_bus_ops_pci, +}; diff --git a/src/devices/pnp_device.c b/src/devices/pnp_device.c index cde571f561..13f12ee4e4 100644 --- a/src/devices/pnp_device.c +++ b/src/devices/pnp_device.c @@ -68,8 +68,10 @@ void pnp_read_resources(device_t dev) static void pnp_set_resource(device_t dev, struct resource *resource) { if (!(resource->flags & IORESOURCE_ASSIGNED)) { - printk_err("ERROR: %s %02x not allocated\n", - dev_path(dev), resource->index); + printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n", + dev_path(dev), resource->index, + resource_type(resource), + resource->size); return; } diff --git a/src/devices/root_device.c b/src/devices/root_device.c index 2bb4f0afe8..3e559ea7c0 100644 --- a/src/devices/root_device.c +++ b/src/devices/root_device.c @@ -1,6 +1,7 @@ #include <console/console.h> #include <device/device.h> #include <device/pci.h> +#include <part/hard_reset.h> /** * Read the resources for the root device, @@ -35,8 +36,9 @@ void root_dev_read_resources(device_t root) } /** - * @brief Write the resources for the root device + * @brief Write the resources for every device * + * Write the resources for the root device, * and every device under it which are all of the devices. * @param root Pointer to the device structure for the system root device */ @@ -45,10 +47,10 @@ void root_dev_set_resources(device_t root) struct bus *bus; bus = &root->link[0]; - compute_allocate_resource(bus, &root->resource[0], - IORESOURCE_IO, IORESOURCE_IO); - compute_allocate_resource(bus, &root->resource[1], - IORESOURCE_MEM, IORESOURCE_MEM); + compute_allocate_resource(bus, + &root->resource[0], IORESOURCE_IO, IORESOURCE_IO); + compute_allocate_resource(bus, + &root->resource[1], IORESOURCE_MEM, IORESOURCE_MEM); assign_resources(bus); } @@ -57,9 +59,9 @@ void root_dev_set_resources(device_t root) * * The enumeration of certain buses is purely static. The existence of * devices on those buses can be completely determined at compile time - * and is specified in the config file. Typical exapmles are the 'PNP' - * devices on a legacy ISA/LPC bus. There is no need of probing of any - * kind, the only thing we have to do is to walk through the bus and + * and is specified in the config file. Typical examples are the 'PNP' + * devices on a legacy ISA/LPC bus. There is no need of probing of any kind, + * the only thing we have to do is to walk through the bus and * enable or disable devices as indicated in the config file. * * On the other hand, some devices are virtual and their existence is @@ -70,47 +72,50 @@ void root_dev_set_resources(device_t root) * This function is the default scan_bus() method for the root device and * LPC bridges. * - * @param root Pointer to the root device which the static buses are attached + * @param bus Pointer to the device structure which the static buses are attached * @param max Maximum bus number currently used before scanning. - * @return Largest bus number used after scanning. + * @return Largest bus number used. */ static int smbus_max = 0; -unsigned int scan_static_bus(device_t root, unsigned int max) +unsigned int scan_static_bus(device_t bus, unsigned int max) { device_t child; unsigned link; - printk_spew("%s for %s\n", __func__, dev_path(root)); + printk_spew("%s for %s\n", __func__, dev_path(bus)); - for (link = 0; link < root->links; link++) { - /* for smbus bus enumerate */ - child = root->link[link].children; - if(child && child->path.type == DEVICE_PATH_I2C) { - root->link[link].secondary = ++smbus_max; - } - for (child = root->link[link].children; child; child = child->sibling) { + for(link = 0; link < bus->links; link++) { + /* for smbus bus enumerate */ + child = bus->link[link].children; + if(child && child->path.type == DEVICE_PATH_I2C) { + bus->link[link].secondary = ++smbus_max; + } + for(child = bus->link[link].children; child; child = child->sibling) { if (child->chip_ops && child->chip_ops->enable_dev) { child->chip_ops->enable_dev(child); } if (child->ops && child->ops->enable) { child->ops->enable(child); } - if (child->path.type == DEVICE_PATH_I2C) - printk_debug("smbus: %s[%d]->", dev_path(child->bus->dev), child->bus->link ); - printk_debug("%s %s\n", dev_path(child), - child->enabled?"enabled": "disabled"); + if (child->path.type == DEVICE_PATH_I2C) { + printk_debug("smbus: %s[%d]->", + dev_path(child->bus->dev), child->bus->link ); + } + printk_debug("%s %s\n", + dev_path(child), + child->enabled?"enabled": "disabled"); } } - for (link = 0; link < root->links; link++) { - for (child = root->link[link].children; child; child = child->sibling) { + for(link = 0; link < bus->links; link++) { + for(child = bus->link[link].children; child; child = child->sibling) { if (!child->ops || !child->ops->scan_bus) continue; printk_spew("%s scanning...\n", dev_path(child)); - max = child->ops->scan_bus(child, max); + max = scan_bus(child, max); } } - printk_spew("%s for %s done\n", __func__, dev_path(root)); + printk_spew("%s for %s done\n", __func__, dev_path(bus)); return max; } @@ -120,7 +125,7 @@ unsigned int scan_static_bus(device_t root, unsigned int max) * * @param dev the device whos children's resources are to be enabled * - * This function is call by the global enable_resources() indirectly via the + * This function is called by the global enable_resource() indirectly via the * device_operation::enable_resources() method of devices. * * Indirect mutual recursion: @@ -131,9 +136,9 @@ unsigned int scan_static_bus(device_t root, unsigned int max) void enable_childrens_resources(device_t dev) { unsigned link; - for (link = 0; link < dev->links; link++) { + for(link = 0; link < dev->links; link++) { device_t child; - for (child = dev->link[link].children; child; child = child->sibling) { + for(child = dev->link[link].children; child; child = child->sibling) { enable_resources(child); } } @@ -161,6 +166,12 @@ void root_dev_init(device_t root) { } +void root_dev_reset(struct bus *bus) +{ + printk_info("Reseting board...\n"); + hard_reset(); +} + /** * @brief Default device operation for root device * @@ -174,6 +185,7 @@ struct device_operations default_dev_ops_root = { .enable_resources = root_dev_enable_resources, .init = root_dev_init, .scan_bus = root_dev_scan_bus, + .reset_bus = root_dev_reset, }; /** diff --git a/src/drivers/generic/debug/debug_dev.c b/src/drivers/generic/debug/debug_dev.c index d5f9e628dd..49d442af1f 100644 --- a/src/drivers/generic/debug/debug_dev.c +++ b/src/drivers/generic/debug/debug_dev.c @@ -268,6 +268,9 @@ static void debug_init(device_t dev) case 7: print_tsc(); break; + case 8: + hard_reset(); + break; } } diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index 3d229d23b9..51c0b511c7 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -34,7 +34,9 @@ #if !defined(__ROMCC__) && !defined (ASSEMBLY) -void x86_setup_mtrrs(void); + +void x86_setup_var_mtrrs(unsigned address_bits); +void x86_setup_mtrrs(unsigned address_bits); int x86_mtrr_check(void); #endif /* __ROMCC__ */ diff --git a/src/include/device/agp.h b/src/include/device/agp.h new file mode 100644 index 0000000000..073858ae10 --- /dev/null +++ b/src/include/device/agp.h @@ -0,0 +1,12 @@ +#ifndef DEVICE_AGP_H +#define DEVICE_AGP_H +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +unsigned int agp_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max); +unsigned int agp_scan_bridge(device_t dev, unsigned int max); + +extern struct device_operations default_agp_ops_bus; + + +#endif /* DEVICE_AGP_H */ diff --git a/src/include/device/cardbus.h b/src/include/device/cardbus.h new file mode 100644 index 0000000000..38aa41cab5 --- /dev/null +++ b/src/include/device/cardbus.h @@ -0,0 +1,12 @@ +#ifndef DEVICE_CARDBUS_H +#define DEVICE_CARDBUS_H +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +void cardbus_read_resources(device_t dev); +unsigned int cardbus_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max); +unsigned int cardbus_scan_bridge(device_t dev, unsigned int max); + +extern struct device_operations default_cardbus_ops_bus; + +#endif /* DEVICE_CARDBUS_H */ diff --git a/src/include/device/device.h b/src/include/device/device.h index be93f554fa..aff5616a88 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -26,6 +26,8 @@ struct chip_operations { #define CHIP_NAME(X) #endif +struct bus; + struct device_operations { void (*read_resources)(device_t dev); void (*set_resources)(device_t dev); @@ -34,6 +36,7 @@ struct device_operations { unsigned int (*scan_bus)(device_t bus, unsigned int max); void (*enable)(device_t dev); void (*set_link)(device_t dev, unsigned int link); + void (*reset_bus)(struct bus *bus); const struct pci_operations *ops_pci; const struct smbus_bus_operations *ops_smbus_bus; const struct pci_bus_operations *ops_pci_bus; @@ -48,6 +51,8 @@ struct bus { unsigned char secondary; /* secondary bus number */ unsigned char subordinate; /* max subordinate bus number */ unsigned char cap; /* PCi capability offset */ + unsigned reset_needed : 1; + unsigned disable_relaxed_ordering : 1; }; #define MAX_RESOURCES 12 @@ -81,7 +86,8 @@ struct device { unsigned int resources; /* link are (down sream) buses attached to the device, usually a leaf - * device with no child have 0 bus attached and a bridge has 1 bus */ + * device with no children have 0 buses attached and a bridge has 1 bus + */ struct bus link[MAX_LINKS]; /* number of buses attached to the device */ unsigned int links; @@ -101,8 +107,11 @@ extern void dev_enumerate(void); extern void dev_configure(void); extern void dev_enable(void); extern void dev_initialize(void); +extern void dev_optimize(void); /* Generic device helper functions */ +extern int reset_bus(struct bus *bus); +extern unsigned int scan_bus(struct device *bus, unsigned int max); extern void compute_allocate_resource(struct bus *bus, struct resource *bridge, unsigned long type_mask, unsigned long type); extern void assign_resources(struct bus *bus); @@ -110,6 +119,9 @@ extern void enable_resources(struct device *dev); extern void enumerate_static_device(void); extern void enumerate_static_devices(void); extern const char *dev_path(device_t dev); +const char *bus_path(struct bus *bus); +extern void dev_set_enabled(device_t dev, int enable); +extern void disable_children(struct bus *bus); /* Helper functions */ device_t find_dev_path(struct bus *parent, struct device_path *path); @@ -134,5 +146,4 @@ extern void enable_childrens_resources(device_t dev); extern void root_dev_enable_resources(device_t dev); extern unsigned int root_dev_scan_bus(device_t root, unsigned int max); extern void root_dev_init(device_t dev); - #endif /* DEVICE_H */ diff --git a/src/include/device/hypertransport.h b/src/include/device/hypertransport.h index 410495cdcb..f04d0eca30 100644 --- a/src/include/device/hypertransport.h +++ b/src/include/device/hypertransport.h @@ -3,7 +3,10 @@ #include <device/hypertransport_def.h> -unsigned int hypertransport_scan_chain(struct bus *bus, unsigned int max); +unsigned int hypertransport_scan_chain(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max); +unsigned int ht_scan_bridge(struct device *dev, unsigned int max); +extern struct device_operations default_ht_ops_bus; #define HT_IO_HOST_ALIGN 4096 #define HT_MEM_HOST_ALIGN (1024*1024) diff --git a/src/include/device/path.h b/src/include/device/path.h index f55827b9c0..cfac751e26 100644 --- a/src/include/device/path.h +++ b/src/include/device/path.h @@ -72,6 +72,7 @@ struct device_path { #define DEVICE_PATH_MAX 30 +#define BUS_PATH_MAX (DEVICE_PATH_MAX+10) extern int path_eq(struct device_path *path1, struct device_path *path2); diff --git a/src/include/device/pci.h b/src/include/device/pci.h index d359a96666..2daa1ca03e 100644 --- a/src/include/device/pci.h +++ b/src/include/device/pci.h @@ -50,16 +50,26 @@ extern struct pci_driver pci_drivers[]; extern struct pci_driver epci_drivers[]; -struct device_operations default_pci_ops_dev; -struct device_operations default_pci_ops_bus; +extern struct device_operations default_pci_ops_dev; +extern struct device_operations default_pci_ops_bus; void pci_dev_read_resources(device_t dev); void pci_bus_read_resources(device_t dev); void pci_dev_set_resources(device_t dev); void pci_dev_enable_resources(device_t dev); void pci_bus_enable_resources(device_t dev); +void pci_bus_reset(struct bus *bus); +device_t pci_probe_dev(device_t dev, struct bus *bus, unsigned devfn); +unsigned int do_pci_scan_bridge(device_t bus, unsigned int max, + unsigned int (*do_scan_bus)(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max)); unsigned int pci_scan_bridge(device_t bus, unsigned int max); unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn, unsigned max_devfn, unsigned int max); +uint8_t pci_moving_config8(struct device *dev, unsigned reg); +uint16_t pci_moving_config16(struct device *dev, unsigned reg); +uint32_t pci_moving_config32(struct device *dev, unsigned reg); +unsigned pci_find_next_capability(device_t dev, unsigned cap, unsigned last); +unsigned pci_find_capability(device_t dev, unsigned cap); struct resource *pci_get_resource(struct device *dev, unsigned long index); void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device); diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h index dc2176babb..6fb7ebd385 100644 --- a/src/include/device/pci_def.h +++ b/src/include/device/pci_def.h @@ -181,15 +181,20 @@ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ #define PCI_CAP_ID_PCIX 0x07 /* PCIX */ #define PCI_CAP_ID_HT 0x08 /* Hypertransport */ +#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_PCIE 0x10 /* PCI Express */ +#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ /* Hypertransport Registers */ #define PCI_HT_CAP_SIZEOF 4 +#define PCI_HT_CAP_HOST_CTRL 4 /* Host link control */ #define PCI_HT_CAP_HOST_WIDTH 6 /* width value & capability */ #define PCI_HT_CAP_HOST_FREQ 0x09 /* Host frequency */ #define PCI_HT_CAP_HOST_FREQ_CAP 0x0a /* Host Frequency capability */ +#define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */ +#define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */ #define PCI_HT_CAP_SLAVE_WIDTH0 6 /* width value & capability */ #define PCI_HT_CAP_SLAVE_WIDTH1 0x0a /* width value & capability to */ #define PCI_HT_CAP_SLAVE_FREQ0 0x0d /* Slave frequency from */ @@ -199,6 +204,7 @@ /* Power Management Registers */ +#define PCI_PM_PMC 2 /* PM Capabilities Register */ #define PCI_PM_CAP_VER_MASK 0x0007 /* Version */ #define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */ #define PCI_PM_CAP_AUX_POWER 0x0010 /* Auxilliary power support */ @@ -260,6 +266,191 @@ #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ +#define PCI_MSI_MASK_BIT 16 /* Mask bits register */ + +/* CompactPCI Hotswap Register */ + +#define PCI_CHSWP_CSR 2 /* Control and Status Register */ +#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */ +#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */ +#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */ +#define PCI_CHSWP_LOO 0x08 /* LED On / Off */ +#define PCI_CHSWP_PI 0x30 /* Programming Interface */ +#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */ +#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */ + +/* PCI-X registers */ + +#define PCI_X_CMD 2 /* Modes & Features */ +#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */ +#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ +#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */ +#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ +#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ +#define PCI_X_STATUS 4 /* PCI-X capabilities */ +#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */ +#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */ +#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */ +#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */ +#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */ +#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */ +#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */ +#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */ +#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */ +#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */ +#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */ +#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ +#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ + +/* PCI-X bridge registers */ +#define PCI_X_SEC_STATUS 2 /* Secondary status */ +#define PCI_X_SSTATUS_64BIT 0x0001 /* The bus behind the bridge is 64bits wide */ +#define PCI_X_SSTATUS_133MHZ 0x0002 /* The bus behind the bridge is 133Mhz Capable */ +#define PCI_X_SSTATUS_SPL_DISC 0x0004 /* Split Completion Discarded */ +#define PCI_X_SSTATUS_UNX_SPL 0x0008 /* Unexpected Split Completion */ +#define PCI_X_SSTATUS_SPL_OVR 0x0010 /* Split Completion Overrun */ +#define PCI_X_SSTATUS_SPL_DLY 0x0020 /* Split Completion Delayed */ +#define PCI_X_SSTATUS_MFREQ(x) (((x) & 0x03c0) >> 6) /* PCI-X mode and frequency */ +#define PCI_X_SSTATUS_CONVENTIONAL_PCI 0x0 +#define PCI_X_SSTATUS_MODE1_66MHZ 0x1 +#define PCI_X_SSTATUS_MODE1_100MHZ 0x2 +#define PCI_X_SSTATUS_MODE1_133MHZ 0x3 +#define PCI_X_SSTATUS_MODE2_266MHZ_REF_66MHZ 0x9 +#define PCI_X_SSTATUS_MODE2_266MHZ_REF_100MHZ 0xa +#define PCI_X_SSTATUS_MODE2_266MHZ_REF_133MHZ 0xb +#define PCI_X_SSTATUS_MODE2_533MHZ_REF_66MHZ 0xd +#define PCI_X_SSTATUS_MODE2_533MHZ_REF_100MHZ 0xe +#define PCI_X_SSTATUS_MODE2_533MHZ_REF_133MHZ 0xf +#define PCI_X_SSTATUS_VERSION(x) (((x) >> 12) & 3) /* Version */ +#define PCI_X_SSTATUS_266MHZ 0x4000 /* The bus behind the bridge is 266Mhz Capable */ +#define PCI_X_SSTAUTS_533MHZ 0x8000 /* The bus behind the bridge is 533Mhz Capable */ + +/* PCI Express capability registers */ + +#define PCI_EXP_FLAGS 2 /* Capabilities register */ +#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */ +#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ +#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */ +#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */ +#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ +#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */ +#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ +#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */ +#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ +#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */ +#define PCI_EXP_DEVCAP 4 /* Device capabilities */ +#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */ +#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */ +#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */ +#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */ +#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */ +#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ +#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ +#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ +#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ +#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ +#define PCI_EXP_DEVCTL 8 /* Device Control */ +#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ +#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ +#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */ +#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ +#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */ +#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ +#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ +#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ +#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ +#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ +#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ +#define PCI_EXP_DEVSTA 10 /* Device Status */ +#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ +#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ +#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */ +#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */ +#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ +#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ +#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKCTL 16 /* Link Control */ +#define PCI_EXP_LNKSTA 18 /* Link Status */ +#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ +#define PCI_EXP_SLTCTL 24 /* Slot Control */ +#define PCI_EXP_SLTSTA 26 /* Slot Status */ +#define PCI_EXP_RTCTL 28 /* Root Control */ +#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */ +#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */ +#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */ +#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */ +#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ +#define PCI_EXP_RTCAP 30 /* Root Capabilities */ +#define PCI_EXP_RTSTA 32 /* Root Status */ + +/* Extended Capabilities (PCI-X 2.0 and Express) */ +#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) +#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) +#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) + +#define PCI_EXT_CAP_ID_ERR 1 +#define PCI_EXT_CAP_ID_VC 2 +#define PCI_EXT_CAP_ID_DSN 3 +#define PCI_EXT_CAP_ID_PWR 4 + +/* Advanced Error Reporting */ +#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ +#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ +#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ +#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ +#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */ +#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */ +#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */ +#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */ +#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */ +#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */ +#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */ +#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */ +#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */ + /* Same bits as above */ +#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */ + /* Same bits as above */ +#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */ +#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */ +#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */ +#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */ +#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */ +#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */ +#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */ + /* Same bits as above */ +#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */ +#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */ +#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */ +#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */ +#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */ +#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ +#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ +#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ +#define PCI_ERR_ROOT_STATUS 48 +#define PCI_ERR_ROOT_COR_SRC 52 +#define PCI_ERR_ROOT_SRC 54 + +/* Virtual Channel */ +#define PCI_VC_PORT_REG1 4 +#define PCI_VC_PORT_REG2 8 +#define PCI_VC_PORT_CTRL 12 +#define PCI_VC_PORT_STATUS 14 +#define PCI_VC_RES_CAP 16 +#define PCI_VC_RES_CTRL 20 +#define PCI_VC_RES_STATUS 26 + +/* Power Budgeting */ +#define PCI_PWR_DSR 4 /* Data Select Register */ +#define PCI_PWR_DATA 8 /* Data Register */ +#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */ +#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */ +#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */ +#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */ +#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */ +#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */ +#define PCI_PWR_CAP 12 /* Capability */ +#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ + /* * The PCI interface treats multi-function devices as independent diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index c0ccdd0fcd..7dba234ba7 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -137,12 +137,14 @@ #define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 #define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 #define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34 +#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33 #define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35 #define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40 #define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43 #define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011 #define PCI_DEVICE_ID_COMPAQ_CISS 0xb060 #define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178 +#define PCI_DEVICE_ID_COMPAQ_CISSC 0x46 #define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130 #define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150 @@ -165,6 +167,7 @@ #define PCI_DEVICE_ID_LSI_53C1010_33 0x0020 #define PCI_DEVICE_ID_LSI_53C1010_66 0x0021 #define PCI_DEVICE_ID_LSI_53C1030 0x0030 +#define PCI_DEVICE_ID_LSI_1030_53C1035 0x0032 #define PCI_DEVICE_ID_LSI_53C1035 0x0040 #define PCI_DEVICE_ID_NCR_53C875J 0x008f #define PCI_DEVICE_ID_LSI_FC909 0x0621 @@ -172,9 +175,21 @@ #define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623 #define PCI_DEVICE_ID_LSI_FC919 0x0624 #define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625 +#define PCI_DEVICE_ID_LSI_FC929X 0x0626 +#define PCI_DEVICE_ID_LSI_FC939X 0x0642 +#define PCI_DEVICE_ID_LSI_FC949X 0x0640 +#define PCI_DEVICE_ID_LSI_FC919X 0x0628 #define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701 #define PCI_DEVICE_ID_LSI_61C102 0x0901 #define PCI_DEVICE_ID_LSI_63C815 0x1000 +#define PCI_DEVICE_ID_LSI_SAS1064 0x0050 +#define PCI_DEVICE_ID_LSI_SAS1066 0x005E +#define PCI_DEVICE_ID_LSI_SAS1068 0x0054 +#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C +#define PCI_DEVICE_ID_LSI_SAS1064E 0x0056 +#define PCI_DEVICE_ID_LSI_SAS1066E 0x005A +#define PCI_DEVICE_ID_LSI_SAS1068E 0x0058 +#define PCI_DEVICE_ID_LSI_SAS1078 0x0060 #define PCI_VENDOR_ID_ATI 0x1002 /* Mach64 */ @@ -901,6 +916,33 @@ #define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029 #define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C #define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D +#define PCI_DEVICE_ID_NVIDIA_CK804_LPC 0x0050 +#define PCI_DEVICE_ID_NVIDIA_CK804_PRO 0x0051 +#define PCI_DEVICE_ID_NVIDIA_CK804_ISA 0x0051 +#define PCI_DEVICE_ID_NVIDIA_CK804_SMB 0x0052 +#define PCI_DEVICE_ID_NVIDIA_CK804_SM 0x0052 +#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI 0x0052 +#define PCI_DEVICE_ID_NVIDIA_CK804_IDE 0x0053 +#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0 0x0054 +#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055 +#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055 +#define PCI_DEVICE_ID_NVIDIA_CK804_ENET 0x0056 +#define PCI_DEVICE_ID_NVIDIA_CK804_NIC 0x0056 +#define PCI_DEVICE_ID_NVIDIA_CK804_ENET2 0x0057 +#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE 0x0057 +#define PCI_DEVICE_ID_NVIDIA_CK804_MODEM 0x0058 +#define PCI_DEVICE_ID_NVIDIA_CK804_MCI 0x0058 +#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 +#define PCI_DEVICE_ID_NVIDIA_CK804_ACI 0x0059 +#define PCI_DEVICE_ID_NVIDIA_CK804_USB 0x005A +#define PCI_DEVICE_ID_NVIDIA_CK804_USB2 0x005B +#define PCI_DEVICE_ID_NVIDIA_CK804_PCI 0x005C +#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005D +#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E 0x005D +#define PCI_DEVICE_ID_NVIDIA_CK804_MEM 0x005E +#define PCI_DEVICE_ID_NVIDIA_CK804_HT 0x005E +#define PCI_DEVICE_ID_NVIDIA_CK804_TRIM 0x005f +#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE 0x00d3 #define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 @@ -919,23 +961,6 @@ #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202 #define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203 -#define PCI_DEVICE_ID_NVIDIA_CK804_HT 0x005e -#define PCI_DEVICE_ID_NVIDIA_CK804_LPC 0x0050 -#define PCI_DEVICE_ID_NVIDIA_CK804_PRO 0x0051 -#define PCI_DEVICE_ID_NVIDIA_CK804_SLAVE 0x00d3 -#define PCI_DEVICE_ID_NVIDIA_CK804_SM 0x0052 -#define PCI_DEVICE_ID_NVIDIA_CK804_ACPI 0x0052 -#define PCI_DEVICE_ID_NVIDIA_CK804_USB 0x005a -#define PCI_DEVICE_ID_NVIDIA_CK804_USB2 0x005b -#define PCI_DEVICE_ID_NVIDIA_CK804_NIC 0x0056 -#define PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE 0x0057 -#define PCI_DEVICE_ID_NVIDIA_CK804_ACI 0x0059 -#define PCI_DEVICE_ID_NVIDIA_CK804_MCI 0x0058 -#define PCI_DEVICE_ID_NVIDIA_CK804_IDE 0x0053 -#define PCI_DEVICE_ID_NVIDIA_CK804_SATA0 0x0054 -#define PCI_DEVICE_ID_NVIDIA_CK804_SATA1 0x0055 -#define PCI_DEVICE_ID_NVIDIA_CK804_PCI 0x005c -#define PCI_DEVICE_ID_NVIDIA_CK804_PCI_E 0x005d #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_8849 0x8849 @@ -1812,7 +1837,9 @@ #define PCI_DEVICE_ID_INTEL_6300ESB_USB2 0x25aa #define PCI_DEVICE_ID_INTEL_6300ESB_USB3 0x25ad #define PCI_DEVICE_ID_INTEL_6300ESB_SATA 0x25a3 +#define PCI_DEVICE_ID_INTEL_6300ESB_SATA_R 0x25b0 #define PCI_DEVICE_ID_INTEL_6300ESB_PIC1 0x25ac +#define PCI_DEVICE_ID_INTEL_6300ESB_BRIDGE1C 0x25ae #define PCI_DEVICE_ID_INTEL_80310 0x530d #define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120 #define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121 diff --git a/src/include/device/pciexp.h b/src/include/device/pciexp.h new file mode 100644 index 0000000000..9ea662d490 --- /dev/null +++ b/src/include/device/pciexp.h @@ -0,0 +1,11 @@ +#ifndef DEVICE_PCIEXP_H +#define DEVICE_PCIEXP_H +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +unsigned int pciexp_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max); +unsigned int pciexp_scan_bridge(device_t dev, unsigned int max); + +extern struct device_operations default_pciexp_ops_bus; + +#endif /* DEVICE_PCIEXP_H */ diff --git a/src/include/device/pcix.h b/src/include/device/pcix.h new file mode 100644 index 0000000000..8bf193530a --- /dev/null +++ b/src/include/device/pcix.h @@ -0,0 +1,12 @@ +#ifndef DEVICE_PCIX_H +#define DEVICE_PCIX_H +/* (c) 2005 Linux Networx GPL see COPYING for details */ + +unsigned int pcix_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max); +unsigned int pcix_scan_bridge(device_t dev, unsigned int max); +const char *pcix_speed(unsigned sstatus); + +extern struct device_operations default_pcix_ops_bus; + +#endif /* DEVICE_PCIX_H */ diff --git a/src/include/device/resource.h b/src/include/device/resource.h index a5c7f0a31a..902cf686c9 100644 --- a/src/include/device/resource.h +++ b/src/include/device/resource.h @@ -98,4 +98,7 @@ extern void search_global_resources( unsigned long type_mask, unsigned long type, resource_search_t search, void *gp); +#define RESOURCE_TYPE_MAX 20 +extern const char *resource_type(struct resource *resource); + #endif /* RESOURCE_H */ diff --git a/src/include/part/fallback_boot.h b/src/include/part/fallback_boot.h index 7d6e790f60..17db5c6d9f 100644 --- a/src/include/part/fallback_boot.h +++ b/src/include/part/fallback_boot.h @@ -4,11 +4,13 @@ #ifndef ASSEMBLY #if HAVE_FALLBACK_BOOT == 1 -void boot_successful(void); +void set_boot_successful(void); #else -#define boot_successful() +#define set_boot_successful() #endif +void boot_successful(void); + #endif /* ASSEMBLY */ #define RTC_BOOT_BYTE 48 diff --git a/src/include/part/watchdog.h b/src/include/part/watchdog.h new file mode 100644 index 0000000000..4374f3060d --- /dev/null +++ b/src/include/part/watchdog.h @@ -0,0 +1,10 @@ +#ifndef PART_WATCHDOG_H +#define PART_WATCHDOG_H + +#if USE_WATCHDOG_ON_BOOT == 1 +void watchdog_off(void); +#else +#define watchdog_off() +#endif + +#endif /* PART_WATCHDOG_H */ diff --git a/src/lib/Config.lb b/src/lib/Config.lb index 32566d2737..3a1baf66c3 100644 --- a/src/lib/Config.lb +++ b/src/lib/Config.lb @@ -9,9 +9,7 @@ object memcmp.o object memmove.o object malloc.o object delay.o -if HAVE_FALLBACK_BOOT - object fallback_boot.o -end +object fallback_boot.o object compute_ip_checksum.o object version.o # Force version.o to recompile every time diff --git a/src/lib/clog2.c b/src/lib/clog2.c index 41e2af9791..b9b173177c 100644 --- a/src/lib/clog2.c +++ b/src/lib/clog2.c @@ -4,16 +4,19 @@ #include <console/console.h> #endif +/* Assume 8 bits per byte */ +#define CHAR_BIT 8 + 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; + unsigned long i = 1ULL << (sizeof(x)* CHAR_BIT - 1ULL); + unsigned long pow = sizeof(x) * CHAR_BIT - 1ULL; if (! x) { #ifdef DEBUG_LOG2 printk_warning("%s called with invalid parameter of 0\n", - __FUNCTION__); + __func__); #endif return -1; } diff --git a/src/lib/fallback_boot.c b/src/lib/fallback_boot.c index fe34e081fb..9e892dd680 100644 --- a/src/lib/fallback_boot.c +++ b/src/lib/fallback_boot.c @@ -1,9 +1,12 @@ #include <console/console.h> #include <part/fallback_boot.h> +#include <part/watchdog.h> #include <pc80/mc146818rtc.h> #include <arch/io.h> -void boot_successful(void) + +#if HAVE_FALLBACK_BOOT == 1 +void set_boot_successful(void) { /* Remember I succesfully booted by setting * the initial boot direction @@ -23,3 +26,13 @@ void boot_successful(void) byte &= 0x0f; outb(byte, RTC_PORT(1)); } +#endif + +void boot_successful(void) +{ + /* Remember this was a successful boot */ + set_boot_successful(); + + /* turn off the boot watchdog */ + watchdog_off(); +} diff --git a/src/mainboard/Iwill/DK8S2/Config.lb b/src/mainboard/Iwill/DK8S2/Config.lb index 661cadcdd2..22c589f6c0 100644 --- a/src/mainboard/Iwill/DK8S2/Config.lb +++ b/src/mainboard/Iwill/DK8S2/Config.lb @@ -45,6 +45,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o ## ATI Rage XL framebuffering graphics driver dir /drivers/ati/ragexl @@ -129,7 +130,7 @@ mainboardinit cpu/x86/mmx/disable_mmx.inc dir /pc80 config chip.h -# config for arima/hdama +# config for Iwill/DK8S2 chip northbridge/amd/amdk8/root_complex device pci_domain 0 on chip northbridge/amd/amdk8 @@ -189,7 +190,7 @@ chip northbridge/amd/amdk8/root_complex end device pci 1.1 on end device pci 1.2 on end - device pci 1.3 on end + device pci 1.3 on end device pci 1.5 off end device pci 1.6 off end end @@ -208,7 +209,7 @@ chip northbridge/amd/amdk8/root_complex device pci 19.2 on end device pci 19.3 on end end - end + end device apic_cluster 0 on chip cpu/amd/socket_940 device apic 0 on end diff --git a/src/mainboard/Iwill/DK8S2/Options.lb b/src/mainboard/Iwill/DK8S2/Options.lb index d7b694d1f8..5cb440f504 100644 --- a/src/mainboard/Iwill/DK8S2/Options.lb +++ b/src/mainboard/Iwill/DK8S2/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -76,13 +73,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/Iwill/DK8S2/reset.c b/src/mainboard/Iwill/DK8S2/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/Iwill/DK8S2/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/Iwill/DK8X/Config.lb b/src/mainboard/Iwill/DK8X/Config.lb index d8fc0cb5e0..59f3828239 100644 --- a/src/mainboard/Iwill/DK8X/Config.lb +++ b/src/mainboard/Iwill/DK8X/Config.lb @@ -45,6 +45,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o ## ## Romcc output diff --git a/src/mainboard/Iwill/DK8X/Options.lb b/src/mainboard/Iwill/DK8X/Options.lb index 0f413f0499..6265e72fe1 100644 --- a/src/mainboard/Iwill/DK8X/Options.lb +++ b/src/mainboard/Iwill/DK8X/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -76,13 +73,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/Iwill/DK8X/reset.c b/src/mainboard/Iwill/DK8X/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/Iwill/DK8X/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/amd/quartet/Config.lb b/src/mainboard/amd/quartet/Config.lb index 2d818d40d1..5adaf354d7 100644 --- a/src/mainboard/amd/quartet/Config.lb +++ b/src/mainboard/amd/quartet/Config.lb @@ -41,6 +41,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o ## ## Romcc output diff --git a/src/mainboard/amd/quartet/Options.lb b/src/mainboard/amd/quartet/Options.lb index 7e2dc489ae..f1013eaadf 100644 --- a/src/mainboard/amd/quartet/Options.lb +++ b/src/mainboard/amd/quartet/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -75,13 +72,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/amd/quartet/reset.c b/src/mainboard/amd/quartet/reset.c new file mode 100644 index 0000000000..63958185f6 --- /dev/null +++ b/src/mainboard/amd/quartet/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 2); +} diff --git a/src/mainboard/amd/serenade/Config.lb b/src/mainboard/amd/serenade/Config.lb index 4fdc235507..deac98b563 100644 --- a/src/mainboard/amd/serenade/Config.lb +++ b/src/mainboard/amd/serenade/Config.lb @@ -41,6 +41,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o ## ## Romcc output diff --git a/src/mainboard/amd/serenade/Options.lb b/src/mainboard/amd/serenade/Options.lb index fedc518d8a..a26f2709f8 100644 --- a/src/mainboard/amd/serenade/Options.lb +++ b/src/mainboard/amd/serenade/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -74,13 +71,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/amd/serenade/reset.c b/src/mainboard/amd/serenade/reset.c new file mode 100644 index 0000000000..63958185f6 --- /dev/null +++ b/src/mainboard/amd/serenade/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 2); +} diff --git a/src/mainboard/amd/solo/Config.lb b/src/mainboard/amd/solo/Config.lb index fdf3c1c769..6feb8b1848 100644 --- a/src/mainboard/amd/solo/Config.lb +++ b/src/mainboard/amd/solo/Config.lb @@ -42,6 +42,7 @@ driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end if HAVE_ACPI_TABLES object acpi_tables.o end +object reset.o ## ## Romcc output diff --git a/src/mainboard/amd/solo/Options.lb b/src/mainboard/amd/solo/Options.lb index 42611440f6..87a2ceb4bc 100644 --- a/src/mainboard/amd/solo/Options.lb +++ b/src/mainboard/amd/solo/Options.lb @@ -4,9 +4,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -76,13 +73,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/amd/solo/reset.c b/src/mainboard/amd/solo/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/amd/solo/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/arima/hdama/Config.lb b/src/mainboard/arima/hdama/Config.lb index a9df17bcdf..0b04d51214 100644 --- a/src/mainboard/arima/hdama/Config.lb +++ b/src/mainboard/arima/hdama/Config.lb @@ -29,7 +29,7 @@ default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) ## XIP_ROM_SIZE must be a power of 2. ## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE ## -default XIP_ROM_SIZE=65536 +default XIP_ROM_SIZE=131072 default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) ## @@ -45,13 +45,13 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o ## ## Romcc output ## makerule ./failover.E - depends "$(MAINBOARD)/failover.c ./romcc" + depends "$(MAINBOARD)/failover.c ./romcc" action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" end @@ -60,11 +60,11 @@ makerule ./failover.inc action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" end -makerule ./auto.E - depends "$(MAINBOARD)/auto.c option_table.h ./romcc" +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" action "./romcc -E -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" end -makerule ./auto.inc +makerule ./auto.inc depends "$(MAINBOARD)/auto.c option_table.h ./romcc" action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" end @@ -129,61 +129,122 @@ config chip.h # config for arima/hdama chip northbridge/amd/amdk8/root_complex - device apic_cluster 0 on - chip cpu/amd/socket_940 - device apic 0 on end - end - chip cpu/amd/socket_940 - device apic 1 on end - end - end device pci_domain 0 on chip northbridge/amd/amdk8 device pci 18.0 on # northbridge # devices on link 0, link 0 == LDT 0 chip southbridge/amd/amd8131 # the on/off keyword is mandatory - device pci 0.0 on end # PCIX bridge + device pci 0.0 on # PCIX bridge + ## On board NIC A + #chip drivers/generic/generic + # device pci 3.0 on + # irq 0 = 0x13 + # end + #end + ## On board NIC B + #chip drivers/generic/generic + # device pci 4.0 on + # irq 0 = 0x13 + # end + #end + ## PCI Slot 3 + #chip drivers/generic/generic + # device pci 1.0 on + # irq 0 = 0x11 + # irq 1 = 0x12 + # irq 2 = 0x13 + # irq 3 = 0x10 + # end + #end + ## PCI Slot 4 + #chip drivers/generic/generic + # device pci 2.0 on + # irq 0 = 0x12 + # irq 1 = 0x13 + # irq 2 = 0x10 + # irq 3 = 0x11 + # end + #end + end device pci 0.1 on end # IOAPIC - device pci 1.0 on end # PCIX bridge - device pci 1.1 on end # IOAPIC + device pci 1.0 on # PCIX bridge + ## PCI Slot 1 + #chip drivers/generic/generic + # device pci 1.0 on + # irq 0 = 0x11 + # irq 1 = 0x12 + # irq 2 = 0x13 + # irq 3 = 0x10 + # end + #end + ## PCI Slot 2 + #chip drivers/generic/generic + # device pci 2.0 on + # irq 0 = 0x12 + # irq 1 = 0x13 + # irq 2 = 0x10 + # irq 3 = 0x11 + # end + #end + end + device pci 1.1 on end # IOAPIC end chip southbridge/amd/amd8111 # this "device pci 0.0" is the parent of the next one # PCI bridge device pci 0.0 on - device pci 0.0 on end # USB0 - device pci 0.1 on end # USB1 - device pci 0.2 off end # USB 2.0 - device pci 1.0 off end # LAN + device pci 0.0 on end # USB0 + device pci 0.1 on end # USB1 + device pci 0.2 off end # USB 2.0 + device pci 1.0 off end # LAN chip drivers/pci/onboard device pci 6.0 on end # ATI Rage XL register "rom_address" = "0xfff80000" end + ## PCI Slot 5 (correct?) + #chip drivers/generic/generic + # device pci 5.0 on + # irq 0 = 0x11 + # irq 1 = 0x12 + # irq 2 = 0x13 + # irq 3 = 0x10 + # end + #end + ## PCI Slot 6 (correct?) + #chip drivers/generic/generic + # device pci 4.0 on + # irq 0 = 0x10 + # irq 1 = 0x11 + # irq 2 = 0x12 + # irq 3 = 0x13 + # end + #end + end # LPC bridge device pci 1.0 on chip superio/NSC/pc87360 - device pnp 2e.0 off # Floppy + device pnp 2e.0 off # Floppy io 0x60 = 0x3f0 irq 0x70 = 6 drq 0x74 = 2 end - device pnp 2e.1 off # Parallel Port + device pnp 2e.1 off # Parallel Port io 0x60 = 0x378 irq 0x70 = 7 end - device pnp 2e.2 off # Com 2 + device pnp 2e.2 off # Com 2 io 0x60 = 0x2f8 irq 0x70 = 3 end - device pnp 2e.3 on # Com 1 + device pnp 2e.3 on # Com 1 io 0x60 = 0x3f8 irq 0x70 = 4 end device pnp 2e.4 off end # SWC device pnp 2e.5 off end # Mouse - device pnp 2e.6 on # Keyboard + device pnp 2e.6 on # Keyboard io 0x60 = 0x60 io 0x62 = 0x64 irq 0x70 = 1 @@ -239,7 +300,7 @@ chip northbridge/amd/amdk8/root_complex register "ide0_enable" = "1" register "ide1_enable" = "1" end - end # device pci 18.0 + end # device pci 18.0 device pci 18.0 on end # LDT1 device pci 18.0 on end # LDT2 @@ -255,6 +316,14 @@ chip northbridge/amd/amdk8/root_complex device pci 19.2 on end device pci 19.3 on end end + end + device apic_cluster 0 on + chip cpu/amd/socket_940 + device apic 0 on end + end + chip cpu/amd/socket_940 + device apic 1 on end + end end end diff --git a/src/mainboard/arima/hdama/Options.lb b/src/mainboard/arima/hdama/Options.lb index 773d698ad2..9d70f5b7ef 100644 --- a/src/mainboard/arima/hdama/Options.lb +++ b/src/mainboard/arima/hdama/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -80,13 +77,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/arima/hdama/auto.c b/src/mainboard/arima/hdama/auto.c index b4d955385f..7790b3ea50 100644 --- a/src/mainboard/arima/hdama/auto.c +++ b/src/mainboard/arima/hdama/auto.c @@ -11,6 +11,7 @@ #include "pc80/serial.c" #include "arch/i386/lib/console.c" #include "ram/ramtest.c" +#include "northbridge/amd/amdk8/cpu_rev.c" #include "northbridge/amd/amdk8/incoherent_ht.c" #include "southbridge/amd/amd8111/amd8111_early_smbus.c" #include "northbridge/amd/amdk8/raminit.h" @@ -18,28 +19,59 @@ #include "lib/delay.c" #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" -#include "northbridge/amd/amdk8/debug.c" -#include "northbridge/amd/amdk8/cpu_rev.c" #include "superio/NSC/pc87360/pc87360_early_serial.c" #include "cpu/amd/mtrr/amd_earlymtrr.c" #include "cpu/x86/bist.h" #define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { - set_bios_reset(); + device_t dev; + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3); + /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); + /* reset */ + set_bios_reset(); outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0); + + /* Reset */ set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } /* @@ -128,6 +160,7 @@ static inline int spd_read_byte(unsigned device, unsigned address) #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" #include "northbridge/amd/amdk8/resourcemap.c" +#include "debug.c" #define FIRST_CPU 1 #define SECOND_CPU 1 @@ -160,13 +193,14 @@ static void main(unsigned long bist) }; int needs_reset; - unsigned nodeid; if (bist == 0) { + unsigned nodeid; /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); enable_lapic(); init_timer(); nodeid = lapicid() & 0xf; + /* Has this cpu already booted? */ if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); @@ -191,13 +225,12 @@ static void main(unsigned long bist) print_info("ht reset -\r\n"); soft_reset(); } - #if 0 print_pci_devices(); #endif enable_smbus(); #if 0 - dump_spd_registers(&cpu[0]); + dump_spd_registers(sizeof(cpu)/sizeof(cpu[0]), cpu); #endif memreset_setup(); @@ -205,6 +238,8 @@ static void main(unsigned long bist) #if 0 dump_pci_devices(); +#endif +#if 0 dump_pci_device(PCI_DEV(0, 0x18, 2)); #endif diff --git a/src/mainboard/arima/hdama/debug.c b/src/mainboard/arima/hdama/debug.c new file mode 100644 index 0000000000..55c62649c8 --- /dev/null +++ b/src/mainboard/arima/hdama/debug.c @@ -0,0 +1,143 @@ + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +static void dump_spd_registers(int controllers, const struct mem_controller *ctrl) +{ + int n; + for(n = 0; n < controllers; n++) { + int i; + print_debug("\r\n"); + activate_spd_rom(&ctrl[n]); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl[n].channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(n); + print_debug_char('.'); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = spd_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } +#if 0 + byte = status & 0xff; + print_debug_hex8(byte); +#else + print_debug_hex8(status & 0xff); +#endif + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl[n].channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(n); + print_debug_char('.'); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = spd_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } +#if 0 + byte = status & 0xff; + print_debug_hex8(byte); +#else + print_debug_hex8(status & 0xff); +#endif + print_debug_char(' '); + } + print_debug("\r\n"); + } + } + } +} diff --git a/src/mainboard/arima/hdama/mptable.c b/src/mainboard/arima/hdama/mptable.c index 9287b7333e..ef32251e7d 100644 --- a/src/mainboard/arima/hdama/mptable.c +++ b/src/mainboard/arima/hdama/mptable.c @@ -4,6 +4,40 @@ #include <string.h> #include <stdint.h> +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -12,6 +46,7 @@ void *smp_write_config_table(void *v) struct mp_config_table *mc; unsigned char bus_num; unsigned char bus_isa; + unsigned char bus_chain_0; unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; @@ -38,8 +73,15 @@ void *smp_write_config_table(void *v) { device_t dev; + /* HT chain 0 */ + bus_chain_0 = node_link_to_bus(0, 0); + if (bus_chain_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_chain_0 = 1; + } + /* 8111 */ - dev = dev_find_slot(1, PCI_DEVFN(0x03,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); @@ -52,7 +94,7 @@ void *smp_write_config_table(void *v) bus_isa = 5; } /* 8131-1 */ - dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0)); if (dev) { bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -63,7 +105,7 @@ void *smp_write_config_table(void *v) bus_8131_1 = 2; } /* 8131-2 */ - dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0)); if (dev) { bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -87,7 +129,7 @@ void *smp_write_config_table(void *v) device_t dev; struct resource *res; /* 8131 apic 3 */ - dev = dev_find_slot(1, PCI_DEVFN(0x01,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { @@ -95,7 +137,7 @@ void *smp_write_config_table(void *v) } } /* 8131 apic 4 */ - dev = dev_find_slot(1, PCI_DEVFN(0x02,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { diff --git a/src/mainboard/arima/hdama/reset.c b/src/mainboard/arima/hdama/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/arima/hdama/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/emulation/qemu-i386/Options.lb b/src/mainboard/emulation/qemu-i386/Options.lb index 9047dc6000..d12a1c3592 100644 --- a/src/mainboard/emulation/qemu-i386/Options.lb +++ b/src/mainboard/emulation/qemu-i386/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -73,13 +70,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=0 ## -## Funky hard reset implementation -## -# default HARD_RESET_BUS=1 -# default HARD_RESET_DEVICE=4 -# default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=0 diff --git a/src/mainboard/ibm/e325/Config.lb b/src/mainboard/ibm/e325/Config.lb index 604a82d46d..1633c8f810 100644 --- a/src/mainboard/ibm/e325/Config.lb +++ b/src/mainboard/ibm/e325/Config.lb @@ -45,6 +45,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o ## ## Romcc output diff --git a/src/mainboard/ibm/e325/Options.lb b/src/mainboard/ibm/e325/Options.lb index 9bad595658..a1b21fd68a 100644 --- a/src/mainboard/ibm/e325/Options.lb +++ b/src/mainboard/ibm/e325/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -75,13 +72,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/ibm/e325/reset.c b/src/mainboard/ibm/e325/reset.c new file mode 100644 index 0000000000..7f58d01410 --- /dev/null +++ b/src/mainboard/ibm/e325/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 1); +} diff --git a/src/mainboard/intel/jarrell/Config.lb b/src/mainboard/intel/jarrell/Config.lb new file mode 100644 index 0000000000..adca342a78 --- /dev/null +++ b/src/mainboard/intel/jarrell/Config.lb @@ -0,0 +1,213 @@ +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can cached to speed up linuxBIOS, +## execution speed. +## +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +## +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -mcpu=p4 -fno-simplify-phi -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7520 + device pci_domain 0 on + device pci 00.0 on end + device pci 00.1 on end + device pci 01.0 on end + device pci 02.0 on + chip southbridge/intel/pxhd # pxhd1 + device pci 00.0 on end + device pci 00.1 on end + device pci 00.2 on + chip drivers/generic/generic + device pci 04.0 on end + device pci 04.1 on end + end + end + device pci 00.3 on end + end + end + device pci 06.0 on end + chip southbridge/intel/ich5r # ich5r + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.2 on end + device pci 1d.3 off end + device pci 1d.7 on end + device pci 1e.0 on + chip drivers/ati/ragexl + device pci 0c.0 on end + end + end + device pci 1f.0 on + chip superio/NSC/pc87427 + device pnp 2e.0 off end + device pnp 2e.2 on +# io 0x60 = 0x2f8 +# irq 0x70 = 3 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on +# io 0x60 = 0x3f8 +# irq 0x70 = 4 + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 on + io 0x60 = 0x60 + io 0x62 = 0x64 + irq 0x70 = 1 + end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a off end + device pnp 2e.f on end + device pnp 2e.10 off end + device pnp 2e.14 off end + end + end + device pci 1f.1 on end + device pci 1f.2 off end + device pci 1f.3 on end + device pci 1f.5 off end + device pci 1f.6 off end + register "gpio[40]" = "ICH5R_GPIO_USE_AS_GPIO" + register "gpio[48]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_OUTPUT | ICH5R_GPIO_LVL_LOW" + register "gpio[41]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_INPUT" + end + end + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # cpu 0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # cpu 1 + device apic 6 on end + end + end +end diff --git a/src/mainboard/intel/jarrell/Options.lb b/src/mainboard/intel/jarrell/Options.lb new file mode 100644 index 0000000000..a7a5c7288a --- /dev/null +++ b/src/mainboard/intel/jarrell/Options.lb @@ -0,0 +1,242 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY +uses MAX_REBOOT_CNT +uses USE_WATCHDOG_ON_BOOT + + +### +### Build options +### + +## +## Because we do the stutter start we need more attempts +## +default MAX_REBOOT_CNT=8 + +## +## Use the watchdog to break out of a lockup condition +## +default USE_WATCHDOG_ON_BOOT=1 + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=2097152 + + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=9 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="SE7520JR22D" +default MAINBOARD_VENDOR= "Intel" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x8086 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x1079 +#default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x3437 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end diff --git a/src/mainboard/intel/jarrell/auto.c b/src/mainboard/intel/jarrell/auto.c new file mode 100644 index 0000000000..7e9cd99e96 --- /dev/null +++ b/src/mainboard/intel/jarrell/auto.c @@ -0,0 +1,150 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/ich5r/ich5r_early_smbus.c" +#include "northbridge/intel/E7520/raminit.h" +#include "superio/NSC/pc87427/pc87427.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "watchdog.c" +#include "reset.c" +#include "power_reset_check.c" +#include "jarrell_fixups.c" +#include "superio/NSC/pc87427/pc87427_early_init.c" +#include "northbridge/intel/E7520/memory_initialized.c" +#include "cpu/x86/bist.h" + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP2) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP1) + +#define DEVPRES_CONFIG (DEVPRES_D1F0 | DEVPRES_D2F0 | DEVPRES_D6F0) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +/* Beta values: 0x00090800 */ +/* Silver values: 0x000a0900 */ +#define RECVENA_CONFIG 0x000a090a +#define RECVENB_CONFIG 0x000a090a +#define DIMM_MAP_LOGICAL 0x0124 + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7520/raminit.c" +#include "sdram/generic_sdram.c" +#include "debug.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = { (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, 0 }, + .channel1 = { (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, 0 }, + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + pc87427_disable_dev(CONSOLE_SERIAL_DEV); + pc87427_disable_dev(HIDDEN_SERIAL_DEV); + pc87427_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + /* Enable Serial 2 lines instead of GPIO */ + outb(0x2c, 0x2e); + outb((inb(0x2f) & (~1<<1)), 0x2f); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); + + pc87427_enable_dev(PC87427_GPIO_DEV, SIO_GPIO_BASE); + + pc87427_enable_dev(PC87427_XBUS_DEV, SIO_XBUS_BASE); + xbus_cfg(PC87427_XBUS_DEV); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + print_pci_devices(); +#endif + enable_smbus(); +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); + power_down_reset_check(); +// dump_ipmi_registers(); + mainboard_set_e7520_leds(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); + ich5_watchdog_on(); +#if 0 + dump_pci_devices(); +#endif +#if 0 + dump_pci_device(PCI_DEV(0, 0x00, 0)); + dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, 0x01000000); + /* check the first 1M in the 3rd Gig */ + ram_check(0x30100000, 0x31000000); +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#endif +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/intel/jarrell/chip.h b/src/mainboard/intel/jarrell/chip.h new file mode 100644 index 0000000000..7cc59091bd --- /dev/null +++ b/src/mainboard/intel/jarrell/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_intel_jarrell_ops; + +struct mainboard_intel_jarrell_config { + int nothing; +}; diff --git a/src/mainboard/intel/jarrell/cmos.layout b/src/mainboard/intel/jarrell/cmos.layout new file mode 100644 index 0000000000..71387a2e4b --- /dev/null +++ b/src/mainboard/intel/jarrell/cmos.layout @@ -0,0 +1,82 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 376 r 0 reserved_memory +376 1 e 1 power_up_watchdog +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 2 hyper_threading +397 1 e 1 pxhd_bus_speed_100 +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/intel/jarrell/debug.c b/src/mainboard/intel/jarrell/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/intel/jarrell/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/intel/jarrell/failover.c b/src/mainboard/intel/jarrell/failover.c new file mode 100644 index 0000000000..5029d98611 --- /dev/null +++ b/src/mainboard/intel/jarrell/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7520/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/intel/jarrell/irq_tables.c b/src/mainboard/intel/jarrell/irq_tables.c new file mode 100644 index 0000000000..75071c131a --- /dev/null +++ b/src/mainboard/intel/jarrell/irq_tables.c @@ -0,0 +1,37 @@ +/* PCI: Interrupt Routing Table found at 0x40114180 size = 320 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 320, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x24d0, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0x38, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x08, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, 0xf8, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, 0xe8, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00, 0x00}, + {0x02, 0x20, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x03, 0x28, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, 0x60, {{0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x02, 0x08, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}}, 0x04, 0x00}, + {0x02, 0x10, {{0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}, {0x60, 0xdcf8}}, 0x05, 0x00}, + {0x02, 0x18, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0xdcf8}}, 0x06, 0x00}, + {0x03, 0x08, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}}, 0x01, 0x00}, + {0x03, 0x10, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x61, 0xdcf8}}, 0x02, 0x00}, + {0x03, 0x18, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x61, 0xdcf8}}, 0x03, 0x00}, + {0x00, 0x10, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00}, + {0x00, 0x18, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00}, + {0x00, 0x20, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00}, + {0x00, 0x28, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00}, + {0x00, 0x30, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00}, + {0x00, 0x38, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdc78}, {0x63, 0xdcf8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/intel/jarrell/jarrell_fixups.c b/src/mainboard/intel/jarrell/jarrell_fixups.c new file mode 100644 index 0000000000..d8c694b4af --- /dev/null +++ b/src/mainboard/intel/jarrell/jarrell_fixups.c @@ -0,0 +1,123 @@ +#include <arch/romcc_io.h> + +static void mch_reset(void) +{ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev != PCI_DEV_INVALID) { + /* I/O space is always enables */ + + /* Set gpio base */ + pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1); + base = ICH5_GPIOBASE; + + /* Enable GPIO Bar */ + value = pci_read_config32(dev, 0x5c); + value |= 0x10; + pci_write_config32(dev, 0x5c, value); + + /* Set GPIO 19 mux to IO usage */ + value = inl(base); + value |= (1 <<19); + outl(value, base); + + /* Pull GPIO 19 low */ + value = inl(base + 0x0c); + value &= ~(1 << 19); + outl(value, base + 0x0c); + } + return; +} + + + +static void mainboard_set_e7520_pll(unsigned bits) +{ + uint16_t gpio_index; + uint8_t data; + device_t dev; + + /* currently only handle the Jarrell/PC87427 case */ + dev = PC87427_GPIO_DEV; + + + pnp_set_logical_device(dev); + gpio_index = pnp_read_iobase(dev, 0x60); + + /* select SIO GPIO port 4, pin 2 */ + pnp_write_config(dev, PC87427_GPSEL, ((pnp_read_config(dev, PC87427_GPSEL) & 0x88) | 0x42)); + /* set to push-pull, enable output */ + pnp_write_config(dev, PC87427_GPCFG1, 0x03); + + /* select SIO GPIO port 4, pin 4 */ + pnp_write_config(dev, PC87427_GPSEL, ((pnp_read_config(dev, PC87427_GPSEL) & 0x88) | 0x44)); + /* set to push-pull, enable output */ + pnp_write_config(dev, PC87427_GPCFG1, 0x03); + + /* set gpio 42,44 signal levels */ + data = inb(gpio_index + PC87427_GPDO_4); + if ((data & 0x14) == (0xff & (((bits&2)?0:1)<<4 | ((bits&1)?0:1)<<2))) { + print_debug("set_pllsel: correct settings detected!\r\n"); + return; /* settings already configured */ + } else { + outb((data & 0xeb) | ((bits&2)?0:1)<<4 | ((bits&1)?0:1)<<2, gpio_index + PC87427_GPDO_4); + /* reset */ + print_debug("set_pllsel: settings adjusted, now resetting...\r\n"); + // hard_reset(); /* should activate a PCI_RST, which should reset MCH, but it doesn't seem to work ???? */ +// mch_reset(); + full_reset(); + } + return; +} + + +static void mainboard_set_e7520_leds(void) +{ + uint8_t cnt; + uint8_t data; + device_t dev; + + /* currently only handle the Jarrell/PC87427 case */ + dev = PC87427_GPIO_DEV; + + pnp_set_logical_device(dev); + + /* enable */ + outb(0x30, 0x2e); + outb(0x01, 0x2f); + outb(0x2d, 0x2e); + outb(0x01, 0x2f); + + /* Set auto mode for dimm leds and post */ + outb(0xf0,0x2e); + outb(0x70,0x2f); + outb(0xf4,0x2e); + outb(0x30,0x2f); + outb(0xf5,0x2e); + outb(0x88,0x2f); + outb(0xf6,0x2e); + outb(0x00,0x2f); + outb(0xf7,0x2e); + outb(0x90,0x2f); + outb(0xf8,0x2e); + outb(0x00,0x2f); + + /* Turn the leds off */ + outb(0x00,0x88); + outb(0x00,0x90); + + /* Disable the ports */ + outb(0xf5,0x2e); + outb(0x00,0x2f); + outb(0xf7,0x2e); + outb(0x00,0x2f); + outb(0xf4,0x2e); + outb(0x00,0x2f); + + return; +} + + + + diff --git a/src/mainboard/intel/jarrell/mainboard.c b/src/mainboard/intel/jarrell/mainboard.c new file mode 100644 index 0000000000..9b25e0adeb --- /dev/null +++ b/src/mainboard/intel/jarrell/mainboard.c @@ -0,0 +1,13 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include <arch/io.h> +#include "chip.h" + +struct chip_operations mainboard_intel_e7520_ops = { + CHIP_NAME("Intel Jarell mainboard ") +}; + diff --git a/src/mainboard/intel/jarrell/microcode_updates.c b/src/mainboard/intel/jarrell/microcode_updates.c new file mode 100644 index 0000000000..54daab0779 --- /dev/null +++ b/src/mainboard/intel/jarrell/microcode_updates.c @@ -0,0 +1,1563 @@ +/* WARNING - Intel has a new data structure that has variable length + * microcode update lengths. They are encoded in int 8 and 9. A + * dummy header of nulls must terminate the list. + */ + +static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = { + /* + Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000. + These microcode updates are distributed for the sole purpose of + installation in the BIOS or Operating System of computer systems + which include an Intel P6 family microprocessor sold or distributed + to or by you. You are authorized to copy and install this material + on such systems. You are not authorized to use this material for + any other purpose. + */ + + /* M1DF340E.TXT - Noconoa D-0 */ + + + 0x00000001, /* Header Version */ + 0x0000000e, /* Patch ID */ + 0x05042004, /* DATE */ + 0x00000f34, /* CPUID */ + 0x9b18561d, /* Checksum */ + 0x00000001, /* Loader Version */ + 0x0000001d, /* Platform ID */ + 0x000017d0, /* Data size */ + 0x00001800, /* Total size */ + 0x00000000, /* reserved */ + 0x00000000, /* reserved */ + 0x00000000, /* reserved */ + 0x9fbf327a, + 0x2b41b451, + 0xb0a79cab, + 0x6b62b8fd, + 0xc953d679, + 0x1e462145, + 0x59d96ae5, + 0xb90dfc00, + 0x4f6bd233, + 0xa8dda234, + 0xb96b5eb7, + 0x588fc98f, + 0xdd59a87c, + 0xb038ad4c, + 0x338af84c, + 0x44842e0d, + 0x2e664aa6, + 0xd46497b7, + 0xddbcd376, + 0xd86dd62a, + 0x27ceec6e, + 0xb089ff2e, + 0xfc549965, + 0x556f5b78, + 0xa8c4732c, + 0x0969180d, + 0x14a346e8, + 0x561a91b3, + 0x1cd21cde, + 0xd09d06bc, + 0x3a4cae91, + 0x5d23fa54, + 0x43747e8d, + 0x19ff0547, + 0xdae0e17a, + 0xc16bab85, + 0x2364fea6, + 0x8508f3c6, + 0x598ca70f, + 0x72fb0579, + 0x24c28f46, + 0xed19ad6b, + 0xcd6206fe, + 0xe3d091e8, + 0xb7f1f9f1, + 0x501c1c77, + 0x5fdda272, + 0xbdc8301b, + 0x64b200ea, + 0xb8460b09, + 0x26d125ea, + 0x03e27414, + 0x3d023f17, + 0x0b0520c8, + 0x74fba5c6, + 0xc3d761de, + 0x672cf9fa, + 0x4c000ff0, + 0x0a8bbda4, + 0x5dd7b3b1, + 0x439e12f1, + 0x235444bb, + 0xa7513c27, + 0x8ce97fbf, + 0xb41f857c, + 0x6e71fd9d, + 0xd11f2fe3, + 0x5d92f44d, + 0x4b06f5fa, + 0x7695eed0, + 0x3aa045e8, + 0x9ce894d4, + 0x02a1723a, + 0xa4d9e99e, + 0x0ca6f5ec, + 0x1df8ee10, + 0x82d9b0a9, + 0xb7fceca0, + 0x0eebfe97, + 0xda2e8c7b, + 0xf9ffdf4b, + 0xb6c84538, + 0xb7eee9d7, + 0x89f8e993, + 0x7d51dbf8, + 0xc75f6389, + 0xd2e76e6c, + 0x60fdc275, + 0x6758a029, + 0x9d463f02, + 0x40069261, + 0x55ebc0b5, + 0xa90d5bb2, + 0x33a3d807, + 0xa6e603c8, + 0x4b0e2505, + 0xd28eb45d, + 0xeab8055b, + 0x97439c5f, + 0xb3ccb9dd, + 0xb33f1bb5, + 0xd34e6009, + 0x946e7d07, + 0x68908cea, + 0x435581e5, + 0xb2ceee79, + 0x112df532, + 0xd7d079f5, + 0xbcb997f9, + 0xdc3c7807, + 0x5c6b4af9, + 0x3f919e49, + 0x62a597b9, + 0x20e4fc37, + 0x4241bc5c, + 0x66636de1, + 0x2a0f3988, + 0x62281e5f, + 0x9d19500a, + 0x9f349dbf, + 0x9b16869d, + 0x0299fec1, + 0xa013cf08, + 0x36e47a83, + 0x8cf78105, + 0xa92a7080, + 0xece3a363, + 0x01361d90, + 0x1555e2b4, + 0x9ec1207c, + 0x93f5f638, + 0x1854d4e4, + 0xa5768108, + 0xe6b867bc, + 0xec91c0a3, + 0xb42c40b9, + 0x7a543ed2, + 0xbe080c40, + 0x72edfcda, + 0xd2ddde37, + 0x1e1f1563, + 0xd24ca500, + 0x761df139, + 0xc9e79091, + 0xab44cdcb, + 0x16c204d7, + 0x5d4ff67b, + 0x8651ea63, + 0x09d8dc41, + 0x643cddcf, + 0x5709c4b7, + 0x04384755, + 0x30e52749, + 0x1329aac2, + 0x7bf64fad, + 0x5d3e6b49, + 0x515aa075, + 0xfe7e7f8d, + 0x5461d781, + 0x0547b8b2, + 0xa71b89c7, + 0x30f03604, + 0xe37970a5, + 0x169e27f9, + 0x1024e384, + 0x62198879, + 0xd689b295, + 0xa5a340c0, + 0x8460b084, + 0x86a301c4, + 0x2e589fca, + 0xf4687ad0, + 0x8d4b4c7d, + 0x0d9635e6, + 0x91aac10f, + 0xcff70e8b, + 0x904c0678, + 0x56237892, + 0x4d8eefc5, + 0xdd1b74d2, + 0x6405fb4b, + 0x8b15cc77, + 0x83f3fca3, + 0x1ad9724c, + 0xbccceb84, + 0x18bb629d, + 0x5ae70712, + 0x6ca076d8, + 0xa231c82b, + 0x6a60573f, + 0x9046baf1, + 0x7e08ade7, + 0xd949e10a, + 0xfc5a396f, + 0x9cb8eaaa, + 0x4e050c89, + 0x751b8672, + 0x0e0d565a, + 0x837787e8, + 0xdb01db4e, + 0xb41d9bb5, + 0x41e4ce55, + 0xfe1700ae, + 0x89e70c4f, + 0x05f007b9, + 0x105a311e, + 0xa8793ba4, + 0xa7572e49, + 0xaf72e942, + 0x59f5c594, + 0x583f872b, + 0x9041d9de, + 0x72f628bd, + 0x8bb19420, + 0x957eca65, + 0x1b3bd477, + 0x581c475a, + 0x9a87bbbc, + 0x2fa9cca5, + 0x6115e020, + 0xd44f74ef, + 0x37ea131f, + 0x3f07b084, + 0x543aca7a, + 0xe91d50c6, + 0xc9139700, + 0xcd0182ac, + 0xe09514f7, + 0xfe01038e, + 0x7c97be09, + 0xbc79c28b, + 0x18aea71f, + 0xd6776f66, + 0xc020822a, + 0xd7fc90ac, + 0x382cd812, + 0x60c49263, + 0xb279295a, + 0x69eb4399, + 0x8e32fd5e, + 0xfe739807, + 0x1495d3e5, + 0xbf025c3f, + 0x190920d3, + 0x1680dbaf, + 0x1eda0681, + 0x93bac657, + 0x0e18680c, + 0x2e5d85f6, + 0x100fa070, + 0x171e7931, + 0x79f779fa, + 0x8723130d, + 0x222c2d90, + 0xbffd0448, + 0x31e7a11e, + 0x15952725, + 0x0a0d6880, + 0x2045bb27, + 0x65903721, + 0x009adfcf, + 0xc5b6017a, + 0x98920c52, + 0x960b5e3f, + 0x5bc23253, + 0x0c299c66, + 0xd0ac9e6e, + 0xf7735ce5, + 0xa4e70ec1, + 0x0b0dac09, + 0x7a5a9bfa, + 0x06001d88, + 0x316f6221, + 0x7fe9aeb1, + 0x22543edc, + 0xf8b94fde, + 0x392bf047, + 0xb0f1bc2c, + 0x984d8795, + 0xa8db0148, + 0xc42addb0, + 0x9883a82c, + 0xe8676a43, + 0x95f5ccf7, + 0x06afe12c, + 0x756a1b33, + 0x1519091b, + 0x61c5ccd2, + 0xf3288b41, + 0x7d33e180, + 0x76cc5a24, + 0xd1a18aa4, + 0xa353a07c, + 0x4e173b6b, + 0x3ad5b70c, + 0x6440b4c9, + 0x37979ae9, + 0x0c517fc6, + 0xc8252fb3, + 0x21a33062, + 0xe21e8070, + 0xa3e8fe61, + 0xb8e22e6e, + 0xd6f2fd79, + 0xc9185337, + 0xd8ef8db8, + 0x952e6ac3, + 0x2ba27d5a, + 0xe4b502d7, + 0xc720f8f4, + 0x5601e451, + 0x2dabcbf3, + 0x06d6bf4e, + 0x580e0ec5, + 0x42099aa9, + 0x288a795a, + 0x09d59ae5, + 0xc56311bf, + 0xc9a0be28, + 0x82ab89e4, + 0x63a6b7de, + 0xb654846e, + 0x53fa8bbc, + 0x766e12b2, + 0xa7a5de15, + 0x951a8fe8, + 0xa638273b, + 0x78ce2cc7, + 0x1cff0475, + 0x53318a42, + 0x1a30f362, + 0x55d14483, + 0xf19b2f8e, + 0x66a791b8, + 0xf454cc9b, + 0xc688da27, + 0x8877ee5d, + 0x7c66e45e, + 0x8fa7945b, + 0x9eb7942f, + 0xdedf49b4, + 0x22ae7a86, + 0xd2eaf279, + 0x5f7547a2, + 0x13872ebf, + 0x70ebb737, + 0x9e433f1c, + 0x40987dc1, + 0x9321c994, + 0x832871b0, + 0x77e8ebad, + 0x0a2853a2, + 0x75460864, + 0x4028c1f7, + 0x066fb1db, + 0x6a8a47dd, + 0x8ec0f102, + 0x3d9502bb, + 0x38e3b20b, + 0x1d24cebb, + 0xcd316180, + 0x2e39fcaa, + 0xd68dff5b, + 0x1b8d3990, + 0xce9715b9, + 0xcb3ef0d4, + 0xc87865ec, + 0x6eb72a87, + 0xf02302f8, + 0x9d06420c, + 0x013ada55, + 0x482dc805, + 0x469d83e4, + 0x4f64348b, + 0xb320168a, + 0x736063a3, + 0xa44e2034, + 0x14cf72d6, + 0x7758468f, + 0xdc130a50, + 0xcd3a98d1, + 0xc7d3ec32, + 0x6008c722, + 0x7729faf1, + 0xca184989, + 0xcdfbfe93, + 0x140df767, + 0xeab2b859, + 0xef388f9e, + 0xcfad00e8, + 0xb3edb3f2, + 0xd9bf19b3, + 0x7a988c4f, + 0xc9478520, + 0xb0120f5a, + 0x6a2639aa, + 0x8a8f628f, + 0x446a7769, + 0xc02ae4de, + 0x0869bd59, + 0xef8ccf75, + 0x46670a06, + 0xea9aeb5a, + 0x16162088, + 0x22b7f89e, + 0x54f46cae, + 0xf401a8fe, + 0xeb80ce25, + 0xfd811c6a, + 0x95714e43, + 0x6369cc4a, + 0x091d595a, + 0x0ed23abc, + 0x8a5b0807, + 0x8f6d34b4, + 0x5f6048fe, + 0x03bfcc6d, + 0x54a49828, + 0x36e096a4, + 0x1dfe968e, + 0x826336c0, + 0xfb2453dd, + 0xab618401, + 0x7c0a4e4a, + 0xab852bb5, + 0xd1182cab, + 0x54688e26, + 0xf8bc5226, + 0x92e39ae8, + 0x4969458d, + 0xb5e9e4e0, + 0x1cc35776, + 0x066a5f0e, + 0xa0f944bd, + 0xe6c4db63, + 0x1c171fd6, + 0x36bdf158, + 0x75c65c25, + 0x4200bb72, + 0x4616777f, + 0xbc70b23c, + 0x4546dda2, + 0x7fa13471, + 0xe4db3be2, + 0x0e1eb25a, + 0xf0253cc3, + 0xcaef50f5, + 0xaa67a3f1, + 0x6fabd333, + 0xe3e3686e, + 0xe4398405, + 0x18334de1, + 0xbb8eedef, + 0xbdfe0fd4, + 0x635a8be2, + 0x502d965f, + 0x41308946, + 0x1e5ae64d, + 0xbeb7ff7a, + 0xc33a7af0, + 0x8d5a19a6, + 0x77547cd0, + 0x8c98d59f, + 0x2daeb33e, + 0x2bace475, + 0x265cd5f1, + 0x4f95e4c4, + 0x7f4dbce2, + 0xebb65b1b, + 0xb4a7740b, + 0x82bcbfed, + 0x7670d288, + 0xbc69ee8f, + 0x0a073dbf, + 0x320f0800, + 0xfa581147, + 0x13989462, + 0x45a6b4a3, + 0x8a651db1, + 0xa35444d4, + 0xbf230bac, + 0xb313dbe4, + 0xbe09cd73, + 0x13c228a2, + 0x85241e58, + 0xeb9e5fc7, + 0xf07df2c7, + 0x5afc6231, + 0x88f06beb, + 0xee11a03c, + 0xf48b6388, + 0x67a1bb4e, + 0x4ab92ac0, + 0x5b29973d, + 0xf59ff86c, + 0x1206dedc, + 0x999ccb7a, + 0x629c3310, + 0x5b3e217f, + 0x92354d19, + 0xc57f1f99, + 0x80652554, + 0x8c44b1ad, + 0xfba863cd, + 0x1a499196, + 0xe6ecddb4, + 0x66d53c7d, + 0x81f63062, + 0x5f6a6cf8, + 0xd493e938, + 0xa3e9fe77, + 0xbc4f2d8a, + 0x733fb762, + 0xa05280d2, + 0x6005f547, + 0x6cf17c67, + 0x5a69d045, + 0x414383a5, + 0xb16f5425, + 0x6ce49c82, + 0x331ed575, + 0x12f830ce, + 0x63bc960a, + 0x38a05f7d, + 0xda50d724, + 0xfc2e58a1, + 0x763ac7d3, + 0x3dd8abdf, + 0xcafc7a77, + 0x80ebae62, + 0xf2d70ca4, + 0xcf9a6db7, + 0xfffda692, + 0x264713c1, + 0x8a1bd6a0, + 0x13711bad, + 0x4a7ca477, + 0x4d07231a, + 0x521210a7, + 0xaea41847, + 0x2197f6cf, + 0x5bbee70c, + 0xbe5aae01, + 0x10e53ed6, + 0x7f00a280, + 0x96d72d54, + 0xa5ae6425, + 0xc721855b, + 0xc2a8a0dc, + 0x60b56433, + 0xd945cc76, + 0x18a092f8, + 0x552020f4, + 0xe46528da, + 0xe4cca6c4, + 0xf4b00110, + 0x714a91de, + 0x10e19450, + 0xcd57f7f8, + 0x7ddcd6ee, + 0xbf3489b8, + 0xd77c098a, + 0x72152d71, + 0x81ab14d4, + 0xd97cfe8a, + 0x4953c6ba, + 0x0853017a, + 0x9a64b325, + 0x1645516f, + 0xd5ece3a9, + 0xab76d41b, + 0xb64936d6, + 0x7162d5d7, + 0x344a0ae3, + 0x7d180b8a, + 0xd8eb3b6c, + 0xfe39169e, + 0x0e32b004, + 0xb1b6ef0f, + 0x4efc612f, + 0x3ed51902, + 0x7ab26840, + 0x3f593b3b, + 0x00ec59e4, + 0x9ac2db9a, + 0x6c42f681, + 0x9b5dec47, + 0x1bd6c7b4, + 0xd9f0fe7c, + 0x9660dac2, + 0x1d2a5d0f, + 0x569465a0, + 0x15780587, + 0xff71e10c, + 0xe42c2a6d, + 0x2a2fc9b7, + 0xd873f66b, + 0x0ace2492, + 0x3b32947a, + 0xb432db31, + 0x23c33b9e, + 0x6698e729, + 0x094d8174, + 0xf0d17bcf, + 0x456706b7, + 0x12ae6c75, + 0xaed5319b, + 0xa874a599, + 0x8fb6643b, + 0xabd58c0c, + 0xc50e83e7, + 0x7a558c8b, + 0x4e11c7e6, + 0x1552bcb1, + 0xd408589f, + 0x679fc9a7, + 0x47c0800d, + 0xb1f7afbe, + 0x109fe2b9, + 0xb54361b9, + 0xea21d805, + 0x461cd956, + 0xc191f1b4, + 0x949eb6a6, + 0x16aedf85, + 0x1020f31e, + 0xfde8914a, + 0x12e27158, + 0xb418a938, + 0x655c23ac, + 0xf3909c7c, + 0x421a309c, + 0xf16d522f, + 0x65f120a2, + 0x51ccd73c, + 0xf1913c82, + 0x25dfd7a9, + 0x62caad88, + 0x76fc1229, + 0xecf5a837, + 0x85282036, + 0x89f74447, + 0xe5d8e2d3, + 0x66375e99, + 0x792b58a2, + 0x85094329, + 0x1b6cd378, + 0x2cb27a8b, + 0xdbda0f3b, + 0x4e8f6f83, + 0xde3626ac, + 0x19bd8301, + 0x30129851, + 0x5ea607ef, + 0x5421188c, + 0xb7fd392e, + 0x286dfb6e, + 0x5be2d96d, + 0xfe4606cc, + 0x13266bd0, + 0x22512e73, + 0x7fe7d929, + 0xa4e42e7e, + 0xeeba5488, + 0xf69949cb, + 0x772ae500, + 0x044f68b6, + 0xcaa790f7, + 0x653d862b, + 0xdab1dca2, + 0x617fae01, + 0x58fcbcdd, + 0xb94cbd50, + 0x4deb82eb, + 0xf3aea152, + 0xa39e0413, + 0xb51f95a9, + 0xbeeb2054, + 0xda3a5a26, + 0xc53dd642, + 0xa01fe6d0, + 0xf60cecfd, + 0x514b4044, + 0x74ca621a, + 0x530b6b6a, + 0x7415aad3, + 0xe89d6436, + 0xe616ffe2, + 0x9daa5272, + 0x25391d23, + 0xfb28424e, + 0x1364802c, + 0xe060f84d, + 0x0ae2f131, + 0x6ce62b10, + 0x39937124, + 0xa3aaca72, + 0x0816c8c2, + 0x11e8f5d1, + 0xd95fdf39, + 0xc2cd550b, + 0x9190a02f, + 0xe8c20598, + 0xdbf56feb, + 0x9caf355b, + 0x9bd648a7, + 0xde575e2e, + 0xb5b45019, + 0x9f390f47, + 0x9b4e7412, + 0x13066ce2, + 0xfa475b46, + 0xfeec8697, + 0x8e0e56a6, + 0xfa6f6aef, + 0x57f6dc81, + 0x5d2316f1, + 0xe28e1249, + 0xcd22f97a, + 0x947ff08d, + 0x1124a7c2, + 0x8dbcfd6e, + 0x8da10ea5, + 0x9962e5e5, + 0x847516b4, + 0x65e725bc, + 0xaacaf361, + 0xacd16e3c, + 0x972a3137, + 0x0e4a4ad6, + 0x983a5779, + 0x9588efa8, + 0x3e320974, + 0x33437ea5, + 0x6e0211cd, + 0x8071a615, + 0x6f372d73, + 0x43880814, + 0x975c105f, + 0x7e571853, + 0xf6254581, + 0x28afacf3, + 0x9bb1937c, + 0x3a3f584a, + 0xa54f46b8, + 0xc23014a9, + 0x71b8f1d0, + 0xa4e997d3, + 0xc823c95a, + 0xfc9c7180, + 0x6c08eaff, + 0x6667f1fd, + 0x2b3852c6, + 0x05ca73d6, + 0x074d88b7, + 0xb9bccd0f, + 0xa9287294, + 0x6ef285b7, + 0x4d8ea775, + 0x51080197, + 0x8516571c, + 0xc50d7bc6, + 0x38f29672, + 0x417e0842, + 0xd8caea6e, + 0xadd9841e, + 0x4874471b, + 0x32714ada, + 0x3a736227, + 0xbec8a741, + 0x93ffa4f7, + 0xc6a65f24, + 0xad353a96, + 0x37f7abe3, + 0x83002f1e, + 0x5344eb50, + 0x1933be53, + 0x3d4aafd5, + 0x44686e7c, + 0xcb3c0c04, + 0x3126c38e, + 0x062eb627, + 0xabba5dc8, + 0x26a8ec35, + 0x751d4863, + 0x23caa099, + 0x032c8c08, + 0xf2428467, + 0x580242e1, + 0x2f1e8114, + 0x177793cb, + 0x2bc1a8a8, + 0x3a95b194, + 0xe6f65760, + 0x0b1cede5, + 0x93f08f46, + 0xbabbf998, + 0x73fc1072, + 0x53217830, + 0xf336109c, + 0x00018216, + 0x4fb6470a, + 0xc715b776, + 0x3f312e0e, + 0x6a9a0cbe, + 0xe719d8bb, + 0x5b434e50, + 0xbe5bc12f, + 0x05fec000, + 0x21b2478a, + 0x7efa9d65, + 0x4b7d2ce1, + 0x4cdb4f14, + 0x1a41a5c4, + 0x424d94f3, + 0xf364aa6e, + 0xe003899b, + 0x2284d34e, + 0xc235c39c, + 0xd0e54c8d, + 0x969ed32e, + 0xadca1e41, + 0x1cf5dd48, + 0xfeaee739, + 0x8aa95f56, + 0x79123691, + 0xa8d5e6df, + 0x14941574, + 0xa002f08e, + 0x81125113, + 0x835eac03, + 0x23e1df47, + 0x5f3856fe, + 0xf5bc6869, + 0xce6f65f1, + 0xf8f88627, + 0xb0a74080, + 0xc2c67512, + 0x47510b62, + 0x757a8619, + 0xd358a6cf, + 0xefd36be3, + 0x0d8e6ebe, + 0xe244e367, + 0xdaf5202b, + 0x9da43b72, + 0x799510b2, + 0x7aba0824, + 0xc9375579, + 0x430b0595, + 0x49aeff96, + 0x471a76a4, + 0x6d902adb, + 0xcd87aab5, + 0x7767a00d, + 0x5960ca6e, + 0x4f8ef870, + 0x309fa8bf, + 0x46d14c6b, + 0xd75ceaf2, + 0x59d42f82, + 0xd282a8bc, + 0x52639643, + 0xd7cf10ce, + 0x943a78f5, + 0xc69e88e3, + 0x10eeeba0, + 0xcafc5c65, + 0xff74b46a, + 0xf79f4d9c, + 0x2630e51a, + 0x7e2214b4, + 0x880f701b, + 0xd93cce83, + 0xc3c79a30, + 0xa0a02241, + 0x33b91b39, + 0x11fcc620, + 0xc9ba6612, + 0xe7443db4, + 0x3cc12aa5, + 0x157f6b71, + 0x5c24d7b8, + 0x19236745, + 0x9db789d6, + 0x5c2d0dfd, + 0xea6d256f, + 0x6d7b3e15, + 0xe7334d29, + 0xf6997706, + 0x30aefa11, + 0x75b11c2f, + 0x66d9f586, + 0x16c2c53e, + 0x537a5647, + 0xb49df107, + 0xf502f5c2, + 0x8a6417a1, + 0xa1ff6fed, + 0xdd7a388c, + 0x484bc008, + 0x96aeb4df, + 0x7e5da879, + 0x39ba7899, + 0x945096f4, + 0xaca0677a, + 0x3aab6837, + 0x693eb6ae, + 0xd2769858, + 0xf8c3a848, + 0x3d416f0d, + 0xc827d5b8, + 0x634a0142, + 0x95307840, + 0x38598312, + 0xebd78517, + 0x9759f546, + 0x96cae151, + 0x41cbbc4a, + 0xd8414d28, + 0x0109dae8, + 0xfcaa2c27, + 0x0d4fe4eb, + 0x4347492e, + 0x3c16415e, + 0xe491356a, + 0x61b4e63f, + 0x00ede80d, + 0xe1fcdfe5, + 0xfa4652e8, + 0x1fc3ba51, + 0x88951c66, + 0x9a692f49, + 0xe18779f7, + 0xb4139fe4, + 0x8d9eaa67, + 0x53543af7, + 0x528fbc3d, + 0x18db3cc7, + 0x56c5f946, + 0xe70a19b3, + 0x13fceeee, + 0x73b311c8, + 0xbed6fe39, + 0xd92e42e7, + 0xee11ab04, + 0x20e4eec8, + 0xca96264f, + 0x948e9472, + 0x609ca9b0, + 0xa08c2aad, + 0xfd2504f9, + 0x36cf63ae, + 0xe0734470, + 0x652751e7, + 0x642273d0, + 0x9823fbe7, + 0x6824fe6a, + 0xe80ac838, + 0x18846710, + 0xfec2c7aa, + 0xd80a48b4, + 0xa66fe74c, + 0x3f30c5dc, + 0x227433b1, + 0x83c4d631, + 0x706c636a, + 0x138b0fad, + 0xe56524c0, + 0xb2ac11f9, + 0xad1799ce, + 0x7ad15722, + 0x1f163bb9, + 0xd94d13e6, + 0xba486e31, + 0x4147dc40, + 0xf294535b, + 0xf3795177, + 0x6cc4c80e, + 0xce535635, + 0xaa7227f5, + 0xf08a7bf1, + 0x04abff71, + 0xc9fa751c, + 0xf507bee7, + 0x36461342, + 0x257fdb9c, + 0x8e7e5088, + 0x82c48383, + 0xbca8a03a, + 0x981b4944, + 0x82761269, + 0x304b3d32, + 0xf3e469b2, + 0x3a26b2af, + 0xccbbba89, + 0xc28a2b71, + 0xa69cef0d, + 0xbcb33016, + 0x5b682012, + 0xfcdf7e05, + 0x0b0ba583, + 0x499ca677, + 0x4fba9f8e, + 0x7b76bc65, + 0x2fc75e51, + 0xc15ddfe9, + 0x861d4c9c, + 0xb8a93900, + 0x92bd9e86, + 0x5ff6d34f, + 0x2709acde, + 0x4e297037, + 0x0e1d5d01, + 0xf17f9166, + 0x4444d54c, + 0xea9aa934, + 0xb5a8ab82, + 0x501c04e6, + 0xe7c53a5e, + 0xb3af5520, + 0x6fa0a711, + 0xd10ae8c8, + 0xbca08561, + 0xdef0f8dc, + 0x2b00a8da, + 0x194cfec5, + 0x53cced19, + 0xd882fd4c, + 0xd2a1f062, + 0xbd9c92ab, + 0x11faa9c4, + 0x6b81821f, + 0xd50e6f83, + 0x9e6a865e, + 0x6af4288a, + 0xc7474730, + 0xa3ee94f6, + 0x53f3a99d, + 0xfe59024c, + 0x93372281, + 0x02abbc57, + 0x97fc1888, + 0xbc99a04c, + 0xd8f811a7, + 0x4687ef67, + 0xd28b56de, + 0x70c55613, + 0xbbad7b20, + 0xd8ef8c62, + 0xcbd82566, + 0x4b42df32, + 0x08ec3009, + 0x75815b67, + 0x72bacd00, + 0xab7f376a, + 0x42eafc17, + 0x4044abef, + 0xdd3e7e25, + 0xc6a85884, + 0x072e2f0c, + 0x68b1f04b, + 0xe406c8aa, + 0x882f5d33, + 0xaa29b242, + 0xe5623462, + 0xc83e4127, + 0x4a7052bc, + 0x0a28ad40, + 0x754b0cc7, + 0x2aad9413, + 0x6b529f22, + 0x07ddc99b, + 0x9cd5e160, + 0x7ff454c5, + 0x7ab0fa49, + 0x330dc0f7, + 0x35f7c492, + 0xfa234caf, + 0xebd6def4, + 0xea7d0b21, + 0x5bf95b14, + 0x0df1a519, + 0x2ec447ac, + 0xd6e80c4c, + 0xc6cba5ff, + 0x74424b66, + 0x994f29ff, + 0x133beb2e, + 0xbf4a6652, + 0x4308b5da, + 0x11fe0718, + 0xca296045, + 0x949be826, + 0x6e2c3fb8, + 0xb850aa5c, + 0x33f58121, + 0x694d49c0, + 0x90e404d8, + 0x7704a82f, + 0x4c55d386, + 0xeb7593e2, + 0x1550ecf0, + 0x9755c436, + 0x00e2bd8c, + 0x819b4cb6, + 0x57047356, + 0xca7f96bb, + 0xd21846d3, + 0xe75c8b6b, + 0x7c64db6a, + 0x66807671, + 0x42afbdac, + 0x898a62a1, + 0x352b4728, + 0xa01ab76a, + 0x3ecaa8ad, + 0x857e137f, + 0x7425aa2c, + 0x59820cd5, + 0x6cabe70e, + 0xdf2b5075, + 0x80d9ace0, + 0x87a585a2, + 0xa8aa2961, + 0xc78ae53d, + 0xad2fe51a, + 0x12fc4d3b, + 0xc2586e62, + 0x3f9af3c1, + 0x31aaca0e, + 0x90de6dfa, + 0xe8423a5d, + 0x3473b38f, + 0xb306a21c, + 0x25c329db, + 0xa63f49ce, + 0xd64d55a5, + 0xf22cd1fa, + 0x5bb1371f, + 0xa9548a1e, + 0xb7e2103f, + 0xfafd86f1, + 0x04f18888, + 0xef929aed, + 0xc7f32159, + 0x187d353c, + 0xace75d6e, + 0x7c8a9d00, + 0xedc5203e, + 0x4f8ad5e8, + 0x270a3740, + 0x136db4c5, + 0x4d745554, + 0xe834508e, + 0x1e7971ec, + 0x52af33bd, + 0xc6be41f2, + 0x06bf9120, + 0x56c34b9f, + 0x27dda918, + 0xa873d58d, + 0xaba2b6d2, + 0x46ee0a64, + 0xf71e6893, + 0x6dadbe93, + 0xc2dd2fc3, + 0xe07ef64c, + 0x2a17ea62, + 0x918e4d24, + 0x226ee1fd, + 0x98b6f003, + 0x75dfe5ba, + 0xb9783d6e, + 0x2847a098, + 0x3b5f8fed, + 0x4a264321, + 0xf0989f25, + 0xea2896e7, + 0x62830aaf, + 0x7ebb47eb, + 0x7b990fc2, + 0xcfe59d2c, + 0xdf7b0cec, + 0xee2bb918, + 0x2e107193, + 0x2ffcc92b, + 0x56c8d7fb, + 0x6d9596a2, + 0xdbade8c2, + 0x96bbd09c, + 0x3be88ddb, + 0x25788736, + 0xf42e08aa, + 0x2ace1c30, + 0x04b3283b, + 0x42abff1c, + 0x9109f92e, + 0xf44f974c, + 0x69de015b, + 0xcb5be1a3, + 0x42006ec8, + 0xf9f7bbae, + 0x0e498747, + 0xe64f42e5, + 0xbdd9769a, + 0xbfefe3ed, + 0x1cf0b302, + 0x304b38bb, + 0x6fe98e02, + 0x198560f0, + 0x5f323a6b, + 0x32d80d5b, + 0xa02926cf, + 0x749673f7, + 0xdc5b89eb, + 0xd7e59060, + 0x08f0c0c8, + 0x05f2b242, + 0x41c621b9, + 0x0f9d75e4, + 0xc10fb771, + 0x723e2009, + 0x609c716a, + 0xc1a4321c, + 0x2a585c54, + 0x512a2333, + 0x9b83b957, + 0xaa789a88, + 0xf77108d3, + 0x9d5dff9c, + 0x3516bf33, + 0x2553ec5e, + 0x5b9cd3fc, + 0xc4c8576c, + 0xf49a4004, + 0xbc0e4aa0, + 0x23dd6368, + 0x41ed272f, + 0x2665d6de, + 0x51ef3bc7, + 0x5a7bbe62, + 0x11711c5a, + 0xd750fbb8, + 0xfe0b186c, + 0x1cacecb5, + 0x4c3e6cff, + 0xa9166568, + 0x5c28eae4, + 0x916df88f, + 0x3581d00f, + 0xfa85b4c6, + 0xade872df, + 0xbd2d75c7, + 0x35a17396, + 0xbe2f15ec, + 0x2ed3dc19, + 0xfc8ccfb4, + 0xd72224ca, + 0x5b467c42, + 0x05740237, + 0xc90cc5af, + 0x7ee94bb7, + 0x341ce345, + 0xf6d5c608, + 0x54395b3e, + 0x86671dc1, + 0xa012736f, + 0xece35f7e, + 0x98b029cf, + 0xc3bac321, + 0xa83bb90f, + 0x4e98f460, + 0x172ad9d0, + 0x0ddf428b, + 0xc732c52e, + 0x751bb0b1, + 0x7e635e70, + 0xcf083db0, + 0xf7665ffb, + 0xd10b7314, + 0x0a0915c2, + 0x9b708e96, + 0xdd6641dc, + 0xd3c5503f, + 0x99fcad3c, + 0x7f7cdac4, + 0xacf81c45, + 0xbb9ac1aa, + 0x9edba02a, + 0xd2674351, + 0x655d6e1a, + 0x316eb98b, + 0xef0da1b0, + 0x230268a6, + 0xa3d15e0c, + 0x1af0fe7a, + 0x545a1440, + 0x58ebb256, + 0x3004ba86, + 0x5625f280, + 0x31fba6e9, + 0x0d816494, + 0x26c6f165, + 0xe871e8de, + 0xe1d7f6d4, + 0x023760f2, + 0x440f27af, + 0x728ba35f, + 0x17ce346a, + 0x3a11f0d1, + 0x6207d713, + 0x20f84bc8, + 0xd6bbd3c5, + 0x54e23e98, + 0x4d55a3f4, + 0x0bcb2af5, + 0xd669176e, + 0x587e3dfc, + 0x76c2cb8f, + 0xf76cf120, + 0x4d5802b4, + 0x5c14c2f2, + 0x75343fec, + 0xdd66b18c, + 0xc71afb83, + 0x98443a88, + 0xdefbb711, + 0xfdb0d451, + 0x26c463d8, + 0xbeb59073, + 0xea637d70, + 0x75ac392c, + 0x8911a2c2, + 0xea8a08c4, + 0xb17c6b41, + 0x95187ba1, + 0xca82b4e0, + 0x47b9b7c5, + 0xd07c16f8, + 0x0b008289, + 0x1638d750, + 0x1c67341e, + 0x3d1c7fcd, + 0x773a6217, + 0x402ce582, + 0xb391379f, + 0x5f329458, + 0x7df3edc8, + 0x939cb659, + 0x54cec0df, + 0x32a63ce6, + 0x5473cd21, + 0x5399ca04, + 0xd48fec8d, + 0x184a35dd, + 0x0259889e, + 0xf5de1e03, + 0xf637e932, + 0xdac59987, + 0x3482e9ef, + 0xc4b0d39c, + 0xc1703b84, + 0x82783cc5, + 0x609005de, + 0xa6f4b2ec, + 0x2cfd9aee, + 0xeeba8f38, + 0x4f1bd205, + 0xa1f30232, + 0x79587a9a, + 0x9032d2a0, + 0x3f2a3667, + 0x0be30687, + 0xab67f3b2, + 0x5e7952bd, + 0x1055730a, + 0x7326e2ef, + 0x4e90bafe, + 0x40098ae4, + 0xbc8b3245, + 0xac40eacf, + 0x990d0b6a, + 0xcc285b9d, + 0x1f84b128, + 0x3d3baa7e, + 0xa25b70c3, + 0x24ad4c19, + 0xea67f99e, + 0x0692f3a5, + 0x282a5acd, + 0x507aa6fe, + 0xb73af27f, + 0x915227cc, + 0xe3c0fb17, + 0x234d8772, + 0x5038947d, + 0xa6770fb2, + 0x0cbe5619, + 0x62310604, + 0x577f3820, + 0xa0f465d0, + 0xd58e64e3, + 0xf9c7c1a0, + 0x02366336, + 0x7514c9ff, + 0xc80e7468, + 0x31c55e4c, + 0x64f2ee36, + 0x65308077, + 0xcc8f7a9c, + 0xd5afe99c, + 0xa3d2f848, + 0xbe343aed, + 0xc9e5d1d9, + 0x7689df57, + 0x436efdb9, + 0x02fe9c78, + 0xbf44d386, + 0xd1a7f051, + 0x688f8e40, + 0xbfc35d3f, + 0x8e9ccf1d, + 0x265725ce, + 0x7b541f84, + 0x04b7534a, + 0x537689b7, + 0xf0196afd, + 0xa1c53118, + 0xdd4b8f2f, + 0x27a4542d, + 0x148fc97f, + 0xcbb1fe8e, + 0xb0f0e359, + 0x619182d1, + 0x7fe52e97, + 0x02112644, + 0xde85b69d, + 0x6ae60743, + 0xc3957d75, + 0x55ec9f1c, + 0xdf5569a7, + 0xff211f65, + 0x9f191bb7, + 0x27b4ed8e, + 0x3d6b7584, + 0x1eb61acd, + 0x5ab3edfe, + 0xb7746746, + 0xe202812e, + 0xc3a6dad6, + 0x6eadbc54, + 0xaaf3dbe5, + 0x0d5d1241, + 0x573db0ba, + 0x6acb9a75, + 0x355f4aad, + 0xb7af5481, + 0xd6895cc1, + 0x9a3576ae, + 0x0a4ce960, + 0xea88e6c0, + 0xf9777f8c, + 0xf5586085, + 0x96aa74a0, + 0x6ba5f631, + 0x98e69a66, + 0xa27317f5, + 0x7a62af6e, + 0x7c640f8c, + 0x40bdba17, + 0xc3e35f92, + 0x257c9a1c, + 0x6ae2ba67, + 0xd53319a8, + 0x82ae2cff, + 0x2b2e2602, + 0x325499f0, + 0x56415add, + 0x2f76d62a, + 0x13a4fea9, + 0x82292dfc, + 0x3452de2e, + 0x21bc5307, + 0xe8dc18ad, + 0xa1cfbcfc, + 0xa61f387b, + 0xfd781889, + 0x98e6417a, + 0x12df4516, + 0xb4946c67, + 0x0cecea65, + 0x04f28274, + 0x9df23422, + 0xb4dc8368, + 0x8e2010e2, + 0x4c304228, + 0x99918a5a, + 0x44cb62e4, + 0xe5d3f6f9, + 0xd45ab4f1, + 0x15956307, + 0x9243a7d6, + 0x0c3ee4ca, + 0xbfbc5d1b, + 0x880c3c65, + 0xe9a1e5f7, + 0x6573caae, + 0x2d971582, + 0x2931af83, + 0xfbab4eef, + 0x9b954125, + 0x16e305b1, + 0xa2aad029, + 0x0c4c4162, + 0x2d29f41e, + 0xd045716c, + 0x836fd651, + 0xb8aa8f3a, + 0x6f884795, + 0x98199e25, + 0xecc70aec, + 0xf85e31c4, + 0x0f06b850, +/* Dummy terminator */ + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, +}; + + diff --git a/src/mainboard/intel/jarrell/mptable.c b/src/mainboard/intel/jarrell/mptable.c new file mode 100644 index 0000000000..07732198ab --- /dev/null +++ b/src/mainboard/intel/jarrell/mptable.c @@ -0,0 +1,293 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "SE7520JR20 "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_pxhd_1; + unsigned char bus_pxhd_2; + unsigned char bus_pxhd_3 = 0; + unsigned char bus_pxhd_4 = 0; + unsigned char bus_pxhd_x; + unsigned char bus_ich5r_1; + unsigned int bus_pxhd_id; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* ich5r */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1f.0, using defaults\n"); + + bus_ich5r_1 = 4; + bus_isa = 5; + } + /* pxhd-1 */ + dev = dev_find_slot(1, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n"); + + bus_pxhd_1 = 2; + } + /* pxhd-2 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n"); + + bus_pxhd_2 = 3; + } + /* test for active riser with 2nd pxh device */ + dev = dev_find_slot(0, PCI_DEVFN(0x06,0)); + if (dev) { + bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID); + if(bus_pxhd_id == 0x35998086) { + bus_pxhd_x = pci_read_config8(dev, PCI_SECONDARY_BUS); + /* pxhd-3 */ + dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID); + if(bus_pxhd_id == 0x03298086) { + bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + } + } + /* pxhd-4 */ + dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID); + if(bus_pxhd_id == 0x032a8086) { + bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); + } + } + } + } + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 8, 0x20, 0xfec00000); + { + struct resource *res; + device_t dev; + /* pxhd apic 3 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x09, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n"); + } + /* pxhd apic 4 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x0a, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n"); + } + /* pxhd apic 5 */ + if(bus_pxhd_3) { /* Active riser pxhd */ + dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x0b, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI %d:00.1\n",bus_pxhd_x); + } + } + /* pxhd apic 6 */ + if(bus_pxhd_4) { /* active riser pxhd */ + dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x0c, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI %d:00.3\n",bus_pxhd_x); + } + } + } + + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, 0x08, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x01, 0x08, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, 0x08, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x03, 0x08, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x04, 0x08, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x06, 0x08, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x08, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x09, 0x08, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0c, 0x08, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0d, 0x08, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0e, 0x08, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x0f, 0x08, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0a, 0x08, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0b, 0x08, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0a, 0x08, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x07, 0x08, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0b, 0x08, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x05, 0x08, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0b, 0x08, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x07, 0x08, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0b, 0x08, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_isa, 0x0a, 0x08, 0x10); + + /* Standard local interrupt assignments */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + + +#warning "FIXME verify I have the irqs handled for all of the risers" + /* 2:3.0 PCI Slot 1 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_1, (3<<2)|0, 0x9, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_1, (3<<2)|1, 0x9, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_1, (3<<2)|2, 0x9, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_1, (3<<2)|3, 0x9, 0x4); + + + /* 3:7.0 PCI Slot 2 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_2, (7<<2)|0, 0xa, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_2, (7<<2)|1, 0xa, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_2, (7<<2)|2, 0xa, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_2, (7<<2)|3, 0xa, 0x1); + + /* PCI Slot 3 (if active riser) */ + if(bus_pxhd_3) { + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_3, (1<<2)|0, 0xb, 0x0); + } + + /* PCI Slot 4 (if active riser) */ + if(bus_pxhd_4) { + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_4, (1<<2)|0, 0xc, 0x0); + } + + /* Onboard SCSI 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_1, (5<<2)|0, 0x9, 0x2); + + /* Onboard SCSI 1 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_1, (5<<2)|1, 0x9, 0x1); + + /* Onboard NIC 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_2, (4<<2)|0, 0xa, 0x6); + + /* Onboard NIC 1 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_pxhd_2, (4<<2)|1, 0xa, 0x7); + + /* Onboard VGA */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, + bus_ich5r_1, (12<<2)|0, 0x8, 0x11); + + /* There is no extension information... */ + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/intel/jarrell/power_reset_check.c b/src/mainboard/intel/jarrell/power_reset_check.c new file mode 100644 index 0000000000..e9008a40dc --- /dev/null +++ b/src/mainboard/intel/jarrell/power_reset_check.c @@ -0,0 +1,12 @@ + +static void power_down_reset_check(void) +{ + uint8_t cmos; + + cmos=cmos_read(RTC_BOOT_BYTE)>>4 ; + print_debug("Boot byte = "); + print_debug_hex8(cmos); + print_debug("\r\n"); + + if((cmos>2)&&(cmos&1)) full_reset(); +} diff --git a/src/mainboard/intel/jarrell/reset.c b/src/mainboard/intel/jarrell/reset.c new file mode 100644 index 0000000000..874bfc4848 --- /dev/null +++ b/src/mainboard/intel/jarrell/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/intel/jarrell/watchdog.c b/src/mainboard/intel/jarrell/watchdog.c new file mode 100644 index 0000000000..29e8ba36f6 --- /dev/null +++ b/src/mainboard/intel/jarrell/watchdog.c @@ -0,0 +1,138 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ICH5_WDBASE 0x400 +#define ICH5_GPIOBASE 0x500 + +static void disable_sio_watchdog(device_t dev) +{ + /* FIXME move me somewhere more appropriate */ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 1); + pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE); + /* disable the sio watchdog */ + outb(0, NSC_WDBASE + 0); + pnp_set_enable(dev, 0); +} + +static void disable_ich5_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ICH5_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ICH5_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_jarell_frb3(void) +{ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 0); + pci_write_config16(dev, 0x04, value); + + /* Set gpio base */ + pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1); + base = ICH5_GPIOBASE; + + /* Enable GPIO Bar */ + value = pci_read_config32(dev, 0x5c); + value |= 0x10; + pci_write_config32(dev, 0x5c, value); + + /* Configure GPIO 48 and 40 as GPIO */ + value = inl(base + 0x30); + value |= (1 << 16) | ( 1 << 8); + outl(value, base + 0x30); + + /* Configure GPIO 48 as Output */ + value = inl(base + 0x34); + value &= ~(1 << 16); + outl(value, base + 0x34); + + /* Toggle GPIO 48 high to low */ + value = inl(base + 0x38); + value |= (1 << 16); + outl(value, base + 0x38); + value &= ~(1 << 16); + outl(value, base + 0x38); + +} + +static void disable_watchdogs(void) +{ + disable_sio_watchdog(NSC_WD_DEV); + disable_ich5_watchdog(); + disable_jarell_frb3(); + print_debug("Watchdogs disabled\r\n"); +} + +static void ich5_watchdog_on(void) +{ + device_t dev; + unsigned long value, base; + unsigned char byte; + + /* check cmos options */ + byte = cmos_read(RTC_BOOT_BYTE-1); + if(!(byte & 1)) return; /* no boot watchdog */ + byte = cmos_read(RTC_BOOT_BYTE); + if(!(byte & 2)) return; /* fallback so ignore */ + + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ICH5_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ICH5_WDBASE + 0x60; + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); + + /* set the time value 1 cnt = .6 sec */ + outw(0x0010, base + 0x01); + /* reload the timer with the value */ + outw(0x0001, base + 0x00); + + /* clear bit 11 in TCO1_CNT to start watchdog */ + value = inw(base + 0x08); + value &= ~(1 << 11); + outw(value, base + 0x08); + + print_debug("Watchdog ICH5 enabled\r\n"); +} diff --git a/src/mainboard/island/aruma/Config.lb b/src/mainboard/island/aruma/Config.lb index f45862d474..b05eb49045 100644 --- a/src/mainboard/island/aruma/Config.lb +++ b/src/mainboard/island/aruma/Config.lb @@ -46,6 +46,7 @@ if HAVE_ACPI_TABLES object fadt.o object dsdt.o end +object reset.o ## diff --git a/src/mainboard/island/aruma/Options.lb b/src/mainboard/island/aruma/Options.lb index fc9489a29d..87ff134cf1 100644 --- a/src/mainboard/island/aruma/Options.lb +++ b/src/mainboard/island/aruma/Options.lb @@ -4,9 +4,6 @@ uses HAVE_ACPI_TABLES uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -82,13 +79,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=0 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/island/aruma/reset.c b/src/mainboard/island/aruma/reset.c new file mode 100644 index 0000000000..7f58d01410 --- /dev/null +++ b/src/mainboard/island/aruma/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 1); +} diff --git a/src/mainboard/newisys/khepri/Config.lb b/src/mainboard/newisys/khepri/Config.lb index 947180d53e..506ae648e7 100644 --- a/src/mainboard/newisys/khepri/Config.lb +++ b/src/mainboard/newisys/khepri/Config.lb @@ -45,6 +45,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o dir /drivers/trident/blade3d diff --git a/src/mainboard/newisys/khepri/Options.lb b/src/mainboard/newisys/khepri/Options.lb index d80f0c3904..37733ac803 100644 --- a/src/mainboard/newisys/khepri/Options.lb +++ b/src/mainboard/newisys/khepri/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -74,13 +71,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/newisys/khepri/reset.c b/src/mainboard/newisys/khepri/reset.c new file mode 100644 index 0000000000..63958185f6 --- /dev/null +++ b/src/mainboard/newisys/khepri/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 2); +} diff --git a/src/mainboard/supermicro/x6dai_g/Config.lb b/src/mainboard/supermicro/x6dai_g/Config.lb new file mode 100644 index 0000000000..8d4ada557b --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/Config.lb @@ -0,0 +1,198 @@ +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can be cached to speed up linuxBIOS, +## execution speed. +## +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +## +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7525 # mch + device pci_domain 0 on + chip southbridge/intel/esb6300 # esb6300 + register "pirq_a_d" = "0x0b0a0a05" + register "pirq_e_h" = "0x0a0b0c80" + + device pci 1c.0 on end + + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.4 on end + device pci 1d.5 on end + device pci 1d.7 on end + + device pci 1e.0 on end + + device pci 1f.0 on + chip superio/winbond/w83627hf + device pnp 2e.0 off end + device pnp 2e.1 off end + device pnp 2e.2 on + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 off end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a on end + device pnp 2e.b off end + device pnp 2e.f off end + device pnp 2e.10 off end + device pnp 2e.14 off end + end + end + device pci 1f.1 on end + device pci 1f.2 on end + device pci 1f.3 on end + device pci 1f.5 off end + device pci 1f.6 on end + end + device pci 00.0 on end + device pci 00.1 on end + device pci 00.2 on end + device pci 02.0 on end + device pci 03.0 on end + device pci 04.0 on end + device pci 08.0 on end + end + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # cpu0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # cpu1 + device apic 6 on end + end + end +end + diff --git a/src/mainboard/supermicro/x6dai_g/Options.lb b/src/mainboard/supermicro/x6dai_g/Options.lb new file mode 100644 index 0000000000..822e31f03f --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/Options.lb @@ -0,0 +1,229 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY + + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=1048576 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=16 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="X6DAI" +default MAINBOARD_VENDOR= "Supermicro" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6780 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end + diff --git a/src/mainboard/supermicro/x6dai_g/auto.c b/src/mainboard/supermicro/x6dai_g/auto.c new file mode 100644 index 0000000000..f148a8c38b --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/auto.c @@ -0,0 +1,139 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/esb6300/esb6300_early_smbus.c" +#include "northbridge/intel/E7525/raminit.h" +#include "superio/winbond/w83627hf/w83627hf.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "superio/winbond/w83627hf/w83627hf_early_init.c" +#include "northbridge/intel/E7525/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0808090a +#define RECVENB_CONFIG 0x0808090a + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7525/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, }, + .channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, }, + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing 6300ESB?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 1 + dump_pci_device(PCI_DEV(0, 0x00, 0)); +// dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, 0x01000000); + /* check the first 1M in the 3rd Gig */ + ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dai_g/chip.h b/src/mainboard/supermicro/x6dai_g/chip.h new file mode 100644 index 0000000000..02f15189d6 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_supermicro_x6dai_g_ops; + +struct mainboard_supermicro_x6dai_g_config { + int nothing; +}; diff --git a/src/mainboard/supermicro/x6dai_g/cmos.layout b/src/mainboard/supermicro/x6dai_g/cmos.layout new file mode 100644 index 0000000000..6f3cd189e3 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/cmos.layout @@ -0,0 +1,80 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 2 hyper_threading +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/supermicro/x6dai_g/debug.c b/src/mainboard/supermicro/x6dai_g/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/supermicro/x6dai_g/failover.c b/src/mainboard/supermicro/x6dai_g/failover.c new file mode 100644 index 0000000000..1a4a88ebfa --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7525/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/supermicro/x6dai_g/irq_tables.c b/src/mainboard/supermicro/x6dai_g/irq_tables.c new file mode 100644 index 0000000000..c34a722141 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/irq_tables.c @@ -0,0 +1,34 @@ +/* PCI: Interrupt Routing Table found at 0x40163ed0 size = 272 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 272, /* u16 Table size 32+(16*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x122e, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0x78, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, 0x00, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0x10, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x01, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x04, 0x00}, + {0x00, 0x20, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x02, 0x00, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}}, 0x06, 0x00}, + {0x00, 0xe0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x04, 0x08, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x01, 0x00}, + {0x04, 0x10, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x07, 0x00}, + {0x04, 0x18, {{0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}, {0x6a, 0x1ef8}}, 0x02, 0x00}, + {0x00, 0xf0, {{0x60, 0xdef8}, {0x61, 0xdef8}, {0x62, 0xdef8}, {0x63, 0xdef8}}, 0x00, 0x00}, + {0x05, 0x40, {{0x68, 0x1ef8}, {0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}}, 0x03, 0x00}, + {0x05, 0x18, {{0x6a, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x08, 0x00}, + {0x05, 0x10, {{0x69, 0x1ef8}, {0x6a, 0x1ef8}, {0x6b, 0x1ef8}, {0x68, 0x1ef8}}, 0x05, 0x00}, + {0x00, 0xf8, {{0x62, 0x1ef8}, {0x61, 0x1ef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x00, 0x00}, + {0x00, 0xe8, {{0x60, 0x1ef8}, {0x63, 0x1ef8}, {0x00, 0xdef8}, {0x6b, 0x1ef8}}, 0x00, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x6dai_g/mainboard.c b/src/mainboard/supermicro/x6dai_g/mainboard.c new file mode 100644 index 0000000000..bf741989ee --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/mainboard.c @@ -0,0 +1,12 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include "chip.h" + +struct chip_operations supermicro_x6dai_g_ops = { + CHIP_NAME("Supermicro X6DAI_G mainboard ") +}; + diff --git a/src/mainboard/supermicro/x6dai_g/mptable.c b/src/mainboard/supermicro/x6dai_g/mptable.c new file mode 100644 index 0000000000..9d793c44a6 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/mptable.c @@ -0,0 +1,142 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "X6DAI-G "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_6300; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* southbridge */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_6300 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n"); + bus_6300 = 5; + bus_isa = 6; + } + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + smp_write_ioapic(mc, 3, 0x20, 0xfec10000); + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x07, 0x02, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x77, 0x02, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x75, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0f, 0x02, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7c, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + /* Slot 1 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 4, 0x04, 0x03, 0x00); + /* Slot 2 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 4, 0x0c, 0x03, 0x01); + /* Slot 3 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_6300, 0x20, 0x02, 0x14); + /* Slot 4 function 0 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_6300, 0x08, 0x02, 0x15); + /* On board NIC */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_6300, 0x0c, 0x02, 0x16); + + /* Standard local interrupt assignments */ +// smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, +// bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + + /* There is no extension information... */ + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/supermicro/x6dai_g/reset.c b/src/mainboard/supermicro/x6dai_g/reset.c new file mode 100644 index 0000000000..1d7f5a3301 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_6300ESB_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/supermicro/x6dai_g/watchdog.c b/src/mainboard/supermicro/x6dai_g/watchdog.c new file mode 100644 index 0000000000..465ba4c7b3 --- /dev/null +++ b/src/mainboard/supermicro/x6dai_g/watchdog.c @@ -0,0 +1,42 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ICH5_WDBASE 0x400 +#define ICH5_GPIOBASE 0x500 + +static void disable_esb6300_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing 6300ESB?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ICH5_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ICH5_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_watchdogs(void) +{ + disable_esb6300_watchdog(); + print_debug("Watchdogs disabled\r\n"); +} + diff --git a/src/mainboard/supermicro/x6dhe_g/Config.lb b/src/mainboard/supermicro/x6dhe_g/Config.lb new file mode 100644 index 0000000000..672da8233c --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/Config.lb @@ -0,0 +1,220 @@ +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of LinuxBIOS will start in the boot rom +## +default _ROMBASE =( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can be cached to speed up linuxBIOS. +## execution speed. +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE= ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7520 # MCH + chip drivers/generic/debug # DEBUGGING + device pnp 00.0 on end + device pnp 00.1 off end + device pnp 00.2 off end + device pnp 00.3 off end + end + device pci_domain 0 on + chip southbridge/intel/esb6300 # ESB6300 + register "pirq_a_d" = "0x0b070a05" + register "pirq_e_h" = "0x0a808080" + + device pci 1c.0 on + chip drivers/generic/generic + device pci 01.0 on end # onboard gige1 + device pci 02.0 on end # onboard gige2 + end + end + + # USB ports + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.4 on end # Southbridge Watchdog timer + device pci 1d.5 on end # Southbridge I/O apic1 + device pci 1d.7 on end + + # VGA / PCI 32-bit + device pci 1e.0 on + chip drivers/generic/generic + device pci 01.0 on end + end + end + + + device pci 1f.0 on # ISA bridge + chip superio/winbond/w83627hf + device pnp 2e.0 off end + device pnp 2e.2 on + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 off end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a on end + device pnp 2e.b off end + end + end + device pci 1f.1 on end + device pci 1f.2 off end + device pci 1f.3 on end # SMBus + device pci 1f.5 off end + device pci 1f.6 off end + end + + device pci 00.0 on end # Northbridge + device pci 00.1 on end # Northbridge Error reporting + device pci 01.0 on end + device pci 02.0 on + chip southbridge/intel/pxhd # PXHD 6700 + device pci 00.0 on end # bridge + device pci 00.1 on end # I/O apic + device pci 00.2 on end # bridge + device pci 00.3 on end # I/O apic + end + end +# device register "intrline" = "0x00070105" + device pci 04.0 on end + device pci 06.0 on end + end + + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # CPU 0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # CPU 1 + device apic 6 on end + end + end +end diff --git a/src/mainboard/supermicro/x6dhe_g/Options.lb b/src/mainboard/supermicro/x6dhe_g/Options.lb new file mode 100644 index 0000000000..d09effc37e --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/Options.lb @@ -0,0 +1,229 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY + + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=1048576 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=16 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="X6DHE_g" +default MAINBOARD_VENDOR= "Supermicro" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6080 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end + diff --git a/src/mainboard/supermicro/x6dhe_g/auto.c b/src/mainboard/supermicro/x6dhe_g/auto.c new file mode 100644 index 0000000000..be5affc04c --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/auto.c @@ -0,0 +1,167 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/esb6300/esb6300_early_smbus.c" +#include "northbridge/intel/E7520/raminit.h" +#include "superio/winbond/w83627hf/w83627hf.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "x6dhe_g_fixups.c" +#include "superio/winbond/w83627hf/w83627hf_early_init.c" +#include "northbridge/intel/E7520/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0808090a +#define RECVENB_CONFIG 0x0808090a + +//void udelay(int usecs) +//{ +// int i; +// for(i = 0; i < usecs; i++) +// outb(i&0xff, 0x80); +//} + +#if 0 +static void hard_reset(void) +{ + /* enable cf9 */ + pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + /* reset */ + outb(0x0e, 0x0cf9); +} +#endif + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7520/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|0, (0xa<<3)|1, (0xa<<3)|2, (0xa<<3)|3, }, + .channel1 = {(0xa<<3)|4, (0xa<<3)|5, (0xa<<3)|6, (0xa<<3)|7, }, + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ +// report_bist_failure(bist); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing esb6300?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); +// dump_ipmi_registers(); +// mainboard_set_e7520_leds(); +// memreset_setup(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 0 + dump_pci_devices(); +#endif +#if 0 + dump_pci_device(PCI_DEV(0, 0x00, 0)); + dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, 0x01000000); + /* check the first 1M in the 3rd Gig */ + ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dhe_g/chip.h b/src/mainboard/supermicro/x6dhe_g/chip.h new file mode 100644 index 0000000000..f8ba112b02 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_supermicro_x6dhe_g_ops; + +struct mainboard_supermicro_x6dhe_g_config { + int nothing; +}; diff --git a/src/mainboard/supermicro/x6dhe_g/cmos.layout b/src/mainboard/supermicro/x6dhe_g/cmos.layout new file mode 100644 index 0000000000..6f3cd189e3 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/cmos.layout @@ -0,0 +1,80 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 2 hyper_threading +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/supermicro/x6dhe_g/debug.c b/src/mainboard/supermicro/x6dhe_g/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/supermicro/x6dhe_g/failover.c b/src/mainboard/supermicro/x6dhe_g/failover.c new file mode 100644 index 0000000000..5029d98611 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7520/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/supermicro/x6dhe_g/irq_tables.c b/src/mainboard/supermicro/x6dhe_g/irq_tables.c new file mode 100644 index 0000000000..0851fbe3f8 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/irq_tables.c @@ -0,0 +1,34 @@ +/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 272, /* u16 Table size 32+(15*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x25a1, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xc4, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06, 0x00}, + {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x6dhe_g/mainboard.c b/src/mainboard/supermicro/x6dhe_g/mainboard.c new file mode 100644 index 0000000000..6cb224f498 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/mainboard.c @@ -0,0 +1,12 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include "chip.h" + +struct chip_operations supermicro_x6dhe_g_ops = { + CHIP_NAME("Supermicro X6DHE_G mainboard") +}; + diff --git a/src/mainboard/supermicro/x6dhe_g/microcode_updates.c b/src/mainboard/supermicro/x6dhe_g/microcode_updates.c new file mode 100644 index 0000000000..b2e72ab616 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/microcode_updates.c @@ -0,0 +1,1563 @@ +/* WARNING - Intel has a new data structure that has variable length
+ * microcode update lengths. They are encoded in int 8 and 9. A
+ * dummy header of nulls must terminate the list.
+ */
+
+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {
+ /*
+ Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000.
+ These microcode updates are distributed for the sole purpose of
+ installation in the BIOS or Operating System of computer systems
+ which include an Intel P6 family microprocessor sold or distributed
+ to or by you. You are authorized to copy and install this material
+ on such systems. You are not authorized to use this material for
+ any other purpose.
+ */
+
+ /* M1DF3413.TXT - Noconoa D-0 */
+
+ 0x00000001, /* Header Version */
+ 0x00000013, /* Patch ID */
+ 0x07302004, /* DATE */
+ 0x00000f34, /* CPUID */
+ 0x95f183f0, /* Checksum */
+ 0x00000001, /* Loader Version */
+ 0x0000001d, /* Platform ID */
+ 0x000017d0, /* Data size */
+ 0x00001800, /* Total size */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+
+ 0x9fbf327a,
+ 0x2b41b451,
+ 0xb2abaca8,
+ 0x6b62b8e0,
+ 0x0af32c41,
+ 0x12ca6048,
+ 0x5bd55ae6,
+ 0xb90dfc1d,
+ 0x565fe2b2,
+ 0x326b1718,
+ 0x61f3a40d,
+ 0xceb53db3,
+ 0x14fb5261,
+ 0xbb23b6c3,
+ 0x9d7c0466,
+ 0xde90a25e,
+ 0x9450e9bb,
+ 0x497bd6e4,
+ 0x97d1041a,
+ 0x1831013f,
+ 0x6e6fa37e,
+ 0x0b5c1d03,
+ 0x5eae4db2,
+ 0xc029d9e3,
+ 0x5373bca3,
+ 0xe15fccca,
+ 0x39043db0,
+ 0xaeb0ea0c,
+ 0x62b4e391,
+ 0x0b280c6b,
+ 0x279eb9d3,
+ 0x98d95ada,
+ 0xc1cb45a7,
+ 0x06917bda,
+ 0xdde8aafa,
+ 0xdff9d15c,
+ 0xd07f8f0a,
+ 0x192bcf9d,
+ 0xf77de31f,
+ 0xadf8be55,
+ 0x3f7a5d95,
+ 0x0e2140b6,
+ 0xf0c75eec,
+ 0x3254876a,
+ 0x684a1698,
+ 0x4ad0cca7,
+ 0x6d705304,
+ 0xf957d91b,
+ 0xe8bb864a,
+ 0x440d636c,
+ 0xaf4d7d06,
+ 0x12680ecf,
+ 0x5d0f9e53,
+ 0x60148a5d,
+ 0x81008364,
+ 0x243a8aed,
+ 0xd55976de,
+ 0xd6a84520,
+ 0x932d4b77,
+ 0xe67e5f19,
+ 0x7dba0e47,
+ 0xfee3b153,
+ 0x46b6a20c,
+ 0x2594e6f6,
+ 0x210cab0f,
+ 0xf6e47d5d,
+ 0xe38276e4,
+ 0x90fc2728,
+ 0x9faefa11,
+ 0xc972217c,
+ 0xc8d079dd,
+ 0x5f7dc338,
+ 0x106f7b7b,
+ 0xd04c0a1c,
+ 0x0eca300e,
+ 0x1ddae8a6,
+ 0x6e7fd42e,
+ 0xa56c514d,
+ 0x56a4e255,
+ 0x975ea2bf,
+ 0x0eaa78cc,
+ 0x0c3e284f,
+ 0xbacb6c71,
+ 0x1645006f,
+ 0xe9a2b955,
+ 0x0677c019,
+ 0x24b33da0,
+ 0x62f200fa,
+ 0x234238c4,
+ 0x81d5ad79,
+ 0x9f754bc9,
+ 0xeffd5016,
+ 0x041b2cc2,
+ 0x2f020bc7,
+ 0x4fcd68b8,
+ 0x22c3579c,
+ 0x4804a114,
+ 0xc42db3ea,
+ 0x7cde8141,
+ 0x47e167c8,
+ 0x01aa38cc,
+ 0x74a5c25e,
+ 0xe0c48d67,
+ 0x562365ad,
+ 0x38321e57,
+ 0x0395885a,
+ 0x6888323e,
+ 0xd6fc518f,
+ 0x1854b64c,
+ 0x06a58476,
+ 0x3662f898,
+ 0xe2bcdaee,
+ 0x84c40693,
+ 0xef09d374,
+ 0x353cc799,
+ 0x742223d4,
+ 0x05b3c99b,
+ 0x0c51ee45,
+ 0xd145824a,
+ 0xac30806c,
+ 0x2ed70c0d,
+ 0x71ae10ff,
+ 0xbf491854,
+ 0x3e1f03b4,
+ 0x76bfd6cd,
+ 0x1449aa8a,
+ 0xf954d3fb,
+ 0xf8c7c940,
+ 0x70233f85,
+ 0x0729e257,
+ 0x10bb8936,
+ 0xc35bb5b5,
+ 0x95d78b5c,
+ 0xcc1ba443,
+ 0x6f507126,
+ 0xa607cfd0,
+ 0xce22f2f3,
+ 0x5134ed8c,
+ 0xec8d2f06,
+ 0xa92413d5,
+ 0xb973f431,
+ 0x16e136dd,
+ 0xf7d41bed,
+ 0x01b002fe,
+ 0x646ed771,
+ 0x76ea3d26,
+ 0x5024af20,
+ 0x84270f51,
+ 0x9b3d7820,
+ 0x2454a2c6,
+ 0xc1f072ed,
+ 0x155e864f,
+ 0x4c39a6e5,
+ 0x928206e5,
+ 0x9d1685f5,
+ 0x45542ee7,
+ 0x1fd27d9e,
+ 0x5f2dd9ff,
+ 0x222005eb,
+ 0x354e8a55,
+ 0x1f0de29a,
+ 0xb86dc696,
+ 0x9eafafad,
+ 0x191b197e,
+ 0x0e0900e1,
+ 0xe0ac42bb,
+ 0x3143236f,
+ 0x44177def,
+ 0x05259274,
+ 0xb21af44a,
+ 0x6ddee4df,
+ 0xc7b56255,
+ 0xb6b1d39d,
+ 0x218f9070,
+ 0x96545a42,
+ 0x98cc2d4a,
+ 0xb21bac9e,
+ 0x83e12d44,
+ 0x2ef4fb39,
+ 0xbc03528f,
+ 0x9485af58,
+ 0xd9f1e6ab,
+ 0xde7607e6,
+ 0x3b398733,
+ 0x9cd9b1a9,
+ 0xabd77984,
+ 0xcce18826,
+ 0x701c5c21,
+ 0xe6591cbf,
+ 0x07a9b9e1,
+ 0x69459c90,
+ 0xe0cdcad6,
+ 0xc4c6c4b6,
+ 0x12748024,
+ 0x4a33c567,
+ 0x7d26a37e,
+ 0xcae163bf,
+ 0xeb7547fa,
+ 0xccc6a01c,
+ 0x3cb8abb8,
+ 0x64aa67b2,
+ 0x51ddf6de,
+ 0xbfe1b905,
+ 0x50923949,
+ 0xacfa43af,
+ 0x1fdb5a44,
+ 0x091533cb,
+ 0x7c92e5dc,
+ 0x1c5d0d3e,
+ 0x195271f5,
+ 0x96e73a4a,
+ 0xe1b11968,
+ 0xb42906f2,
+ 0x5a2940b3,
+ 0x611283e9,
+ 0x65829161,
+ 0x5d1357b7,
+ 0x019428ad,
+ 0x836c5c3c,
+ 0xc0e5e169,
+ 0xd360e424,
+ 0x257a9d69,
+ 0xdca09040,
+ 0x85f1c060,
+ 0xae7cae79,
+ 0xa5ddcfd6,
+ 0xdba8f68e,
+ 0xd98df596,
+ 0xe6e3cd51,
+ 0xcfb2be8f,
+ 0x368fe6cd,
+ 0x58486b75,
+ 0x791f1a48,
+ 0xf81a61f2,
+ 0x58a38155,
+ 0x30a86547,
+ 0xd7fb2db1,
+ 0x300e0b1d,
+ 0x3f838461,
+ 0xf278805a,
+ 0x49529931,
+ 0x601d5649,
+ 0xe500ba1a,
+ 0xc4f78965,
+ 0xe10ed02d,
+ 0x1f777ebd,
+ 0x2db1d17d,
+ 0x48a22e6a,
+ 0x5a14b738,
+ 0xdcf899e0,
+ 0xc845bd04,
+ 0xd04a52b9,
+ 0xf2f19b06,
+ 0xdb5ba97a,
+ 0xf05605ff,
+ 0xc787b72c,
+ 0x9f197770,
+ 0x87b31150,
+ 0x3ff00d57,
+ 0x89d1dcb3,
+ 0x07528ff4,
+ 0x4105fcef,
+ 0xb087de2e,
+ 0x3bd333a5,
+ 0x84a094f4,
+ 0x9ab8fb97,
+ 0xc9bba063,
+ 0x664c52e5,
+ 0x27fd05e4,
+ 0x3f0e491d,
+ 0xab8f4b9a,
+ 0x344a0249,
+ 0x727dd74f,
+ 0x29587211,
+ 0xbba262b9,
+ 0x319ecbb3,
+ 0xec54b023,
+ 0xd0fa096d,
+ 0x3d223f23,
+ 0x0b6013e7,
+ 0x513e045b,
+ 0xcb1edf15,
+ 0xfd44bb25,
+ 0x023eb973,
+ 0x3f55dac6,
+ 0xc2df6514,
+ 0x68589880,
+ 0x4556878e,
+ 0x86f6acfb,
+ 0xbcd23f0b,
+ 0x32c417c1,
+ 0x45f3bb56,
+ 0xbe60872b,
+ 0x09457cc0,
+ 0x2e18b62d,
+ 0x065f54d1,
+ 0xae3b4a20,
+ 0x265b10ae,
+ 0xb7547a1d,
+ 0x5a9481a9,
+ 0xd477ed02,
+ 0x601ed0fc,
+ 0x9a43257e,
+ 0xc9922b72,
+ 0xa2a696ae,
+ 0xe9d6c37b,
+ 0xfab8bdf9,
+ 0x1deb34dc,
+ 0xaa6bb090,
+ 0xbdc3b72f,
+ 0xecb3b010,
+ 0xe64376e7,
+ 0x40356095,
+ 0x928b5047,
+ 0xbd271c09,
+ 0xfd806f61,
+ 0x0821e090,
+ 0x6afb3588,
+ 0xd10e91ea,
+ 0xbbc7fedd,
+ 0xb1ac6d33,
+ 0x07788e4b,
+ 0xa10f8013,
+ 0x4f8efd9d,
+ 0xe5d8728d,
+ 0x017f3e82,
+ 0xf09ec7eb,
+ 0x6bfd7906,
+ 0xbcefcb44,
+ 0x76699ad5,
+ 0x1b976522,
+ 0xa55b3dbd,
+ 0x88bb33e2,
+ 0x98ac5b7f,
+ 0x61ac4c8b,
+ 0xfd948f3d,
+ 0xee610413,
+ 0xc77c5035,
+ 0x662825a9,
+ 0x0009fcba,
+ 0x3450fd88,
+ 0xeb391fef,
+ 0x6949960d,
+ 0x1ccb13c3,
+ 0x21dac5a6,
+ 0x6bcc6b37,
+ 0x37ad77a5,
+ 0xf71d58b1,
+ 0x84ed440d,
+ 0xe606b699,
+ 0xe43067a4,
+ 0x21d5b8b3,
+ 0xe11f83e2,
+ 0xa0cc6585,
+ 0x40eb6d16,
+ 0xc5a6879f,
+ 0xbd333fd5,
+ 0xb44acab4,
+ 0x68c016fc,
+ 0xfbcd3cfc,
+ 0xadf76e42,
+ 0xc520e516,
+ 0x7468cb61,
+ 0x585c0d52,
+ 0xea83cefe,
+ 0x615d7760,
+ 0x89c9b8fd,
+ 0x367c355a,
+ 0x409371a2,
+ 0x7edb38a7,
+ 0xca86d263,
+ 0xda18250d,
+ 0x26e1ed8b,
+ 0x02fefede,
+ 0x704cb5c8,
+ 0x52cbe1eb,
+ 0x9cdbc71a,
+ 0xa0637560,
+ 0xe31f03ca,
+ 0x2b78969b,
+ 0x803d5866,
+ 0xec52d984,
+ 0xd8df8bdb,
+ 0x6cb1d5e8,
+ 0x7b9aec01,
+ 0xf7d39401,
+ 0xdd04c6ae,
+ 0x0e5ca4eb,
+ 0x12b593c8,
+ 0x38f6d4e5,
+ 0x13a91268,
+ 0x60c8251b,
+ 0xa136cf9a,
+ 0xda070cdd,
+ 0x6142408c,
+ 0xc28065dd,
+ 0x50b73718,
+ 0x36074eee,
+ 0xc7b20fcb,
+ 0x18d29f9b,
+ 0xe97eb966,
+ 0xe6936bcc,
+ 0x1c9188ea,
+ 0x7cff40e2,
+ 0xee791ac8,
+ 0xb099a323,
+ 0x571d69b7,
+ 0x22c1f7d0,
+ 0x0b9662ee,
+ 0x76e45cb9,
+ 0xbd0d7020,
+ 0x7794bd95,
+ 0x1b0fe51a,
+ 0xda2754ef,
+ 0x7f3ad7a9,
+ 0x58f627d3,
+ 0x211670a3,
+ 0xc7471b81,
+ 0x495a93ac,
+ 0xaad4f030,
+ 0xa76614c8,
+ 0xd63dba3c,
+ 0x9c4f729c,
+ 0x6e831cfb,
+ 0xa6105c75,
+ 0x95c62188,
+ 0x723ef45d,
+ 0xf59f2dd1,
+ 0x5825283d,
+ 0x768d8a86,
+ 0x070d02ac,
+ 0xfdbcbd73,
+ 0x0d479795,
+ 0x797aa7f7,
+ 0x6c9e468b,
+ 0xa961571d,
+ 0xc7127ef0,
+ 0x4b0442e7,
+ 0xd99a9e87,
+ 0x6c876cba,
+ 0xe4f9f814,
+ 0x120eeb8d,
+ 0x4bbb9c8e,
+ 0x22c0a29e,
+ 0xff681fcc,
+ 0x26777226,
+ 0x6339e667,
+ 0x2402333e,
+ 0x2bf66a17,
+ 0x63806e6c,
+ 0x98416b75,
+ 0x791b3e91,
+ 0x79c09cd7,
+ 0x0c157436,
+ 0x6d99157c,
+ 0xc8990984,
+ 0xaf7d2ae4,
+ 0xfe3ee7d9,
+ 0xb7676de0,
+ 0x9df8722e,
+ 0x08462a7e,
+ 0x99032839,
+ 0xd726ff95,
+ 0x5c1c78e8,
+ 0x4ef1b747,
+ 0x4e257ba7,
+ 0xa83ad5f3,
+ 0x523b3809,
+ 0xc2ce4f19,
+ 0xabfadaa5,
+ 0x370b005c,
+ 0x2d6a02e1,
+ 0xbf6ee428,
+ 0xfd84be50,
+ 0xb79801b3,
+ 0x488ad789,
+ 0x65a87bda,
+ 0x59f0fd6a,
+ 0xa4106878,
+ 0xdbadd916,
+ 0x1f86f200,
+ 0xefb7fc72,
+ 0x26d4d47f,
+ 0xf7892efc,
+ 0x41f50167,
+ 0xc6a28f9e,
+ 0xffd4a8e0,
+ 0xa00e4ea0,
+ 0x8183f648,
+ 0x030faa4c,
+ 0x26c1715f,
+ 0x322c9ea3,
+ 0x5d60d054,
+ 0x413470cb,
+ 0x3d131892,
+ 0x22f2ae86,
+ 0x9f1c96b6,
+ 0x015563f4,
+ 0x3a5625ba,
+ 0xcb95b598,
+ 0xf0685fb9,
+ 0x158af5ec,
+ 0xfc01a406,
+ 0x01841d19,
+ 0x210b7e73,
+ 0x19a416a1,
+ 0xed254c44,
+ 0x5bd51335,
+ 0xb8905dc9,
+ 0x9e52f38c,
+ 0xef5d7dd0,
+ 0x1516f6bb,
+ 0xf13bb426,
+ 0x9ee6d6cb,
+ 0x28bde0a6,
+ 0x766b655e,
+ 0xaf2e0e52,
+ 0xdec60f49,
+ 0x254a0959,
+ 0xb009d431,
+ 0x2f6d3533,
+ 0x0a074afc,
+ 0xcd3d3a72,
+ 0x52aa4fce,
+ 0x16c4507d,
+ 0x2f842898,
+ 0xb087e98b,
+ 0x68b41826,
+ 0xd4adc5c9,
+ 0x53b3e498,
+ 0x2dff7b03,
+ 0xda931e65,
+ 0xf1d66edd,
+ 0x2beb7555,
+ 0x97b3f152,
+ 0x035676f8,
+ 0xca9c7cf6,
+ 0x57992a53,
+ 0x578a1004,
+ 0x458e23c8,
+ 0x2a2494bf,
+ 0xa92c549b,
+ 0x2ca46deb,
+ 0xcd907478,
+ 0x93baaeb5,
+ 0xa70af4c6,
+ 0x9767d5b8,
+ 0x9874bcee,
+ 0xb0413973,
+ 0x9bfef4f7,
+ 0x7fbed607,
+ 0x2a255991,
+ 0xa5e3109d,
+ 0x90f09fef,
+ 0xb7a3d468,
+ 0x6db437aa,
+ 0xe8dad585,
+ 0xfbc19cbc,
+ 0x34cacc6f,
+ 0x6c5cc449,
+ 0xcc6dc144,
+ 0x70c6aaa0,
+ 0x183bc459,
+ 0x490ea5a8,
+ 0xddf105bf,
+ 0x3429facf,
+ 0x79020f72,
+ 0xd2de786d,
+ 0xb776f3ed,
+ 0x553e3da7,
+ 0xaecff099,
+ 0x2b471ce1,
+ 0xe3a72af9,
+ 0x04c9b2bf,
+ 0xe84d9702,
+ 0xec7cd831,
+ 0xda66c6c1,
+ 0x451b207c,
+ 0x68243bc3,
+ 0xb3012b1e,
+ 0x1855c026,
+ 0x1addac14,
+ 0xc73834a2,
+ 0xea91596d,
+ 0x08f0d135,
+ 0xc6021aa0,
+ 0xc5d1726b,
+ 0xc21d1f0b,
+ 0x92b7c740,
+ 0x9f024526,
+ 0x6c91df6c,
+ 0xfec85435,
+ 0x3d5a9150,
+ 0x93249836,
+ 0x2ec5e71f,
+ 0x23e96579,
+ 0x81ce78d6,
+ 0x49e45ccf,
+ 0x4d5e9c78,
+ 0x2a2cdfab,
+ 0x148e1833,
+ 0xa3fab11b,
+ 0xd0ceb7e9,
+ 0x4789b634,
+ 0x147fc687,
+ 0x48f4f59c,
+ 0x21eea4e3,
+ 0x411dfb7d,
+ 0x033fe075,
+ 0x57c9e07d,
+ 0xb09edf4e,
+ 0x9db83f5f,
+ 0x6ef1343a,
+ 0x64a68315,
+ 0x300e34c3,
+ 0x72ac2766,
+ 0x640271a4,
+ 0x0a282b82,
+ 0xcaf1ec1b,
+ 0x7d4849f9,
+ 0x108c5eaa,
+ 0xfaa96613,
+ 0x0476639b,
+ 0x70ee8371,
+ 0x9db599ba,
+ 0x85158d5f,
+ 0x02912911,
+ 0xe6fec86a,
+ 0xcf3036f3,
+ 0xccdd49a0,
+ 0xe650b3cd,
+ 0xf5429ef0,
+ 0x411e4690,
+ 0xa526e30b,
+ 0x275822af,
+ 0x91e12d05,
+ 0x958881aa,
+ 0xabf76cc4,
+ 0x06e794a9,
+ 0xa97d1577,
+ 0x0188613c,
+ 0x17c96558,
+ 0x96c31832,
+ 0x5696b201,
+ 0x03e3dad2,
+ 0xbe44d0ba,
+ 0x4d552a6c,
+ 0xe9fafb48,
+ 0x4968ad28,
+ 0xf109edce,
+ 0xd1534f30,
+ 0xc2d8b9e8,
+ 0x66e911d7,
+ 0xd67a594b,
+ 0x4492b2b4,
+ 0xeb86848d,
+ 0x4106979b,
+ 0x0f75039f,
+ 0xf5f3ee2c,
+ 0x04baf613,
+ 0x00c6fd60,
+ 0x32ebe198,
+ 0xc7f129eb,
+ 0x7cac0839,
+ 0x57a1fde4,
+ 0x2da04cfc,
+ 0x93179aa5,
+ 0xf3f4d2d9,
+ 0xd8d2528a,
+ 0x5fdd42af,
+ 0xd08c7bdb,
+ 0x53acd639,
+ 0xe37aab85,
+ 0x2d55b5a2,
+ 0x7bc96248,
+ 0x2fb42401,
+ 0x2ff99915,
+ 0x2be3b5ea,
+ 0xf0ff9bdd,
+ 0x1b6bbaa3,
+ 0x83a13de0,
+ 0x4503fc83,
+ 0x08c24640,
+ 0x2463a2b2,
+ 0x2e264872,
+ 0xc451a29d,
+ 0xbfd2e09c,
+ 0x15bcb009,
+ 0x69102223,
+ 0x4c8581e9,
+ 0x4ec94cf0,
+ 0x75017d7b,
+ 0x0e5d8cf1,
+ 0x50b9ca97,
+ 0x55df1100,
+ 0x245162e0,
+ 0x0df18bca,
+ 0x00776990,
+ 0xf6790a03,
+ 0x599ef43e,
+ 0xe8bf7afb,
+ 0xea141ddc,
+ 0xad1a54b2,
+ 0x55f767f8,
+ 0xb661981c,
+ 0xe1650342,
+ 0x365adc95,
+ 0xbb44e3a0,
+ 0xa064fea1,
+ 0x3516bf27,
+ 0xfd40a414,
+ 0x53f9a9e6,
+ 0x2071a5ee,
+ 0x56ca2713,
+ 0x7afdd07a,
+ 0xd62b7f6e,
+ 0xe9dac904,
+ 0xca212105,
+ 0xb9d6e3de,
+ 0x6af5033f,
+ 0x34d9049b,
+ 0xc51ec095,
+ 0xe5eddb9d,
+ 0x122b5c6a,
+ 0x9f562e58,
+ 0x20ec8986,
+ 0x760857f2,
+ 0x8d8aadb3,
+ 0xbc8f0807,
+ 0x0f79eae7,
+ 0xbfa6bfa8,
+ 0x28151aeb,
+ 0xbe4b4d4b,
+ 0xc65d58b0,
+ 0xcf99ba1b,
+ 0xc1049197,
+ 0xe36d8c87,
+ 0x548b7676,
+ 0xbe7bb2c4,
+ 0x77923781,
+ 0x5fbd631e,
+ 0x770e5a41,
+ 0xd2f2948a,
+ 0x074f5428,
+ 0xc7a1562e,
+ 0xf55618c6,
+ 0x8bf8a3d1,
+ 0x837ed4a8,
+ 0xe42e0298,
+ 0xd3754b0c,
+ 0xbaa24c25,
+ 0x793ac973,
+ 0x814e66ec,
+ 0xa4154fa9,
+ 0x3e0e65ca,
+ 0x5a783bd5,
+ 0x2bb37f6c,
+ 0xb3c2526e,
+ 0x34c9a28a,
+ 0x6c8b4795,
+ 0x64605fa8,
+ 0x2e6aae2e,
+ 0xd9b28f27,
+ 0x6a9a200b,
+ 0x3acd1e3a,
+ 0xce9a4a6c,
+ 0xd2a0bd14,
+ 0x700f2003,
+ 0x501cbef7,
+ 0x4068b05e,
+ 0xa24c4580,
+ 0x4da75506,
+ 0x500b9b0f,
+ 0x22e3a600,
+ 0x7bec4e94,
+ 0x8f0958e2,
+ 0x42129a1e,
+ 0xb46d8dc5,
+ 0x29f8851c,
+ 0x83fb38bd,
+ 0x17b0de15,
+ 0x15340d20,
+ 0x74f00fde,
+ 0x6c646b32,
+ 0x905897c4,
+ 0x4d8ed991,
+ 0x3cf91fd5,
+ 0x0ee02ddf,
+ 0xec069ce6,
+ 0x0b977683,
+ 0xa0bf31f6,
+ 0xa1d135a9,
+ 0xa882d1db,
+ 0xa731a63a,
+ 0x48e211f1,
+ 0xf3d89e99,
+ 0xf982e6ea,
+ 0x23dde303,
+ 0x7f1ff8da,
+ 0xdc8c6414,
+ 0x806f432e,
+ 0xd047bc02,
+ 0x671bacff,
+ 0xd40ba2a8,
+ 0xe3666685,
+ 0x31265f9f,
+ 0x3931a952,
+ 0x62f35606,
+ 0xc48f0c5e,
+ 0xfd107640,
+ 0xf636da24,
+ 0xb8f5c3b0,
+ 0x1c91e88f,
+ 0xed9dd432,
+ 0x2b85fa5d,
+ 0x8b15d2ac,
+ 0x1e06cf24,
+ 0x1def6e9c,
+ 0xfae9175f,
+ 0x03ac6f02,
+ 0x37318c87,
+ 0xbc0b1ce5,
+ 0xa0640cab,
+ 0x6cc20a3c,
+ 0x1c7b2524,
+ 0x4685dacc,
+ 0xeab8bb31,
+ 0x8063b5d0,
+ 0x79817d52,
+ 0x211b1972,
+ 0xd7bfc987,
+ 0xab9128dc,
+ 0x150d9b36,
+ 0x6a5838ab,
+ 0x9a0a304d,
+ 0x2e43c331,
+ 0x84f2c4b8,
+ 0x435146c1,
+ 0xed64a280,
+ 0x553ecb4c,
+ 0x5c800db2,
+ 0xeef4df95,
+ 0x5dcf2c37,
+ 0x70755ddf,
+ 0x4274737b,
+ 0xe610350e,
+ 0xd97a5997,
+ 0x7af5edce,
+ 0xfd18ba0c,
+ 0xb7587cd8,
+ 0xfa5e42d6,
+ 0x76bde9eb,
+ 0xec41eead,
+ 0x604d2423,
+ 0xb4adbcf9,
+ 0xce728fa3,
+ 0x02361c31,
+ 0x02fab64d,
+ 0x00316b1c,
+ 0x562f9aa4,
+ 0x71f85790,
+ 0x9cb6d464,
+ 0x32949ebf,
+ 0x434fc23d,
+ 0xee7fac51,
+ 0xda5cc63a,
+ 0x17e616b4,
+ 0xcd1bd1bc,
+ 0x14638cae,
+ 0xd31808fa,
+ 0xb16e0727,
+ 0xfdda2b0f,
+ 0xbc11c678,
+ 0xfe79dc6e,
+ 0xe26eefb4,
+ 0x9a78de16,
+ 0xb68f2df2,
+ 0xd47da234,
+ 0xbdff28a4,
+ 0x937bb1f4,
+ 0x0786dd46,
+ 0xbd1160f5,
+ 0xf77b070c,
+ 0x72b7c51e,
+ 0xcbb3a371,
+ 0x5e50e904,
+ 0x00fbc379,
+ 0x680757dd,
+ 0xd38193f7,
+ 0x93113e25,
+ 0x7b258da7,
+ 0x991aaa09,
+ 0xab1415be,
+ 0xa3740774,
+ 0x370b72e5,
+ 0x2fc643f4,
+ 0x3916d70e,
+ 0xea2838d3,
+ 0xe4840c42,
+ 0xd18e6959,
+ 0x69a270ee,
+ 0xee4a494e,
+ 0x0329799b,
+ 0x07480357,
+ 0x0260c46f,
+ 0x7b75346e,
+ 0x787234f4,
+ 0xe0adf25b,
+ 0xba85cacf,
+ 0xb5724eb1,
+ 0xfde2c080,
+ 0x2b6bb492,
+ 0xd2f70545,
+ 0x9ca97510,
+ 0x4034c18f,
+ 0x616bcb12,
+ 0x5667f52a,
+ 0xe2f6bfce,
+ 0x1f25969e,
+ 0x569eaab7,
+ 0x27ad8196,
+ 0x2d30a6d0,
+ 0x96d6c10a,
+ 0xcb9f024f,
+ 0x3d7941ef,
+ 0xf7a76bc5,
+ 0xe9a701d4,
+ 0xd53293a3,
+ 0x252cf5df,
+ 0xaf9172f6,
+ 0xd090c809,
+ 0xb1a17387,
+ 0x045a0987,
+ 0x92d9ffd9,
+ 0xb30c449c,
+ 0x2180ff58,
+ 0x2929f7de,
+ 0x3f91766e,
+ 0x9f488e3d,
+ 0x05dd6734,
+ 0x82482f5b,
+ 0x01da3ca2,
+ 0x42f33408,
+ 0xf8e3ba89,
+ 0x750ac2ff,
+ 0x39f11551,
+ 0x71087971,
+ 0x368fa634,
+ 0xefda0572,
+ 0x14b8f750,
+ 0xe5768705,
+ 0x71c168e2,
+ 0x8c012c63,
+ 0x12ad74ce,
+ 0x841c17ea,
+ 0xe6f44176,
+ 0x36cf2557,
+ 0x14760a6d,
+ 0x4bb3b7c2,
+ 0x14d1437d,
+ 0xbe673210,
+ 0x4d6ba9f5,
+ 0xe68abbf9,
+ 0xc311908d,
+ 0x46b63956,
+ 0xac2c9fb3,
+ 0xab769ce8,
+ 0xa29d7040,
+ 0xec3d67e3,
+ 0xdef311de,
+ 0x52a53b14,
+ 0xca924769,
+ 0xf35d1514,
+ 0x524b0471,
+ 0xc0d08591,
+ 0x454fc34c,
+ 0xca719639,
+ 0x9af2f230,
+ 0xa023a821,
+ 0x3d6539ba,
+ 0x90d0d7a2,
+ 0xc65fc56e,
+ 0x4eb2aa19,
+ 0xeba3b0e7,
+ 0x1bb5b33e,
+ 0xab8c68c2,
+ 0x0f1793d3,
+ 0xdcf176e9,
+ 0x1b7bbba0,
+ 0x96170a27,
+ 0x1955452d,
+ 0x42e88c71,
+ 0x48cad4b3,
+ 0xdcc36042,
+ 0x90619951,
+ 0x7566bc7c,
+ 0xe14ba224,
+ 0xc24ad73d,
+ 0xdb04144d,
+ 0xd9792727,
+ 0x11150943,
+ 0xe45f0c57,
+ 0xb87d184e,
+ 0x3cf13243,
+ 0x2010d95c,
+ 0x84c347c1,
+ 0x6d0f2461,
+ 0xb5c41194,
+ 0xde7ccb2e,
+ 0xb929ecb0,
+ 0x51fbd8f7,
+ 0x45dc65fb,
+ 0x6902d2c0,
+ 0xb940814f,
+ 0xf339e083,
+ 0x6f370d56,
+ 0xcaf5638e,
+ 0xe8a3cb83,
+ 0xacf414b6,
+ 0xe61095a1,
+ 0x99b4cde4,
+ 0x55112fed,
+ 0x606b9d53,
+ 0x5a05974a,
+ 0xa4c7db34,
+ 0xdc92469b,
+ 0xf9280621,
+ 0xe7b1ef95,
+ 0xc0fc5be8,
+ 0x74a1da09,
+ 0xa92a4b7f,
+ 0x3d65d75e,
+ 0xe3804335,
+ 0x1ff49e19,
+ 0x71da8170,
+ 0xac69069b,
+ 0x04aae3d5,
+ 0xc0ef4b46,
+ 0x091a3482,
+ 0x8356c7ae,
+ 0x32ecb208,
+ 0x900c89ed,
+ 0x2a206ff5,
+ 0x7eed5032,
+ 0x5b55b25d,
+ 0xf98d6df2,
+ 0xf52bc8a9,
+ 0x1aa2f5fe,
+ 0x1d33c0bf,
+ 0x3cd34e89,
+ 0x9a0da4ae,
+ 0x1c205917,
+ 0x7ca784cd,
+ 0xf7dda662,
+ 0xad97f3ff,
+ 0x525c53ec,
+ 0x024f11ff,
+ 0x32c3ae5b,
+ 0xbf372800,
+ 0x8ff15f4d,
+ 0x7605d019,
+ 0x0dae7740,
+ 0x5f5dd0ef,
+ 0x0f6c37d0,
+ 0xee6fa91e,
+ 0xb9f51051,
+ 0x39a9f0d1,
+ 0x22bf03fb,
+ 0x485a0922,
+ 0x7384b30e,
+ 0x85ba7f16,
+ 0xb1f0a524,
+ 0x7e9c5113,
+ 0x240d9306,
+ 0x1ca7b0ea,
+ 0x18a0d114,
+ 0x76b64213,
+ 0x31212cc0,
+ 0xc9dca5c3,
+ 0x69f2ae52,
+ 0x545caa7c,
+ 0xfb2ff045,
+ 0x3f3a1af5,
+ 0xe75b6913,
+ 0x775a1c79,
+ 0x4627e25f,
+ 0x90a14b97,
+ 0x06456383,
+ 0x3d52cf69,
+ 0xfb2492c3,
+ 0x39f25a22,
+ 0x81f68c55,
+ 0x87b14e15,
+ 0x0920af5d,
+ 0xe2585678,
+ 0x0671e46d,
+ 0xb77ddb67,
+ 0x3948c4b3,
+ 0x122dddef,
+ 0xd0726172,
+ 0xd3302234,
+ 0x58bab4e4,
+ 0x195ac247,
+ 0x082459f0,
+ 0x18a2566d,
+ 0xbf56078d,
+ 0x116ed409,
+ 0x5ccc0f80,
+ 0xbae0b4ca,
+ 0x21a6325d,
+ 0x7e1f0c40,
+ 0x595326d4,
+ 0x518b2244,
+ 0x8ab3cdb7,
+ 0xbe6b4835,
+ 0xfc39f8ac,
+ 0x63b167aa,
+ 0x194f070d,
+ 0xed3d0416,
+ 0xae16758a,
+ 0xb9bb6bbf,
+ 0x477d9c85,
+ 0x9808c304,
+ 0xe1d8cec4,
+ 0x7ee22e17,
+ 0x0a7a9d7f,
+ 0xcc98173a,
+ 0x5f78dc21,
+ 0x364bc95e,
+ 0xb54608d9,
+ 0x5d4d70ea,
+ 0x083a7f79,
+ 0x59ffbd73,
+ 0x4f3e9eaf,
+ 0x68755ad4,
+ 0xab254689,
+ 0x11bf09a8,
+ 0xbbc40098,
+ 0x969ca3eb,
+ 0x30eee9d2,
+ 0xe35bc37e,
+ 0xcb2d678f,
+ 0x7846876b,
+ 0xf0d28ae7,
+ 0xc092fbb2,
+ 0x321b344a,
+ 0xcc5ee81b,
+ 0xd2afa00f,
+ 0xfeccd86a,
+ 0x6e5e55c2,
+ 0x2b5543ea,
+ 0x810e4009,
+ 0xea2d8e20,
+ 0x6acae3b9,
+ 0x3828e15e,
+ 0xe1e4821c,
+ 0xf429da70,
+ 0x35f6565c,
+ 0x64b1baa8,
+ 0x350e9583,
+ 0xd2522d4f,
+ 0x5e28a3f1,
+ 0x949ff0aa,
+ 0x3c1b5694,
+ 0x146dde1f,
+ 0x6f3430e1,
+ 0x71c077b7,
+ 0x4d145924,
+ 0xe431cd28,
+ 0xb315cfde,
+ 0xa0365a4a,
+ 0x473de1aa,
+ 0xcbe4e999,
+ 0x319906e9,
+ 0xad0fea9c,
+ 0x89e4e72d,
+ 0x9dbba94d,
+ 0xd395c1c5,
+ 0xa1fff11a,
+ 0x8447e120,
+ 0xe5c59100,
+ 0xa07cb778,
+ 0x8f30a039,
+ 0xed78facb,
+ 0x86de9373,
+ 0x550c4889,
+ 0xce71e3a8,
+ 0x06167b3a,
+ 0x5abdd9a3,
+ 0xc8a9e48d,
+ 0xe3312905,
+ 0x7a63a146,
+ 0xc0f19763,
+ 0xda0cf9db,
+ 0x1d708306,
+ 0x0e41f0ba,
+ 0x4c7939fe,
+ 0x768e48c2,
+ 0xe925fd31,
+ 0x309e7870,
+ 0xfc261b87,
+ 0xc897b2de,
+ 0x6c714792,
+ 0x41c7fbac,
+ 0x57d0b3c3,
+ 0x4fa82a55,
+ 0xd56b4a87,
+ 0x81e5cabc,
+ 0xb260cb7b,
+ 0x520927ab,
+ 0x20d0ab46,
+ 0xc9f92ddf,
+ 0x81f4a21d,
+ 0xfc5a0ca2,
+ 0x95d16aad,
+ 0xe54d7847,
+ 0x6080cc07,
+ 0x0df73f7e,
+ 0xaa8d5187,
+ 0x97a0bc12,
+ 0xb22c5e68,
+ 0x0954d7dc,
+ 0x3368ab5a,
+ 0xd12541df,
+ 0x58119260,
+ 0xe5b0e1df,
+ 0x25027fa4,
+ 0x5780425d,
+ 0x29bb8791,
+ 0x4100b7a9,
+ 0x076b3519,
+ 0x15e0ebb4,
+ 0xe5fb9273,
+ 0x6dbf07e7,
+ 0x1f82bddd,
+ 0x03691b6b,
+ 0xbacef28c,
+ 0x9909ed5a,
+ 0x98886793,
+ 0x544f9a82,
+ 0x9d9749d0,
+ 0x38441606,
+ 0xc4a9f4d2,
+ 0x6ce2bcf1,
+ 0x1c7c3abd,
+ 0x62c621f1,
+ 0x871ee1e4,
+ 0xa83930ce,
+ 0xbe1ee459,
+ 0xd61f1ca4,
+ 0x8c4450e5,
+ 0x98031ca9,
+ 0xe52f54e2,
+ 0xd0c4c737,
+ 0x76074160,
+ 0xbf050c3b,
+ 0x2603af14,
+ 0x43cbb0bc,
+ 0xc631b9e8,
+ 0x26030719,
+ 0x993f570c,
+ 0xdda34038,
+ 0xe34a9793,
+ 0x337a124c,
+ 0x2aa8af16,
+ 0xf80d7473,
+ 0xf01d9397,
+ 0x68e1afb9,
+ 0x0eb37ad2,
+ 0xf71969f9,
+ 0xdf020552,
+ 0x75aa9b30,
+ 0xffa210cf,
+ 0x543c414f,
+ 0xa1e3faec,
+ 0x40891d7e,
+ 0x6b48a6c5,
+ 0xec09a1a0,
+ 0x97a31f2a,
+ 0x5a6be2d7,
+ 0xd06e492b,
+ 0xc54290af,
+ 0xcb524021,
+ 0x420e8c4d,
+ 0xfb135c17,
+ 0x2bfc8adb,
+ 0x9f0cfb46,
+ 0x564db712,
+ 0x7a97a227,
+ 0x8bb98daf,
+ 0xdd0d6180,
+ 0x3d28b9e3,
+ 0xe505050f,
+ 0x19a9868e,
+ 0x7bf5685f,
+ 0x35d698c4,
+ 0xce7e1de3,
+ 0x360a64af,
+ 0x25a1f022,
+ 0xe26c1d04,
+ 0x5b3fb364,
+ 0x932f25f7,
+ 0x9a2aa00d,
+ 0xc50fb773,
+ 0xec45ea3a,
+ 0x22ddf8e4,
+ 0xafb6a6c8,
+ 0x876d04f7,
+ 0xd9c86c3c,
+ 0xd54bee2d,
+ 0xf4e28199,
+ 0xc3456776,
+ 0x04c3107b,
+ 0xbf914e9d,
+ 0x23fefaa5,
+ 0x0931a133,
+ 0x41467758,
+ 0x8ec49707,
+ 0x5ed48709,
+ 0xd11c2de8,
+ 0xb687a0b9,
+ 0xdc908383,
+ 0xd8037ff3,
+ 0xd4311a9f,
+ 0xd00aeb6a,
+ 0xfe54df3b,
+ 0x9c51ce4d,
+ 0x36956408,
+ 0xcd28ef09,
+ 0xc68932b0,
+ 0x7c31e782,
+ 0x28b4723c,
+ 0xededacc2,
+ 0x6ddbac6b,
+ 0x775a7fc1,
+ 0x6909906f,
+ 0xa774123c,
+ 0xf63145ad,
+ 0x287b191e,
+ 0x59d79300,
+ 0xbf76a2fc,
+ 0xfbaf9207,
+ 0x2fe5b7f6,
+ 0xebe7c103,
+ 0x71ac0a8d,
+ 0x2028c3c7,
+ 0xd2cb4917,
+ 0xd74a4ee4,
+ 0xfce405d8,
+ 0xad83fd0f,
+ 0x8f9ec3da,
+ 0xaab2301c,
+ 0xc6f1339f,
+ 0xc652bced,
+ 0xe378b272,
+ 0x18e1ff34,
+ 0x9ec778b6,
+ 0xce1a3883,
+ 0x7c5e5eaf,
+ 0xd16ec37a,
+ 0xa69e45f4,
+ 0xc36cd4aa,
+ 0x045b391f,
+ 0x5a2a08f1,
+ 0x4dd8d53e,
+ 0xd64796ec,
+ 0x4476fc28,
+ 0x18dbaa50,
+ 0x00fb2407,
+ 0x177db915,
+ 0x5969758b,
+ 0x3030964a,
+ 0x81d6485b,
+ 0x7d2e12b0,
+ 0x624d6c5f,
+ 0x0746bbc0,
+ 0xe669d150,
+ 0x0465eef7,
+ 0x09764011,
+ 0x551995e4,
+ 0x8422dedf,
+ 0x0ca56194,
+ 0x293eab2e,
+ 0xf20a137a,
+ 0x55117fc2,
+ 0xbc5431af,
+ 0x064751fa,
+ 0xc0dafdb2,
+ 0x6c3b1d4f,
+ 0xeac335b3,
+ 0x71173afc,
+ 0x31c84b7c,
+ 0xfef2b4ab,
+ 0x59ca5fa2,
+ 0x664c8b4e,
+ 0x7dfd560b,
+ 0xdb0daff3,
+ 0x51f87bfa,
+ 0x58015d2e,
+ 0x67a827b4,
+ 0x62cebc1a,
+ 0x24b37298,
+ 0x75b589be,
+ 0x874f1800,
+ 0x277b795c,
+ 0xf762489e,
+ 0x87d00752,
+ 0x9be45ed1,
+ 0x296ec120,
+ 0x61162480,
+ 0x792e8a2c,
+ 0x3b631590,
+ 0xe33ba0cf,
+ 0x542ac23c,
+ 0xe1e8cffa,
+ 0xfc084cd8,
+ 0xc115ad31,
+ 0x71559928,
+ 0x791f1e33,
+ 0x662ed92b,
+ 0x7222c76d,
+ 0x02dcd566,
+ 0x8db9b4d4,
+ 0xa5f344c8,
+ 0x15806b12,
+ 0x81e572f7,
+ 0x3b3fbe25,
+ 0x2133b413,
+ 0x2d68a367,
+ 0x356f6ce7,
+ 0xcd6dfed1,
+ 0xd8b3a26e,
+ 0xe9d328da,
+ 0x127425ab,
+ 0x83a60aac,
+ 0x8cc26190,
+ 0x7f87ab26,
+ 0x56faab5f,
+ 0x76d0feaa,
+ 0x4b25dd10,
+ 0x4f6286ea,
+ 0x79298d06,
+ 0x8002bf83,
+ 0x2977c85e,
+ 0xd3b3d19a,
+ 0xa92bf132,
+ 0xa280efd8,
+ 0x83f7ad6e,
+ 0x748969c7,
+ 0x25ff411d,
+ 0x3854d3a8,
+ 0x55746aa2,
+ 0x00db5c54,
+ 0x36949e0d,
+ 0x40402ab6,
+ 0x1a720211,
+ 0xe02ce823,
+ 0x4ac104a2,
+ 0x214d2e4b,
+ 0x267e5c83,
+ 0x38a3a483,
+ 0xd1da1f67,
+ 0x0c68db2c,
+ 0xd7035d63,
+ 0xa29393bb,
+ 0xa5743519,
+ 0xcb97c84e,
+ 0xa853974f,
+ 0x147360a0,
+ 0x2df9b3f4,
+ 0x0aff129e,
+ 0x177d687f,
+ 0x87eff911,
+ 0x6c60b354,
+ 0x6c356c38,
+ 0x7d480965,
+ 0xbb06a193,
+ 0x25b0568e,
+ 0x6fd6da9a,
+ 0x82b64f14,
+ 0x3d267a78,
+ 0xf100b6a7,
+ 0x32c74539,
+ 0x6042e152,
+ 0x4548276e,
+ 0xa3a32b70,
+ 0xf029fe15,
+ 0xa9b8bd2f,
+ 0x5618eee4,
+ 0x9815a5f0,
+ 0x89fb2850,
+ 0xa9261b26,
+ 0xded9e505,
+ 0x37e9d749,
+ 0xdc4aeb78,
+ 0x9e634f7a,
+ 0xcf638d2d,
+ 0x6b679f92,
+ 0x2b64911d,
+ 0xe6d1312f,
+ 0x88b3e76a,
+ 0x56311f62,
+ 0x00916de7,
+ 0x39d0bc61,
+ 0x8ac09356,
+ 0x47abcfce,
+ 0x324cb73e,
+ 0xfadcd0a8,
+ 0x2f2fbca8,
+ 0x945eda22,
+ 0xba23cab1,
+ 0xf9fb4212,
+ 0x1fa71d45,
+ 0x867a034e,
+ 0x3bee5db1,
+ 0xf54adced,
+ 0x6633ba77,
+ 0xe1eb4f1e,
+ 0x97ef01f6,
+ 0x57fd3b32,
+ 0x5234d80d,
+ 0xe8ee95f3,
+ 0x5dc990bf,
+ 0xaba833e1,
+/* Dummy terminator */
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+};
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g/mptable.c b/src/mainboard/supermicro/x6dhe_g/mptable.c new file mode 100644 index 0000000000..6a284981b0 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/mptable.c @@ -0,0 +1,202 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "X6DHE "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_pxhd_1; + unsigned char bus_pxhd_2; + unsigned char bus_esb6300_1; + unsigned char bus_esb6300_2; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* esb6300_2 */ + dev = dev_find_slot(0, PCI_DEVFN(0x1c,0)); + if (dev) { + bus_esb6300_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + } + else { + printk_debug("ERROR - could not find PCI 0:1c.0, using defaults\n"); + + bus_esb6300_2 = 6; + } + /* esb6300_1 */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_esb6300_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n"); + + bus_esb6300_1 = 7; + bus_isa = 8; + } + /* pxhd-1 */ + dev = dev_find_slot(1, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n"); + + bus_pxhd_1 = 2; + } + /* pxhd-2 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n"); + + bus_pxhd_2 = 3; + } + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + smp_write_ioapic(mc, 3, 0x20, 0xfec10000); + { + struct resource *res; + device_t dev; + /* PXHd apic 4 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x04, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n"); + printk_debug("DEBUG: Dev= %p\n", dev); + } + /* PXHd apic 5 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x05, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n"); + printk_debug("DEBUG: Dev= %p\n", dev); + } + } + + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, // added + bus_isa, 0x07, 0x02, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x77, 0x02, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x75, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0f, 0x02, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7c, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + 0x03, 0x08, 0x05, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + 0x03, 0x08, 0x05, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_1, 0x04, 0x03, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_1, 0x08, 0x03, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_2, 0x04, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_2, 0x08, 0x02, 0x14); + + /* Standard local interrupt assignments */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + +#warning "FIXME verify I have the irqs handled for all of the risers" + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/supermicro/x6dhe_g/reset.c b/src/mainboard/supermicro/x6dhe_g/reset.c new file mode 100644 index 0000000000..874bfc4848 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/supermicro/x6dhe_g/watchdog.c b/src/mainboard/supermicro/x6dhe_g/watchdog.c new file mode 100644 index 0000000000..3904a7dc94 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/watchdog.c @@ -0,0 +1,99 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ESB6300_WDBASE 0x400 +#define ESB6300_GPIOBASE 0x500 + +static void disable_sio_watchdog(device_t dev) +{ +#if 0 + /* FIXME move me somewhere more appropriate */ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 1); + pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE); + /* disable the sio watchdog */ + outb(0, NSC_WDBASE + 0); + pnp_set_enable(dev, 0); +#endif +} + +static void disable_esb6300_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing esb6300?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ESB6300_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ESB6300_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_jarell_frb3(void) +{ +#if 0 + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing esb6300?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 0); + pci_write_config16(dev, 0x04, value); + + /* Set gpio base */ + pci_write_config32(dev, 0x58, ESB6300_GPIOBASE | 1); + base = ESB6300_GPIOBASE; + + /* Enable GPIO Bar */ + value = pci_read_config32(dev, 0x5c); + value |= 0x10; + pci_write_config32(dev, 0x5c, value); + + /* Configure GPIO 48 and 40 as GPIO */ + value = inl(base + 0x30); + value |= (1 << 16) | ( 1 << 8); + outl(value, base + 0x30); + + /* Configure GPIO 48 as Output */ + value = inl(base + 0x34); + value &= ~(1 << 16); + outl(value, base + 0x34); + + /* Toggle GPIO 48 high to low */ + value = inl(base + 0x38); + value |= (1 << 16); + outl(value, base + 0x38); + value &= ~(1 << 16); + outl(value, base + 0x38); +#endif +} + +static void disable_watchdogs(void) +{ +// disable_sio_watchdog(NSC_WD_DEV); + disable_esb6300_watchdog(); +// disable_jarell_frb3(); + print_debug("Watchdogs disabled\r\n"); +} + diff --git a/src/mainboard/supermicro/x6dhe_g/x6dhe_g_fixups.c b/src/mainboard/supermicro/x6dhe_g/x6dhe_g_fixups.c new file mode 100644 index 0000000000..82c070b0c1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g/x6dhe_g_fixups.c @@ -0,0 +1,23 @@ +#include <arch/romcc_io.h> + +static void mch_reset(void) +{ + return; +} + + + +static void mainboard_set_e7520_pll(unsigned bits) +{ + return; +} + + +static void mainboard_set_e7520_leds(void) +{ + return; +} + + + + diff --git a/src/mainboard/supermicro/x6dhe_g2/Config.lb b/src/mainboard/supermicro/x6dhe_g2/Config.lb new file mode 100644 index 0000000000..65a990017f --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/Config.lb @@ -0,0 +1,220 @@ +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of LinuxBIOS will start in the boot rom +## +default _ROMBASE =( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can be cached to speed up linuxBIOS. +## execution speed. +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE= ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7520 # MCH + chip drivers/generic/debug # DEBUGGING + device pnp 00.0 off end + device pnp 00.1 off end + device pnp 00.2 off end + device pnp 00.3 off end + end + device pci_domain 0 on + chip southbridge/intel/ich5r # ICH5R + register "pirq_a_d" = "0x0b070a05" + register "pirq_e_h" = "0x0a808080" + + device pci 1c.0 on + chip drivers/generic/generic + device pci 01.0 on end # onboard gige1 + device pci 02.0 on end # onboard gige2 + end + end + + # USB ports + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.4 on end # Southbridge Watchdog timer + device pci 1d.5 on end # Southbridge I/O apic1 + device pci 1d.7 on end + + # VGA / PCI 32-bit + device pci 1e.0 on + chip drivers/generic/generic + device pci 01.0 on end + end + end + + + device pci 1f.0 on # ISA bridge + chip superio/NSC/pc87427 + device pnp 2e.0 off end + device pnp 2e.2 on + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 off end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a on end + device pnp 2e.b off end + end + end + device pci 1f.1 on end + device pci 1f.2 on end + device pci 1f.3 on end # SMBus + device pci 1f.5 off end + device pci 1f.6 off end + end + + device pci 00.0 on end # Northbridge + device pci 00.1 on end # Northbridge Error reporting + device pci 01.0 on end + device pci 02.0 on + chip southbridge/intel/pxhd # PXHD 6700 + device pci 00.0 on end # bridge + device pci 00.1 on end # I/O apic + device pci 00.2 on end # bridge + device pci 00.3 on end # I/O apic + end + end +# device register "intrline" = "0x00070105" + device pci 04.0 on end + device pci 06.0 on end + end + + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # CPU 0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # CPU 1 + device apic 6 on end + end + end +end diff --git a/src/mainboard/supermicro/x6dhe_g2/Options.lb b/src/mainboard/supermicro/x6dhe_g2/Options.lb new file mode 100644 index 0000000000..d09effc37e --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/Options.lb @@ -0,0 +1,229 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY + + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=1048576 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=16 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="X6DHE_g" +default MAINBOARD_VENDOR= "Supermicro" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x6080 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end + diff --git a/src/mainboard/supermicro/x6dhe_g2/auto.c b/src/mainboard/supermicro/x6dhe_g2/auto.c new file mode 100644 index 0000000000..978356c0ee --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/auto.c @@ -0,0 +1,168 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/ich5r/ich5r_early_smbus.c" +#include "northbridge/intel/E7520/raminit.h" +#include "superio/NSC/pc87427/pc87427.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "x6dhe_g2_fixups.c" +#include "superio/NSC/pc87427/pc87427_early_init.c" +#include "northbridge/intel/E7520/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, PC87427_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0708090a +#define RECVENB_CONFIG 0x0708090a + +//void udelay(int usecs) +//{ +// int i; +// for(i = 0; i < usecs; i++) +// outb(i&0xff, 0x80); +//} + +#if 0 +static void hard_reset(void) +{ + /* enable cf9 */ + pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + /* reset */ + outb(0x0e, 0x0cf9); +} +#endif + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7520/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, }, + .channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, }, + + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + pc87427_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ +// report_bist_failure(bist); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5r?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); +// dump_ipmi_registers(); +// mainboard_set_e7520_leds(); +// memreset_setup(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 0 + dump_pci_devices(); +#endif +#if 1 + dump_pci_device(PCI_DEV(0, 0x00, 0)); + //dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, 0x01000000); + /* check the first 1M in the 3rd Gig */ + ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dhe_g2/auto.updated.c b/src/mainboard/supermicro/x6dhe_g2/auto.updated.c new file mode 100644 index 0000000000..b4966a7f18 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/auto.updated.c @@ -0,0 +1,168 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/esb6300/esb6300_early_smbus.c" +#include "northbridge/intel/E7520/raminit.h" +#include "superio/winbond/w83627hf/w83627hf.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "x6dhe_g_fixups.c" +#include "superio/winbond/w83627hf/w83627hf_early_init.c" +#include "northbridge/intel/E7520/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0708090a +#define RECVENB_CONFIG 0x0708090a + +//void udelay(int usecs) +//{ +// int i; +// for(i = 0; i < usecs; i++) +// outb(i&0xff, 0x80); +//} + +#if 0 +static void hard_reset(void) +{ + /* enable cf9 */ + pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + /* reset */ + outb(0x0e, 0x0cf9); +} +#endif + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7520/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, }, + .channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, }, + + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ +// report_bist_failure(bist); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing esb6300?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); +// dump_ipmi_registers(); +// mainboard_set_e7520_leds(); +// memreset_setup(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 0 + dump_pci_devices(); +#endif +#if 1 + dump_pci_device(PCI_DEV(0, 0x00, 0)); + //dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, 0x01000000); + /* check the first 1M in the 3rd Gig */ + ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dhe_g2/chip.h b/src/mainboard/supermicro/x6dhe_g2/chip.h new file mode 100644 index 0000000000..ff86e23bfc --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_supermicro_x6dhe_g2_ops; + +struct mainboard_supermicro_x6dhe_g2_config { + int nothing; +}; diff --git a/src/mainboard/supermicro/x6dhe_g2/cmos.layout b/src/mainboard/supermicro/x6dhe_g2/cmos.layout new file mode 100644 index 0000000000..6f3cd189e3 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/cmos.layout @@ -0,0 +1,80 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 2 hyper_threading +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/supermicro/x6dhe_g2/debug.c b/src/mainboard/supermicro/x6dhe_g2/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/supermicro/x6dhe_g2/failover.c b/src/mainboard/supermicro/x6dhe_g2/failover.c new file mode 100644 index 0000000000..5029d98611 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7520/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/supermicro/x6dhe_g2/irq_tables.c b/src/mainboard/supermicro/x6dhe_g2/irq_tables.c new file mode 100644 index 0000000000..0851fbe3f8 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/irq_tables.c @@ -0,0 +1,34 @@ +/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 272, /* u16 Table size 32+(15*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x25a1, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xc4, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06, 0x00}, + {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x6dhe_g2/mainboard.c b/src/mainboard/supermicro/x6dhe_g2/mainboard.c new file mode 100644 index 0000000000..dcdb6f642c --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/mainboard.c @@ -0,0 +1,12 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include "chip.h" + +struct chip_operations supermicro_x6dhe_g2_ops = { + CHIP_NAME("Supermicro X6DHE_G2 mainboard") +}; + diff --git a/src/mainboard/supermicro/x6dhe_g2/microcode_updates.c b/src/mainboard/supermicro/x6dhe_g2/microcode_updates.c new file mode 100644 index 0000000000..b2e72ab616 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/microcode_updates.c @@ -0,0 +1,1563 @@ +/* WARNING - Intel has a new data structure that has variable length
+ * microcode update lengths. They are encoded in int 8 and 9. A
+ * dummy header of nulls must terminate the list.
+ */
+
+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {
+ /*
+ Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000.
+ These microcode updates are distributed for the sole purpose of
+ installation in the BIOS or Operating System of computer systems
+ which include an Intel P6 family microprocessor sold or distributed
+ to or by you. You are authorized to copy and install this material
+ on such systems. You are not authorized to use this material for
+ any other purpose.
+ */
+
+ /* M1DF3413.TXT - Noconoa D-0 */
+
+ 0x00000001, /* Header Version */
+ 0x00000013, /* Patch ID */
+ 0x07302004, /* DATE */
+ 0x00000f34, /* CPUID */
+ 0x95f183f0, /* Checksum */
+ 0x00000001, /* Loader Version */
+ 0x0000001d, /* Platform ID */
+ 0x000017d0, /* Data size */
+ 0x00001800, /* Total size */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+
+ 0x9fbf327a,
+ 0x2b41b451,
+ 0xb2abaca8,
+ 0x6b62b8e0,
+ 0x0af32c41,
+ 0x12ca6048,
+ 0x5bd55ae6,
+ 0xb90dfc1d,
+ 0x565fe2b2,
+ 0x326b1718,
+ 0x61f3a40d,
+ 0xceb53db3,
+ 0x14fb5261,
+ 0xbb23b6c3,
+ 0x9d7c0466,
+ 0xde90a25e,
+ 0x9450e9bb,
+ 0x497bd6e4,
+ 0x97d1041a,
+ 0x1831013f,
+ 0x6e6fa37e,
+ 0x0b5c1d03,
+ 0x5eae4db2,
+ 0xc029d9e3,
+ 0x5373bca3,
+ 0xe15fccca,
+ 0x39043db0,
+ 0xaeb0ea0c,
+ 0x62b4e391,
+ 0x0b280c6b,
+ 0x279eb9d3,
+ 0x98d95ada,
+ 0xc1cb45a7,
+ 0x06917bda,
+ 0xdde8aafa,
+ 0xdff9d15c,
+ 0xd07f8f0a,
+ 0x192bcf9d,
+ 0xf77de31f,
+ 0xadf8be55,
+ 0x3f7a5d95,
+ 0x0e2140b6,
+ 0xf0c75eec,
+ 0x3254876a,
+ 0x684a1698,
+ 0x4ad0cca7,
+ 0x6d705304,
+ 0xf957d91b,
+ 0xe8bb864a,
+ 0x440d636c,
+ 0xaf4d7d06,
+ 0x12680ecf,
+ 0x5d0f9e53,
+ 0x60148a5d,
+ 0x81008364,
+ 0x243a8aed,
+ 0xd55976de,
+ 0xd6a84520,
+ 0x932d4b77,
+ 0xe67e5f19,
+ 0x7dba0e47,
+ 0xfee3b153,
+ 0x46b6a20c,
+ 0x2594e6f6,
+ 0x210cab0f,
+ 0xf6e47d5d,
+ 0xe38276e4,
+ 0x90fc2728,
+ 0x9faefa11,
+ 0xc972217c,
+ 0xc8d079dd,
+ 0x5f7dc338,
+ 0x106f7b7b,
+ 0xd04c0a1c,
+ 0x0eca300e,
+ 0x1ddae8a6,
+ 0x6e7fd42e,
+ 0xa56c514d,
+ 0x56a4e255,
+ 0x975ea2bf,
+ 0x0eaa78cc,
+ 0x0c3e284f,
+ 0xbacb6c71,
+ 0x1645006f,
+ 0xe9a2b955,
+ 0x0677c019,
+ 0x24b33da0,
+ 0x62f200fa,
+ 0x234238c4,
+ 0x81d5ad79,
+ 0x9f754bc9,
+ 0xeffd5016,
+ 0x041b2cc2,
+ 0x2f020bc7,
+ 0x4fcd68b8,
+ 0x22c3579c,
+ 0x4804a114,
+ 0xc42db3ea,
+ 0x7cde8141,
+ 0x47e167c8,
+ 0x01aa38cc,
+ 0x74a5c25e,
+ 0xe0c48d67,
+ 0x562365ad,
+ 0x38321e57,
+ 0x0395885a,
+ 0x6888323e,
+ 0xd6fc518f,
+ 0x1854b64c,
+ 0x06a58476,
+ 0x3662f898,
+ 0xe2bcdaee,
+ 0x84c40693,
+ 0xef09d374,
+ 0x353cc799,
+ 0x742223d4,
+ 0x05b3c99b,
+ 0x0c51ee45,
+ 0xd145824a,
+ 0xac30806c,
+ 0x2ed70c0d,
+ 0x71ae10ff,
+ 0xbf491854,
+ 0x3e1f03b4,
+ 0x76bfd6cd,
+ 0x1449aa8a,
+ 0xf954d3fb,
+ 0xf8c7c940,
+ 0x70233f85,
+ 0x0729e257,
+ 0x10bb8936,
+ 0xc35bb5b5,
+ 0x95d78b5c,
+ 0xcc1ba443,
+ 0x6f507126,
+ 0xa607cfd0,
+ 0xce22f2f3,
+ 0x5134ed8c,
+ 0xec8d2f06,
+ 0xa92413d5,
+ 0xb973f431,
+ 0x16e136dd,
+ 0xf7d41bed,
+ 0x01b002fe,
+ 0x646ed771,
+ 0x76ea3d26,
+ 0x5024af20,
+ 0x84270f51,
+ 0x9b3d7820,
+ 0x2454a2c6,
+ 0xc1f072ed,
+ 0x155e864f,
+ 0x4c39a6e5,
+ 0x928206e5,
+ 0x9d1685f5,
+ 0x45542ee7,
+ 0x1fd27d9e,
+ 0x5f2dd9ff,
+ 0x222005eb,
+ 0x354e8a55,
+ 0x1f0de29a,
+ 0xb86dc696,
+ 0x9eafafad,
+ 0x191b197e,
+ 0x0e0900e1,
+ 0xe0ac42bb,
+ 0x3143236f,
+ 0x44177def,
+ 0x05259274,
+ 0xb21af44a,
+ 0x6ddee4df,
+ 0xc7b56255,
+ 0xb6b1d39d,
+ 0x218f9070,
+ 0x96545a42,
+ 0x98cc2d4a,
+ 0xb21bac9e,
+ 0x83e12d44,
+ 0x2ef4fb39,
+ 0xbc03528f,
+ 0x9485af58,
+ 0xd9f1e6ab,
+ 0xde7607e6,
+ 0x3b398733,
+ 0x9cd9b1a9,
+ 0xabd77984,
+ 0xcce18826,
+ 0x701c5c21,
+ 0xe6591cbf,
+ 0x07a9b9e1,
+ 0x69459c90,
+ 0xe0cdcad6,
+ 0xc4c6c4b6,
+ 0x12748024,
+ 0x4a33c567,
+ 0x7d26a37e,
+ 0xcae163bf,
+ 0xeb7547fa,
+ 0xccc6a01c,
+ 0x3cb8abb8,
+ 0x64aa67b2,
+ 0x51ddf6de,
+ 0xbfe1b905,
+ 0x50923949,
+ 0xacfa43af,
+ 0x1fdb5a44,
+ 0x091533cb,
+ 0x7c92e5dc,
+ 0x1c5d0d3e,
+ 0x195271f5,
+ 0x96e73a4a,
+ 0xe1b11968,
+ 0xb42906f2,
+ 0x5a2940b3,
+ 0x611283e9,
+ 0x65829161,
+ 0x5d1357b7,
+ 0x019428ad,
+ 0x836c5c3c,
+ 0xc0e5e169,
+ 0xd360e424,
+ 0x257a9d69,
+ 0xdca09040,
+ 0x85f1c060,
+ 0xae7cae79,
+ 0xa5ddcfd6,
+ 0xdba8f68e,
+ 0xd98df596,
+ 0xe6e3cd51,
+ 0xcfb2be8f,
+ 0x368fe6cd,
+ 0x58486b75,
+ 0x791f1a48,
+ 0xf81a61f2,
+ 0x58a38155,
+ 0x30a86547,
+ 0xd7fb2db1,
+ 0x300e0b1d,
+ 0x3f838461,
+ 0xf278805a,
+ 0x49529931,
+ 0x601d5649,
+ 0xe500ba1a,
+ 0xc4f78965,
+ 0xe10ed02d,
+ 0x1f777ebd,
+ 0x2db1d17d,
+ 0x48a22e6a,
+ 0x5a14b738,
+ 0xdcf899e0,
+ 0xc845bd04,
+ 0xd04a52b9,
+ 0xf2f19b06,
+ 0xdb5ba97a,
+ 0xf05605ff,
+ 0xc787b72c,
+ 0x9f197770,
+ 0x87b31150,
+ 0x3ff00d57,
+ 0x89d1dcb3,
+ 0x07528ff4,
+ 0x4105fcef,
+ 0xb087de2e,
+ 0x3bd333a5,
+ 0x84a094f4,
+ 0x9ab8fb97,
+ 0xc9bba063,
+ 0x664c52e5,
+ 0x27fd05e4,
+ 0x3f0e491d,
+ 0xab8f4b9a,
+ 0x344a0249,
+ 0x727dd74f,
+ 0x29587211,
+ 0xbba262b9,
+ 0x319ecbb3,
+ 0xec54b023,
+ 0xd0fa096d,
+ 0x3d223f23,
+ 0x0b6013e7,
+ 0x513e045b,
+ 0xcb1edf15,
+ 0xfd44bb25,
+ 0x023eb973,
+ 0x3f55dac6,
+ 0xc2df6514,
+ 0x68589880,
+ 0x4556878e,
+ 0x86f6acfb,
+ 0xbcd23f0b,
+ 0x32c417c1,
+ 0x45f3bb56,
+ 0xbe60872b,
+ 0x09457cc0,
+ 0x2e18b62d,
+ 0x065f54d1,
+ 0xae3b4a20,
+ 0x265b10ae,
+ 0xb7547a1d,
+ 0x5a9481a9,
+ 0xd477ed02,
+ 0x601ed0fc,
+ 0x9a43257e,
+ 0xc9922b72,
+ 0xa2a696ae,
+ 0xe9d6c37b,
+ 0xfab8bdf9,
+ 0x1deb34dc,
+ 0xaa6bb090,
+ 0xbdc3b72f,
+ 0xecb3b010,
+ 0xe64376e7,
+ 0x40356095,
+ 0x928b5047,
+ 0xbd271c09,
+ 0xfd806f61,
+ 0x0821e090,
+ 0x6afb3588,
+ 0xd10e91ea,
+ 0xbbc7fedd,
+ 0xb1ac6d33,
+ 0x07788e4b,
+ 0xa10f8013,
+ 0x4f8efd9d,
+ 0xe5d8728d,
+ 0x017f3e82,
+ 0xf09ec7eb,
+ 0x6bfd7906,
+ 0xbcefcb44,
+ 0x76699ad5,
+ 0x1b976522,
+ 0xa55b3dbd,
+ 0x88bb33e2,
+ 0x98ac5b7f,
+ 0x61ac4c8b,
+ 0xfd948f3d,
+ 0xee610413,
+ 0xc77c5035,
+ 0x662825a9,
+ 0x0009fcba,
+ 0x3450fd88,
+ 0xeb391fef,
+ 0x6949960d,
+ 0x1ccb13c3,
+ 0x21dac5a6,
+ 0x6bcc6b37,
+ 0x37ad77a5,
+ 0xf71d58b1,
+ 0x84ed440d,
+ 0xe606b699,
+ 0xe43067a4,
+ 0x21d5b8b3,
+ 0xe11f83e2,
+ 0xa0cc6585,
+ 0x40eb6d16,
+ 0xc5a6879f,
+ 0xbd333fd5,
+ 0xb44acab4,
+ 0x68c016fc,
+ 0xfbcd3cfc,
+ 0xadf76e42,
+ 0xc520e516,
+ 0x7468cb61,
+ 0x585c0d52,
+ 0xea83cefe,
+ 0x615d7760,
+ 0x89c9b8fd,
+ 0x367c355a,
+ 0x409371a2,
+ 0x7edb38a7,
+ 0xca86d263,
+ 0xda18250d,
+ 0x26e1ed8b,
+ 0x02fefede,
+ 0x704cb5c8,
+ 0x52cbe1eb,
+ 0x9cdbc71a,
+ 0xa0637560,
+ 0xe31f03ca,
+ 0x2b78969b,
+ 0x803d5866,
+ 0xec52d984,
+ 0xd8df8bdb,
+ 0x6cb1d5e8,
+ 0x7b9aec01,
+ 0xf7d39401,
+ 0xdd04c6ae,
+ 0x0e5ca4eb,
+ 0x12b593c8,
+ 0x38f6d4e5,
+ 0x13a91268,
+ 0x60c8251b,
+ 0xa136cf9a,
+ 0xda070cdd,
+ 0x6142408c,
+ 0xc28065dd,
+ 0x50b73718,
+ 0x36074eee,
+ 0xc7b20fcb,
+ 0x18d29f9b,
+ 0xe97eb966,
+ 0xe6936bcc,
+ 0x1c9188ea,
+ 0x7cff40e2,
+ 0xee791ac8,
+ 0xb099a323,
+ 0x571d69b7,
+ 0x22c1f7d0,
+ 0x0b9662ee,
+ 0x76e45cb9,
+ 0xbd0d7020,
+ 0x7794bd95,
+ 0x1b0fe51a,
+ 0xda2754ef,
+ 0x7f3ad7a9,
+ 0x58f627d3,
+ 0x211670a3,
+ 0xc7471b81,
+ 0x495a93ac,
+ 0xaad4f030,
+ 0xa76614c8,
+ 0xd63dba3c,
+ 0x9c4f729c,
+ 0x6e831cfb,
+ 0xa6105c75,
+ 0x95c62188,
+ 0x723ef45d,
+ 0xf59f2dd1,
+ 0x5825283d,
+ 0x768d8a86,
+ 0x070d02ac,
+ 0xfdbcbd73,
+ 0x0d479795,
+ 0x797aa7f7,
+ 0x6c9e468b,
+ 0xa961571d,
+ 0xc7127ef0,
+ 0x4b0442e7,
+ 0xd99a9e87,
+ 0x6c876cba,
+ 0xe4f9f814,
+ 0x120eeb8d,
+ 0x4bbb9c8e,
+ 0x22c0a29e,
+ 0xff681fcc,
+ 0x26777226,
+ 0x6339e667,
+ 0x2402333e,
+ 0x2bf66a17,
+ 0x63806e6c,
+ 0x98416b75,
+ 0x791b3e91,
+ 0x79c09cd7,
+ 0x0c157436,
+ 0x6d99157c,
+ 0xc8990984,
+ 0xaf7d2ae4,
+ 0xfe3ee7d9,
+ 0xb7676de0,
+ 0x9df8722e,
+ 0x08462a7e,
+ 0x99032839,
+ 0xd726ff95,
+ 0x5c1c78e8,
+ 0x4ef1b747,
+ 0x4e257ba7,
+ 0xa83ad5f3,
+ 0x523b3809,
+ 0xc2ce4f19,
+ 0xabfadaa5,
+ 0x370b005c,
+ 0x2d6a02e1,
+ 0xbf6ee428,
+ 0xfd84be50,
+ 0xb79801b3,
+ 0x488ad789,
+ 0x65a87bda,
+ 0x59f0fd6a,
+ 0xa4106878,
+ 0xdbadd916,
+ 0x1f86f200,
+ 0xefb7fc72,
+ 0x26d4d47f,
+ 0xf7892efc,
+ 0x41f50167,
+ 0xc6a28f9e,
+ 0xffd4a8e0,
+ 0xa00e4ea0,
+ 0x8183f648,
+ 0x030faa4c,
+ 0x26c1715f,
+ 0x322c9ea3,
+ 0x5d60d054,
+ 0x413470cb,
+ 0x3d131892,
+ 0x22f2ae86,
+ 0x9f1c96b6,
+ 0x015563f4,
+ 0x3a5625ba,
+ 0xcb95b598,
+ 0xf0685fb9,
+ 0x158af5ec,
+ 0xfc01a406,
+ 0x01841d19,
+ 0x210b7e73,
+ 0x19a416a1,
+ 0xed254c44,
+ 0x5bd51335,
+ 0xb8905dc9,
+ 0x9e52f38c,
+ 0xef5d7dd0,
+ 0x1516f6bb,
+ 0xf13bb426,
+ 0x9ee6d6cb,
+ 0x28bde0a6,
+ 0x766b655e,
+ 0xaf2e0e52,
+ 0xdec60f49,
+ 0x254a0959,
+ 0xb009d431,
+ 0x2f6d3533,
+ 0x0a074afc,
+ 0xcd3d3a72,
+ 0x52aa4fce,
+ 0x16c4507d,
+ 0x2f842898,
+ 0xb087e98b,
+ 0x68b41826,
+ 0xd4adc5c9,
+ 0x53b3e498,
+ 0x2dff7b03,
+ 0xda931e65,
+ 0xf1d66edd,
+ 0x2beb7555,
+ 0x97b3f152,
+ 0x035676f8,
+ 0xca9c7cf6,
+ 0x57992a53,
+ 0x578a1004,
+ 0x458e23c8,
+ 0x2a2494bf,
+ 0xa92c549b,
+ 0x2ca46deb,
+ 0xcd907478,
+ 0x93baaeb5,
+ 0xa70af4c6,
+ 0x9767d5b8,
+ 0x9874bcee,
+ 0xb0413973,
+ 0x9bfef4f7,
+ 0x7fbed607,
+ 0x2a255991,
+ 0xa5e3109d,
+ 0x90f09fef,
+ 0xb7a3d468,
+ 0x6db437aa,
+ 0xe8dad585,
+ 0xfbc19cbc,
+ 0x34cacc6f,
+ 0x6c5cc449,
+ 0xcc6dc144,
+ 0x70c6aaa0,
+ 0x183bc459,
+ 0x490ea5a8,
+ 0xddf105bf,
+ 0x3429facf,
+ 0x79020f72,
+ 0xd2de786d,
+ 0xb776f3ed,
+ 0x553e3da7,
+ 0xaecff099,
+ 0x2b471ce1,
+ 0xe3a72af9,
+ 0x04c9b2bf,
+ 0xe84d9702,
+ 0xec7cd831,
+ 0xda66c6c1,
+ 0x451b207c,
+ 0x68243bc3,
+ 0xb3012b1e,
+ 0x1855c026,
+ 0x1addac14,
+ 0xc73834a2,
+ 0xea91596d,
+ 0x08f0d135,
+ 0xc6021aa0,
+ 0xc5d1726b,
+ 0xc21d1f0b,
+ 0x92b7c740,
+ 0x9f024526,
+ 0x6c91df6c,
+ 0xfec85435,
+ 0x3d5a9150,
+ 0x93249836,
+ 0x2ec5e71f,
+ 0x23e96579,
+ 0x81ce78d6,
+ 0x49e45ccf,
+ 0x4d5e9c78,
+ 0x2a2cdfab,
+ 0x148e1833,
+ 0xa3fab11b,
+ 0xd0ceb7e9,
+ 0x4789b634,
+ 0x147fc687,
+ 0x48f4f59c,
+ 0x21eea4e3,
+ 0x411dfb7d,
+ 0x033fe075,
+ 0x57c9e07d,
+ 0xb09edf4e,
+ 0x9db83f5f,
+ 0x6ef1343a,
+ 0x64a68315,
+ 0x300e34c3,
+ 0x72ac2766,
+ 0x640271a4,
+ 0x0a282b82,
+ 0xcaf1ec1b,
+ 0x7d4849f9,
+ 0x108c5eaa,
+ 0xfaa96613,
+ 0x0476639b,
+ 0x70ee8371,
+ 0x9db599ba,
+ 0x85158d5f,
+ 0x02912911,
+ 0xe6fec86a,
+ 0xcf3036f3,
+ 0xccdd49a0,
+ 0xe650b3cd,
+ 0xf5429ef0,
+ 0x411e4690,
+ 0xa526e30b,
+ 0x275822af,
+ 0x91e12d05,
+ 0x958881aa,
+ 0xabf76cc4,
+ 0x06e794a9,
+ 0xa97d1577,
+ 0x0188613c,
+ 0x17c96558,
+ 0x96c31832,
+ 0x5696b201,
+ 0x03e3dad2,
+ 0xbe44d0ba,
+ 0x4d552a6c,
+ 0xe9fafb48,
+ 0x4968ad28,
+ 0xf109edce,
+ 0xd1534f30,
+ 0xc2d8b9e8,
+ 0x66e911d7,
+ 0xd67a594b,
+ 0x4492b2b4,
+ 0xeb86848d,
+ 0x4106979b,
+ 0x0f75039f,
+ 0xf5f3ee2c,
+ 0x04baf613,
+ 0x00c6fd60,
+ 0x32ebe198,
+ 0xc7f129eb,
+ 0x7cac0839,
+ 0x57a1fde4,
+ 0x2da04cfc,
+ 0x93179aa5,
+ 0xf3f4d2d9,
+ 0xd8d2528a,
+ 0x5fdd42af,
+ 0xd08c7bdb,
+ 0x53acd639,
+ 0xe37aab85,
+ 0x2d55b5a2,
+ 0x7bc96248,
+ 0x2fb42401,
+ 0x2ff99915,
+ 0x2be3b5ea,
+ 0xf0ff9bdd,
+ 0x1b6bbaa3,
+ 0x83a13de0,
+ 0x4503fc83,
+ 0x08c24640,
+ 0x2463a2b2,
+ 0x2e264872,
+ 0xc451a29d,
+ 0xbfd2e09c,
+ 0x15bcb009,
+ 0x69102223,
+ 0x4c8581e9,
+ 0x4ec94cf0,
+ 0x75017d7b,
+ 0x0e5d8cf1,
+ 0x50b9ca97,
+ 0x55df1100,
+ 0x245162e0,
+ 0x0df18bca,
+ 0x00776990,
+ 0xf6790a03,
+ 0x599ef43e,
+ 0xe8bf7afb,
+ 0xea141ddc,
+ 0xad1a54b2,
+ 0x55f767f8,
+ 0xb661981c,
+ 0xe1650342,
+ 0x365adc95,
+ 0xbb44e3a0,
+ 0xa064fea1,
+ 0x3516bf27,
+ 0xfd40a414,
+ 0x53f9a9e6,
+ 0x2071a5ee,
+ 0x56ca2713,
+ 0x7afdd07a,
+ 0xd62b7f6e,
+ 0xe9dac904,
+ 0xca212105,
+ 0xb9d6e3de,
+ 0x6af5033f,
+ 0x34d9049b,
+ 0xc51ec095,
+ 0xe5eddb9d,
+ 0x122b5c6a,
+ 0x9f562e58,
+ 0x20ec8986,
+ 0x760857f2,
+ 0x8d8aadb3,
+ 0xbc8f0807,
+ 0x0f79eae7,
+ 0xbfa6bfa8,
+ 0x28151aeb,
+ 0xbe4b4d4b,
+ 0xc65d58b0,
+ 0xcf99ba1b,
+ 0xc1049197,
+ 0xe36d8c87,
+ 0x548b7676,
+ 0xbe7bb2c4,
+ 0x77923781,
+ 0x5fbd631e,
+ 0x770e5a41,
+ 0xd2f2948a,
+ 0x074f5428,
+ 0xc7a1562e,
+ 0xf55618c6,
+ 0x8bf8a3d1,
+ 0x837ed4a8,
+ 0xe42e0298,
+ 0xd3754b0c,
+ 0xbaa24c25,
+ 0x793ac973,
+ 0x814e66ec,
+ 0xa4154fa9,
+ 0x3e0e65ca,
+ 0x5a783bd5,
+ 0x2bb37f6c,
+ 0xb3c2526e,
+ 0x34c9a28a,
+ 0x6c8b4795,
+ 0x64605fa8,
+ 0x2e6aae2e,
+ 0xd9b28f27,
+ 0x6a9a200b,
+ 0x3acd1e3a,
+ 0xce9a4a6c,
+ 0xd2a0bd14,
+ 0x700f2003,
+ 0x501cbef7,
+ 0x4068b05e,
+ 0xa24c4580,
+ 0x4da75506,
+ 0x500b9b0f,
+ 0x22e3a600,
+ 0x7bec4e94,
+ 0x8f0958e2,
+ 0x42129a1e,
+ 0xb46d8dc5,
+ 0x29f8851c,
+ 0x83fb38bd,
+ 0x17b0de15,
+ 0x15340d20,
+ 0x74f00fde,
+ 0x6c646b32,
+ 0x905897c4,
+ 0x4d8ed991,
+ 0x3cf91fd5,
+ 0x0ee02ddf,
+ 0xec069ce6,
+ 0x0b977683,
+ 0xa0bf31f6,
+ 0xa1d135a9,
+ 0xa882d1db,
+ 0xa731a63a,
+ 0x48e211f1,
+ 0xf3d89e99,
+ 0xf982e6ea,
+ 0x23dde303,
+ 0x7f1ff8da,
+ 0xdc8c6414,
+ 0x806f432e,
+ 0xd047bc02,
+ 0x671bacff,
+ 0xd40ba2a8,
+ 0xe3666685,
+ 0x31265f9f,
+ 0x3931a952,
+ 0x62f35606,
+ 0xc48f0c5e,
+ 0xfd107640,
+ 0xf636da24,
+ 0xb8f5c3b0,
+ 0x1c91e88f,
+ 0xed9dd432,
+ 0x2b85fa5d,
+ 0x8b15d2ac,
+ 0x1e06cf24,
+ 0x1def6e9c,
+ 0xfae9175f,
+ 0x03ac6f02,
+ 0x37318c87,
+ 0xbc0b1ce5,
+ 0xa0640cab,
+ 0x6cc20a3c,
+ 0x1c7b2524,
+ 0x4685dacc,
+ 0xeab8bb31,
+ 0x8063b5d0,
+ 0x79817d52,
+ 0x211b1972,
+ 0xd7bfc987,
+ 0xab9128dc,
+ 0x150d9b36,
+ 0x6a5838ab,
+ 0x9a0a304d,
+ 0x2e43c331,
+ 0x84f2c4b8,
+ 0x435146c1,
+ 0xed64a280,
+ 0x553ecb4c,
+ 0x5c800db2,
+ 0xeef4df95,
+ 0x5dcf2c37,
+ 0x70755ddf,
+ 0x4274737b,
+ 0xe610350e,
+ 0xd97a5997,
+ 0x7af5edce,
+ 0xfd18ba0c,
+ 0xb7587cd8,
+ 0xfa5e42d6,
+ 0x76bde9eb,
+ 0xec41eead,
+ 0x604d2423,
+ 0xb4adbcf9,
+ 0xce728fa3,
+ 0x02361c31,
+ 0x02fab64d,
+ 0x00316b1c,
+ 0x562f9aa4,
+ 0x71f85790,
+ 0x9cb6d464,
+ 0x32949ebf,
+ 0x434fc23d,
+ 0xee7fac51,
+ 0xda5cc63a,
+ 0x17e616b4,
+ 0xcd1bd1bc,
+ 0x14638cae,
+ 0xd31808fa,
+ 0xb16e0727,
+ 0xfdda2b0f,
+ 0xbc11c678,
+ 0xfe79dc6e,
+ 0xe26eefb4,
+ 0x9a78de16,
+ 0xb68f2df2,
+ 0xd47da234,
+ 0xbdff28a4,
+ 0x937bb1f4,
+ 0x0786dd46,
+ 0xbd1160f5,
+ 0xf77b070c,
+ 0x72b7c51e,
+ 0xcbb3a371,
+ 0x5e50e904,
+ 0x00fbc379,
+ 0x680757dd,
+ 0xd38193f7,
+ 0x93113e25,
+ 0x7b258da7,
+ 0x991aaa09,
+ 0xab1415be,
+ 0xa3740774,
+ 0x370b72e5,
+ 0x2fc643f4,
+ 0x3916d70e,
+ 0xea2838d3,
+ 0xe4840c42,
+ 0xd18e6959,
+ 0x69a270ee,
+ 0xee4a494e,
+ 0x0329799b,
+ 0x07480357,
+ 0x0260c46f,
+ 0x7b75346e,
+ 0x787234f4,
+ 0xe0adf25b,
+ 0xba85cacf,
+ 0xb5724eb1,
+ 0xfde2c080,
+ 0x2b6bb492,
+ 0xd2f70545,
+ 0x9ca97510,
+ 0x4034c18f,
+ 0x616bcb12,
+ 0x5667f52a,
+ 0xe2f6bfce,
+ 0x1f25969e,
+ 0x569eaab7,
+ 0x27ad8196,
+ 0x2d30a6d0,
+ 0x96d6c10a,
+ 0xcb9f024f,
+ 0x3d7941ef,
+ 0xf7a76bc5,
+ 0xe9a701d4,
+ 0xd53293a3,
+ 0x252cf5df,
+ 0xaf9172f6,
+ 0xd090c809,
+ 0xb1a17387,
+ 0x045a0987,
+ 0x92d9ffd9,
+ 0xb30c449c,
+ 0x2180ff58,
+ 0x2929f7de,
+ 0x3f91766e,
+ 0x9f488e3d,
+ 0x05dd6734,
+ 0x82482f5b,
+ 0x01da3ca2,
+ 0x42f33408,
+ 0xf8e3ba89,
+ 0x750ac2ff,
+ 0x39f11551,
+ 0x71087971,
+ 0x368fa634,
+ 0xefda0572,
+ 0x14b8f750,
+ 0xe5768705,
+ 0x71c168e2,
+ 0x8c012c63,
+ 0x12ad74ce,
+ 0x841c17ea,
+ 0xe6f44176,
+ 0x36cf2557,
+ 0x14760a6d,
+ 0x4bb3b7c2,
+ 0x14d1437d,
+ 0xbe673210,
+ 0x4d6ba9f5,
+ 0xe68abbf9,
+ 0xc311908d,
+ 0x46b63956,
+ 0xac2c9fb3,
+ 0xab769ce8,
+ 0xa29d7040,
+ 0xec3d67e3,
+ 0xdef311de,
+ 0x52a53b14,
+ 0xca924769,
+ 0xf35d1514,
+ 0x524b0471,
+ 0xc0d08591,
+ 0x454fc34c,
+ 0xca719639,
+ 0x9af2f230,
+ 0xa023a821,
+ 0x3d6539ba,
+ 0x90d0d7a2,
+ 0xc65fc56e,
+ 0x4eb2aa19,
+ 0xeba3b0e7,
+ 0x1bb5b33e,
+ 0xab8c68c2,
+ 0x0f1793d3,
+ 0xdcf176e9,
+ 0x1b7bbba0,
+ 0x96170a27,
+ 0x1955452d,
+ 0x42e88c71,
+ 0x48cad4b3,
+ 0xdcc36042,
+ 0x90619951,
+ 0x7566bc7c,
+ 0xe14ba224,
+ 0xc24ad73d,
+ 0xdb04144d,
+ 0xd9792727,
+ 0x11150943,
+ 0xe45f0c57,
+ 0xb87d184e,
+ 0x3cf13243,
+ 0x2010d95c,
+ 0x84c347c1,
+ 0x6d0f2461,
+ 0xb5c41194,
+ 0xde7ccb2e,
+ 0xb929ecb0,
+ 0x51fbd8f7,
+ 0x45dc65fb,
+ 0x6902d2c0,
+ 0xb940814f,
+ 0xf339e083,
+ 0x6f370d56,
+ 0xcaf5638e,
+ 0xe8a3cb83,
+ 0xacf414b6,
+ 0xe61095a1,
+ 0x99b4cde4,
+ 0x55112fed,
+ 0x606b9d53,
+ 0x5a05974a,
+ 0xa4c7db34,
+ 0xdc92469b,
+ 0xf9280621,
+ 0xe7b1ef95,
+ 0xc0fc5be8,
+ 0x74a1da09,
+ 0xa92a4b7f,
+ 0x3d65d75e,
+ 0xe3804335,
+ 0x1ff49e19,
+ 0x71da8170,
+ 0xac69069b,
+ 0x04aae3d5,
+ 0xc0ef4b46,
+ 0x091a3482,
+ 0x8356c7ae,
+ 0x32ecb208,
+ 0x900c89ed,
+ 0x2a206ff5,
+ 0x7eed5032,
+ 0x5b55b25d,
+ 0xf98d6df2,
+ 0xf52bc8a9,
+ 0x1aa2f5fe,
+ 0x1d33c0bf,
+ 0x3cd34e89,
+ 0x9a0da4ae,
+ 0x1c205917,
+ 0x7ca784cd,
+ 0xf7dda662,
+ 0xad97f3ff,
+ 0x525c53ec,
+ 0x024f11ff,
+ 0x32c3ae5b,
+ 0xbf372800,
+ 0x8ff15f4d,
+ 0x7605d019,
+ 0x0dae7740,
+ 0x5f5dd0ef,
+ 0x0f6c37d0,
+ 0xee6fa91e,
+ 0xb9f51051,
+ 0x39a9f0d1,
+ 0x22bf03fb,
+ 0x485a0922,
+ 0x7384b30e,
+ 0x85ba7f16,
+ 0xb1f0a524,
+ 0x7e9c5113,
+ 0x240d9306,
+ 0x1ca7b0ea,
+ 0x18a0d114,
+ 0x76b64213,
+ 0x31212cc0,
+ 0xc9dca5c3,
+ 0x69f2ae52,
+ 0x545caa7c,
+ 0xfb2ff045,
+ 0x3f3a1af5,
+ 0xe75b6913,
+ 0x775a1c79,
+ 0x4627e25f,
+ 0x90a14b97,
+ 0x06456383,
+ 0x3d52cf69,
+ 0xfb2492c3,
+ 0x39f25a22,
+ 0x81f68c55,
+ 0x87b14e15,
+ 0x0920af5d,
+ 0xe2585678,
+ 0x0671e46d,
+ 0xb77ddb67,
+ 0x3948c4b3,
+ 0x122dddef,
+ 0xd0726172,
+ 0xd3302234,
+ 0x58bab4e4,
+ 0x195ac247,
+ 0x082459f0,
+ 0x18a2566d,
+ 0xbf56078d,
+ 0x116ed409,
+ 0x5ccc0f80,
+ 0xbae0b4ca,
+ 0x21a6325d,
+ 0x7e1f0c40,
+ 0x595326d4,
+ 0x518b2244,
+ 0x8ab3cdb7,
+ 0xbe6b4835,
+ 0xfc39f8ac,
+ 0x63b167aa,
+ 0x194f070d,
+ 0xed3d0416,
+ 0xae16758a,
+ 0xb9bb6bbf,
+ 0x477d9c85,
+ 0x9808c304,
+ 0xe1d8cec4,
+ 0x7ee22e17,
+ 0x0a7a9d7f,
+ 0xcc98173a,
+ 0x5f78dc21,
+ 0x364bc95e,
+ 0xb54608d9,
+ 0x5d4d70ea,
+ 0x083a7f79,
+ 0x59ffbd73,
+ 0x4f3e9eaf,
+ 0x68755ad4,
+ 0xab254689,
+ 0x11bf09a8,
+ 0xbbc40098,
+ 0x969ca3eb,
+ 0x30eee9d2,
+ 0xe35bc37e,
+ 0xcb2d678f,
+ 0x7846876b,
+ 0xf0d28ae7,
+ 0xc092fbb2,
+ 0x321b344a,
+ 0xcc5ee81b,
+ 0xd2afa00f,
+ 0xfeccd86a,
+ 0x6e5e55c2,
+ 0x2b5543ea,
+ 0x810e4009,
+ 0xea2d8e20,
+ 0x6acae3b9,
+ 0x3828e15e,
+ 0xe1e4821c,
+ 0xf429da70,
+ 0x35f6565c,
+ 0x64b1baa8,
+ 0x350e9583,
+ 0xd2522d4f,
+ 0x5e28a3f1,
+ 0x949ff0aa,
+ 0x3c1b5694,
+ 0x146dde1f,
+ 0x6f3430e1,
+ 0x71c077b7,
+ 0x4d145924,
+ 0xe431cd28,
+ 0xb315cfde,
+ 0xa0365a4a,
+ 0x473de1aa,
+ 0xcbe4e999,
+ 0x319906e9,
+ 0xad0fea9c,
+ 0x89e4e72d,
+ 0x9dbba94d,
+ 0xd395c1c5,
+ 0xa1fff11a,
+ 0x8447e120,
+ 0xe5c59100,
+ 0xa07cb778,
+ 0x8f30a039,
+ 0xed78facb,
+ 0x86de9373,
+ 0x550c4889,
+ 0xce71e3a8,
+ 0x06167b3a,
+ 0x5abdd9a3,
+ 0xc8a9e48d,
+ 0xe3312905,
+ 0x7a63a146,
+ 0xc0f19763,
+ 0xda0cf9db,
+ 0x1d708306,
+ 0x0e41f0ba,
+ 0x4c7939fe,
+ 0x768e48c2,
+ 0xe925fd31,
+ 0x309e7870,
+ 0xfc261b87,
+ 0xc897b2de,
+ 0x6c714792,
+ 0x41c7fbac,
+ 0x57d0b3c3,
+ 0x4fa82a55,
+ 0xd56b4a87,
+ 0x81e5cabc,
+ 0xb260cb7b,
+ 0x520927ab,
+ 0x20d0ab46,
+ 0xc9f92ddf,
+ 0x81f4a21d,
+ 0xfc5a0ca2,
+ 0x95d16aad,
+ 0xe54d7847,
+ 0x6080cc07,
+ 0x0df73f7e,
+ 0xaa8d5187,
+ 0x97a0bc12,
+ 0xb22c5e68,
+ 0x0954d7dc,
+ 0x3368ab5a,
+ 0xd12541df,
+ 0x58119260,
+ 0xe5b0e1df,
+ 0x25027fa4,
+ 0x5780425d,
+ 0x29bb8791,
+ 0x4100b7a9,
+ 0x076b3519,
+ 0x15e0ebb4,
+ 0xe5fb9273,
+ 0x6dbf07e7,
+ 0x1f82bddd,
+ 0x03691b6b,
+ 0xbacef28c,
+ 0x9909ed5a,
+ 0x98886793,
+ 0x544f9a82,
+ 0x9d9749d0,
+ 0x38441606,
+ 0xc4a9f4d2,
+ 0x6ce2bcf1,
+ 0x1c7c3abd,
+ 0x62c621f1,
+ 0x871ee1e4,
+ 0xa83930ce,
+ 0xbe1ee459,
+ 0xd61f1ca4,
+ 0x8c4450e5,
+ 0x98031ca9,
+ 0xe52f54e2,
+ 0xd0c4c737,
+ 0x76074160,
+ 0xbf050c3b,
+ 0x2603af14,
+ 0x43cbb0bc,
+ 0xc631b9e8,
+ 0x26030719,
+ 0x993f570c,
+ 0xdda34038,
+ 0xe34a9793,
+ 0x337a124c,
+ 0x2aa8af16,
+ 0xf80d7473,
+ 0xf01d9397,
+ 0x68e1afb9,
+ 0x0eb37ad2,
+ 0xf71969f9,
+ 0xdf020552,
+ 0x75aa9b30,
+ 0xffa210cf,
+ 0x543c414f,
+ 0xa1e3faec,
+ 0x40891d7e,
+ 0x6b48a6c5,
+ 0xec09a1a0,
+ 0x97a31f2a,
+ 0x5a6be2d7,
+ 0xd06e492b,
+ 0xc54290af,
+ 0xcb524021,
+ 0x420e8c4d,
+ 0xfb135c17,
+ 0x2bfc8adb,
+ 0x9f0cfb46,
+ 0x564db712,
+ 0x7a97a227,
+ 0x8bb98daf,
+ 0xdd0d6180,
+ 0x3d28b9e3,
+ 0xe505050f,
+ 0x19a9868e,
+ 0x7bf5685f,
+ 0x35d698c4,
+ 0xce7e1de3,
+ 0x360a64af,
+ 0x25a1f022,
+ 0xe26c1d04,
+ 0x5b3fb364,
+ 0x932f25f7,
+ 0x9a2aa00d,
+ 0xc50fb773,
+ 0xec45ea3a,
+ 0x22ddf8e4,
+ 0xafb6a6c8,
+ 0x876d04f7,
+ 0xd9c86c3c,
+ 0xd54bee2d,
+ 0xf4e28199,
+ 0xc3456776,
+ 0x04c3107b,
+ 0xbf914e9d,
+ 0x23fefaa5,
+ 0x0931a133,
+ 0x41467758,
+ 0x8ec49707,
+ 0x5ed48709,
+ 0xd11c2de8,
+ 0xb687a0b9,
+ 0xdc908383,
+ 0xd8037ff3,
+ 0xd4311a9f,
+ 0xd00aeb6a,
+ 0xfe54df3b,
+ 0x9c51ce4d,
+ 0x36956408,
+ 0xcd28ef09,
+ 0xc68932b0,
+ 0x7c31e782,
+ 0x28b4723c,
+ 0xededacc2,
+ 0x6ddbac6b,
+ 0x775a7fc1,
+ 0x6909906f,
+ 0xa774123c,
+ 0xf63145ad,
+ 0x287b191e,
+ 0x59d79300,
+ 0xbf76a2fc,
+ 0xfbaf9207,
+ 0x2fe5b7f6,
+ 0xebe7c103,
+ 0x71ac0a8d,
+ 0x2028c3c7,
+ 0xd2cb4917,
+ 0xd74a4ee4,
+ 0xfce405d8,
+ 0xad83fd0f,
+ 0x8f9ec3da,
+ 0xaab2301c,
+ 0xc6f1339f,
+ 0xc652bced,
+ 0xe378b272,
+ 0x18e1ff34,
+ 0x9ec778b6,
+ 0xce1a3883,
+ 0x7c5e5eaf,
+ 0xd16ec37a,
+ 0xa69e45f4,
+ 0xc36cd4aa,
+ 0x045b391f,
+ 0x5a2a08f1,
+ 0x4dd8d53e,
+ 0xd64796ec,
+ 0x4476fc28,
+ 0x18dbaa50,
+ 0x00fb2407,
+ 0x177db915,
+ 0x5969758b,
+ 0x3030964a,
+ 0x81d6485b,
+ 0x7d2e12b0,
+ 0x624d6c5f,
+ 0x0746bbc0,
+ 0xe669d150,
+ 0x0465eef7,
+ 0x09764011,
+ 0x551995e4,
+ 0x8422dedf,
+ 0x0ca56194,
+ 0x293eab2e,
+ 0xf20a137a,
+ 0x55117fc2,
+ 0xbc5431af,
+ 0x064751fa,
+ 0xc0dafdb2,
+ 0x6c3b1d4f,
+ 0xeac335b3,
+ 0x71173afc,
+ 0x31c84b7c,
+ 0xfef2b4ab,
+ 0x59ca5fa2,
+ 0x664c8b4e,
+ 0x7dfd560b,
+ 0xdb0daff3,
+ 0x51f87bfa,
+ 0x58015d2e,
+ 0x67a827b4,
+ 0x62cebc1a,
+ 0x24b37298,
+ 0x75b589be,
+ 0x874f1800,
+ 0x277b795c,
+ 0xf762489e,
+ 0x87d00752,
+ 0x9be45ed1,
+ 0x296ec120,
+ 0x61162480,
+ 0x792e8a2c,
+ 0x3b631590,
+ 0xe33ba0cf,
+ 0x542ac23c,
+ 0xe1e8cffa,
+ 0xfc084cd8,
+ 0xc115ad31,
+ 0x71559928,
+ 0x791f1e33,
+ 0x662ed92b,
+ 0x7222c76d,
+ 0x02dcd566,
+ 0x8db9b4d4,
+ 0xa5f344c8,
+ 0x15806b12,
+ 0x81e572f7,
+ 0x3b3fbe25,
+ 0x2133b413,
+ 0x2d68a367,
+ 0x356f6ce7,
+ 0xcd6dfed1,
+ 0xd8b3a26e,
+ 0xe9d328da,
+ 0x127425ab,
+ 0x83a60aac,
+ 0x8cc26190,
+ 0x7f87ab26,
+ 0x56faab5f,
+ 0x76d0feaa,
+ 0x4b25dd10,
+ 0x4f6286ea,
+ 0x79298d06,
+ 0x8002bf83,
+ 0x2977c85e,
+ 0xd3b3d19a,
+ 0xa92bf132,
+ 0xa280efd8,
+ 0x83f7ad6e,
+ 0x748969c7,
+ 0x25ff411d,
+ 0x3854d3a8,
+ 0x55746aa2,
+ 0x00db5c54,
+ 0x36949e0d,
+ 0x40402ab6,
+ 0x1a720211,
+ 0xe02ce823,
+ 0x4ac104a2,
+ 0x214d2e4b,
+ 0x267e5c83,
+ 0x38a3a483,
+ 0xd1da1f67,
+ 0x0c68db2c,
+ 0xd7035d63,
+ 0xa29393bb,
+ 0xa5743519,
+ 0xcb97c84e,
+ 0xa853974f,
+ 0x147360a0,
+ 0x2df9b3f4,
+ 0x0aff129e,
+ 0x177d687f,
+ 0x87eff911,
+ 0x6c60b354,
+ 0x6c356c38,
+ 0x7d480965,
+ 0xbb06a193,
+ 0x25b0568e,
+ 0x6fd6da9a,
+ 0x82b64f14,
+ 0x3d267a78,
+ 0xf100b6a7,
+ 0x32c74539,
+ 0x6042e152,
+ 0x4548276e,
+ 0xa3a32b70,
+ 0xf029fe15,
+ 0xa9b8bd2f,
+ 0x5618eee4,
+ 0x9815a5f0,
+ 0x89fb2850,
+ 0xa9261b26,
+ 0xded9e505,
+ 0x37e9d749,
+ 0xdc4aeb78,
+ 0x9e634f7a,
+ 0xcf638d2d,
+ 0x6b679f92,
+ 0x2b64911d,
+ 0xe6d1312f,
+ 0x88b3e76a,
+ 0x56311f62,
+ 0x00916de7,
+ 0x39d0bc61,
+ 0x8ac09356,
+ 0x47abcfce,
+ 0x324cb73e,
+ 0xfadcd0a8,
+ 0x2f2fbca8,
+ 0x945eda22,
+ 0xba23cab1,
+ 0xf9fb4212,
+ 0x1fa71d45,
+ 0x867a034e,
+ 0x3bee5db1,
+ 0xf54adced,
+ 0x6633ba77,
+ 0xe1eb4f1e,
+ 0x97ef01f6,
+ 0x57fd3b32,
+ 0x5234d80d,
+ 0xe8ee95f3,
+ 0x5dc990bf,
+ 0xaba833e1,
+/* Dummy terminator */
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+};
+
+
diff --git a/src/mainboard/supermicro/x6dhe_g2/mptable.c b/src/mainboard/supermicro/x6dhe_g2/mptable.c new file mode 100644 index 0000000000..6a284981b0 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/mptable.c @@ -0,0 +1,202 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "X6DHE "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_pxhd_1; + unsigned char bus_pxhd_2; + unsigned char bus_esb6300_1; + unsigned char bus_esb6300_2; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* esb6300_2 */ + dev = dev_find_slot(0, PCI_DEVFN(0x1c,0)); + if (dev) { + bus_esb6300_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + } + else { + printk_debug("ERROR - could not find PCI 0:1c.0, using defaults\n"); + + bus_esb6300_2 = 6; + } + /* esb6300_1 */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_esb6300_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n"); + + bus_esb6300_1 = 7; + bus_isa = 8; + } + /* pxhd-1 */ + dev = dev_find_slot(1, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n"); + + bus_pxhd_1 = 2; + } + /* pxhd-2 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n"); + + bus_pxhd_2 = 3; + } + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + smp_write_ioapic(mc, 3, 0x20, 0xfec10000); + { + struct resource *res; + device_t dev; + /* PXHd apic 4 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x04, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n"); + printk_debug("DEBUG: Dev= %p\n", dev); + } + /* PXHd apic 5 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x05, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n"); + printk_debug("DEBUG: Dev= %p\n", dev); + } + } + + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, // added + bus_isa, 0x07, 0x02, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x77, 0x02, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x75, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0f, 0x02, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7c, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + 0x03, 0x08, 0x05, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + 0x03, 0x08, 0x05, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_1, 0x04, 0x03, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_1, 0x08, 0x03, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_2, 0x04, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, // -- added + bus_esb6300_2, 0x08, 0x02, 0x14); + + /* Standard local interrupt assignments */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + +#warning "FIXME verify I have the irqs handled for all of the risers" + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/supermicro/x6dhe_g2/reset.c b/src/mainboard/supermicro/x6dhe_g2/reset.c new file mode 100644 index 0000000000..874bfc4848 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/supermicro/x6dhe_g2/watchdog.c b/src/mainboard/supermicro/x6dhe_g2/watchdog.c new file mode 100644 index 0000000000..3904a7dc94 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/watchdog.c @@ -0,0 +1,99 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ESB6300_WDBASE 0x400 +#define ESB6300_GPIOBASE 0x500 + +static void disable_sio_watchdog(device_t dev) +{ +#if 0 + /* FIXME move me somewhere more appropriate */ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 1); + pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE); + /* disable the sio watchdog */ + outb(0, NSC_WDBASE + 0); + pnp_set_enable(dev, 0); +#endif +} + +static void disable_esb6300_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing esb6300?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ESB6300_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ESB6300_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_jarell_frb3(void) +{ +#if 0 + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing esb6300?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 0); + pci_write_config16(dev, 0x04, value); + + /* Set gpio base */ + pci_write_config32(dev, 0x58, ESB6300_GPIOBASE | 1); + base = ESB6300_GPIOBASE; + + /* Enable GPIO Bar */ + value = pci_read_config32(dev, 0x5c); + value |= 0x10; + pci_write_config32(dev, 0x5c, value); + + /* Configure GPIO 48 and 40 as GPIO */ + value = inl(base + 0x30); + value |= (1 << 16) | ( 1 << 8); + outl(value, base + 0x30); + + /* Configure GPIO 48 as Output */ + value = inl(base + 0x34); + value &= ~(1 << 16); + outl(value, base + 0x34); + + /* Toggle GPIO 48 high to low */ + value = inl(base + 0x38); + value |= (1 << 16); + outl(value, base + 0x38); + value &= ~(1 << 16); + outl(value, base + 0x38); +#endif +} + +static void disable_watchdogs(void) +{ +// disable_sio_watchdog(NSC_WD_DEV); + disable_esb6300_watchdog(); +// disable_jarell_frb3(); + print_debug("Watchdogs disabled\r\n"); +} + diff --git a/src/mainboard/supermicro/x6dhe_g2/x6dhe_g2_fixups.c b/src/mainboard/supermicro/x6dhe_g2/x6dhe_g2_fixups.c new file mode 100644 index 0000000000..82c070b0c1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhe_g2/x6dhe_g2_fixups.c @@ -0,0 +1,23 @@ +#include <arch/romcc_io.h> + +static void mch_reset(void) +{ + return; +} + + + +static void mainboard_set_e7520_pll(unsigned bits) +{ + return; +} + + +static void mainboard_set_e7520_leds(void) +{ + return; +} + + + + diff --git a/src/mainboard/supermicro/x6dhr_ig/Config.lb b/src/mainboard/supermicro/x6dhr_ig/Config.lb new file mode 100644 index 0000000000..e6cdc0c5f9 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/Config.lb @@ -0,0 +1,218 @@ +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can cached to speed up linuxBIOS, +## execution speed. +## +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +## +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7520 # mch + device pci_domain 0 on + chip southbridge/intel/ich5r # ich5r + # USB ports + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.2 on end + device pci 1d.3 on end + device pci 1d.7 on end + + # -> VGA + device pci 1e.0 on end + + # -> IDE + device pci 1f.0 on + chip superio/winbond/w83627hf + device pnp 2e.0 off end + device pnp 2e.2 on + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 off end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a on end + device pnp 2e.b off end + end + end + device pci 1f.1 on end + device pci 1f.2 on end + device pci 1f.3 on end + + register "pirq_a_d" = "0x0b070a05" + register "pirq_e_h" = "0x0a808080" + end + device pci 00.0 on end + device pci 00.1 on end + device pci 01.0 on end + device pci 02.0 on end + device pci 03.0 on + chip southbridge/intel/pxhd # pxhd1 + # Bus bridges and ioapics usually bus 2 + device pci 0.0 on end + device pci 0.1 on end + device pci 0.2 on + # On board gig e1000 + chip drivers/generic/generic + device pci 02.0 on end + device pci 02.1 on end + end + end + device pci 0.3 on end + end + end + device pci 04.0 on + chip southbridge/intel/pxhd # pxhd2 + # Bus bridges and ioapics usually bus 5 + device pci 0.0 on end + # Slot 6 is usually 6:2.0 + device pci 0.1 on end + device pci 0.2 on end + # Slot 7 is usually 7:2.0 + device pci 0.3 on end + end + end + device pci 06.0 on end + end + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # cpu 0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # cpu 1 + device apic 6 on end + end + end + register "intrline" = "0x00070105" +end + diff --git a/src/mainboard/supermicro/x6dhr_ig/Options.lb b/src/mainboard/supermicro/x6dhr_ig/Options.lb new file mode 100644 index 0000000000..8461cdb7d1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/Options.lb @@ -0,0 +1,228 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY + + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=1048576 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=16 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="X6DHR" +default MAINBOARD_VENDOR= "Supermicro" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x5580 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end diff --git a/src/mainboard/supermicro/x6dhr_ig/auto.c b/src/mainboard/supermicro/x6dhr_ig/auto.c new file mode 100644 index 0000000000..ce729546e6 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/auto.c @@ -0,0 +1,169 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/ich5r/ich5r_early_smbus.c" +#include "northbridge/intel/E7520/raminit.h" +#include "superio/winbond/w83627hf/w83627hf.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "x6dhr_fixups.c" +#include "superio/winbond/w83627hf/w83627hf_early_init.c" +#include "northbridge/intel/E7520/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D0F0 | \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0808090a +#define RECVENB_CONFIG 0x0808090a + +//void udelay(int usecs) +//{ +// int i; +// for(i = 0; i < usecs; i++) +// outb(i&0xff, 0x80); +//} + +#if 0 +static void hard_reset(void) +{ + /* enable cf9 */ + pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + /* reset */ + outb(0x0e, 0x0cf9); +} +#endif + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7520/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, }, + .channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, }, + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ +// report_bist_failure(bist); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); +// dump_ipmi_registers(); + mainboard_set_e7520_leds(); +// memreset_setup(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 1 + dump_pci_devices(); +#endif +#if 0 + dump_pci_device(PCI_DEV(0, 0x00, 0)); + dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); +// ram_check(0x00100000, 0x01000000); + ram_check(0x00100000, 0x00100100); + /* check the first 1M in the 3rd Gig */ +// ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dhr_ig/chip.h b/src/mainboard/supermicro/x6dhr_ig/chip.h new file mode 100644 index 0000000000..495788e43c --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_supermicro_x6dhr_ig_ops; + +struct mainboard_supermicro_x6dhr_ig_config { + int nothing; +}; diff --git a/src/mainboard/supermicro/x6dhr_ig/cmos.layout b/src/mainboard/supermicro/x6dhr_ig/cmos.layout new file mode 100644 index 0000000000..6f3cd189e3 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/cmos.layout @@ -0,0 +1,80 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 2 hyper_threading +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/supermicro/x6dhr_ig/debug.c b/src/mainboard/supermicro/x6dhr_ig/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/supermicro/x6dhr_ig/failover.c b/src/mainboard/supermicro/x6dhr_ig/failover.c new file mode 100644 index 0000000000..5029d98611 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7520/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/supermicro/x6dhr_ig/irq_tables.c b/src/mainboard/supermicro/x6dhr_ig/irq_tables.c new file mode 100644 index 0000000000..5ed51feaa1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/irq_tables.c @@ -0,0 +1,34 @@ +/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 272, /* u16 Table size 32+(15*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x24d0, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xc4, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06, 0x00}, + {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x6dhr_ig/mainboard.c b/src/mainboard/supermicro/x6dhr_ig/mainboard.c new file mode 100644 index 0000000000..cae000d5c7 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/mainboard.c @@ -0,0 +1,12 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include "chip.h" + +struct chip_operations mainboard_supermicro_x6dhr_ig_ops = { + CHIP_NAME("Supermicro x6dhr-ig") +}; + diff --git a/src/mainboard/supermicro/x6dhr_ig/microcode_updates.c b/src/mainboard/supermicro/x6dhr_ig/microcode_updates.c new file mode 100644 index 0000000000..b2e72ab616 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/microcode_updates.c @@ -0,0 +1,1563 @@ +/* WARNING - Intel has a new data structure that has variable length
+ * microcode update lengths. They are encoded in int 8 and 9. A
+ * dummy header of nulls must terminate the list.
+ */
+
+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {
+ /*
+ Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000.
+ These microcode updates are distributed for the sole purpose of
+ installation in the BIOS or Operating System of computer systems
+ which include an Intel P6 family microprocessor sold or distributed
+ to or by you. You are authorized to copy and install this material
+ on such systems. You are not authorized to use this material for
+ any other purpose.
+ */
+
+ /* M1DF3413.TXT - Noconoa D-0 */
+
+ 0x00000001, /* Header Version */
+ 0x00000013, /* Patch ID */
+ 0x07302004, /* DATE */
+ 0x00000f34, /* CPUID */
+ 0x95f183f0, /* Checksum */
+ 0x00000001, /* Loader Version */
+ 0x0000001d, /* Platform ID */
+ 0x000017d0, /* Data size */
+ 0x00001800, /* Total size */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+
+ 0x9fbf327a,
+ 0x2b41b451,
+ 0xb2abaca8,
+ 0x6b62b8e0,
+ 0x0af32c41,
+ 0x12ca6048,
+ 0x5bd55ae6,
+ 0xb90dfc1d,
+ 0x565fe2b2,
+ 0x326b1718,
+ 0x61f3a40d,
+ 0xceb53db3,
+ 0x14fb5261,
+ 0xbb23b6c3,
+ 0x9d7c0466,
+ 0xde90a25e,
+ 0x9450e9bb,
+ 0x497bd6e4,
+ 0x97d1041a,
+ 0x1831013f,
+ 0x6e6fa37e,
+ 0x0b5c1d03,
+ 0x5eae4db2,
+ 0xc029d9e3,
+ 0x5373bca3,
+ 0xe15fccca,
+ 0x39043db0,
+ 0xaeb0ea0c,
+ 0x62b4e391,
+ 0x0b280c6b,
+ 0x279eb9d3,
+ 0x98d95ada,
+ 0xc1cb45a7,
+ 0x06917bda,
+ 0xdde8aafa,
+ 0xdff9d15c,
+ 0xd07f8f0a,
+ 0x192bcf9d,
+ 0xf77de31f,
+ 0xadf8be55,
+ 0x3f7a5d95,
+ 0x0e2140b6,
+ 0xf0c75eec,
+ 0x3254876a,
+ 0x684a1698,
+ 0x4ad0cca7,
+ 0x6d705304,
+ 0xf957d91b,
+ 0xe8bb864a,
+ 0x440d636c,
+ 0xaf4d7d06,
+ 0x12680ecf,
+ 0x5d0f9e53,
+ 0x60148a5d,
+ 0x81008364,
+ 0x243a8aed,
+ 0xd55976de,
+ 0xd6a84520,
+ 0x932d4b77,
+ 0xe67e5f19,
+ 0x7dba0e47,
+ 0xfee3b153,
+ 0x46b6a20c,
+ 0x2594e6f6,
+ 0x210cab0f,
+ 0xf6e47d5d,
+ 0xe38276e4,
+ 0x90fc2728,
+ 0x9faefa11,
+ 0xc972217c,
+ 0xc8d079dd,
+ 0x5f7dc338,
+ 0x106f7b7b,
+ 0xd04c0a1c,
+ 0x0eca300e,
+ 0x1ddae8a6,
+ 0x6e7fd42e,
+ 0xa56c514d,
+ 0x56a4e255,
+ 0x975ea2bf,
+ 0x0eaa78cc,
+ 0x0c3e284f,
+ 0xbacb6c71,
+ 0x1645006f,
+ 0xe9a2b955,
+ 0x0677c019,
+ 0x24b33da0,
+ 0x62f200fa,
+ 0x234238c4,
+ 0x81d5ad79,
+ 0x9f754bc9,
+ 0xeffd5016,
+ 0x041b2cc2,
+ 0x2f020bc7,
+ 0x4fcd68b8,
+ 0x22c3579c,
+ 0x4804a114,
+ 0xc42db3ea,
+ 0x7cde8141,
+ 0x47e167c8,
+ 0x01aa38cc,
+ 0x74a5c25e,
+ 0xe0c48d67,
+ 0x562365ad,
+ 0x38321e57,
+ 0x0395885a,
+ 0x6888323e,
+ 0xd6fc518f,
+ 0x1854b64c,
+ 0x06a58476,
+ 0x3662f898,
+ 0xe2bcdaee,
+ 0x84c40693,
+ 0xef09d374,
+ 0x353cc799,
+ 0x742223d4,
+ 0x05b3c99b,
+ 0x0c51ee45,
+ 0xd145824a,
+ 0xac30806c,
+ 0x2ed70c0d,
+ 0x71ae10ff,
+ 0xbf491854,
+ 0x3e1f03b4,
+ 0x76bfd6cd,
+ 0x1449aa8a,
+ 0xf954d3fb,
+ 0xf8c7c940,
+ 0x70233f85,
+ 0x0729e257,
+ 0x10bb8936,
+ 0xc35bb5b5,
+ 0x95d78b5c,
+ 0xcc1ba443,
+ 0x6f507126,
+ 0xa607cfd0,
+ 0xce22f2f3,
+ 0x5134ed8c,
+ 0xec8d2f06,
+ 0xa92413d5,
+ 0xb973f431,
+ 0x16e136dd,
+ 0xf7d41bed,
+ 0x01b002fe,
+ 0x646ed771,
+ 0x76ea3d26,
+ 0x5024af20,
+ 0x84270f51,
+ 0x9b3d7820,
+ 0x2454a2c6,
+ 0xc1f072ed,
+ 0x155e864f,
+ 0x4c39a6e5,
+ 0x928206e5,
+ 0x9d1685f5,
+ 0x45542ee7,
+ 0x1fd27d9e,
+ 0x5f2dd9ff,
+ 0x222005eb,
+ 0x354e8a55,
+ 0x1f0de29a,
+ 0xb86dc696,
+ 0x9eafafad,
+ 0x191b197e,
+ 0x0e0900e1,
+ 0xe0ac42bb,
+ 0x3143236f,
+ 0x44177def,
+ 0x05259274,
+ 0xb21af44a,
+ 0x6ddee4df,
+ 0xc7b56255,
+ 0xb6b1d39d,
+ 0x218f9070,
+ 0x96545a42,
+ 0x98cc2d4a,
+ 0xb21bac9e,
+ 0x83e12d44,
+ 0x2ef4fb39,
+ 0xbc03528f,
+ 0x9485af58,
+ 0xd9f1e6ab,
+ 0xde7607e6,
+ 0x3b398733,
+ 0x9cd9b1a9,
+ 0xabd77984,
+ 0xcce18826,
+ 0x701c5c21,
+ 0xe6591cbf,
+ 0x07a9b9e1,
+ 0x69459c90,
+ 0xe0cdcad6,
+ 0xc4c6c4b6,
+ 0x12748024,
+ 0x4a33c567,
+ 0x7d26a37e,
+ 0xcae163bf,
+ 0xeb7547fa,
+ 0xccc6a01c,
+ 0x3cb8abb8,
+ 0x64aa67b2,
+ 0x51ddf6de,
+ 0xbfe1b905,
+ 0x50923949,
+ 0xacfa43af,
+ 0x1fdb5a44,
+ 0x091533cb,
+ 0x7c92e5dc,
+ 0x1c5d0d3e,
+ 0x195271f5,
+ 0x96e73a4a,
+ 0xe1b11968,
+ 0xb42906f2,
+ 0x5a2940b3,
+ 0x611283e9,
+ 0x65829161,
+ 0x5d1357b7,
+ 0x019428ad,
+ 0x836c5c3c,
+ 0xc0e5e169,
+ 0xd360e424,
+ 0x257a9d69,
+ 0xdca09040,
+ 0x85f1c060,
+ 0xae7cae79,
+ 0xa5ddcfd6,
+ 0xdba8f68e,
+ 0xd98df596,
+ 0xe6e3cd51,
+ 0xcfb2be8f,
+ 0x368fe6cd,
+ 0x58486b75,
+ 0x791f1a48,
+ 0xf81a61f2,
+ 0x58a38155,
+ 0x30a86547,
+ 0xd7fb2db1,
+ 0x300e0b1d,
+ 0x3f838461,
+ 0xf278805a,
+ 0x49529931,
+ 0x601d5649,
+ 0xe500ba1a,
+ 0xc4f78965,
+ 0xe10ed02d,
+ 0x1f777ebd,
+ 0x2db1d17d,
+ 0x48a22e6a,
+ 0x5a14b738,
+ 0xdcf899e0,
+ 0xc845bd04,
+ 0xd04a52b9,
+ 0xf2f19b06,
+ 0xdb5ba97a,
+ 0xf05605ff,
+ 0xc787b72c,
+ 0x9f197770,
+ 0x87b31150,
+ 0x3ff00d57,
+ 0x89d1dcb3,
+ 0x07528ff4,
+ 0x4105fcef,
+ 0xb087de2e,
+ 0x3bd333a5,
+ 0x84a094f4,
+ 0x9ab8fb97,
+ 0xc9bba063,
+ 0x664c52e5,
+ 0x27fd05e4,
+ 0x3f0e491d,
+ 0xab8f4b9a,
+ 0x344a0249,
+ 0x727dd74f,
+ 0x29587211,
+ 0xbba262b9,
+ 0x319ecbb3,
+ 0xec54b023,
+ 0xd0fa096d,
+ 0x3d223f23,
+ 0x0b6013e7,
+ 0x513e045b,
+ 0xcb1edf15,
+ 0xfd44bb25,
+ 0x023eb973,
+ 0x3f55dac6,
+ 0xc2df6514,
+ 0x68589880,
+ 0x4556878e,
+ 0x86f6acfb,
+ 0xbcd23f0b,
+ 0x32c417c1,
+ 0x45f3bb56,
+ 0xbe60872b,
+ 0x09457cc0,
+ 0x2e18b62d,
+ 0x065f54d1,
+ 0xae3b4a20,
+ 0x265b10ae,
+ 0xb7547a1d,
+ 0x5a9481a9,
+ 0xd477ed02,
+ 0x601ed0fc,
+ 0x9a43257e,
+ 0xc9922b72,
+ 0xa2a696ae,
+ 0xe9d6c37b,
+ 0xfab8bdf9,
+ 0x1deb34dc,
+ 0xaa6bb090,
+ 0xbdc3b72f,
+ 0xecb3b010,
+ 0xe64376e7,
+ 0x40356095,
+ 0x928b5047,
+ 0xbd271c09,
+ 0xfd806f61,
+ 0x0821e090,
+ 0x6afb3588,
+ 0xd10e91ea,
+ 0xbbc7fedd,
+ 0xb1ac6d33,
+ 0x07788e4b,
+ 0xa10f8013,
+ 0x4f8efd9d,
+ 0xe5d8728d,
+ 0x017f3e82,
+ 0xf09ec7eb,
+ 0x6bfd7906,
+ 0xbcefcb44,
+ 0x76699ad5,
+ 0x1b976522,
+ 0xa55b3dbd,
+ 0x88bb33e2,
+ 0x98ac5b7f,
+ 0x61ac4c8b,
+ 0xfd948f3d,
+ 0xee610413,
+ 0xc77c5035,
+ 0x662825a9,
+ 0x0009fcba,
+ 0x3450fd88,
+ 0xeb391fef,
+ 0x6949960d,
+ 0x1ccb13c3,
+ 0x21dac5a6,
+ 0x6bcc6b37,
+ 0x37ad77a5,
+ 0xf71d58b1,
+ 0x84ed440d,
+ 0xe606b699,
+ 0xe43067a4,
+ 0x21d5b8b3,
+ 0xe11f83e2,
+ 0xa0cc6585,
+ 0x40eb6d16,
+ 0xc5a6879f,
+ 0xbd333fd5,
+ 0xb44acab4,
+ 0x68c016fc,
+ 0xfbcd3cfc,
+ 0xadf76e42,
+ 0xc520e516,
+ 0x7468cb61,
+ 0x585c0d52,
+ 0xea83cefe,
+ 0x615d7760,
+ 0x89c9b8fd,
+ 0x367c355a,
+ 0x409371a2,
+ 0x7edb38a7,
+ 0xca86d263,
+ 0xda18250d,
+ 0x26e1ed8b,
+ 0x02fefede,
+ 0x704cb5c8,
+ 0x52cbe1eb,
+ 0x9cdbc71a,
+ 0xa0637560,
+ 0xe31f03ca,
+ 0x2b78969b,
+ 0x803d5866,
+ 0xec52d984,
+ 0xd8df8bdb,
+ 0x6cb1d5e8,
+ 0x7b9aec01,
+ 0xf7d39401,
+ 0xdd04c6ae,
+ 0x0e5ca4eb,
+ 0x12b593c8,
+ 0x38f6d4e5,
+ 0x13a91268,
+ 0x60c8251b,
+ 0xa136cf9a,
+ 0xda070cdd,
+ 0x6142408c,
+ 0xc28065dd,
+ 0x50b73718,
+ 0x36074eee,
+ 0xc7b20fcb,
+ 0x18d29f9b,
+ 0xe97eb966,
+ 0xe6936bcc,
+ 0x1c9188ea,
+ 0x7cff40e2,
+ 0xee791ac8,
+ 0xb099a323,
+ 0x571d69b7,
+ 0x22c1f7d0,
+ 0x0b9662ee,
+ 0x76e45cb9,
+ 0xbd0d7020,
+ 0x7794bd95,
+ 0x1b0fe51a,
+ 0xda2754ef,
+ 0x7f3ad7a9,
+ 0x58f627d3,
+ 0x211670a3,
+ 0xc7471b81,
+ 0x495a93ac,
+ 0xaad4f030,
+ 0xa76614c8,
+ 0xd63dba3c,
+ 0x9c4f729c,
+ 0x6e831cfb,
+ 0xa6105c75,
+ 0x95c62188,
+ 0x723ef45d,
+ 0xf59f2dd1,
+ 0x5825283d,
+ 0x768d8a86,
+ 0x070d02ac,
+ 0xfdbcbd73,
+ 0x0d479795,
+ 0x797aa7f7,
+ 0x6c9e468b,
+ 0xa961571d,
+ 0xc7127ef0,
+ 0x4b0442e7,
+ 0xd99a9e87,
+ 0x6c876cba,
+ 0xe4f9f814,
+ 0x120eeb8d,
+ 0x4bbb9c8e,
+ 0x22c0a29e,
+ 0xff681fcc,
+ 0x26777226,
+ 0x6339e667,
+ 0x2402333e,
+ 0x2bf66a17,
+ 0x63806e6c,
+ 0x98416b75,
+ 0x791b3e91,
+ 0x79c09cd7,
+ 0x0c157436,
+ 0x6d99157c,
+ 0xc8990984,
+ 0xaf7d2ae4,
+ 0xfe3ee7d9,
+ 0xb7676de0,
+ 0x9df8722e,
+ 0x08462a7e,
+ 0x99032839,
+ 0xd726ff95,
+ 0x5c1c78e8,
+ 0x4ef1b747,
+ 0x4e257ba7,
+ 0xa83ad5f3,
+ 0x523b3809,
+ 0xc2ce4f19,
+ 0xabfadaa5,
+ 0x370b005c,
+ 0x2d6a02e1,
+ 0xbf6ee428,
+ 0xfd84be50,
+ 0xb79801b3,
+ 0x488ad789,
+ 0x65a87bda,
+ 0x59f0fd6a,
+ 0xa4106878,
+ 0xdbadd916,
+ 0x1f86f200,
+ 0xefb7fc72,
+ 0x26d4d47f,
+ 0xf7892efc,
+ 0x41f50167,
+ 0xc6a28f9e,
+ 0xffd4a8e0,
+ 0xa00e4ea0,
+ 0x8183f648,
+ 0x030faa4c,
+ 0x26c1715f,
+ 0x322c9ea3,
+ 0x5d60d054,
+ 0x413470cb,
+ 0x3d131892,
+ 0x22f2ae86,
+ 0x9f1c96b6,
+ 0x015563f4,
+ 0x3a5625ba,
+ 0xcb95b598,
+ 0xf0685fb9,
+ 0x158af5ec,
+ 0xfc01a406,
+ 0x01841d19,
+ 0x210b7e73,
+ 0x19a416a1,
+ 0xed254c44,
+ 0x5bd51335,
+ 0xb8905dc9,
+ 0x9e52f38c,
+ 0xef5d7dd0,
+ 0x1516f6bb,
+ 0xf13bb426,
+ 0x9ee6d6cb,
+ 0x28bde0a6,
+ 0x766b655e,
+ 0xaf2e0e52,
+ 0xdec60f49,
+ 0x254a0959,
+ 0xb009d431,
+ 0x2f6d3533,
+ 0x0a074afc,
+ 0xcd3d3a72,
+ 0x52aa4fce,
+ 0x16c4507d,
+ 0x2f842898,
+ 0xb087e98b,
+ 0x68b41826,
+ 0xd4adc5c9,
+ 0x53b3e498,
+ 0x2dff7b03,
+ 0xda931e65,
+ 0xf1d66edd,
+ 0x2beb7555,
+ 0x97b3f152,
+ 0x035676f8,
+ 0xca9c7cf6,
+ 0x57992a53,
+ 0x578a1004,
+ 0x458e23c8,
+ 0x2a2494bf,
+ 0xa92c549b,
+ 0x2ca46deb,
+ 0xcd907478,
+ 0x93baaeb5,
+ 0xa70af4c6,
+ 0x9767d5b8,
+ 0x9874bcee,
+ 0xb0413973,
+ 0x9bfef4f7,
+ 0x7fbed607,
+ 0x2a255991,
+ 0xa5e3109d,
+ 0x90f09fef,
+ 0xb7a3d468,
+ 0x6db437aa,
+ 0xe8dad585,
+ 0xfbc19cbc,
+ 0x34cacc6f,
+ 0x6c5cc449,
+ 0xcc6dc144,
+ 0x70c6aaa0,
+ 0x183bc459,
+ 0x490ea5a8,
+ 0xddf105bf,
+ 0x3429facf,
+ 0x79020f72,
+ 0xd2de786d,
+ 0xb776f3ed,
+ 0x553e3da7,
+ 0xaecff099,
+ 0x2b471ce1,
+ 0xe3a72af9,
+ 0x04c9b2bf,
+ 0xe84d9702,
+ 0xec7cd831,
+ 0xda66c6c1,
+ 0x451b207c,
+ 0x68243bc3,
+ 0xb3012b1e,
+ 0x1855c026,
+ 0x1addac14,
+ 0xc73834a2,
+ 0xea91596d,
+ 0x08f0d135,
+ 0xc6021aa0,
+ 0xc5d1726b,
+ 0xc21d1f0b,
+ 0x92b7c740,
+ 0x9f024526,
+ 0x6c91df6c,
+ 0xfec85435,
+ 0x3d5a9150,
+ 0x93249836,
+ 0x2ec5e71f,
+ 0x23e96579,
+ 0x81ce78d6,
+ 0x49e45ccf,
+ 0x4d5e9c78,
+ 0x2a2cdfab,
+ 0x148e1833,
+ 0xa3fab11b,
+ 0xd0ceb7e9,
+ 0x4789b634,
+ 0x147fc687,
+ 0x48f4f59c,
+ 0x21eea4e3,
+ 0x411dfb7d,
+ 0x033fe075,
+ 0x57c9e07d,
+ 0xb09edf4e,
+ 0x9db83f5f,
+ 0x6ef1343a,
+ 0x64a68315,
+ 0x300e34c3,
+ 0x72ac2766,
+ 0x640271a4,
+ 0x0a282b82,
+ 0xcaf1ec1b,
+ 0x7d4849f9,
+ 0x108c5eaa,
+ 0xfaa96613,
+ 0x0476639b,
+ 0x70ee8371,
+ 0x9db599ba,
+ 0x85158d5f,
+ 0x02912911,
+ 0xe6fec86a,
+ 0xcf3036f3,
+ 0xccdd49a0,
+ 0xe650b3cd,
+ 0xf5429ef0,
+ 0x411e4690,
+ 0xa526e30b,
+ 0x275822af,
+ 0x91e12d05,
+ 0x958881aa,
+ 0xabf76cc4,
+ 0x06e794a9,
+ 0xa97d1577,
+ 0x0188613c,
+ 0x17c96558,
+ 0x96c31832,
+ 0x5696b201,
+ 0x03e3dad2,
+ 0xbe44d0ba,
+ 0x4d552a6c,
+ 0xe9fafb48,
+ 0x4968ad28,
+ 0xf109edce,
+ 0xd1534f30,
+ 0xc2d8b9e8,
+ 0x66e911d7,
+ 0xd67a594b,
+ 0x4492b2b4,
+ 0xeb86848d,
+ 0x4106979b,
+ 0x0f75039f,
+ 0xf5f3ee2c,
+ 0x04baf613,
+ 0x00c6fd60,
+ 0x32ebe198,
+ 0xc7f129eb,
+ 0x7cac0839,
+ 0x57a1fde4,
+ 0x2da04cfc,
+ 0x93179aa5,
+ 0xf3f4d2d9,
+ 0xd8d2528a,
+ 0x5fdd42af,
+ 0xd08c7bdb,
+ 0x53acd639,
+ 0xe37aab85,
+ 0x2d55b5a2,
+ 0x7bc96248,
+ 0x2fb42401,
+ 0x2ff99915,
+ 0x2be3b5ea,
+ 0xf0ff9bdd,
+ 0x1b6bbaa3,
+ 0x83a13de0,
+ 0x4503fc83,
+ 0x08c24640,
+ 0x2463a2b2,
+ 0x2e264872,
+ 0xc451a29d,
+ 0xbfd2e09c,
+ 0x15bcb009,
+ 0x69102223,
+ 0x4c8581e9,
+ 0x4ec94cf0,
+ 0x75017d7b,
+ 0x0e5d8cf1,
+ 0x50b9ca97,
+ 0x55df1100,
+ 0x245162e0,
+ 0x0df18bca,
+ 0x00776990,
+ 0xf6790a03,
+ 0x599ef43e,
+ 0xe8bf7afb,
+ 0xea141ddc,
+ 0xad1a54b2,
+ 0x55f767f8,
+ 0xb661981c,
+ 0xe1650342,
+ 0x365adc95,
+ 0xbb44e3a0,
+ 0xa064fea1,
+ 0x3516bf27,
+ 0xfd40a414,
+ 0x53f9a9e6,
+ 0x2071a5ee,
+ 0x56ca2713,
+ 0x7afdd07a,
+ 0xd62b7f6e,
+ 0xe9dac904,
+ 0xca212105,
+ 0xb9d6e3de,
+ 0x6af5033f,
+ 0x34d9049b,
+ 0xc51ec095,
+ 0xe5eddb9d,
+ 0x122b5c6a,
+ 0x9f562e58,
+ 0x20ec8986,
+ 0x760857f2,
+ 0x8d8aadb3,
+ 0xbc8f0807,
+ 0x0f79eae7,
+ 0xbfa6bfa8,
+ 0x28151aeb,
+ 0xbe4b4d4b,
+ 0xc65d58b0,
+ 0xcf99ba1b,
+ 0xc1049197,
+ 0xe36d8c87,
+ 0x548b7676,
+ 0xbe7bb2c4,
+ 0x77923781,
+ 0x5fbd631e,
+ 0x770e5a41,
+ 0xd2f2948a,
+ 0x074f5428,
+ 0xc7a1562e,
+ 0xf55618c6,
+ 0x8bf8a3d1,
+ 0x837ed4a8,
+ 0xe42e0298,
+ 0xd3754b0c,
+ 0xbaa24c25,
+ 0x793ac973,
+ 0x814e66ec,
+ 0xa4154fa9,
+ 0x3e0e65ca,
+ 0x5a783bd5,
+ 0x2bb37f6c,
+ 0xb3c2526e,
+ 0x34c9a28a,
+ 0x6c8b4795,
+ 0x64605fa8,
+ 0x2e6aae2e,
+ 0xd9b28f27,
+ 0x6a9a200b,
+ 0x3acd1e3a,
+ 0xce9a4a6c,
+ 0xd2a0bd14,
+ 0x700f2003,
+ 0x501cbef7,
+ 0x4068b05e,
+ 0xa24c4580,
+ 0x4da75506,
+ 0x500b9b0f,
+ 0x22e3a600,
+ 0x7bec4e94,
+ 0x8f0958e2,
+ 0x42129a1e,
+ 0xb46d8dc5,
+ 0x29f8851c,
+ 0x83fb38bd,
+ 0x17b0de15,
+ 0x15340d20,
+ 0x74f00fde,
+ 0x6c646b32,
+ 0x905897c4,
+ 0x4d8ed991,
+ 0x3cf91fd5,
+ 0x0ee02ddf,
+ 0xec069ce6,
+ 0x0b977683,
+ 0xa0bf31f6,
+ 0xa1d135a9,
+ 0xa882d1db,
+ 0xa731a63a,
+ 0x48e211f1,
+ 0xf3d89e99,
+ 0xf982e6ea,
+ 0x23dde303,
+ 0x7f1ff8da,
+ 0xdc8c6414,
+ 0x806f432e,
+ 0xd047bc02,
+ 0x671bacff,
+ 0xd40ba2a8,
+ 0xe3666685,
+ 0x31265f9f,
+ 0x3931a952,
+ 0x62f35606,
+ 0xc48f0c5e,
+ 0xfd107640,
+ 0xf636da24,
+ 0xb8f5c3b0,
+ 0x1c91e88f,
+ 0xed9dd432,
+ 0x2b85fa5d,
+ 0x8b15d2ac,
+ 0x1e06cf24,
+ 0x1def6e9c,
+ 0xfae9175f,
+ 0x03ac6f02,
+ 0x37318c87,
+ 0xbc0b1ce5,
+ 0xa0640cab,
+ 0x6cc20a3c,
+ 0x1c7b2524,
+ 0x4685dacc,
+ 0xeab8bb31,
+ 0x8063b5d0,
+ 0x79817d52,
+ 0x211b1972,
+ 0xd7bfc987,
+ 0xab9128dc,
+ 0x150d9b36,
+ 0x6a5838ab,
+ 0x9a0a304d,
+ 0x2e43c331,
+ 0x84f2c4b8,
+ 0x435146c1,
+ 0xed64a280,
+ 0x553ecb4c,
+ 0x5c800db2,
+ 0xeef4df95,
+ 0x5dcf2c37,
+ 0x70755ddf,
+ 0x4274737b,
+ 0xe610350e,
+ 0xd97a5997,
+ 0x7af5edce,
+ 0xfd18ba0c,
+ 0xb7587cd8,
+ 0xfa5e42d6,
+ 0x76bde9eb,
+ 0xec41eead,
+ 0x604d2423,
+ 0xb4adbcf9,
+ 0xce728fa3,
+ 0x02361c31,
+ 0x02fab64d,
+ 0x00316b1c,
+ 0x562f9aa4,
+ 0x71f85790,
+ 0x9cb6d464,
+ 0x32949ebf,
+ 0x434fc23d,
+ 0xee7fac51,
+ 0xda5cc63a,
+ 0x17e616b4,
+ 0xcd1bd1bc,
+ 0x14638cae,
+ 0xd31808fa,
+ 0xb16e0727,
+ 0xfdda2b0f,
+ 0xbc11c678,
+ 0xfe79dc6e,
+ 0xe26eefb4,
+ 0x9a78de16,
+ 0xb68f2df2,
+ 0xd47da234,
+ 0xbdff28a4,
+ 0x937bb1f4,
+ 0x0786dd46,
+ 0xbd1160f5,
+ 0xf77b070c,
+ 0x72b7c51e,
+ 0xcbb3a371,
+ 0x5e50e904,
+ 0x00fbc379,
+ 0x680757dd,
+ 0xd38193f7,
+ 0x93113e25,
+ 0x7b258da7,
+ 0x991aaa09,
+ 0xab1415be,
+ 0xa3740774,
+ 0x370b72e5,
+ 0x2fc643f4,
+ 0x3916d70e,
+ 0xea2838d3,
+ 0xe4840c42,
+ 0xd18e6959,
+ 0x69a270ee,
+ 0xee4a494e,
+ 0x0329799b,
+ 0x07480357,
+ 0x0260c46f,
+ 0x7b75346e,
+ 0x787234f4,
+ 0xe0adf25b,
+ 0xba85cacf,
+ 0xb5724eb1,
+ 0xfde2c080,
+ 0x2b6bb492,
+ 0xd2f70545,
+ 0x9ca97510,
+ 0x4034c18f,
+ 0x616bcb12,
+ 0x5667f52a,
+ 0xe2f6bfce,
+ 0x1f25969e,
+ 0x569eaab7,
+ 0x27ad8196,
+ 0x2d30a6d0,
+ 0x96d6c10a,
+ 0xcb9f024f,
+ 0x3d7941ef,
+ 0xf7a76bc5,
+ 0xe9a701d4,
+ 0xd53293a3,
+ 0x252cf5df,
+ 0xaf9172f6,
+ 0xd090c809,
+ 0xb1a17387,
+ 0x045a0987,
+ 0x92d9ffd9,
+ 0xb30c449c,
+ 0x2180ff58,
+ 0x2929f7de,
+ 0x3f91766e,
+ 0x9f488e3d,
+ 0x05dd6734,
+ 0x82482f5b,
+ 0x01da3ca2,
+ 0x42f33408,
+ 0xf8e3ba89,
+ 0x750ac2ff,
+ 0x39f11551,
+ 0x71087971,
+ 0x368fa634,
+ 0xefda0572,
+ 0x14b8f750,
+ 0xe5768705,
+ 0x71c168e2,
+ 0x8c012c63,
+ 0x12ad74ce,
+ 0x841c17ea,
+ 0xe6f44176,
+ 0x36cf2557,
+ 0x14760a6d,
+ 0x4bb3b7c2,
+ 0x14d1437d,
+ 0xbe673210,
+ 0x4d6ba9f5,
+ 0xe68abbf9,
+ 0xc311908d,
+ 0x46b63956,
+ 0xac2c9fb3,
+ 0xab769ce8,
+ 0xa29d7040,
+ 0xec3d67e3,
+ 0xdef311de,
+ 0x52a53b14,
+ 0xca924769,
+ 0xf35d1514,
+ 0x524b0471,
+ 0xc0d08591,
+ 0x454fc34c,
+ 0xca719639,
+ 0x9af2f230,
+ 0xa023a821,
+ 0x3d6539ba,
+ 0x90d0d7a2,
+ 0xc65fc56e,
+ 0x4eb2aa19,
+ 0xeba3b0e7,
+ 0x1bb5b33e,
+ 0xab8c68c2,
+ 0x0f1793d3,
+ 0xdcf176e9,
+ 0x1b7bbba0,
+ 0x96170a27,
+ 0x1955452d,
+ 0x42e88c71,
+ 0x48cad4b3,
+ 0xdcc36042,
+ 0x90619951,
+ 0x7566bc7c,
+ 0xe14ba224,
+ 0xc24ad73d,
+ 0xdb04144d,
+ 0xd9792727,
+ 0x11150943,
+ 0xe45f0c57,
+ 0xb87d184e,
+ 0x3cf13243,
+ 0x2010d95c,
+ 0x84c347c1,
+ 0x6d0f2461,
+ 0xb5c41194,
+ 0xde7ccb2e,
+ 0xb929ecb0,
+ 0x51fbd8f7,
+ 0x45dc65fb,
+ 0x6902d2c0,
+ 0xb940814f,
+ 0xf339e083,
+ 0x6f370d56,
+ 0xcaf5638e,
+ 0xe8a3cb83,
+ 0xacf414b6,
+ 0xe61095a1,
+ 0x99b4cde4,
+ 0x55112fed,
+ 0x606b9d53,
+ 0x5a05974a,
+ 0xa4c7db34,
+ 0xdc92469b,
+ 0xf9280621,
+ 0xe7b1ef95,
+ 0xc0fc5be8,
+ 0x74a1da09,
+ 0xa92a4b7f,
+ 0x3d65d75e,
+ 0xe3804335,
+ 0x1ff49e19,
+ 0x71da8170,
+ 0xac69069b,
+ 0x04aae3d5,
+ 0xc0ef4b46,
+ 0x091a3482,
+ 0x8356c7ae,
+ 0x32ecb208,
+ 0x900c89ed,
+ 0x2a206ff5,
+ 0x7eed5032,
+ 0x5b55b25d,
+ 0xf98d6df2,
+ 0xf52bc8a9,
+ 0x1aa2f5fe,
+ 0x1d33c0bf,
+ 0x3cd34e89,
+ 0x9a0da4ae,
+ 0x1c205917,
+ 0x7ca784cd,
+ 0xf7dda662,
+ 0xad97f3ff,
+ 0x525c53ec,
+ 0x024f11ff,
+ 0x32c3ae5b,
+ 0xbf372800,
+ 0x8ff15f4d,
+ 0x7605d019,
+ 0x0dae7740,
+ 0x5f5dd0ef,
+ 0x0f6c37d0,
+ 0xee6fa91e,
+ 0xb9f51051,
+ 0x39a9f0d1,
+ 0x22bf03fb,
+ 0x485a0922,
+ 0x7384b30e,
+ 0x85ba7f16,
+ 0xb1f0a524,
+ 0x7e9c5113,
+ 0x240d9306,
+ 0x1ca7b0ea,
+ 0x18a0d114,
+ 0x76b64213,
+ 0x31212cc0,
+ 0xc9dca5c3,
+ 0x69f2ae52,
+ 0x545caa7c,
+ 0xfb2ff045,
+ 0x3f3a1af5,
+ 0xe75b6913,
+ 0x775a1c79,
+ 0x4627e25f,
+ 0x90a14b97,
+ 0x06456383,
+ 0x3d52cf69,
+ 0xfb2492c3,
+ 0x39f25a22,
+ 0x81f68c55,
+ 0x87b14e15,
+ 0x0920af5d,
+ 0xe2585678,
+ 0x0671e46d,
+ 0xb77ddb67,
+ 0x3948c4b3,
+ 0x122dddef,
+ 0xd0726172,
+ 0xd3302234,
+ 0x58bab4e4,
+ 0x195ac247,
+ 0x082459f0,
+ 0x18a2566d,
+ 0xbf56078d,
+ 0x116ed409,
+ 0x5ccc0f80,
+ 0xbae0b4ca,
+ 0x21a6325d,
+ 0x7e1f0c40,
+ 0x595326d4,
+ 0x518b2244,
+ 0x8ab3cdb7,
+ 0xbe6b4835,
+ 0xfc39f8ac,
+ 0x63b167aa,
+ 0x194f070d,
+ 0xed3d0416,
+ 0xae16758a,
+ 0xb9bb6bbf,
+ 0x477d9c85,
+ 0x9808c304,
+ 0xe1d8cec4,
+ 0x7ee22e17,
+ 0x0a7a9d7f,
+ 0xcc98173a,
+ 0x5f78dc21,
+ 0x364bc95e,
+ 0xb54608d9,
+ 0x5d4d70ea,
+ 0x083a7f79,
+ 0x59ffbd73,
+ 0x4f3e9eaf,
+ 0x68755ad4,
+ 0xab254689,
+ 0x11bf09a8,
+ 0xbbc40098,
+ 0x969ca3eb,
+ 0x30eee9d2,
+ 0xe35bc37e,
+ 0xcb2d678f,
+ 0x7846876b,
+ 0xf0d28ae7,
+ 0xc092fbb2,
+ 0x321b344a,
+ 0xcc5ee81b,
+ 0xd2afa00f,
+ 0xfeccd86a,
+ 0x6e5e55c2,
+ 0x2b5543ea,
+ 0x810e4009,
+ 0xea2d8e20,
+ 0x6acae3b9,
+ 0x3828e15e,
+ 0xe1e4821c,
+ 0xf429da70,
+ 0x35f6565c,
+ 0x64b1baa8,
+ 0x350e9583,
+ 0xd2522d4f,
+ 0x5e28a3f1,
+ 0x949ff0aa,
+ 0x3c1b5694,
+ 0x146dde1f,
+ 0x6f3430e1,
+ 0x71c077b7,
+ 0x4d145924,
+ 0xe431cd28,
+ 0xb315cfde,
+ 0xa0365a4a,
+ 0x473de1aa,
+ 0xcbe4e999,
+ 0x319906e9,
+ 0xad0fea9c,
+ 0x89e4e72d,
+ 0x9dbba94d,
+ 0xd395c1c5,
+ 0xa1fff11a,
+ 0x8447e120,
+ 0xe5c59100,
+ 0xa07cb778,
+ 0x8f30a039,
+ 0xed78facb,
+ 0x86de9373,
+ 0x550c4889,
+ 0xce71e3a8,
+ 0x06167b3a,
+ 0x5abdd9a3,
+ 0xc8a9e48d,
+ 0xe3312905,
+ 0x7a63a146,
+ 0xc0f19763,
+ 0xda0cf9db,
+ 0x1d708306,
+ 0x0e41f0ba,
+ 0x4c7939fe,
+ 0x768e48c2,
+ 0xe925fd31,
+ 0x309e7870,
+ 0xfc261b87,
+ 0xc897b2de,
+ 0x6c714792,
+ 0x41c7fbac,
+ 0x57d0b3c3,
+ 0x4fa82a55,
+ 0xd56b4a87,
+ 0x81e5cabc,
+ 0xb260cb7b,
+ 0x520927ab,
+ 0x20d0ab46,
+ 0xc9f92ddf,
+ 0x81f4a21d,
+ 0xfc5a0ca2,
+ 0x95d16aad,
+ 0xe54d7847,
+ 0x6080cc07,
+ 0x0df73f7e,
+ 0xaa8d5187,
+ 0x97a0bc12,
+ 0xb22c5e68,
+ 0x0954d7dc,
+ 0x3368ab5a,
+ 0xd12541df,
+ 0x58119260,
+ 0xe5b0e1df,
+ 0x25027fa4,
+ 0x5780425d,
+ 0x29bb8791,
+ 0x4100b7a9,
+ 0x076b3519,
+ 0x15e0ebb4,
+ 0xe5fb9273,
+ 0x6dbf07e7,
+ 0x1f82bddd,
+ 0x03691b6b,
+ 0xbacef28c,
+ 0x9909ed5a,
+ 0x98886793,
+ 0x544f9a82,
+ 0x9d9749d0,
+ 0x38441606,
+ 0xc4a9f4d2,
+ 0x6ce2bcf1,
+ 0x1c7c3abd,
+ 0x62c621f1,
+ 0x871ee1e4,
+ 0xa83930ce,
+ 0xbe1ee459,
+ 0xd61f1ca4,
+ 0x8c4450e5,
+ 0x98031ca9,
+ 0xe52f54e2,
+ 0xd0c4c737,
+ 0x76074160,
+ 0xbf050c3b,
+ 0x2603af14,
+ 0x43cbb0bc,
+ 0xc631b9e8,
+ 0x26030719,
+ 0x993f570c,
+ 0xdda34038,
+ 0xe34a9793,
+ 0x337a124c,
+ 0x2aa8af16,
+ 0xf80d7473,
+ 0xf01d9397,
+ 0x68e1afb9,
+ 0x0eb37ad2,
+ 0xf71969f9,
+ 0xdf020552,
+ 0x75aa9b30,
+ 0xffa210cf,
+ 0x543c414f,
+ 0xa1e3faec,
+ 0x40891d7e,
+ 0x6b48a6c5,
+ 0xec09a1a0,
+ 0x97a31f2a,
+ 0x5a6be2d7,
+ 0xd06e492b,
+ 0xc54290af,
+ 0xcb524021,
+ 0x420e8c4d,
+ 0xfb135c17,
+ 0x2bfc8adb,
+ 0x9f0cfb46,
+ 0x564db712,
+ 0x7a97a227,
+ 0x8bb98daf,
+ 0xdd0d6180,
+ 0x3d28b9e3,
+ 0xe505050f,
+ 0x19a9868e,
+ 0x7bf5685f,
+ 0x35d698c4,
+ 0xce7e1de3,
+ 0x360a64af,
+ 0x25a1f022,
+ 0xe26c1d04,
+ 0x5b3fb364,
+ 0x932f25f7,
+ 0x9a2aa00d,
+ 0xc50fb773,
+ 0xec45ea3a,
+ 0x22ddf8e4,
+ 0xafb6a6c8,
+ 0x876d04f7,
+ 0xd9c86c3c,
+ 0xd54bee2d,
+ 0xf4e28199,
+ 0xc3456776,
+ 0x04c3107b,
+ 0xbf914e9d,
+ 0x23fefaa5,
+ 0x0931a133,
+ 0x41467758,
+ 0x8ec49707,
+ 0x5ed48709,
+ 0xd11c2de8,
+ 0xb687a0b9,
+ 0xdc908383,
+ 0xd8037ff3,
+ 0xd4311a9f,
+ 0xd00aeb6a,
+ 0xfe54df3b,
+ 0x9c51ce4d,
+ 0x36956408,
+ 0xcd28ef09,
+ 0xc68932b0,
+ 0x7c31e782,
+ 0x28b4723c,
+ 0xededacc2,
+ 0x6ddbac6b,
+ 0x775a7fc1,
+ 0x6909906f,
+ 0xa774123c,
+ 0xf63145ad,
+ 0x287b191e,
+ 0x59d79300,
+ 0xbf76a2fc,
+ 0xfbaf9207,
+ 0x2fe5b7f6,
+ 0xebe7c103,
+ 0x71ac0a8d,
+ 0x2028c3c7,
+ 0xd2cb4917,
+ 0xd74a4ee4,
+ 0xfce405d8,
+ 0xad83fd0f,
+ 0x8f9ec3da,
+ 0xaab2301c,
+ 0xc6f1339f,
+ 0xc652bced,
+ 0xe378b272,
+ 0x18e1ff34,
+ 0x9ec778b6,
+ 0xce1a3883,
+ 0x7c5e5eaf,
+ 0xd16ec37a,
+ 0xa69e45f4,
+ 0xc36cd4aa,
+ 0x045b391f,
+ 0x5a2a08f1,
+ 0x4dd8d53e,
+ 0xd64796ec,
+ 0x4476fc28,
+ 0x18dbaa50,
+ 0x00fb2407,
+ 0x177db915,
+ 0x5969758b,
+ 0x3030964a,
+ 0x81d6485b,
+ 0x7d2e12b0,
+ 0x624d6c5f,
+ 0x0746bbc0,
+ 0xe669d150,
+ 0x0465eef7,
+ 0x09764011,
+ 0x551995e4,
+ 0x8422dedf,
+ 0x0ca56194,
+ 0x293eab2e,
+ 0xf20a137a,
+ 0x55117fc2,
+ 0xbc5431af,
+ 0x064751fa,
+ 0xc0dafdb2,
+ 0x6c3b1d4f,
+ 0xeac335b3,
+ 0x71173afc,
+ 0x31c84b7c,
+ 0xfef2b4ab,
+ 0x59ca5fa2,
+ 0x664c8b4e,
+ 0x7dfd560b,
+ 0xdb0daff3,
+ 0x51f87bfa,
+ 0x58015d2e,
+ 0x67a827b4,
+ 0x62cebc1a,
+ 0x24b37298,
+ 0x75b589be,
+ 0x874f1800,
+ 0x277b795c,
+ 0xf762489e,
+ 0x87d00752,
+ 0x9be45ed1,
+ 0x296ec120,
+ 0x61162480,
+ 0x792e8a2c,
+ 0x3b631590,
+ 0xe33ba0cf,
+ 0x542ac23c,
+ 0xe1e8cffa,
+ 0xfc084cd8,
+ 0xc115ad31,
+ 0x71559928,
+ 0x791f1e33,
+ 0x662ed92b,
+ 0x7222c76d,
+ 0x02dcd566,
+ 0x8db9b4d4,
+ 0xa5f344c8,
+ 0x15806b12,
+ 0x81e572f7,
+ 0x3b3fbe25,
+ 0x2133b413,
+ 0x2d68a367,
+ 0x356f6ce7,
+ 0xcd6dfed1,
+ 0xd8b3a26e,
+ 0xe9d328da,
+ 0x127425ab,
+ 0x83a60aac,
+ 0x8cc26190,
+ 0x7f87ab26,
+ 0x56faab5f,
+ 0x76d0feaa,
+ 0x4b25dd10,
+ 0x4f6286ea,
+ 0x79298d06,
+ 0x8002bf83,
+ 0x2977c85e,
+ 0xd3b3d19a,
+ 0xa92bf132,
+ 0xa280efd8,
+ 0x83f7ad6e,
+ 0x748969c7,
+ 0x25ff411d,
+ 0x3854d3a8,
+ 0x55746aa2,
+ 0x00db5c54,
+ 0x36949e0d,
+ 0x40402ab6,
+ 0x1a720211,
+ 0xe02ce823,
+ 0x4ac104a2,
+ 0x214d2e4b,
+ 0x267e5c83,
+ 0x38a3a483,
+ 0xd1da1f67,
+ 0x0c68db2c,
+ 0xd7035d63,
+ 0xa29393bb,
+ 0xa5743519,
+ 0xcb97c84e,
+ 0xa853974f,
+ 0x147360a0,
+ 0x2df9b3f4,
+ 0x0aff129e,
+ 0x177d687f,
+ 0x87eff911,
+ 0x6c60b354,
+ 0x6c356c38,
+ 0x7d480965,
+ 0xbb06a193,
+ 0x25b0568e,
+ 0x6fd6da9a,
+ 0x82b64f14,
+ 0x3d267a78,
+ 0xf100b6a7,
+ 0x32c74539,
+ 0x6042e152,
+ 0x4548276e,
+ 0xa3a32b70,
+ 0xf029fe15,
+ 0xa9b8bd2f,
+ 0x5618eee4,
+ 0x9815a5f0,
+ 0x89fb2850,
+ 0xa9261b26,
+ 0xded9e505,
+ 0x37e9d749,
+ 0xdc4aeb78,
+ 0x9e634f7a,
+ 0xcf638d2d,
+ 0x6b679f92,
+ 0x2b64911d,
+ 0xe6d1312f,
+ 0x88b3e76a,
+ 0x56311f62,
+ 0x00916de7,
+ 0x39d0bc61,
+ 0x8ac09356,
+ 0x47abcfce,
+ 0x324cb73e,
+ 0xfadcd0a8,
+ 0x2f2fbca8,
+ 0x945eda22,
+ 0xba23cab1,
+ 0xf9fb4212,
+ 0x1fa71d45,
+ 0x867a034e,
+ 0x3bee5db1,
+ 0xf54adced,
+ 0x6633ba77,
+ 0xe1eb4f1e,
+ 0x97ef01f6,
+ 0x57fd3b32,
+ 0x5234d80d,
+ 0xe8ee95f3,
+ 0x5dc990bf,
+ 0xaba833e1,
+/* Dummy terminator */
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+};
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig/mptable.c b/src/mainboard/supermicro/x6dhr_ig/mptable.c new file mode 100644 index 0000000000..7c13b8fd32 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/mptable.c @@ -0,0 +1,236 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "X6DHR-iG "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_pxhd_1; + unsigned char bus_pxhd_2; + unsigned char bus_pxhd_3; + unsigned char bus_pxhd_4; + unsigned char bus_ich5r_1; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* ich5r */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1f.0, using defaults\n"); + + bus_ich5r_1 = 9; + bus_isa = 10; + } + /* pxhd-1 */ + dev = dev_find_slot(2, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n"); + + bus_pxhd_1 = 3; + } + /* pxhd-2 */ + dev = dev_find_slot(2, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n"); + + bus_pxhd_2 = 4; + } + + /* pxhd-3 */ + dev = dev_find_slot(5, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.1, using defaults\n"); + + bus_pxhd_3 = 6; + } + /* pxhd-4 */ + dev = dev_find_slot(5, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n"); + + bus_pxhd_4 = 7; + } + + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + { + struct resource *res; + device_t dev; + /* pxhd apic 3 */ + dev = dev_find_slot(2, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x03, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 2:00.1\n"); + } + /* pxhd apic 4 */ + dev = dev_find_slot(2, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x04, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 2:00.3\n"); + } + /* pxhd apic 5 */ + dev = dev_find_slot(5, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x05, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 5:00.1\n"); + } + /* pxhd apic 8 */ + dev = dev_find_slot(5, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x08, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 5:00.3\n"); + } + } + + + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x76, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x77, 0x02, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x75, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0f, 0x02, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7c, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_2, 0x08, 0x04, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_2, 0x09, 0x04, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_3, 0x08, 0x05, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_4, 0x08, 0x08, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + (bus_isa - 1), 0x04, 0x02, 0x10); + + /* Standard local interrupt assignments */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x00); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + + /* There is no extension information... */ + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/supermicro/x6dhr_ig/reset.c b/src/mainboard/supermicro/x6dhr_ig/reset.c new file mode 100644 index 0000000000..874bfc4848 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/supermicro/x6dhr_ig/watchdog.c b/src/mainboard/supermicro/x6dhr_ig/watchdog.c new file mode 100644 index 0000000000..e9012a49f3 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/watchdog.c @@ -0,0 +1,99 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ICH5_WDBASE 0x400 +#define ICH5_GPIOBASE 0x500 + +static void disable_sio_watchdog(device_t dev) +{ +#if 0 + /* FIXME move me somewhere more appropriate */ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 1); + pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE); + /* disable the sio watchdog */ + outb(0, NSC_WDBASE + 0); + pnp_set_enable(dev, 0); +#endif +} + +static void disable_ich5_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ICH5_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ICH5_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_jarell_frb3(void) +{ +#if 0 + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 0); + pci_write_config16(dev, 0x04, value); + + /* Set gpio base */ + pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1); + base = ICH5_GPIOBASE; + + /* Enable GPIO Bar */ + value = pci_read_config32(dev, 0x5c); + value |= 0x10; + pci_write_config32(dev, 0x5c, value); + + /* Configure GPIO 48 and 40 as GPIO */ + value = inl(base + 0x30); + value |= (1 << 16) | ( 1 << 8); + outl(value, base + 0x30); + + /* Configure GPIO 48 as Output */ + value = inl(base + 0x34); + value &= ~(1 << 16); + outl(value, base + 0x34); + + /* Toggle GPIO 48 high to low */ + value = inl(base + 0x38); + value |= (1 << 16); + outl(value, base + 0x38); + value &= ~(1 << 16); + outl(value, base + 0x38); +#endif +} + +static void disable_watchdogs(void) +{ +// disable_sio_watchdog(NSC_WD_DEV); + disable_ich5_watchdog(); +// disable_jarell_frb3(); + print_debug("Watchdogs disabled\r\n"); +} + diff --git a/src/mainboard/supermicro/x6dhr_ig/x6dhr_fixups.c b/src/mainboard/supermicro/x6dhr_ig/x6dhr_fixups.c new file mode 100644 index 0000000000..82c070b0c1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig/x6dhr_fixups.c @@ -0,0 +1,23 @@ +#include <arch/romcc_io.h> + +static void mch_reset(void) +{ + return; +} + + + +static void mainboard_set_e7520_pll(unsigned bits) +{ + return; +} + + +static void mainboard_set_e7520_leds(void) +{ + return; +} + + + + diff --git a/src/mainboard/supermicro/x6dhr_ig2/Config.lb b/src/mainboard/supermicro/x6dhr_ig2/Config.lb new file mode 100644 index 0000000000..dff583ce2c --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/Config.lb @@ -0,0 +1,209 @@ +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## Compute the location and size of where this firmware image +## (linuxBIOS plus bootloader) will live in the boot rom chip. +## +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = ( ROM_SIZE - FALLBACK_SIZE ) +else + default ROM_SECTION_SIZE = ( ROM_SIZE - FALLBACK_SIZE ) + default ROM_SECTION_OFFSET = 0 +end + +## +## Compute the start location and size size of +## The linuxBIOS bootloader. +## +default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE ) +default CONFIG_ROM_STREAM_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) + +## +## Compute where this copy of linuxBIOS will start in the boot rom +## +default _ROMBASE = ( CONFIG_ROM_STREAM_START + PAYLOAD_SIZE ) + +## +## Compute a range of ROM that can cached to speed up linuxBIOS, +## execution speed. +## +## XIP_ROM_SIZE must be a power of 2. +## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE +## +default XIP_ROM_SIZE=131072 +default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +## +## Set all of the defaults for an x86 architecture +## + +arch i386 end + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o +if HAVE_MP_TABLE object mptable.o end +if HAVE_PIRQ_TABLE object irq_tables.o end +object reset.o + +## +## Romcc output +## +makerule ./failover.E + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -fno-simplify-phi -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./failover.inc + depends "$(MAINBOARD)/failover.c ./romcc" + action "./romcc -fno-simplify-phi -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/failover.c -o $@" +end + +makerule ./auto.E + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -fno-simplify-phi -E -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end +makerule ./auto.inc + depends "$(MAINBOARD)/auto.c option_table.h ./romcc" + action "./romcc -fno-simplify-phi -mcpu=p4 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" +end + +## +## Build our 16 bit and 32 bit linuxBIOS entry code +## +mainboardinit cpu/x86/16bit/entry16.inc +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/16bit/entry16.lds +ldscript /cpu/x86/32bit/entry32.lds + +## +## Build our reset vector (This is where linuxBIOS is entered) +## +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +### Should this be in the northbridge code? +mainboardinit arch/i386/lib/cpu_reset.inc + +## +## Include an id string (For safe flashing) +## +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +### +### This is the early phase of linuxBIOS startup +### Things are delicate and we test to see if we should +### failover to another image. +### +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end + +### +### O.k. We aren't just an intermediary anymore! +### + +## +## Setup RAM +## +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/enable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc +mainboardinit ./auto.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc + +## +## Include the secondary Configuration files +## +dir /pc80 +config chip.h + +chip northbridge/intel/E7520 # mch + device pci_domain 0 on + chip southbridge/intel/ich5r # ich5r + # USB ports + device pci 1d.0 on end + device pci 1d.1 on end + device pci 1d.2 on end + device pci 1d.3 on end + device pci 1d.7 on end + + # -> Bridge + device pci 1e.0 on end + + # -> ISA + device pci 1f.0 on + chip superio/winbond/w83627hf + device pnp 2e.0 off end + device pnp 2e.2 on + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 on + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.4 off end + device pnp 2e.5 off end + device pnp 2e.6 off end + device pnp 2e.7 off end + device pnp 2e.9 off end + device pnp 2e.a on end + device pnp 2e.b off end + end + end + # -> IDE + device pci 1f.1 on end + # -> SATA + device pci 1f.2 on end + device pci 1f.3 on end + + register "pirq_a_d" = "0x0b070a05" + register "pirq_e_h" = "0x0a808080" + end + device pci 00.0 on end + device pci 00.1 on end + device pci 01.0 on end + device pci 02.0 on + chip southbridge/intel/pxhd # pxhd1 + # Bus bridges and ioapics usually bus 1 + device pci 0.0 on + # On board gig e1000 + chip drivers/generic/generic + device pci 03.0 on end + device pci 03.1 on end + end + end + device pci 0.1 on end + device pci 0.2 on end + device pci 0.3 on end + end + end + device pci 04.0 on end + device pci 06.0 on end + end + device apic_cluster 0 on + chip cpu/intel/socket_mPGA604_800Mhz # cpu 0 + device apic 0 on end + end + chip cpu/intel/socket_mPGA604_800Mhz # cpu 1 + device apic 6 on end + end + end + register "intrline" = "0x00070105" +end + diff --git a/src/mainboard/supermicro/x6dhr_ig2/Options.lb b/src/mainboard/supermicro/x6dhr_ig2/Options.lb new file mode 100644 index 0000000000..8461cdb7d1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/Options.lb @@ -0,0 +1,228 @@ +uses HAVE_MP_TABLE +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses IRQ_SLOT_COUNT +uses HAVE_OPTION_TABLE +uses CONFIG_LOGICAL_CPUS +uses CONFIG_MAX_CPUS +uses CONFIG_IOAPIC +uses CONFIG_SMP +uses FALLBACK_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_STREAM +uses CONFIG_ROM_STREAM_START +uses PAYLOAD_SIZE +uses _ROMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses STACK_SIZE +uses HEAP_SIZE +uses USE_OPTION_TABLE +uses LB_CKS_RANGE_START +uses LB_CKS_RANGE_END +uses LB_CKS_LOC +uses MAINBOARD +uses MAINBOARD_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CONFIG_CONSOLE_SERIAL8250 +uses TTYS0_BAUD +uses TTYS0_BASE +uses TTYS0_LCS +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL +uses CONFIG_CONSOLE_BTEXT +uses CC +uses HOSTCC +uses CROSS_COMPILE +uses OBJCOPY + + +### +### Build options +### + +## +## ROM_SIZE is the size of boot ROM that this board will use. +## +default ROM_SIZE=1048576 + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Delay timer options +## Use timer2 +## +default CONFIG_UDELAY_TSC=1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +default HAVE_HARD_RESET=1 + +## +## Build code to export a programmable irq routing table +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=16 + +## +## Build code to export an x86 MP table +## Useful for specifying IRQ routing values +## +default HAVE_MP_TABLE=1 + +## +## Build code to export a CMOS option table +## +default HAVE_OPTION_TABLE=1 + +## +## Move the default LinuxBIOS cmos range off of AMD RTC registers +## +default LB_CKS_RANGE_START=49 +default LB_CKS_RANGE_END=122 +default LB_CKS_LOC=123 + +## +## Build code for SMP support +## Only worry about 2 micro processors +## +default CONFIG_SMP=1 +default CONFIG_MAX_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="X6DHR" +default MAINBOARD_VENDOR= "Supermicro" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x15D9 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x5580 + +### +### LinuxBIOS layout values +### + +## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy. +default ROM_IMAGE_SIZE = 65536 + +## +## Use a small 8K stack +## +default STACK_SIZE=0x2000 + +## +## Use a small 32K heap +## +default HEAP_SIZE=0x8000 + + +### +### Compute the location and size of where this firmware image +### (linuxBIOS plus bootloader) will live in the boot rom chip. +### +default FALLBACK_SIZE=131072 + +## +## LinuxBIOS C code runs at this location in RAM +## +default _RAMBASE=0x00004000 + +## +## Load the payload from the ROM +## +default CONFIG_ROM_STREAM=1 + + +### +### Defaults of options that you may want to override in the target config file +### + +## +## The default compiler +## +default CC="$(CROSS_COMPILE)gcc -m32" +default HOSTCC="gcc" + +## +## Disable the gdb stub by default +## +default CONFIG_GDB_STUB=0 + +## +## The Serial Console +## + +# To Enable the Serial Console +default CONFIG_CONSOLE_SERIAL8250=1 + +## Select the serial console baud rate +default TTYS0_BAUD=115200 +#default TTYS0_BAUD=57600 +#default TTYS0_BAUD=38400 +#default TTYS0_BAUD=19200 +#default TTYS0_BAUD=9600 +#default TTYS0_BAUD=4800 +#default TTYS0_BAUD=2400 +#default TTYS0_BAUD=1200 + +# Select the serial console base port +default TTYS0_BASE=0x3f8 + +# Select the serial protocol +# This defaults to 8 data bits, 1 stop bit, and no parity +default TTYS0_LCS=0x3 + +## +### Select the linuxBIOS loglevel +## +## EMERG 1 system is unusable +## ALERT 2 action must be taken immediately +## CRIT 3 critical conditions +## ERR 4 error conditions +## WARNING 5 warning conditions +## NOTICE 6 normal but significant condition +## INFO 7 informational +## DEBUG 8 debug-level messages +## SPEW 9 Way too many details + +## Request this level of debugging output +default DEFAULT_CONSOLE_LOGLEVEL=8 +## At a maximum only compile in this level of debugging +default MAXIMUM_CONSOLE_LOGLEVEL=8 + +## +## Select power on after power fail setting +default MAINBOARD_POWER_ON_AFTER_POWER_FAIL="MAINBOARD_POWER_ON" + +## +## Don't enable the btext console +## +default CONFIG_CONSOLE_BTEXT=0 + + +### End Options.lb +end diff --git a/src/mainboard/supermicro/x6dhr_ig2/auto.c b/src/mainboard/supermicro/x6dhr_ig2/auto.c new file mode 100644 index 0000000000..cd7c18111f --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/auto.c @@ -0,0 +1,169 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/x86/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 "southbridge/intel/ich5r/ich5r_early_smbus.c" +#include "northbridge/intel/E7520/raminit.h" +#include "superio/winbond/w83627hf/w83627hf.h" +#include "cpu/x86/lapic/boot_cpu.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "debug.c" +#include "watchdog.c" +#include "reset.c" +#include "x6dhr2_fixups.c" +#include "superio/winbond/w83627hf/w83627hf_early_init.c" +#include "northbridge/intel/E7520/memory_initialized.c" +#include "cpu/x86/bist.h" + + +#define SIO_GPIO_BASE 0x680 +#define SIO_XBUS_BASE 0x4880 + +#define CONSOLE_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +#define HIDDEN_SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP2) + +#define DEVPRES_CONFIG ( \ + DEVPRES_D0F0 | \ + DEVPRES_D1F0 | \ + DEVPRES_D2F0 | \ + DEVPRES_D3F0 | \ + DEVPRES_D4F0 | \ + DEVPRES_D6F0 | \ + 0 ) +#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0) + +#define RECVENA_CONFIG 0x0808090a +#define RECVENB_CONFIG 0x0808090a + +//void udelay(int usecs) +//{ +// int i; +// for(i = 0; i < usecs; i++) +// outb(i&0xff, 0x80); +//} + +#if 0 +static void hard_reset(void) +{ + /* enable cf9 */ + pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + /* reset */ + outb(0x0e, 0x0cf9); +} +#endif + +static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + /* nothing to do */ +} +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +#include "northbridge/intel/E7520/raminit.c" +#include "sdram/generic_sdram.c" + + +static void main(unsigned long bist) +{ + /* + * + * + */ + static const struct mem_controller mch[] = { + { + .node_id = 0, + .f0 = PCI_DEV(0, 0x00, 0), + .f1 = PCI_DEV(0, 0x00, 1), + .f2 = PCI_DEV(0, 0x00, 2), + .f3 = PCI_DEV(0, 0x00, 3), + .channel0 = {(0xa<<3)|3, (0xa<<3)|2, (0xa<<3)|1, (0xa<<3)|0, }, + .channel1 = {(0xa<<3)|7, (0xa<<3)|6, (0xa<<3)|5, (0xa<<3)|4, }, + } + }; + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + early_mtrr_init(); + if (memory_initialized()) { + asm volatile ("jmp __cpu_reset"); + } + } + /* Setup the console */ + outb(0x87,0x2e); + outb(0x87,0x2e); + pnp_write_config(CONSOLE_SERIAL_DEV, 0x24, 0x84 | (1 << 6)); + w83627hf_enable_dev(CONSOLE_SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ +// report_bist_failure(bist); + + /* MOVE ME TO A BETTER LOCATION !!! */ + /* config LPC decode for flash memory access */ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + pci_write_config32(dev, 0xe8, 0x00000000); + pci_write_config8(dev, 0xf0, 0x00); + +#if 0 + display_cpuid_update_microcode(); +#endif +#if 0 + print_pci_devices(); +#endif +#if 1 + enable_smbus(); +#endif +#if 0 +// dump_spd_registers(&cpu[0]); + int i; + for(i = 0; i < 1; i++) { + dump_spd_registers(); + } +#endif + disable_watchdogs(); +// dump_ipmi_registers(); + mainboard_set_e7520_leds(); +// memreset_setup(); + sdram_initialize(sizeof(mch)/sizeof(mch[0]), mch); +#if 0 + dump_pci_devices(); +#endif +#if 0 + dump_pci_device(PCI_DEV(0, 0x00, 0)); + dump_bar14(PCI_DEV(0, 0x00, 0)); +#endif + +#if 0 // temporarily disabled + /* Check the first 1M */ +// ram_check(0x00000000, 0x000100000); +// ram_check(0x00000000, 0x000a0000); +// ram_check(0x00100000, 0x01000000); + ram_check(0x00100000, 0x00100100); + /* check the first 1M in the 3rd Gig */ +// ram_check(0x30100000, 0x31000000); +#endif +#if 0 + ram_check(0x00000000, 0x02000000); +#endif + +#if 0 + while(1) { + hlt(); + } +#endif +} diff --git a/src/mainboard/supermicro/x6dhr_ig2/chip.h b/src/mainboard/supermicro/x6dhr_ig2/chip.h new file mode 100644 index 0000000000..016f20a3fd --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/chip.h @@ -0,0 +1,5 @@ +struct chip_operations mainboard_supermicro_x6dhr_ig2_ops; + +struct mainboard_supermicro_x6dhr_ig2_config { + int nothing; +}; diff --git a/src/mainboard/supermicro/x6dhr_ig2/cmos.layout b/src/mainboard/supermicro/x6dhr_ig2/cmos.layout new file mode 100644 index 0000000000..6f3cd189e3 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/cmos.layout @@ -0,0 +1,80 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 2 hyper_threading +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 reserved_memory + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/supermicro/x6dhr_ig2/debug.c b/src/mainboard/supermicro/x6dhr_ig2/debug.c new file mode 100644 index 0000000000..5546421156 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/debug.c @@ -0,0 +1,330 @@ +#define SMBUS_MEM_DEVICE_START 0x50 +#define SMBUS_MEM_DEVICE_END 0x57 +#define SMBUS_MEM_DEVICE_INC 1 + +static void print_reg(unsigned char index) +{ + unsigned char data; + + outb(index, 0x2e); + data = inb(0x2f); + print_debug("0x"); + print_debug_hex8(index); + print_debug(": 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + return; +} + +static void xbus_en(void) +{ + /* select the XBUS function in the SIO */ + outb(0x07, 0x2e); + outb(0x0f, 0x2f); + outb(0x30, 0x2e); + outb(0x01, 0x2f); + return; +} + +static void setup_func(unsigned char func) +{ + /* select the function in the SIO */ + outb(0x07, 0x2e); + outb(func, 0x2f); + /* print out the regs */ + print_reg(0x30); + print_reg(0x60); + print_reg(0x61); + print_reg(0x62); + print_reg(0x63); + print_reg(0x70); + print_reg(0x71); + print_reg(0x74); + print_reg(0x75); + return; +} + +static void siodump(void) +{ + int i; + unsigned char data; + + print_debug("\r\n*** SERVER I/O REGISTERS ***\r\n"); + for (i=0x10; i<=0x2d; i++) { + print_reg((unsigned char)i); + } +#if 0 + print_debug("\r\n*** XBUS REGISTERS ***\r\n"); + setup_func(0x0f); + for (i=0xf0; i<=0xff; i++) { + print_reg((unsigned char)i); + } + + print_debug("\r\n*** SERIAL 1 CONFIG REGISTERS ***\r\n"); + setup_func(0x03); + print_reg(0xf0); + + print_debug("\r\n*** SERIAL 2 CONFIG REGISTERS ***\r\n"); + setup_func(0x02); + print_reg(0xf0); + +#endif + print_debug("\r\n*** GPIO REGISTERS ***\r\n"); + setup_func(0x07); + for (i=0xf0; i<=0xf8; i++) { + print_reg((unsigned char)i); + } + print_debug("\r\n*** GPIO VALUES ***\r\n"); + data = inb(0x68a); + print_debug("\r\nGPDO 4: 0x"); + print_debug_hex8(data); + data = inb(0x68b); + print_debug("\r\nGPDI 4: 0x"); + print_debug_hex8(data); + print_debug("\r\n"); + +#if 0 + + print_debug("\r\n*** WATCHDOG TIMER REGISTERS ***\r\n"); + setup_func(0x0a); + print_reg(0xf0); + + print_debug("\r\n*** FAN CONTROL REGISTERS ***\r\n"); + setup_func(0x09); + print_reg(0xf0); + print_reg(0xf1); + + print_debug("\r\n*** RTC REGISTERS ***\r\n"); + setup_func(0x10); + print_reg(0xf0); + print_reg(0xf1); + print_reg(0xf3); + print_reg(0xf6); + print_reg(0xf7); + print_reg(0xfe); + print_reg(0xff); + + print_debug("\r\n*** HEALTH MONITORING & CONTROL REGISTERS ***\r\n"); + setup_func(0x14); + print_reg(0xf0); +#endif + return; +} + +static void print_debug_pci_dev(unsigned dev) +{ + print_debug("PCI: "); + print_debug_hex8((dev >> 16) & 0xff); + print_debug_char(':'); + print_debug_hex8((dev >> 11) & 0x1f); + print_debug_char('.'); + print_debug_hex8((dev >> 8) & 7); +} + +static void print_pci_devices(void) +{ + 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_dev(dev); + print_debug("\r\n"); + } +} + +static void dump_pci_device(unsigned dev) +{ + int i; + print_debug_pci_dev(dev); + print_debug("\r\n"); + + for(i = 0; i <= 255; i++) { + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); + print_debug_char(' '); + print_debug_hex8(val); + if ((i & 0x0f) == 0x0f) { + print_debug("\r\n"); + } + } +} + +static void dump_bar14(unsigned dev) +{ + int i; + unsigned long bar; + + print_debug("BAR 14 Dump\r\n"); + + bar = pci_read_config32(dev, 0x14); + for(i = 0; i <= 0x300; i+=4) { +#if 0 + unsigned char val; + if ((i & 0x0f) == 0) { + print_debug_hex8(i); + print_debug_char(':'); + } + val = pci_read_config8(dev, i); +#endif + if((i%4)==0) { + print_debug("\r\n"); + print_debug_hex16(i); + print_debug_char(' '); + } + print_debug_hex32(read32(bar + i)); + print_debug_char(' '); + } + print_debug("\r\n"); +} + +static void dump_pci_devices(void) +{ + 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; + } + dump_pci_device(dev); + } +} + +#if 0 +static void dump_spd_registers(const struct mem_controller *ctrl) +{ + int i; + print_debug("\r\n"); + for(i = 0; i < 4; i++) { + unsigned device; + device = ctrl->channel0[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".0: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + device = ctrl->channel1[i]; + if (device) { + int j; + print_debug("dimm: "); + print_debug_hex8(i); + print_debug(".1: "); + print_debug_hex8(device); + for(j = 0; j < 256; j++) { + int status; + unsigned char byte; + if ((j & 0xf) == 0) { + print_debug("\r\n"); + print_debug_hex8(j); + print_debug(": "); + } + status = smbus_read_byte(device, j); + if (status < 0) { + print_debug("bad device\r\n"); + break; + } + byte = status & 0xff; + print_debug_hex8(byte); + print_debug_char(' '); + } + print_debug("\r\n"); + } + } +} +#endif + +void dump_spd_registers(void) +{ + unsigned device; + device = SMBUS_MEM_DEVICE_START; + while(device <= SMBUS_MEM_DEVICE_END) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("dimm "); + print_debug_hex8(device); + + for(i = 0; (i < 256) ; i++) { + unsigned char byte; + if ((i % 16) == 0) { + print_debug("\r\n"); + print_debug_hex8(i); + print_debug(": "); + } + status = smbus_read_byte(device, i); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} + +void dump_ipmi_registers(void) +{ + unsigned device; + device = 0x42; + while(device <= 0x42) { + int status = 0; + int i; + print_debug("\r\n"); + print_debug("ipmi "); + print_debug_hex8(device); + + for(i = 0; (i < 8) ; i++) { + unsigned char byte; + status = smbus_read_byte(device, 2); + if (status < 0) { + print_debug("bad device: "); + print_debug_hex8(-status); + print_debug("\r\n"); + break; + } + print_debug_hex8(status); + print_debug_char(' '); + } + device += SMBUS_MEM_DEVICE_INC; + print_debug("\n"); + } +} diff --git a/src/mainboard/supermicro/x6dhr_ig2/failover.c b/src/mainboard/supermicro/x6dhr_ig2/failover.c new file mode 100644 index 0000000000..5029d98611 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/failover.c @@ -0,0 +1,46 @@ +#define ASSEMBLY 1 +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/romcc_io.h> +#include <cpu/x86/lapic.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "pc80/mc146818rtc_early.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/intel/E7520/memory_initialized.c" + +static unsigned long main(unsigned long bist) +{ + /* Did just the cpu reset? */ + if (memory_initialized()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* This is the primary cpu how should I boot? */ + else if (do_normal_boot()) { + goto normal_image; + } + else { + goto fallback_image; + } + normal_image: + asm volatile ("jmp __normal_image" + : /* outputs */ + : "a" (bist) /* inputs */ + : /* clobbers */ + ); + cpu_reset: + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); + fallback_image: + return bist; +} diff --git a/src/mainboard/supermicro/x6dhr_ig2/irq_tables.c b/src/mainboard/supermicro/x6dhr_ig2/irq_tables.c new file mode 100644 index 0000000000..5ed51feaa1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/irq_tables.c @@ -0,0 +1,34 @@ +/* PCI: Interrupt Routing Table found at 0x4010f000 size = 176 */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + 0x52495024, /* u32 signature */ + 0x0100, /* u16 version */ + 272, /* u16 Table size 32+(15*devices) */ + 0x00, /* u8 Bus 0 */ + 0xf8, /* u8 Device 1, Function 0 */ + 0x0000, /* u16 reserve IRQ for PCI */ + 0x8086, /* u16 Vendor */ + 0x24d0, /* Device ID */ + 0x00000000, /* u32 miniport_data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xc4, /* u8 checksum - mod 256 checksum must give zero */ + { /* bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, (0x01<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x02<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x03<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x04<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x06<<3)|0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|0, {{0x60, 0xdcf8}, {0x63, 0xdcf8}, {0x62, 0xdc78}, {0x6b, 0xdcf8}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|1, {{0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|2, {{0x62, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1d<<3)|3, {{0x60, 0xdcf8}, {0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|0, {{0x62, 0xdc78}, {0x61, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x00, (0x1f<<3)|1, {{0x62, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|0, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x04, (0x02<<3)|1, {{0x62, 0xdc78}, {0x63, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x00, 0x00}, + {0x06, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x06, 0x00}, + {0x07, (0x02<<3)|0, {{0x60, 0xdc78}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x07, 0x00} + } +}; diff --git a/src/mainboard/supermicro/x6dhr_ig2/mainboard.c b/src/mainboard/supermicro/x6dhr_ig2/mainboard.c new file mode 100644 index 0000000000..c1891a222b --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/mainboard.c @@ -0,0 +1,12 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <cpu/x86/msr.h> +#include "chip.h" + +struct chip_operations mainboard_supermicro_x6dhr_ig2_ops = { + CHIP_NAME("Supermicro x6dhr-ig2") +}; + diff --git a/src/mainboard/supermicro/x6dhr_ig2/microcode_updates.c b/src/mainboard/supermicro/x6dhr_ig2/microcode_updates.c new file mode 100644 index 0000000000..b2e72ab616 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/microcode_updates.c @@ -0,0 +1,1563 @@ +/* WARNING - Intel has a new data structure that has variable length
+ * microcode update lengths. They are encoded in int 8 and 9. A
+ * dummy header of nulls must terminate the list.
+ */
+
+static const unsigned int microcode_updates[] __attribute__ ((aligned(16))) = {
+ /*
+ Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000.
+ These microcode updates are distributed for the sole purpose of
+ installation in the BIOS or Operating System of computer systems
+ which include an Intel P6 family microprocessor sold or distributed
+ to or by you. You are authorized to copy and install this material
+ on such systems. You are not authorized to use this material for
+ any other purpose.
+ */
+
+ /* M1DF3413.TXT - Noconoa D-0 */
+
+ 0x00000001, /* Header Version */
+ 0x00000013, /* Patch ID */
+ 0x07302004, /* DATE */
+ 0x00000f34, /* CPUID */
+ 0x95f183f0, /* Checksum */
+ 0x00000001, /* Loader Version */
+ 0x0000001d, /* Platform ID */
+ 0x000017d0, /* Data size */
+ 0x00001800, /* Total size */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+ 0x00000000, /* reserved */
+
+ 0x9fbf327a,
+ 0x2b41b451,
+ 0xb2abaca8,
+ 0x6b62b8e0,
+ 0x0af32c41,
+ 0x12ca6048,
+ 0x5bd55ae6,
+ 0xb90dfc1d,
+ 0x565fe2b2,
+ 0x326b1718,
+ 0x61f3a40d,
+ 0xceb53db3,
+ 0x14fb5261,
+ 0xbb23b6c3,
+ 0x9d7c0466,
+ 0xde90a25e,
+ 0x9450e9bb,
+ 0x497bd6e4,
+ 0x97d1041a,
+ 0x1831013f,
+ 0x6e6fa37e,
+ 0x0b5c1d03,
+ 0x5eae4db2,
+ 0xc029d9e3,
+ 0x5373bca3,
+ 0xe15fccca,
+ 0x39043db0,
+ 0xaeb0ea0c,
+ 0x62b4e391,
+ 0x0b280c6b,
+ 0x279eb9d3,
+ 0x98d95ada,
+ 0xc1cb45a7,
+ 0x06917bda,
+ 0xdde8aafa,
+ 0xdff9d15c,
+ 0xd07f8f0a,
+ 0x192bcf9d,
+ 0xf77de31f,
+ 0xadf8be55,
+ 0x3f7a5d95,
+ 0x0e2140b6,
+ 0xf0c75eec,
+ 0x3254876a,
+ 0x684a1698,
+ 0x4ad0cca7,
+ 0x6d705304,
+ 0xf957d91b,
+ 0xe8bb864a,
+ 0x440d636c,
+ 0xaf4d7d06,
+ 0x12680ecf,
+ 0x5d0f9e53,
+ 0x60148a5d,
+ 0x81008364,
+ 0x243a8aed,
+ 0xd55976de,
+ 0xd6a84520,
+ 0x932d4b77,
+ 0xe67e5f19,
+ 0x7dba0e47,
+ 0xfee3b153,
+ 0x46b6a20c,
+ 0x2594e6f6,
+ 0x210cab0f,
+ 0xf6e47d5d,
+ 0xe38276e4,
+ 0x90fc2728,
+ 0x9faefa11,
+ 0xc972217c,
+ 0xc8d079dd,
+ 0x5f7dc338,
+ 0x106f7b7b,
+ 0xd04c0a1c,
+ 0x0eca300e,
+ 0x1ddae8a6,
+ 0x6e7fd42e,
+ 0xa56c514d,
+ 0x56a4e255,
+ 0x975ea2bf,
+ 0x0eaa78cc,
+ 0x0c3e284f,
+ 0xbacb6c71,
+ 0x1645006f,
+ 0xe9a2b955,
+ 0x0677c019,
+ 0x24b33da0,
+ 0x62f200fa,
+ 0x234238c4,
+ 0x81d5ad79,
+ 0x9f754bc9,
+ 0xeffd5016,
+ 0x041b2cc2,
+ 0x2f020bc7,
+ 0x4fcd68b8,
+ 0x22c3579c,
+ 0x4804a114,
+ 0xc42db3ea,
+ 0x7cde8141,
+ 0x47e167c8,
+ 0x01aa38cc,
+ 0x74a5c25e,
+ 0xe0c48d67,
+ 0x562365ad,
+ 0x38321e57,
+ 0x0395885a,
+ 0x6888323e,
+ 0xd6fc518f,
+ 0x1854b64c,
+ 0x06a58476,
+ 0x3662f898,
+ 0xe2bcdaee,
+ 0x84c40693,
+ 0xef09d374,
+ 0x353cc799,
+ 0x742223d4,
+ 0x05b3c99b,
+ 0x0c51ee45,
+ 0xd145824a,
+ 0xac30806c,
+ 0x2ed70c0d,
+ 0x71ae10ff,
+ 0xbf491854,
+ 0x3e1f03b4,
+ 0x76bfd6cd,
+ 0x1449aa8a,
+ 0xf954d3fb,
+ 0xf8c7c940,
+ 0x70233f85,
+ 0x0729e257,
+ 0x10bb8936,
+ 0xc35bb5b5,
+ 0x95d78b5c,
+ 0xcc1ba443,
+ 0x6f507126,
+ 0xa607cfd0,
+ 0xce22f2f3,
+ 0x5134ed8c,
+ 0xec8d2f06,
+ 0xa92413d5,
+ 0xb973f431,
+ 0x16e136dd,
+ 0xf7d41bed,
+ 0x01b002fe,
+ 0x646ed771,
+ 0x76ea3d26,
+ 0x5024af20,
+ 0x84270f51,
+ 0x9b3d7820,
+ 0x2454a2c6,
+ 0xc1f072ed,
+ 0x155e864f,
+ 0x4c39a6e5,
+ 0x928206e5,
+ 0x9d1685f5,
+ 0x45542ee7,
+ 0x1fd27d9e,
+ 0x5f2dd9ff,
+ 0x222005eb,
+ 0x354e8a55,
+ 0x1f0de29a,
+ 0xb86dc696,
+ 0x9eafafad,
+ 0x191b197e,
+ 0x0e0900e1,
+ 0xe0ac42bb,
+ 0x3143236f,
+ 0x44177def,
+ 0x05259274,
+ 0xb21af44a,
+ 0x6ddee4df,
+ 0xc7b56255,
+ 0xb6b1d39d,
+ 0x218f9070,
+ 0x96545a42,
+ 0x98cc2d4a,
+ 0xb21bac9e,
+ 0x83e12d44,
+ 0x2ef4fb39,
+ 0xbc03528f,
+ 0x9485af58,
+ 0xd9f1e6ab,
+ 0xde7607e6,
+ 0x3b398733,
+ 0x9cd9b1a9,
+ 0xabd77984,
+ 0xcce18826,
+ 0x701c5c21,
+ 0xe6591cbf,
+ 0x07a9b9e1,
+ 0x69459c90,
+ 0xe0cdcad6,
+ 0xc4c6c4b6,
+ 0x12748024,
+ 0x4a33c567,
+ 0x7d26a37e,
+ 0xcae163bf,
+ 0xeb7547fa,
+ 0xccc6a01c,
+ 0x3cb8abb8,
+ 0x64aa67b2,
+ 0x51ddf6de,
+ 0xbfe1b905,
+ 0x50923949,
+ 0xacfa43af,
+ 0x1fdb5a44,
+ 0x091533cb,
+ 0x7c92e5dc,
+ 0x1c5d0d3e,
+ 0x195271f5,
+ 0x96e73a4a,
+ 0xe1b11968,
+ 0xb42906f2,
+ 0x5a2940b3,
+ 0x611283e9,
+ 0x65829161,
+ 0x5d1357b7,
+ 0x019428ad,
+ 0x836c5c3c,
+ 0xc0e5e169,
+ 0xd360e424,
+ 0x257a9d69,
+ 0xdca09040,
+ 0x85f1c060,
+ 0xae7cae79,
+ 0xa5ddcfd6,
+ 0xdba8f68e,
+ 0xd98df596,
+ 0xe6e3cd51,
+ 0xcfb2be8f,
+ 0x368fe6cd,
+ 0x58486b75,
+ 0x791f1a48,
+ 0xf81a61f2,
+ 0x58a38155,
+ 0x30a86547,
+ 0xd7fb2db1,
+ 0x300e0b1d,
+ 0x3f838461,
+ 0xf278805a,
+ 0x49529931,
+ 0x601d5649,
+ 0xe500ba1a,
+ 0xc4f78965,
+ 0xe10ed02d,
+ 0x1f777ebd,
+ 0x2db1d17d,
+ 0x48a22e6a,
+ 0x5a14b738,
+ 0xdcf899e0,
+ 0xc845bd04,
+ 0xd04a52b9,
+ 0xf2f19b06,
+ 0xdb5ba97a,
+ 0xf05605ff,
+ 0xc787b72c,
+ 0x9f197770,
+ 0x87b31150,
+ 0x3ff00d57,
+ 0x89d1dcb3,
+ 0x07528ff4,
+ 0x4105fcef,
+ 0xb087de2e,
+ 0x3bd333a5,
+ 0x84a094f4,
+ 0x9ab8fb97,
+ 0xc9bba063,
+ 0x664c52e5,
+ 0x27fd05e4,
+ 0x3f0e491d,
+ 0xab8f4b9a,
+ 0x344a0249,
+ 0x727dd74f,
+ 0x29587211,
+ 0xbba262b9,
+ 0x319ecbb3,
+ 0xec54b023,
+ 0xd0fa096d,
+ 0x3d223f23,
+ 0x0b6013e7,
+ 0x513e045b,
+ 0xcb1edf15,
+ 0xfd44bb25,
+ 0x023eb973,
+ 0x3f55dac6,
+ 0xc2df6514,
+ 0x68589880,
+ 0x4556878e,
+ 0x86f6acfb,
+ 0xbcd23f0b,
+ 0x32c417c1,
+ 0x45f3bb56,
+ 0xbe60872b,
+ 0x09457cc0,
+ 0x2e18b62d,
+ 0x065f54d1,
+ 0xae3b4a20,
+ 0x265b10ae,
+ 0xb7547a1d,
+ 0x5a9481a9,
+ 0xd477ed02,
+ 0x601ed0fc,
+ 0x9a43257e,
+ 0xc9922b72,
+ 0xa2a696ae,
+ 0xe9d6c37b,
+ 0xfab8bdf9,
+ 0x1deb34dc,
+ 0xaa6bb090,
+ 0xbdc3b72f,
+ 0xecb3b010,
+ 0xe64376e7,
+ 0x40356095,
+ 0x928b5047,
+ 0xbd271c09,
+ 0xfd806f61,
+ 0x0821e090,
+ 0x6afb3588,
+ 0xd10e91ea,
+ 0xbbc7fedd,
+ 0xb1ac6d33,
+ 0x07788e4b,
+ 0xa10f8013,
+ 0x4f8efd9d,
+ 0xe5d8728d,
+ 0x017f3e82,
+ 0xf09ec7eb,
+ 0x6bfd7906,
+ 0xbcefcb44,
+ 0x76699ad5,
+ 0x1b976522,
+ 0xa55b3dbd,
+ 0x88bb33e2,
+ 0x98ac5b7f,
+ 0x61ac4c8b,
+ 0xfd948f3d,
+ 0xee610413,
+ 0xc77c5035,
+ 0x662825a9,
+ 0x0009fcba,
+ 0x3450fd88,
+ 0xeb391fef,
+ 0x6949960d,
+ 0x1ccb13c3,
+ 0x21dac5a6,
+ 0x6bcc6b37,
+ 0x37ad77a5,
+ 0xf71d58b1,
+ 0x84ed440d,
+ 0xe606b699,
+ 0xe43067a4,
+ 0x21d5b8b3,
+ 0xe11f83e2,
+ 0xa0cc6585,
+ 0x40eb6d16,
+ 0xc5a6879f,
+ 0xbd333fd5,
+ 0xb44acab4,
+ 0x68c016fc,
+ 0xfbcd3cfc,
+ 0xadf76e42,
+ 0xc520e516,
+ 0x7468cb61,
+ 0x585c0d52,
+ 0xea83cefe,
+ 0x615d7760,
+ 0x89c9b8fd,
+ 0x367c355a,
+ 0x409371a2,
+ 0x7edb38a7,
+ 0xca86d263,
+ 0xda18250d,
+ 0x26e1ed8b,
+ 0x02fefede,
+ 0x704cb5c8,
+ 0x52cbe1eb,
+ 0x9cdbc71a,
+ 0xa0637560,
+ 0xe31f03ca,
+ 0x2b78969b,
+ 0x803d5866,
+ 0xec52d984,
+ 0xd8df8bdb,
+ 0x6cb1d5e8,
+ 0x7b9aec01,
+ 0xf7d39401,
+ 0xdd04c6ae,
+ 0x0e5ca4eb,
+ 0x12b593c8,
+ 0x38f6d4e5,
+ 0x13a91268,
+ 0x60c8251b,
+ 0xa136cf9a,
+ 0xda070cdd,
+ 0x6142408c,
+ 0xc28065dd,
+ 0x50b73718,
+ 0x36074eee,
+ 0xc7b20fcb,
+ 0x18d29f9b,
+ 0xe97eb966,
+ 0xe6936bcc,
+ 0x1c9188ea,
+ 0x7cff40e2,
+ 0xee791ac8,
+ 0xb099a323,
+ 0x571d69b7,
+ 0x22c1f7d0,
+ 0x0b9662ee,
+ 0x76e45cb9,
+ 0xbd0d7020,
+ 0x7794bd95,
+ 0x1b0fe51a,
+ 0xda2754ef,
+ 0x7f3ad7a9,
+ 0x58f627d3,
+ 0x211670a3,
+ 0xc7471b81,
+ 0x495a93ac,
+ 0xaad4f030,
+ 0xa76614c8,
+ 0xd63dba3c,
+ 0x9c4f729c,
+ 0x6e831cfb,
+ 0xa6105c75,
+ 0x95c62188,
+ 0x723ef45d,
+ 0xf59f2dd1,
+ 0x5825283d,
+ 0x768d8a86,
+ 0x070d02ac,
+ 0xfdbcbd73,
+ 0x0d479795,
+ 0x797aa7f7,
+ 0x6c9e468b,
+ 0xa961571d,
+ 0xc7127ef0,
+ 0x4b0442e7,
+ 0xd99a9e87,
+ 0x6c876cba,
+ 0xe4f9f814,
+ 0x120eeb8d,
+ 0x4bbb9c8e,
+ 0x22c0a29e,
+ 0xff681fcc,
+ 0x26777226,
+ 0x6339e667,
+ 0x2402333e,
+ 0x2bf66a17,
+ 0x63806e6c,
+ 0x98416b75,
+ 0x791b3e91,
+ 0x79c09cd7,
+ 0x0c157436,
+ 0x6d99157c,
+ 0xc8990984,
+ 0xaf7d2ae4,
+ 0xfe3ee7d9,
+ 0xb7676de0,
+ 0x9df8722e,
+ 0x08462a7e,
+ 0x99032839,
+ 0xd726ff95,
+ 0x5c1c78e8,
+ 0x4ef1b747,
+ 0x4e257ba7,
+ 0xa83ad5f3,
+ 0x523b3809,
+ 0xc2ce4f19,
+ 0xabfadaa5,
+ 0x370b005c,
+ 0x2d6a02e1,
+ 0xbf6ee428,
+ 0xfd84be50,
+ 0xb79801b3,
+ 0x488ad789,
+ 0x65a87bda,
+ 0x59f0fd6a,
+ 0xa4106878,
+ 0xdbadd916,
+ 0x1f86f200,
+ 0xefb7fc72,
+ 0x26d4d47f,
+ 0xf7892efc,
+ 0x41f50167,
+ 0xc6a28f9e,
+ 0xffd4a8e0,
+ 0xa00e4ea0,
+ 0x8183f648,
+ 0x030faa4c,
+ 0x26c1715f,
+ 0x322c9ea3,
+ 0x5d60d054,
+ 0x413470cb,
+ 0x3d131892,
+ 0x22f2ae86,
+ 0x9f1c96b6,
+ 0x015563f4,
+ 0x3a5625ba,
+ 0xcb95b598,
+ 0xf0685fb9,
+ 0x158af5ec,
+ 0xfc01a406,
+ 0x01841d19,
+ 0x210b7e73,
+ 0x19a416a1,
+ 0xed254c44,
+ 0x5bd51335,
+ 0xb8905dc9,
+ 0x9e52f38c,
+ 0xef5d7dd0,
+ 0x1516f6bb,
+ 0xf13bb426,
+ 0x9ee6d6cb,
+ 0x28bde0a6,
+ 0x766b655e,
+ 0xaf2e0e52,
+ 0xdec60f49,
+ 0x254a0959,
+ 0xb009d431,
+ 0x2f6d3533,
+ 0x0a074afc,
+ 0xcd3d3a72,
+ 0x52aa4fce,
+ 0x16c4507d,
+ 0x2f842898,
+ 0xb087e98b,
+ 0x68b41826,
+ 0xd4adc5c9,
+ 0x53b3e498,
+ 0x2dff7b03,
+ 0xda931e65,
+ 0xf1d66edd,
+ 0x2beb7555,
+ 0x97b3f152,
+ 0x035676f8,
+ 0xca9c7cf6,
+ 0x57992a53,
+ 0x578a1004,
+ 0x458e23c8,
+ 0x2a2494bf,
+ 0xa92c549b,
+ 0x2ca46deb,
+ 0xcd907478,
+ 0x93baaeb5,
+ 0xa70af4c6,
+ 0x9767d5b8,
+ 0x9874bcee,
+ 0xb0413973,
+ 0x9bfef4f7,
+ 0x7fbed607,
+ 0x2a255991,
+ 0xa5e3109d,
+ 0x90f09fef,
+ 0xb7a3d468,
+ 0x6db437aa,
+ 0xe8dad585,
+ 0xfbc19cbc,
+ 0x34cacc6f,
+ 0x6c5cc449,
+ 0xcc6dc144,
+ 0x70c6aaa0,
+ 0x183bc459,
+ 0x490ea5a8,
+ 0xddf105bf,
+ 0x3429facf,
+ 0x79020f72,
+ 0xd2de786d,
+ 0xb776f3ed,
+ 0x553e3da7,
+ 0xaecff099,
+ 0x2b471ce1,
+ 0xe3a72af9,
+ 0x04c9b2bf,
+ 0xe84d9702,
+ 0xec7cd831,
+ 0xda66c6c1,
+ 0x451b207c,
+ 0x68243bc3,
+ 0xb3012b1e,
+ 0x1855c026,
+ 0x1addac14,
+ 0xc73834a2,
+ 0xea91596d,
+ 0x08f0d135,
+ 0xc6021aa0,
+ 0xc5d1726b,
+ 0xc21d1f0b,
+ 0x92b7c740,
+ 0x9f024526,
+ 0x6c91df6c,
+ 0xfec85435,
+ 0x3d5a9150,
+ 0x93249836,
+ 0x2ec5e71f,
+ 0x23e96579,
+ 0x81ce78d6,
+ 0x49e45ccf,
+ 0x4d5e9c78,
+ 0x2a2cdfab,
+ 0x148e1833,
+ 0xa3fab11b,
+ 0xd0ceb7e9,
+ 0x4789b634,
+ 0x147fc687,
+ 0x48f4f59c,
+ 0x21eea4e3,
+ 0x411dfb7d,
+ 0x033fe075,
+ 0x57c9e07d,
+ 0xb09edf4e,
+ 0x9db83f5f,
+ 0x6ef1343a,
+ 0x64a68315,
+ 0x300e34c3,
+ 0x72ac2766,
+ 0x640271a4,
+ 0x0a282b82,
+ 0xcaf1ec1b,
+ 0x7d4849f9,
+ 0x108c5eaa,
+ 0xfaa96613,
+ 0x0476639b,
+ 0x70ee8371,
+ 0x9db599ba,
+ 0x85158d5f,
+ 0x02912911,
+ 0xe6fec86a,
+ 0xcf3036f3,
+ 0xccdd49a0,
+ 0xe650b3cd,
+ 0xf5429ef0,
+ 0x411e4690,
+ 0xa526e30b,
+ 0x275822af,
+ 0x91e12d05,
+ 0x958881aa,
+ 0xabf76cc4,
+ 0x06e794a9,
+ 0xa97d1577,
+ 0x0188613c,
+ 0x17c96558,
+ 0x96c31832,
+ 0x5696b201,
+ 0x03e3dad2,
+ 0xbe44d0ba,
+ 0x4d552a6c,
+ 0xe9fafb48,
+ 0x4968ad28,
+ 0xf109edce,
+ 0xd1534f30,
+ 0xc2d8b9e8,
+ 0x66e911d7,
+ 0xd67a594b,
+ 0x4492b2b4,
+ 0xeb86848d,
+ 0x4106979b,
+ 0x0f75039f,
+ 0xf5f3ee2c,
+ 0x04baf613,
+ 0x00c6fd60,
+ 0x32ebe198,
+ 0xc7f129eb,
+ 0x7cac0839,
+ 0x57a1fde4,
+ 0x2da04cfc,
+ 0x93179aa5,
+ 0xf3f4d2d9,
+ 0xd8d2528a,
+ 0x5fdd42af,
+ 0xd08c7bdb,
+ 0x53acd639,
+ 0xe37aab85,
+ 0x2d55b5a2,
+ 0x7bc96248,
+ 0x2fb42401,
+ 0x2ff99915,
+ 0x2be3b5ea,
+ 0xf0ff9bdd,
+ 0x1b6bbaa3,
+ 0x83a13de0,
+ 0x4503fc83,
+ 0x08c24640,
+ 0x2463a2b2,
+ 0x2e264872,
+ 0xc451a29d,
+ 0xbfd2e09c,
+ 0x15bcb009,
+ 0x69102223,
+ 0x4c8581e9,
+ 0x4ec94cf0,
+ 0x75017d7b,
+ 0x0e5d8cf1,
+ 0x50b9ca97,
+ 0x55df1100,
+ 0x245162e0,
+ 0x0df18bca,
+ 0x00776990,
+ 0xf6790a03,
+ 0x599ef43e,
+ 0xe8bf7afb,
+ 0xea141ddc,
+ 0xad1a54b2,
+ 0x55f767f8,
+ 0xb661981c,
+ 0xe1650342,
+ 0x365adc95,
+ 0xbb44e3a0,
+ 0xa064fea1,
+ 0x3516bf27,
+ 0xfd40a414,
+ 0x53f9a9e6,
+ 0x2071a5ee,
+ 0x56ca2713,
+ 0x7afdd07a,
+ 0xd62b7f6e,
+ 0xe9dac904,
+ 0xca212105,
+ 0xb9d6e3de,
+ 0x6af5033f,
+ 0x34d9049b,
+ 0xc51ec095,
+ 0xe5eddb9d,
+ 0x122b5c6a,
+ 0x9f562e58,
+ 0x20ec8986,
+ 0x760857f2,
+ 0x8d8aadb3,
+ 0xbc8f0807,
+ 0x0f79eae7,
+ 0xbfa6bfa8,
+ 0x28151aeb,
+ 0xbe4b4d4b,
+ 0xc65d58b0,
+ 0xcf99ba1b,
+ 0xc1049197,
+ 0xe36d8c87,
+ 0x548b7676,
+ 0xbe7bb2c4,
+ 0x77923781,
+ 0x5fbd631e,
+ 0x770e5a41,
+ 0xd2f2948a,
+ 0x074f5428,
+ 0xc7a1562e,
+ 0xf55618c6,
+ 0x8bf8a3d1,
+ 0x837ed4a8,
+ 0xe42e0298,
+ 0xd3754b0c,
+ 0xbaa24c25,
+ 0x793ac973,
+ 0x814e66ec,
+ 0xa4154fa9,
+ 0x3e0e65ca,
+ 0x5a783bd5,
+ 0x2bb37f6c,
+ 0xb3c2526e,
+ 0x34c9a28a,
+ 0x6c8b4795,
+ 0x64605fa8,
+ 0x2e6aae2e,
+ 0xd9b28f27,
+ 0x6a9a200b,
+ 0x3acd1e3a,
+ 0xce9a4a6c,
+ 0xd2a0bd14,
+ 0x700f2003,
+ 0x501cbef7,
+ 0x4068b05e,
+ 0xa24c4580,
+ 0x4da75506,
+ 0x500b9b0f,
+ 0x22e3a600,
+ 0x7bec4e94,
+ 0x8f0958e2,
+ 0x42129a1e,
+ 0xb46d8dc5,
+ 0x29f8851c,
+ 0x83fb38bd,
+ 0x17b0de15,
+ 0x15340d20,
+ 0x74f00fde,
+ 0x6c646b32,
+ 0x905897c4,
+ 0x4d8ed991,
+ 0x3cf91fd5,
+ 0x0ee02ddf,
+ 0xec069ce6,
+ 0x0b977683,
+ 0xa0bf31f6,
+ 0xa1d135a9,
+ 0xa882d1db,
+ 0xa731a63a,
+ 0x48e211f1,
+ 0xf3d89e99,
+ 0xf982e6ea,
+ 0x23dde303,
+ 0x7f1ff8da,
+ 0xdc8c6414,
+ 0x806f432e,
+ 0xd047bc02,
+ 0x671bacff,
+ 0xd40ba2a8,
+ 0xe3666685,
+ 0x31265f9f,
+ 0x3931a952,
+ 0x62f35606,
+ 0xc48f0c5e,
+ 0xfd107640,
+ 0xf636da24,
+ 0xb8f5c3b0,
+ 0x1c91e88f,
+ 0xed9dd432,
+ 0x2b85fa5d,
+ 0x8b15d2ac,
+ 0x1e06cf24,
+ 0x1def6e9c,
+ 0xfae9175f,
+ 0x03ac6f02,
+ 0x37318c87,
+ 0xbc0b1ce5,
+ 0xa0640cab,
+ 0x6cc20a3c,
+ 0x1c7b2524,
+ 0x4685dacc,
+ 0xeab8bb31,
+ 0x8063b5d0,
+ 0x79817d52,
+ 0x211b1972,
+ 0xd7bfc987,
+ 0xab9128dc,
+ 0x150d9b36,
+ 0x6a5838ab,
+ 0x9a0a304d,
+ 0x2e43c331,
+ 0x84f2c4b8,
+ 0x435146c1,
+ 0xed64a280,
+ 0x553ecb4c,
+ 0x5c800db2,
+ 0xeef4df95,
+ 0x5dcf2c37,
+ 0x70755ddf,
+ 0x4274737b,
+ 0xe610350e,
+ 0xd97a5997,
+ 0x7af5edce,
+ 0xfd18ba0c,
+ 0xb7587cd8,
+ 0xfa5e42d6,
+ 0x76bde9eb,
+ 0xec41eead,
+ 0x604d2423,
+ 0xb4adbcf9,
+ 0xce728fa3,
+ 0x02361c31,
+ 0x02fab64d,
+ 0x00316b1c,
+ 0x562f9aa4,
+ 0x71f85790,
+ 0x9cb6d464,
+ 0x32949ebf,
+ 0x434fc23d,
+ 0xee7fac51,
+ 0xda5cc63a,
+ 0x17e616b4,
+ 0xcd1bd1bc,
+ 0x14638cae,
+ 0xd31808fa,
+ 0xb16e0727,
+ 0xfdda2b0f,
+ 0xbc11c678,
+ 0xfe79dc6e,
+ 0xe26eefb4,
+ 0x9a78de16,
+ 0xb68f2df2,
+ 0xd47da234,
+ 0xbdff28a4,
+ 0x937bb1f4,
+ 0x0786dd46,
+ 0xbd1160f5,
+ 0xf77b070c,
+ 0x72b7c51e,
+ 0xcbb3a371,
+ 0x5e50e904,
+ 0x00fbc379,
+ 0x680757dd,
+ 0xd38193f7,
+ 0x93113e25,
+ 0x7b258da7,
+ 0x991aaa09,
+ 0xab1415be,
+ 0xa3740774,
+ 0x370b72e5,
+ 0x2fc643f4,
+ 0x3916d70e,
+ 0xea2838d3,
+ 0xe4840c42,
+ 0xd18e6959,
+ 0x69a270ee,
+ 0xee4a494e,
+ 0x0329799b,
+ 0x07480357,
+ 0x0260c46f,
+ 0x7b75346e,
+ 0x787234f4,
+ 0xe0adf25b,
+ 0xba85cacf,
+ 0xb5724eb1,
+ 0xfde2c080,
+ 0x2b6bb492,
+ 0xd2f70545,
+ 0x9ca97510,
+ 0x4034c18f,
+ 0x616bcb12,
+ 0x5667f52a,
+ 0xe2f6bfce,
+ 0x1f25969e,
+ 0x569eaab7,
+ 0x27ad8196,
+ 0x2d30a6d0,
+ 0x96d6c10a,
+ 0xcb9f024f,
+ 0x3d7941ef,
+ 0xf7a76bc5,
+ 0xe9a701d4,
+ 0xd53293a3,
+ 0x252cf5df,
+ 0xaf9172f6,
+ 0xd090c809,
+ 0xb1a17387,
+ 0x045a0987,
+ 0x92d9ffd9,
+ 0xb30c449c,
+ 0x2180ff58,
+ 0x2929f7de,
+ 0x3f91766e,
+ 0x9f488e3d,
+ 0x05dd6734,
+ 0x82482f5b,
+ 0x01da3ca2,
+ 0x42f33408,
+ 0xf8e3ba89,
+ 0x750ac2ff,
+ 0x39f11551,
+ 0x71087971,
+ 0x368fa634,
+ 0xefda0572,
+ 0x14b8f750,
+ 0xe5768705,
+ 0x71c168e2,
+ 0x8c012c63,
+ 0x12ad74ce,
+ 0x841c17ea,
+ 0xe6f44176,
+ 0x36cf2557,
+ 0x14760a6d,
+ 0x4bb3b7c2,
+ 0x14d1437d,
+ 0xbe673210,
+ 0x4d6ba9f5,
+ 0xe68abbf9,
+ 0xc311908d,
+ 0x46b63956,
+ 0xac2c9fb3,
+ 0xab769ce8,
+ 0xa29d7040,
+ 0xec3d67e3,
+ 0xdef311de,
+ 0x52a53b14,
+ 0xca924769,
+ 0xf35d1514,
+ 0x524b0471,
+ 0xc0d08591,
+ 0x454fc34c,
+ 0xca719639,
+ 0x9af2f230,
+ 0xa023a821,
+ 0x3d6539ba,
+ 0x90d0d7a2,
+ 0xc65fc56e,
+ 0x4eb2aa19,
+ 0xeba3b0e7,
+ 0x1bb5b33e,
+ 0xab8c68c2,
+ 0x0f1793d3,
+ 0xdcf176e9,
+ 0x1b7bbba0,
+ 0x96170a27,
+ 0x1955452d,
+ 0x42e88c71,
+ 0x48cad4b3,
+ 0xdcc36042,
+ 0x90619951,
+ 0x7566bc7c,
+ 0xe14ba224,
+ 0xc24ad73d,
+ 0xdb04144d,
+ 0xd9792727,
+ 0x11150943,
+ 0xe45f0c57,
+ 0xb87d184e,
+ 0x3cf13243,
+ 0x2010d95c,
+ 0x84c347c1,
+ 0x6d0f2461,
+ 0xb5c41194,
+ 0xde7ccb2e,
+ 0xb929ecb0,
+ 0x51fbd8f7,
+ 0x45dc65fb,
+ 0x6902d2c0,
+ 0xb940814f,
+ 0xf339e083,
+ 0x6f370d56,
+ 0xcaf5638e,
+ 0xe8a3cb83,
+ 0xacf414b6,
+ 0xe61095a1,
+ 0x99b4cde4,
+ 0x55112fed,
+ 0x606b9d53,
+ 0x5a05974a,
+ 0xa4c7db34,
+ 0xdc92469b,
+ 0xf9280621,
+ 0xe7b1ef95,
+ 0xc0fc5be8,
+ 0x74a1da09,
+ 0xa92a4b7f,
+ 0x3d65d75e,
+ 0xe3804335,
+ 0x1ff49e19,
+ 0x71da8170,
+ 0xac69069b,
+ 0x04aae3d5,
+ 0xc0ef4b46,
+ 0x091a3482,
+ 0x8356c7ae,
+ 0x32ecb208,
+ 0x900c89ed,
+ 0x2a206ff5,
+ 0x7eed5032,
+ 0x5b55b25d,
+ 0xf98d6df2,
+ 0xf52bc8a9,
+ 0x1aa2f5fe,
+ 0x1d33c0bf,
+ 0x3cd34e89,
+ 0x9a0da4ae,
+ 0x1c205917,
+ 0x7ca784cd,
+ 0xf7dda662,
+ 0xad97f3ff,
+ 0x525c53ec,
+ 0x024f11ff,
+ 0x32c3ae5b,
+ 0xbf372800,
+ 0x8ff15f4d,
+ 0x7605d019,
+ 0x0dae7740,
+ 0x5f5dd0ef,
+ 0x0f6c37d0,
+ 0xee6fa91e,
+ 0xb9f51051,
+ 0x39a9f0d1,
+ 0x22bf03fb,
+ 0x485a0922,
+ 0x7384b30e,
+ 0x85ba7f16,
+ 0xb1f0a524,
+ 0x7e9c5113,
+ 0x240d9306,
+ 0x1ca7b0ea,
+ 0x18a0d114,
+ 0x76b64213,
+ 0x31212cc0,
+ 0xc9dca5c3,
+ 0x69f2ae52,
+ 0x545caa7c,
+ 0xfb2ff045,
+ 0x3f3a1af5,
+ 0xe75b6913,
+ 0x775a1c79,
+ 0x4627e25f,
+ 0x90a14b97,
+ 0x06456383,
+ 0x3d52cf69,
+ 0xfb2492c3,
+ 0x39f25a22,
+ 0x81f68c55,
+ 0x87b14e15,
+ 0x0920af5d,
+ 0xe2585678,
+ 0x0671e46d,
+ 0xb77ddb67,
+ 0x3948c4b3,
+ 0x122dddef,
+ 0xd0726172,
+ 0xd3302234,
+ 0x58bab4e4,
+ 0x195ac247,
+ 0x082459f0,
+ 0x18a2566d,
+ 0xbf56078d,
+ 0x116ed409,
+ 0x5ccc0f80,
+ 0xbae0b4ca,
+ 0x21a6325d,
+ 0x7e1f0c40,
+ 0x595326d4,
+ 0x518b2244,
+ 0x8ab3cdb7,
+ 0xbe6b4835,
+ 0xfc39f8ac,
+ 0x63b167aa,
+ 0x194f070d,
+ 0xed3d0416,
+ 0xae16758a,
+ 0xb9bb6bbf,
+ 0x477d9c85,
+ 0x9808c304,
+ 0xe1d8cec4,
+ 0x7ee22e17,
+ 0x0a7a9d7f,
+ 0xcc98173a,
+ 0x5f78dc21,
+ 0x364bc95e,
+ 0xb54608d9,
+ 0x5d4d70ea,
+ 0x083a7f79,
+ 0x59ffbd73,
+ 0x4f3e9eaf,
+ 0x68755ad4,
+ 0xab254689,
+ 0x11bf09a8,
+ 0xbbc40098,
+ 0x969ca3eb,
+ 0x30eee9d2,
+ 0xe35bc37e,
+ 0xcb2d678f,
+ 0x7846876b,
+ 0xf0d28ae7,
+ 0xc092fbb2,
+ 0x321b344a,
+ 0xcc5ee81b,
+ 0xd2afa00f,
+ 0xfeccd86a,
+ 0x6e5e55c2,
+ 0x2b5543ea,
+ 0x810e4009,
+ 0xea2d8e20,
+ 0x6acae3b9,
+ 0x3828e15e,
+ 0xe1e4821c,
+ 0xf429da70,
+ 0x35f6565c,
+ 0x64b1baa8,
+ 0x350e9583,
+ 0xd2522d4f,
+ 0x5e28a3f1,
+ 0x949ff0aa,
+ 0x3c1b5694,
+ 0x146dde1f,
+ 0x6f3430e1,
+ 0x71c077b7,
+ 0x4d145924,
+ 0xe431cd28,
+ 0xb315cfde,
+ 0xa0365a4a,
+ 0x473de1aa,
+ 0xcbe4e999,
+ 0x319906e9,
+ 0xad0fea9c,
+ 0x89e4e72d,
+ 0x9dbba94d,
+ 0xd395c1c5,
+ 0xa1fff11a,
+ 0x8447e120,
+ 0xe5c59100,
+ 0xa07cb778,
+ 0x8f30a039,
+ 0xed78facb,
+ 0x86de9373,
+ 0x550c4889,
+ 0xce71e3a8,
+ 0x06167b3a,
+ 0x5abdd9a3,
+ 0xc8a9e48d,
+ 0xe3312905,
+ 0x7a63a146,
+ 0xc0f19763,
+ 0xda0cf9db,
+ 0x1d708306,
+ 0x0e41f0ba,
+ 0x4c7939fe,
+ 0x768e48c2,
+ 0xe925fd31,
+ 0x309e7870,
+ 0xfc261b87,
+ 0xc897b2de,
+ 0x6c714792,
+ 0x41c7fbac,
+ 0x57d0b3c3,
+ 0x4fa82a55,
+ 0xd56b4a87,
+ 0x81e5cabc,
+ 0xb260cb7b,
+ 0x520927ab,
+ 0x20d0ab46,
+ 0xc9f92ddf,
+ 0x81f4a21d,
+ 0xfc5a0ca2,
+ 0x95d16aad,
+ 0xe54d7847,
+ 0x6080cc07,
+ 0x0df73f7e,
+ 0xaa8d5187,
+ 0x97a0bc12,
+ 0xb22c5e68,
+ 0x0954d7dc,
+ 0x3368ab5a,
+ 0xd12541df,
+ 0x58119260,
+ 0xe5b0e1df,
+ 0x25027fa4,
+ 0x5780425d,
+ 0x29bb8791,
+ 0x4100b7a9,
+ 0x076b3519,
+ 0x15e0ebb4,
+ 0xe5fb9273,
+ 0x6dbf07e7,
+ 0x1f82bddd,
+ 0x03691b6b,
+ 0xbacef28c,
+ 0x9909ed5a,
+ 0x98886793,
+ 0x544f9a82,
+ 0x9d9749d0,
+ 0x38441606,
+ 0xc4a9f4d2,
+ 0x6ce2bcf1,
+ 0x1c7c3abd,
+ 0x62c621f1,
+ 0x871ee1e4,
+ 0xa83930ce,
+ 0xbe1ee459,
+ 0xd61f1ca4,
+ 0x8c4450e5,
+ 0x98031ca9,
+ 0xe52f54e2,
+ 0xd0c4c737,
+ 0x76074160,
+ 0xbf050c3b,
+ 0x2603af14,
+ 0x43cbb0bc,
+ 0xc631b9e8,
+ 0x26030719,
+ 0x993f570c,
+ 0xdda34038,
+ 0xe34a9793,
+ 0x337a124c,
+ 0x2aa8af16,
+ 0xf80d7473,
+ 0xf01d9397,
+ 0x68e1afb9,
+ 0x0eb37ad2,
+ 0xf71969f9,
+ 0xdf020552,
+ 0x75aa9b30,
+ 0xffa210cf,
+ 0x543c414f,
+ 0xa1e3faec,
+ 0x40891d7e,
+ 0x6b48a6c5,
+ 0xec09a1a0,
+ 0x97a31f2a,
+ 0x5a6be2d7,
+ 0xd06e492b,
+ 0xc54290af,
+ 0xcb524021,
+ 0x420e8c4d,
+ 0xfb135c17,
+ 0x2bfc8adb,
+ 0x9f0cfb46,
+ 0x564db712,
+ 0x7a97a227,
+ 0x8bb98daf,
+ 0xdd0d6180,
+ 0x3d28b9e3,
+ 0xe505050f,
+ 0x19a9868e,
+ 0x7bf5685f,
+ 0x35d698c4,
+ 0xce7e1de3,
+ 0x360a64af,
+ 0x25a1f022,
+ 0xe26c1d04,
+ 0x5b3fb364,
+ 0x932f25f7,
+ 0x9a2aa00d,
+ 0xc50fb773,
+ 0xec45ea3a,
+ 0x22ddf8e4,
+ 0xafb6a6c8,
+ 0x876d04f7,
+ 0xd9c86c3c,
+ 0xd54bee2d,
+ 0xf4e28199,
+ 0xc3456776,
+ 0x04c3107b,
+ 0xbf914e9d,
+ 0x23fefaa5,
+ 0x0931a133,
+ 0x41467758,
+ 0x8ec49707,
+ 0x5ed48709,
+ 0xd11c2de8,
+ 0xb687a0b9,
+ 0xdc908383,
+ 0xd8037ff3,
+ 0xd4311a9f,
+ 0xd00aeb6a,
+ 0xfe54df3b,
+ 0x9c51ce4d,
+ 0x36956408,
+ 0xcd28ef09,
+ 0xc68932b0,
+ 0x7c31e782,
+ 0x28b4723c,
+ 0xededacc2,
+ 0x6ddbac6b,
+ 0x775a7fc1,
+ 0x6909906f,
+ 0xa774123c,
+ 0xf63145ad,
+ 0x287b191e,
+ 0x59d79300,
+ 0xbf76a2fc,
+ 0xfbaf9207,
+ 0x2fe5b7f6,
+ 0xebe7c103,
+ 0x71ac0a8d,
+ 0x2028c3c7,
+ 0xd2cb4917,
+ 0xd74a4ee4,
+ 0xfce405d8,
+ 0xad83fd0f,
+ 0x8f9ec3da,
+ 0xaab2301c,
+ 0xc6f1339f,
+ 0xc652bced,
+ 0xe378b272,
+ 0x18e1ff34,
+ 0x9ec778b6,
+ 0xce1a3883,
+ 0x7c5e5eaf,
+ 0xd16ec37a,
+ 0xa69e45f4,
+ 0xc36cd4aa,
+ 0x045b391f,
+ 0x5a2a08f1,
+ 0x4dd8d53e,
+ 0xd64796ec,
+ 0x4476fc28,
+ 0x18dbaa50,
+ 0x00fb2407,
+ 0x177db915,
+ 0x5969758b,
+ 0x3030964a,
+ 0x81d6485b,
+ 0x7d2e12b0,
+ 0x624d6c5f,
+ 0x0746bbc0,
+ 0xe669d150,
+ 0x0465eef7,
+ 0x09764011,
+ 0x551995e4,
+ 0x8422dedf,
+ 0x0ca56194,
+ 0x293eab2e,
+ 0xf20a137a,
+ 0x55117fc2,
+ 0xbc5431af,
+ 0x064751fa,
+ 0xc0dafdb2,
+ 0x6c3b1d4f,
+ 0xeac335b3,
+ 0x71173afc,
+ 0x31c84b7c,
+ 0xfef2b4ab,
+ 0x59ca5fa2,
+ 0x664c8b4e,
+ 0x7dfd560b,
+ 0xdb0daff3,
+ 0x51f87bfa,
+ 0x58015d2e,
+ 0x67a827b4,
+ 0x62cebc1a,
+ 0x24b37298,
+ 0x75b589be,
+ 0x874f1800,
+ 0x277b795c,
+ 0xf762489e,
+ 0x87d00752,
+ 0x9be45ed1,
+ 0x296ec120,
+ 0x61162480,
+ 0x792e8a2c,
+ 0x3b631590,
+ 0xe33ba0cf,
+ 0x542ac23c,
+ 0xe1e8cffa,
+ 0xfc084cd8,
+ 0xc115ad31,
+ 0x71559928,
+ 0x791f1e33,
+ 0x662ed92b,
+ 0x7222c76d,
+ 0x02dcd566,
+ 0x8db9b4d4,
+ 0xa5f344c8,
+ 0x15806b12,
+ 0x81e572f7,
+ 0x3b3fbe25,
+ 0x2133b413,
+ 0x2d68a367,
+ 0x356f6ce7,
+ 0xcd6dfed1,
+ 0xd8b3a26e,
+ 0xe9d328da,
+ 0x127425ab,
+ 0x83a60aac,
+ 0x8cc26190,
+ 0x7f87ab26,
+ 0x56faab5f,
+ 0x76d0feaa,
+ 0x4b25dd10,
+ 0x4f6286ea,
+ 0x79298d06,
+ 0x8002bf83,
+ 0x2977c85e,
+ 0xd3b3d19a,
+ 0xa92bf132,
+ 0xa280efd8,
+ 0x83f7ad6e,
+ 0x748969c7,
+ 0x25ff411d,
+ 0x3854d3a8,
+ 0x55746aa2,
+ 0x00db5c54,
+ 0x36949e0d,
+ 0x40402ab6,
+ 0x1a720211,
+ 0xe02ce823,
+ 0x4ac104a2,
+ 0x214d2e4b,
+ 0x267e5c83,
+ 0x38a3a483,
+ 0xd1da1f67,
+ 0x0c68db2c,
+ 0xd7035d63,
+ 0xa29393bb,
+ 0xa5743519,
+ 0xcb97c84e,
+ 0xa853974f,
+ 0x147360a0,
+ 0x2df9b3f4,
+ 0x0aff129e,
+ 0x177d687f,
+ 0x87eff911,
+ 0x6c60b354,
+ 0x6c356c38,
+ 0x7d480965,
+ 0xbb06a193,
+ 0x25b0568e,
+ 0x6fd6da9a,
+ 0x82b64f14,
+ 0x3d267a78,
+ 0xf100b6a7,
+ 0x32c74539,
+ 0x6042e152,
+ 0x4548276e,
+ 0xa3a32b70,
+ 0xf029fe15,
+ 0xa9b8bd2f,
+ 0x5618eee4,
+ 0x9815a5f0,
+ 0x89fb2850,
+ 0xa9261b26,
+ 0xded9e505,
+ 0x37e9d749,
+ 0xdc4aeb78,
+ 0x9e634f7a,
+ 0xcf638d2d,
+ 0x6b679f92,
+ 0x2b64911d,
+ 0xe6d1312f,
+ 0x88b3e76a,
+ 0x56311f62,
+ 0x00916de7,
+ 0x39d0bc61,
+ 0x8ac09356,
+ 0x47abcfce,
+ 0x324cb73e,
+ 0xfadcd0a8,
+ 0x2f2fbca8,
+ 0x945eda22,
+ 0xba23cab1,
+ 0xf9fb4212,
+ 0x1fa71d45,
+ 0x867a034e,
+ 0x3bee5db1,
+ 0xf54adced,
+ 0x6633ba77,
+ 0xe1eb4f1e,
+ 0x97ef01f6,
+ 0x57fd3b32,
+ 0x5234d80d,
+ 0xe8ee95f3,
+ 0x5dc990bf,
+ 0xaba833e1,
+/* Dummy terminator */
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0,
+};
+
+
diff --git a/src/mainboard/supermicro/x6dhr_ig2/mptable.c b/src/mainboard/supermicro/x6dhr_ig2/mptable.c new file mode 100644 index 0000000000..61ece13f5a --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/mptable.c @@ -0,0 +1,219 @@ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "LNXI "; + static const char productid[12] = "X6DHR-iG "; + struct mp_config_table *mc; + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_pxhd_1; + unsigned char bus_pxhd_2; + unsigned char bus_pxhd_3; + unsigned char bus_pxhd_4; + unsigned char bus_ich5r_1; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* initially just the header */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* not yet computed */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet... */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + { + device_t dev; + + /* ich5r */ + dev = dev_find_slot(0, PCI_DEVFN(0x1e,0)); + if (dev) { + bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_isa++; + } + else { + printk_debug("ERROR - could not find PCI 0:1e.0, using defaults\n"); + + bus_ich5r_1 = 7; + bus_isa = 8; + } + /* pxhd-1 */ + dev = dev_find_slot(1, PCI_DEVFN(0x0,0)); + if (dev) { + bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.0, using defaults\n"); + + bus_pxhd_1 = 2; + } + /* pxhd-2 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,2)); + if (dev) { + bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 1:00.2, using defaults\n"); + + bus_pxhd_2 = 3; + } + + /* pxhd-3 */ + dev = dev_find_slot(0, PCI_DEVFN(0x4,0)); + if (dev) { + bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 0:04.0, using defaults\n"); + + bus_pxhd_3 = 5; + } + /* pxhd-4 */ + dev = dev_find_slot(0, PCI_DEVFN(0x06,0)); + if (dev) { + bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); + + } + else { + printk_debug("ERROR - could not find PCI 0:06.0, using defaults\n"); + + bus_pxhd_4 = 6; + } + + } + + /* define bus and isa numbers */ + for(bus_num = 0; bus_num < bus_isa; bus_num++) { + smp_write_bus(mc, bus_num, "PCI "); + } + smp_write_bus(mc, bus_isa, "ISA "); + + /* IOAPIC handling */ + + smp_write_ioapic(mc, 2, 0x20, 0xfec00000); + { + struct resource *res; + device_t dev; + /* pxhd apic 3 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x03, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.1\n"); + } + /* pxhd apic 4 */ + dev = dev_find_slot(1, PCI_DEVFN(0x00,3)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, 0x04, 0x20, res->base); + } + } + else { + printk_debug("ERROR - could not find IOAPIC PCI 1:00.3\n"); + } + } + /* ISA backward compatibility interrupts */ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x01, 0x02, 0x01); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, 0x02, 0x02); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x03, 0x02, 0x03); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x04, 0x02, 0x04); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x06, 0x02, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x76, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x08, 0x02, 0x08); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x09, 0x02, 0x09); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x77, 0x02, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x75, 0x02, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0c, 0x02, 0x0c); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0d, 0x02, 0x0d); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0e, 0x02, 0x0e); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x0f, 0x02, 0x0f); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x74, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7c, 0x02, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + 0x00, 0x7d, 0x02, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_1, 0x08, 0x03, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_1, 0x0c, 0x03, 0x06); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_1, 0x0d, 0x03, 0x07); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_2, 0x08, 0x04, 0x00); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_ich5r_1, 0x04, 0x02, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + bus_pxhd_4, 0x00, 0x02, 0x10); +#if 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + (bus_isa - 1), 0x04, 0x02, 0x10); +#endif + /* Standard local interrupt assignments */ +#if 0 + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x00); +#endif + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, + bus_isa, 0x00, MP_APIC_ALL, 0x01); + + /* There is no extension information... */ + + /* Compute the checksums */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk_debug("Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} + diff --git a/src/mainboard/supermicro/x6dhr_ig2/reset.c b/src/mainboard/supermicro/x6dhr_ig2/reset.c new file mode 100644 index 0000000000..874bfc4848 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/reset.c @@ -0,0 +1,40 @@ +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#ifndef __ROMCC__ +#include <device/device.h> +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) +#define PCI_DEV_INVALID 0 + +static inline device_t pci_locate_device(unsigned pci_id, device_t from) +{ + return dev_find_device(pci_id >> 16, pci_id & 0xffff, from); +} +#endif + +void soft_reset(void) +{ + outb(0x04, 0xcf9); +} +void hard_reset(void) +{ + outb(0x02, 0xcf9); + outb(0x06, 0xcf9); +} +void full_reset(void) +{ + device_t dev; + /* Enable power on after power fail... */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801ER_ISA), 0); + if (dev != PCI_DEV_INVALID) { + unsigned byte; + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + pci_write_config8(dev, 0xa4, byte); + + } + outb(0x0e, 0xcf9); +} + + diff --git a/src/mainboard/supermicro/x6dhr_ig2/watchdog.c b/src/mainboard/supermicro/x6dhr_ig2/watchdog.c new file mode 100644 index 0000000000..e9012a49f3 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/watchdog.c @@ -0,0 +1,99 @@ +#include <device/pnp_def.h> + +#define NSC_WD_DEV PNP_DEV(0x2e, 0xa) +#define NSC_WDBASE 0x600 +#define ICH5_WDBASE 0x400 +#define ICH5_GPIOBASE 0x500 + +static void disable_sio_watchdog(device_t dev) +{ +#if 0 + /* FIXME move me somewhere more appropriate */ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 1); + pnp_set_iobase(dev, PNP_IDX_IO0, NSC_WDBASE); + /* disable the sio watchdog */ + outb(0, NSC_WDBASE + 0); + pnp_set_enable(dev, 0); +#endif +} + +static void disable_ich5_watchdog(void) +{ + /* FIXME move me somewhere more appropriate */ + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + + /* Set and enable acpibase */ + pci_write_config32(dev, 0x40, ICH5_WDBASE | 1); + pci_write_config8(dev, 0x44, 0x10); + base = ICH5_WDBASE + 0x60; + + /* Set bit 11 in TCO1_CNT */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); +} + +static void disable_jarell_frb3(void) +{ +#if 0 + device_t dev; + unsigned long value, base; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("Missing ich5?"); + } + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 0); + pci_write_config16(dev, 0x04, value); + + /* Set gpio base */ + pci_write_config32(dev, 0x58, ICH5_GPIOBASE | 1); + base = ICH5_GPIOBASE; + + /* Enable GPIO Bar */ + value = pci_read_config32(dev, 0x5c); + value |= 0x10; + pci_write_config32(dev, 0x5c, value); + + /* Configure GPIO 48 and 40 as GPIO */ + value = inl(base + 0x30); + value |= (1 << 16) | ( 1 << 8); + outl(value, base + 0x30); + + /* Configure GPIO 48 as Output */ + value = inl(base + 0x34); + value &= ~(1 << 16); + outl(value, base + 0x34); + + /* Toggle GPIO 48 high to low */ + value = inl(base + 0x38); + value |= (1 << 16); + outl(value, base + 0x38); + value &= ~(1 << 16); + outl(value, base + 0x38); +#endif +} + +static void disable_watchdogs(void) +{ +// disable_sio_watchdog(NSC_WD_DEV); + disable_ich5_watchdog(); +// disable_jarell_frb3(); + print_debug("Watchdogs disabled\r\n"); +} + diff --git a/src/mainboard/supermicro/x6dhr_ig2/x6dhr2_fixups.c b/src/mainboard/supermicro/x6dhr_ig2/x6dhr2_fixups.c new file mode 100644 index 0000000000..82c070b0c1 --- /dev/null +++ b/src/mainboard/supermicro/x6dhr_ig2/x6dhr2_fixups.c @@ -0,0 +1,23 @@ +#include <arch/romcc_io.h> + +static void mch_reset(void) +{ + return; +} + + + +static void mainboard_set_e7520_pll(unsigned bits) +{ + return; +} + + +static void mainboard_set_e7520_leds(void) +{ + return; +} + + + + diff --git a/src/mainboard/tyan/s2735/Config.lb b/src/mainboard/tyan/s2735/Config.lb index 568bc9b211..3977db16b9 100644 --- a/src/mainboard/tyan/s2735/Config.lb +++ b/src/mainboard/tyan/s2735/Config.lb @@ -43,7 +43,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o if USE_DCACHE_RAM if CONFIG_USE_INIT diff --git a/src/mainboard/tyan/s2735/Options.lb b/src/mainboard/tyan/s2735/Options.lb index 16b23a66bd..ada1beb593 100644 --- a/src/mainboard/tyan/s2735/Options.lb +++ b/src/mainboard/tyan/s2735/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -92,21 +89,16 @@ default HAVE_FALLBACK_BOOT=1 ## default HAVE_HARD_RESET=1 -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - ## Delay timer options ## default CONFIG_UDELAY_TSC=1 default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1 - ## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 -default IRQ_SLOT_COUNT=11 +default IRQ_SLOT_COUNT=15 ## ## Build code to export an x86 MP table @@ -148,8 +140,8 @@ default SERIAL_CPU_INIT=0 ## enable CACHE_AS_RAM specifics ## default USE_DCACHE_RAM=1 -default DCACHE_RAM_BASE=0xF2000000 -#default DCACHE_RAM_BASE=0xcf000 +#default DCACHE_RAM_BASE=0xF2000000 +default DCACHE_RAM_BASE=0xcf000 default DCACHE_RAM_SIZE=0x1000 #default CONFIG_USE_INIT=1 diff --git a/src/mainboard/tyan/s2735/reset.c b/src/mainboard/tyan/s2735/reset.c new file mode 100644 index 0000000000..3cc3d54988 --- /dev/null +++ b/src/mainboard/tyan/s2735/reset.c @@ -0,0 +1,5 @@ + +void hard_reset(void) +{ + i82801er_hard_reset(); +} diff --git a/src/mainboard/tyan/s2850/Config.lb b/src/mainboard/tyan/s2850/Config.lb index 89de7dba33..df8788233b 100644 --- a/src/mainboard/tyan/s2850/Config.lb +++ b/src/mainboard/tyan/s2850/Config.lb @@ -39,9 +39,33 @@ arch i386 end ## driver mainboard.o + +#dir /drivers/si/3114 + if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o + +if USE_DCACHE_RAM + +if CONFIG_USE_INIT + +makerule ./auto.o + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o auto.o" +end + +else + +makerule ./auto.inc + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@" + action "perl -e 's/.rodata/.rom.data/g' -pi $@" + action "perl -e 's/.text/.section .rom.text/g' -pi $@" +end + +end +else ## ## Romcc output @@ -65,13 +89,22 @@ makerule ./auto.inc action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" end +end ## ## Build our 16 bit and 32 bit linuxBIOS entry code ## mainboardinit cpu/x86/16bit/entry16.inc mainboardinit cpu/x86/32bit/entry32.inc ldscript /cpu/x86/16bit/entry16.lds -ldscript /cpu/x86/32bit/entry32.lds +if USE_DCACHE_RAM + if CONFIG_USE_INIT + ldscript /cpu/x86/32bit/entry32.lds + end + + if CONFIG_USE_INIT + ldscript /cpu/amd/car/cache_as_ram.lds + end +end ## ## Build our reset vector (This is where linuxBIOS is entered) @@ -84,8 +117,11 @@ else ldscript /cpu/x86/32bit/reset32.lds end +if USE_DCACHE_RAM +else ### Should this be in the northbridge code? mainboardinit arch/i386/lib/cpu_reset.inc +end ## ## Include an id string (For safe flashing) @@ -93,14 +129,25 @@ mainboardinit arch/i386/lib/cpu_reset.inc mainboardinit arch/i386/lib/id.inc ldscript /arch/i386/lib/id.lds +if USE_DCACHE_RAM +## +## Setup Cache-As-Ram +## +mainboardinit cpu/amd/car/cache_as_ram.inc +end + ### ### This is the early phase of linuxBIOS startup ### Things are delicate and we test to see if we should ### failover to another image. ### if USE_FALLBACK_IMAGE - ldscript /arch/i386/lib/failover.lds - mainboardinit ./failover.inc +if USE_DCACHE_RAM + ldscript /arch/i386/lib/failover.lds +else + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end end ### @@ -110,6 +157,19 @@ end ## ## Setup RAM ## +if USE_DCACHE_RAM + +if CONFIG_USE_INIT +initobject auto.o +else +mainboardinit ./auto.inc +end + +else + +## +## Setup RAM +## mainboardinit cpu/x86/fpu/enable_fpu.inc mainboardinit cpu/x86/mmx/enable_mmx.inc mainboardinit cpu/x86/sse/enable_sse.inc @@ -117,11 +177,13 @@ mainboardinit ./auto.inc mainboardinit cpu/x86/sse/disable_sse.inc mainboardinit cpu/x86/mmx/disable_mmx.inc +end + ## ## Include the secondary Configuration files ## if CONFIG_CHIP_NAME - config chip.h + config chip.h end # sample config for tyan/s2850 diff --git a/src/mainboard/tyan/s2850/Options.lb b/src/mainboard/tyan/s2850/Options.lb index c9b56b2811..646293e20e 100644 --- a/src/mainboard/tyan/s2850/Options.lb +++ b/src/mainboard/tyan/s2850/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -45,9 +42,9 @@ uses DEFAULT_CONSOLE_LOGLEVEL uses MAXIMUM_CONSOLE_LOGLEVEL uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL uses CONFIG_CONSOLE_SERIAL8250 -uses CONFIG_CONSOLE_BTEXT uses HAVE_INIT_TIMER uses CONFIG_GDB_STUB +uses CONFIG_GDB_STUB uses CROSS_COMPILE uses CC uses HOSTCC @@ -57,6 +54,9 @@ uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN uses K8_E0_MEM_HOLE_SIZEK +uses USE_DCACHE_RAM +uses DCACHE_RAM_BASE +uses DCACHE_RAM_SIZE uses CONFIG_USE_INIT ### @@ -84,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=2 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 @@ -119,20 +112,29 @@ default LB_CKS_LOC=123 ## Only worry about 2 micro processors ## default CONFIG_SMP=1 -default CONFIG_MAX_CPUS=1 +default CONFIG_MAX_CPUS=2 default CONFIG_MAX_PHYSICAL_CPUS=1 -default CONFIG_LOGICAL_CPUS=0 +default CONFIG_LOGICAL_CPUS=1 + +#CHIP_NAME ? +default CONFIG_CHIP_NAME=1 #1G memory hole default K8_E0_MEM_HOLE_SIZEK=0x100000 -#BTEXT CONSOLE -#default CONFIG_CONSOLE_BTEXT=1 - -#VGA +#VGA Console default CONFIG_CONSOLE_VGA=1 default CONFIG_PCI_ROM_RUN=1 + +## +## enable CACHE_AS_RAM specifics +## +default USE_DCACHE_RAM=1 +default DCACHE_RAM_BASE=0xcf000 +default DCACHE_RAM_SIZE=0x1000 +default CONFIG_USE_INIT=1 + ## ## Build code to setup a generic IOAPIC ## @@ -141,7 +143,7 @@ default CONFIG_IOAPIC=1 ## ## Clean up the motherboard id strings ## -default MAINBOARD_PART_NUMBER="s2850" +default MAINBOARD_PART_NUMBER="S2850" default MAINBOARD_VENDOR="Tyan" default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2850 @@ -231,9 +233,9 @@ default TTYS0_LCS=0x3 ## SPEW 9 Way too many details ## Request this level of debugging output -default DEFAULT_CONSOLE_LOGLEVEL=7 +default DEFAULT_CONSOLE_LOGLEVEL=8 ## At a maximum only compile in this level of debugging -default MAXIMUM_CONSOLE_LOGLEVEL=7 +default MAXIMUM_CONSOLE_LOGLEVEL=8 ## ## Select power on after power fail setting diff --git a/src/mainboard/tyan/s2850/auto.c b/src/mainboard/tyan/s2850/auto.c index 9220738d87..0b9012aca8 100644 --- a/src/mainboard/tyan/s2850/auto.c +++ b/src/mainboard/tyan/s2850/auto.c @@ -25,21 +25,52 @@ #include "cpu/x86/bist.h" #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} static void hard_reset(void) { - set_bios_reset(); + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3); + + set_bios_reset(); - /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x02, 3), 0x41, 0xf1); - /* reset */ - outb(0x0e, 0x0cf9); + /* enable cf9 */ + pci_write_config8(dev, 0x41, 0xf1); + /* reset */ + outb(0x0e, 0x0cf9); } static void soft_reset(void) { - set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x02, 0), 0x47, 1); + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0); + + set_bios_reset(); + pci_write_config8(dev, 0x47, 1); } #define REV_B_RESET 0 diff --git a/src/mainboard/tyan/s2850/mptable.c b/src/mainboard/tyan/s2850/mptable.c index 6a28ecbe79..fe175795e2 100644 --- a/src/mainboard/tyan/s2850/mptable.c +++ b/src/mainboard/tyan/s2850/mptable.c @@ -7,6 +7,42 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -16,6 +52,7 @@ void *smp_write_config_table(void *v) unsigned char bus_num; unsigned char bus_isa; + unsigned char bus_chain_0; unsigned char bus_8111_1; unsigned apicid_base; unsigned apicid_8111; @@ -41,8 +78,14 @@ void *smp_write_config_table(void *v) { device_t dev; + /* HT chain 0 */ + bus_chain_0 = node_link_to_bus(0, 0); + if (bus_chain_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_chain_0 = 1; + } /* 8111 */ - dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); @@ -89,7 +132,7 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (2<<2)|3, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (2<<2)|3, apicid_8111, 0x13); //On Board AMD USB smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); diff --git a/src/mainboard/tyan/s2850/reset.c b/src/mainboard/tyan/s2850/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/tyan/s2850/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/tyan/s2875/Config.lb b/src/mainboard/tyan/s2875/Config.lb index f042467f5c..bd61fcb34f 100644 --- a/src/mainboard/tyan/s2875/Config.lb +++ b/src/mainboard/tyan/s2875/Config.lb @@ -39,11 +39,34 @@ arch i386 end ## driver mainboard.o + +#dir /drivers/si/3114 + if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o + +if USE_DCACHE_RAM +if CONFIG_USE_INIT + +makerule ./auto.o + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o auto.o" +end +else + +makerule ./auto.inc + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@" + action "perl -e 's/.rodata/.rom.data/g' -pi $@" + action "perl -e 's/.text/.section .rom.text/g' -pi $@" +end + +end +else + ## ## Romcc output ## @@ -66,13 +89,22 @@ makerule ./auto.inc action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" end +end ## ## Build our 16 bit and 32 bit linuxBIOS entry code ## mainboardinit cpu/x86/16bit/entry16.inc mainboardinit cpu/x86/32bit/entry32.inc ldscript /cpu/x86/16bit/entry16.lds -ldscript /cpu/x86/32bit/entry32.lds +if USE_DCACHE_RAM + if CONFIG_USE_INIT + ldscript /cpu/x86/32bit/entry32.lds + end + + if CONFIG_USE_INIT + ldscript /cpu/amd/car/cache_as_ram.lds + end +end ## ## Build our reset vector (This is where linuxBIOS is entered) @@ -85,8 +117,11 @@ else ldscript /cpu/x86/32bit/reset32.lds end +if USE_DCACHE_RAM +else ### Should this be in the northbridge code? mainboardinit arch/i386/lib/cpu_reset.inc +end ## ## Include an id string (For safe flashing) @@ -94,14 +129,25 @@ mainboardinit arch/i386/lib/cpu_reset.inc mainboardinit arch/i386/lib/id.inc ldscript /arch/i386/lib/id.lds +if USE_DCACHE_RAM +## +## Setup Cache-As-Ram +## +mainboardinit cpu/amd/car/cache_as_ram.inc +end + ### ### This is the early phase of linuxBIOS startup ### Things are delicate and we test to see if we should ### failover to another image. ### if USE_FALLBACK_IMAGE - ldscript /arch/i386/lib/failover.lds - mainboardinit ./failover.inc +if USE_DCACHE_RAM + ldscript /arch/i386/lib/failover.lds +else + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end end ### @@ -111,6 +157,19 @@ end ## ## Setup RAM ## +if USE_DCACHE_RAM + +if CONFIG_USE_INIT +initobject auto.o +else +mainboardinit ./auto.inc +end + +else + +## +## Setup RAM +## mainboardinit cpu/x86/fpu/enable_fpu.inc mainboardinit cpu/x86/mmx/enable_mmx.inc mainboardinit cpu/x86/sse/enable_sse.inc @@ -118,11 +177,13 @@ mainboardinit ./auto.inc mainboardinit cpu/x86/sse/disable_sse.inc mainboardinit cpu/x86/mmx/disable_mmx.inc +end + ## ## Include the secondary Configuration files ## if CONFIG_CHIP_NAME - config chip.h + config chip.h end # sample config for tyan/s2875 diff --git a/src/mainboard/tyan/s2875/Options.lb b/src/mainboard/tyan/s2875/Options.lb index 5851318be6..a584d1b436 100644 --- a/src/mainboard/tyan/s2875/Options.lb +++ b/src/mainboard/tyan/s2875/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -47,6 +44,7 @@ uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL uses CONFIG_CONSOLE_SERIAL8250 uses HAVE_INIT_TIMER uses CONFIG_GDB_STUB +uses CONFIG_GDB_STUB uses CROSS_COMPILE uses CC uses HOSTCC @@ -56,6 +54,9 @@ uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN uses K8_E0_MEM_HOLE_SIZEK +uses USE_DCACHE_RAM +uses DCACHE_RAM_BASE +uses DCACHE_RAM_SIZE uses CONFIG_USE_INIT ### @@ -83,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=5 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 @@ -118,16 +112,28 @@ default LB_CKS_LOC=123 ## Only worry about 2 micro processors ## default CONFIG_SMP=1 -default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_CPUS=4 default CONFIG_MAX_PHYSICAL_CPUS=2 -default CONFIG_LOGICAL_CPUS=0 +default CONFIG_LOGICAL_CPUS=1 + +#CHIP_NAME ? +default CONFIG_CHIP_NAME=1 #1G memory hole default K8_E0_MEM_HOLE_SIZEK=0x100000 #VGA Console -#default CONFIG_CONSOLE_VGA=1 -#default CONFIG_PCI_ROM_RUN=1 +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 + + +## +## enable CACHE_AS_RAM specifics +## +default USE_DCACHE_RAM=1 +default DCACHE_RAM_BASE=0xcf000 +default DCACHE_RAM_SIZE=0x1000 +default CONFIG_USE_INIT=1 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/tyan/s2875/auto.c b/src/mainboard/tyan/s2875/auto.c index 1b055bf2ec..7b75db20ab 100644 --- a/src/mainboard/tyan/s2875/auto.c +++ b/src/mainboard/tyan/s2875/auto.c @@ -27,20 +27,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x05, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x05, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -141,6 +173,7 @@ static void main(unsigned long bist) asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(id.nodeid); +// start_other_core(id.nodeid); } #else nodeid = lapicid(); @@ -155,7 +188,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } diff --git a/src/mainboard/tyan/s2875/mptable.c b/src/mainboard/tyan/s2875/mptable.c index 9b93decd80..394410b5ba 100644 --- a/src/mainboard/tyan/s2875/mptable.c +++ b/src/mainboard/tyan/s2875/mptable.c @@ -7,6 +7,40 @@ #include <cpu/amd/dualcore.h> #endif +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -16,6 +50,7 @@ void *smp_write_config_table(void *v) unsigned char bus_num; unsigned char bus_isa; + unsigned char bus_chain_0; unsigned char bus_8111_1; unsigned char bus_8151_1; unsigned apicid_base; @@ -43,8 +78,15 @@ void *smp_write_config_table(void *v) { device_t dev; + /* HT chain 0 */ + bus_chain_0 = node_link_to_bus(0, 0); + if (bus_chain_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_chain_0 = 1; + } + /* 8111 */ - dev = dev_find_slot(1, PCI_DEVFN(0x04,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x04,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); @@ -58,7 +100,7 @@ void *smp_write_config_table(void *v) bus_isa = 4; } /* 8151 */ - dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0)); if (dev) { bus_8151_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); printk_debug("bus_8151_1=%d\n",bus_8151_1); @@ -105,9 +147,9 @@ void *smp_write_config_table(void *v) //??? What - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (5<<2)|3, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (5<<2)|3, apicid_8111, 0x13); //Onboard AMD AC97 Audio ??? - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (5<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (5<<2)|1, apicid_8111, 0x11); // Onboard AMD USB smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); diff --git a/src/mainboard/tyan/s2875/reset.c b/src/mainboard/tyan/s2875/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/tyan/s2875/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/tyan/s2880/Config.lb b/src/mainboard/tyan/s2880/Config.lb index 6c4ac7b7c1..f7ad508347 100644 --- a/src/mainboard/tyan/s2880/Config.lb +++ b/src/mainboard/tyan/s2880/Config.lb @@ -39,10 +39,33 @@ arch i386 end ## driver mainboard.o + +#dir /drivers/si/3114 + if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o + +if USE_DCACHE_RAM + +if CONFIG_USE_INIT + +makerule ./auto.o + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o auto.o" +end + +else + +makerule ./auto.inc + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@" + action "perl -e 's/.rodata/.rom.data/g' -pi $@" + action "perl -e 's/.text/.section .rom.text/g' -pi $@" +end +end +else ## ## Romcc output @@ -66,13 +89,22 @@ makerule ./auto.inc action "./romcc -mcpu=k8 -O2 -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@" end +end ## ## Build our 16 bit and 32 bit linuxBIOS entry code ## mainboardinit cpu/x86/16bit/entry16.inc mainboardinit cpu/x86/32bit/entry32.inc ldscript /cpu/x86/16bit/entry16.lds -ldscript /cpu/x86/32bit/entry32.lds +if USE_DCACHE_RAM + if CONFIG_USE_INIT + ldscript /cpu/x86/32bit/entry32.lds + end + + if CONFIG_USE_INIT + ldscript /cpu/amd/car/cache_as_ram.lds + end +end ## ## Build our reset vector (This is where linuxBIOS is entered) @@ -85,8 +117,11 @@ else ldscript /cpu/x86/32bit/reset32.lds end +if USE_DCACHE_RAM +else ### Should this be in the northbridge code? mainboardinit arch/i386/lib/cpu_reset.inc +end ## ## Include an id string (For safe flashing) @@ -94,14 +129,25 @@ mainboardinit arch/i386/lib/cpu_reset.inc mainboardinit arch/i386/lib/id.inc ldscript /arch/i386/lib/id.lds +if USE_DCACHE_RAM +## +## Setup Cache-As-Ram +## +mainboardinit cpu/amd/car/cache_as_ram.inc +end + ### ### This is the early phase of linuxBIOS startup ### Things are delicate and we test to see if we should ### failover to another image. ### if USE_FALLBACK_IMAGE - ldscript /arch/i386/lib/failover.lds - mainboardinit ./failover.inc +if USE_DCACHE_RAM + ldscript /arch/i386/lib/failover.lds +else + ldscript /arch/i386/lib/failover.lds + mainboardinit ./failover.inc +end end ### @@ -111,6 +157,19 @@ end ## ## Setup RAM ## +if USE_DCACHE_RAM + +if CONFIG_USE_INIT +initobject auto.o +else +mainboardinit ./auto.inc +end + +else + +## +## Setup RAM +## mainboardinit cpu/x86/fpu/enable_fpu.inc mainboardinit cpu/x86/mmx/enable_mmx.inc mainboardinit cpu/x86/sse/enable_sse.inc @@ -118,11 +177,13 @@ mainboardinit ./auto.inc mainboardinit cpu/x86/sse/disable_sse.inc mainboardinit cpu/x86/mmx/disable_mmx.inc +end + ## ## Include the secondary Configuration files ## if CONFIG_CHIP_NAME - config chip.h + config chip.h end # sample config for tyan/s2880 diff --git a/src/mainboard/tyan/s2880/Options.lb b/src/mainboard/tyan/s2880/Options.lb index a6b4e86f50..1f929b0edc 100644 --- a/src/mainboard/tyan/s2880/Options.lb +++ b/src/mainboard/tyan/s2880/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -47,6 +44,7 @@ uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL uses CONFIG_CONSOLE_SERIAL8250 uses HAVE_INIT_TIMER uses CONFIG_GDB_STUB +uses CONFIG_GDB_STUB uses CROSS_COMPILE uses CC uses HOSTCC @@ -56,6 +54,9 @@ uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN uses K8_E0_MEM_HOLE_SIZEK +uses USE_DCACHE_RAM +uses DCACHE_RAM_BASE +uses DCACHE_RAM_SIZE uses CONFIG_USE_INIT ### @@ -83,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 @@ -122,6 +116,9 @@ default CONFIG_MAX_CPUS=2 default CONFIG_MAX_PHYSICAL_CPUS=2 default CONFIG_LOGICAL_CPUS=0 +#CHIP_NAME ? +default CONFIG_CHIP_NAME=1 + #1G memory hole default K8_E0_MEM_HOLE_SIZEK=0x100000 @@ -129,6 +126,15 @@ default K8_E0_MEM_HOLE_SIZEK=0x100000 default CONFIG_CONSOLE_VGA=1 default CONFIG_PCI_ROM_RUN=1 + +## +## enable CACHE_AS_RAM specifics +## +default USE_DCACHE_RAM=1 +default DCACHE_RAM_BASE=0xcf000 +default DCACHE_RAM_SIZE=0x1000 +default CONFIG_USE_INIT=1 + ## ## Build code to setup a generic IOAPIC ## @@ -137,7 +143,7 @@ default CONFIG_IOAPIC=1 ## ## Clean up the motherboard id strings ## -default MAINBOARD_PART_NUMBER="s2880" +default MAINBOARD_PART_NUMBER="S2880" default MAINBOARD_VENDOR="Tyan" default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2880 diff --git a/src/mainboard/tyan/s2880/auto.c b/src/mainboard/tyan/s2880/auto.c index 1ed43bc19e..2532386132 100644 --- a/src/mainboard/tyan/s2880/auto.c +++ b/src/mainboard/tyan/s2880/auto.c @@ -27,20 +27,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -155,7 +187,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } @@ -179,8 +211,4 @@ static void main(unsigned long bist) soft_reset(); } - enable_smbus(); - memreset_setup(); - sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); - } diff --git a/src/mainboard/tyan/s2880/irq_tables.c b/src/mainboard/tyan/s2880/irq_tables.c index 4ffc5cffa0..08c51795fd 100644 --- a/src/mainboard/tyan/s2880/irq_tables.c +++ b/src/mainboard/tyan/s2880/irq_tables.c @@ -37,5 +37,5 @@ const struct irq_routing_table intel_irq_routing_table = { }; unsigned long write_pirq_routing_table(unsigned long addr) { - return copy_pirq_routing_table(addr); + return copy_pirq_routing_table(addr); } diff --git a/src/mainboard/tyan/s2880/mptable.c b/src/mainboard/tyan/s2880/mptable.c index 9c4764a77b..d013a463fa 100644 --- a/src/mainboard/tyan/s2880/mptable.c +++ b/src/mainboard/tyan/s2880/mptable.c @@ -7,6 +7,42 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -16,6 +52,7 @@ void *smp_write_config_table(void *v) unsigned char bus_num; unsigned char bus_isa; + unsigned char bus_chain_0; unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; @@ -45,9 +82,16 @@ void *smp_write_config_table(void *v) { device_t dev; + + /* HT chain 0 */ + bus_chain_0 = node_link_to_bus(0, 0); + if (bus_chain_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_chain_0 = 1; + } /* 8111 */ - dev = dev_find_slot(1, PCI_DEVFN(0x03,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); @@ -60,7 +104,7 @@ void *smp_write_config_table(void *v) bus_isa = 5; } /* 8131-1 */ - dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0)); if (dev) { bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -71,7 +115,7 @@ void *smp_write_config_table(void *v) bus_8131_1 = 2; } /* 8131-2 */ - dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0)); if (dev) { bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -105,14 +149,14 @@ void *smp_write_config_table(void *v) device_t dev; struct resource *res; - dev = dev_find_slot(1, PCI_DEVFN(0x1,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x1,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } - dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { @@ -137,7 +181,7 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (4<<2)|0, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (4<<2)|0, apicid_8111, 0x13); //On Board AMD USB diff --git a/src/mainboard/tyan/s2880/reset.c b/src/mainboard/tyan/s2880/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/tyan/s2880/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/tyan/s2881/Config.lb b/src/mainboard/tyan/s2881/Config.lb index 2e564ce9ea..02c6ec8255 100644 --- a/src/mainboard/tyan/s2881/Config.lb +++ b/src/mainboard/tyan/s2881/Config.lb @@ -44,8 +44,7 @@ driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o - +object reset.o if USE_DCACHE_RAM if CONFIG_USE_INIT @@ -67,6 +66,7 @@ end end else + ## ## Romcc output ## diff --git a/src/mainboard/tyan/s2881/Options.lb b/src/mainboard/tyan/s2881/Options.lb index 84fa34e568..38eb3be4ef 100644 --- a/src/mainboard/tyan/s2881/Options.lb +++ b/src/mainboard/tyan/s2881/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -87,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/tyan/s2881/auto.c b/src/mainboard/tyan/s2881/auto.c index 391be78879..fc622793d3 100644 --- a/src/mainboard/tyan/s2881/auto.c +++ b/src/mainboard/tyan/s2881/auto.c @@ -27,20 +27,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -155,7 +187,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } diff --git a/src/mainboard/tyan/s2881/cache_as_ram_auto.c b/src/mainboard/tyan/s2881/cache_as_ram_auto.c index 5ac861d5da..bb037a4f61 100644 --- a/src/mainboard/tyan/s2881/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s2881/cache_as_ram_auto.c @@ -13,6 +13,7 @@ #include "arch/i386/lib/console.c" #include "ram/ramtest.c" + #include "northbridge/amd/amdk8/cpu_rev.c" #define K8_HT_FREQ_1G_SUPPORT 0 #include "northbridge/amd/amdk8/incoherent_ht.c" @@ -37,20 +38,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -93,6 +126,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 @@ -136,7 +171,6 @@ void amd64_main(unsigned long bist) } /* Is this a secondary cpu? */ -// post_code(0x21); if (!boot_cpu()) { if (last_boot_normal()) { goto normal_image; @@ -154,7 +188,6 @@ void amd64_main(unsigned long bist) amd8111_enable_rom(); /* Is this a deliberate reset by the bios */ -// post_code(0x22); if (bios_reset_detected() && last_boot_normal()) { goto normal_image; } @@ -166,13 +199,11 @@ void amd64_main(unsigned long bist) goto fallback_image; } normal_image: -// post_code(0x23); __asm__ volatile ("jmp __normal_image" : /* outputs */ : "a" (bist) /* inputs */ ); cpu_reset: -// post_code(0x24); #if 0 //CPU reset will reset memtroller ??? asm volatile ("jmp __cpu_reset" @@ -182,7 +213,6 @@ void amd64_main(unsigned long bist) #endif fallback_image: -// post_code(0x25); real_main(bist); } void real_main(unsigned long bist) @@ -275,17 +305,13 @@ void amd64_main(unsigned long bist) report_bist_failure(bist); setup_s2881_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif - needs_reset |= ht_setup_chains_x(); if (needs_reset) { @@ -294,20 +320,10 @@ void amd64_main(unsigned long bist) } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif -#if 0 - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif - #if 1 { /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ @@ -324,6 +340,8 @@ void amd64_main(unsigned long bist) } #endif +#if 1 + cpu_reset_x: @@ -386,6 +404,7 @@ cpu_reset_x: copy_and_run(new_cpu_reset); /* We will not return */ } +#endif print_debug("should not be here -\r\n"); diff --git a/src/mainboard/tyan/s2881/mptable.c b/src/mainboard/tyan/s2881/mptable.c index 06f1301ee5..ee92919db8 100644 --- a/src/mainboard/tyan/s2881/mptable.c +++ b/src/mainboard/tyan/s2881/mptable.c @@ -7,6 +7,41 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -16,6 +51,7 @@ void *smp_write_config_table(void *v) unsigned char bus_num; unsigned char bus_isa; + unsigned char bus_chain_0; unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; @@ -46,9 +82,16 @@ void *smp_write_config_table(void *v) { device_t dev; + + /* HT chain 0 */ + bus_chain_0 = node_link_to_bus(0, 2); + if (bus_chain_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_chain_0 = 1; + } /* 8111 */ - dev = dev_find_slot(1, PCI_DEVFN(0x03,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); @@ -61,7 +104,7 @@ void *smp_write_config_table(void *v) bus_isa = 5; } /* 8131-1 */ - dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0)); if (dev) { bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -72,7 +115,7 @@ void *smp_write_config_table(void *v) bus_8131_1 = 2; } /* 8131-2 */ - dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0)); if (dev) { bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -106,14 +149,14 @@ void *smp_write_config_table(void *v) { device_t dev; struct resource *res; - dev = dev_find_slot(1, PCI_DEVFN(0x1,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x1,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } - dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { @@ -138,7 +181,7 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); //8111 LPC ???? - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (4<<2)|0, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (4<<2)|0, apicid_8111, 0x13); //On Board AMD USB ??? smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); diff --git a/src/mainboard/tyan/s2881/reset.c b/src/mainboard/tyan/s2881/reset.c new file mode 100644 index 0000000000..63958185f6 --- /dev/null +++ b/src/mainboard/tyan/s2881/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 2); +} diff --git a/src/mainboard/tyan/s2882/Config.lb b/src/mainboard/tyan/s2882/Config.lb index 7739a67ca6..6f71a49864 100644 --- a/src/mainboard/tyan/s2882/Config.lb +++ b/src/mainboard/tyan/s2882/Config.lb @@ -44,7 +44,7 @@ driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o if USE_DCACHE_RAM @@ -278,36 +278,37 @@ chip northbridge/amd/amdk8/root_complex end device pci 1.1 on end device pci 1.2 on end - device pci 1.3 on -# chip drivers/generic/generic #dimm 0-0-0 -# device i2c 50 on end -# end -# chip drivers/generic/generic #dimm 0-0-1 -# device i2c 51 on end -# end -# chip drivers/generic/generic #dimm 0-1-0 -# device i2c 52 on end -# end -# chip drivers/generic/generic #dimm 0-1-1 -# device i2c 53 on end -# end -# chip drivers/generic/generic #dimm 1-0-0 -# device i2c 54 on end -# end -# chip drivers/generic/generic #dimm 1-0-1 -# device i2c 55 on end -# end -# chip drivers/generic/generic #dimm 1-1-0 -# device i2c 56 on end -# end -# chip drivers/generic/generic #dimm 1-1-1 -# device i2c 57 on end -# end + device pci 1.3 on end + device pci 1.3 on +# chip drivers/generic/generic #dimm 0-0-0 +# device i2c 50 on end +# end +# chip drivers/generic/generic #dimm 0-0-1 +# device i2c 51 on end +# end +# chip drivers/generic/generic #dimm 0-1-0 +# device i2c 52 on end +# end +# chip drivers/generic/generic #dimm 0-1-1 +# device i2c 53 on end +# end +# chip drivers/generic/generic #dimm 1-0-0 +# device i2c 54 on end +# end +# chip drivers/generic/generic #dimm 1-0-1 +# device i2c 55 on end +# end +# chip drivers/generic/generic #dimm 1-1-0 +# device i2c 56 on end +# end +# chip drivers/generic/generic #dimm 1-1-1 +# device i2c 57 on end +# end end # acpi device pci 1.5 off end device pci 1.6 off end - register "ide0_enable" = "1" - register "ide1_enable" = "1" + register "ide0_enable" = "1" + register "ide1_enable" = "1" end end # device pci 18.0 diff --git a/src/mainboard/tyan/s2882/Options.lb b/src/mainboard/tyan/s2882/Options.lb index 1249719210..ffa34c4f08 100644 --- a/src/mainboard/tyan/s2882/Options.lb +++ b/src/mainboard/tyan/s2882/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -87,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=1 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 @@ -153,7 +143,7 @@ default CONFIG_IOAPIC=1 ## ## Clean up the motherboard id strings ## -default MAINBOARD_PART_NUMBER="s2882" +default MAINBOARD_PART_NUMBER="S2882" default MAINBOARD_VENDOR="Tyan" default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2882 diff --git a/src/mainboard/tyan/s2882/auto.c b/src/mainboard/tyan/s2882/auto.c index fb7a63abb5..910db9e8a5 100644 --- a/src/mainboard/tyan/s2882/auto.c +++ b/src/mainboard/tyan/s2882/auto.c @@ -27,20 +27,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3); + set_bios_reset(); - + /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } #define REV_B_RESET 0 @@ -64,7 +96,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -160,7 +191,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } @@ -176,7 +207,6 @@ static void main(unsigned long bist) #if CONFIG_LOGICAL_CPUS==1 start_other_cores(); #endif - // automatically set that for you, but you might meet tight space needs_reset |= ht_setup_chains_x(); if (needs_reset) { print_info("ht reset -\r\n"); diff --git a/src/mainboard/tyan/s2882/cache_as_ram_auto.c b/src/mainboard/tyan/s2882/cache_as_ram_auto.c index 1b3d77a206..f0adb4204b 100644 --- a/src/mainboard/tyan/s2882/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s2882/cache_as_ram_auto.c @@ -36,21 +36,52 @@ #include "northbridge/amd/amdk8/setup_resource_map.c" #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 0), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -93,6 +124,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 @@ -236,6 +269,7 @@ void amd64_main(unsigned long bist) #if CONFIG_LOGICAL_CPUS==1 if(id.coreid == 0) { if (cpu_init_detected(id.nodeid)) { +// __asm__ volatile ("jmp __cpu_reset"); cpu_reset = 1; goto cpu_reset_x; } @@ -249,7 +283,6 @@ void amd64_main(unsigned long bist) distinguish_cpu_resets(nodeid); #endif - if (!boot_cpu() #if CONFIG_LOGICAL_CPUS==1 || (id.coreid != 0) @@ -261,7 +294,6 @@ void amd64_main(unsigned long bist) } } - w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); @@ -270,14 +302,11 @@ void amd64_main(unsigned long bist) report_bist_failure(bist); setup_default_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif needs_reset |= ht_setup_chains_x(); @@ -288,21 +317,10 @@ void amd64_main(unsigned long bist) } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif -#if 0 - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif - - #if 1 { /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ @@ -319,6 +337,7 @@ void amd64_main(unsigned long bist) } #endif +#if 1 cpu_reset_x: @@ -382,6 +401,7 @@ cpu_reset_x: copy_and_run(new_cpu_reset); /* We will not return */ } +#endif print_debug("should not be here -\r\n"); diff --git a/src/mainboard/tyan/s2882/irq_tables.c b/src/mainboard/tyan/s2882/irq_tables.c index cdff230a2f..add22b4e03 100644 --- a/src/mainboard/tyan/s2882/irq_tables.c +++ b/src/mainboard/tyan/s2882/irq_tables.c @@ -1,301 +1,48 @@ -/* This file was generated by getpir.c, do not modify! - (but if you do, please run checkpir on it to verify) - Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up - - Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM -*/ -#include <console/console.h> -#include <device/pci.h> -#include <string.h> -#include <stdint.h> #include <arch/pirq_routing.h> +#include <device/pci.h> -const struct irq_routing_table intel_irq_routing_table = { - PIRQ_SIGNATURE, /* u32 signature */ - PIRQ_VERSION, /* u16 version */ - 32+16*15, /* there can be total 15 devices on the bus */ - 1, /* Where the interrupt router lies (bus) */ - (4<<3)|3, /* Where the interrupt router lies (dev) */ - 0, /* IRQs devoted exclusively to PCI usage */ - 0x1022, /* Vendor */ - 0x746b, /* Device */ - 0, /* Crap (miniport) */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ - 0xff, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structu -re (including checksum) */ - { - {1,(4<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0}, - {0x4,0, {{0, 0}, {0, 0}, {0, 0}, {0x4, 0xdef8}}, 0, 0}, - {0x4,(6<<3)|0, {{0x3, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0}, - {0x3,(3<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x1, 0}, - {0x3,(1<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x2, 0}, - {0x2,(3<<3)|0, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x3, 0}, - {0x2,(2<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0}, - {0x4,(4<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x5, 0}, - {0x4,(5<<3)|0, {{0x4, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0}, - {0x4,(8<<3)|0, {{0x3, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0}, - {0x2,(6<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0}, - {0x2,(5<<3)|0, {{0x3, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0, 0}}, 0, 0}, - {0x2,(9<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0}, - {0x3,(4<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x6, 0}, - {0x3,(5<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x7, 0}, - } -}; - -static unsigned node_link_to_bus(unsigned node, unsigned link) -{ - device_t dev; - unsigned reg; +#define IRQ_ROUTER_BUS 1 +#define IRQ_ROUTER_DEVFN PCI_DEVFN(4,3) +#define IRQ_ROUTER_VENDOR 0x1022 +#define IRQ_ROUTER_DEVICE 0x746b - dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); - if (!dev) { - return 0; - } - for(reg = 0xE0; reg < 0xF0; reg += 0x04) { - uint32_t config_map; - unsigned dst_node; - unsigned dst_link; - unsigned bus_base; - config_map = pci_read_config32(dev, reg); - if ((config_map & 3) != 3) { - continue; - } - dst_node = (config_map >> 4) & 7; - dst_link = (config_map >> 8) & 3; - bus_base = (config_map >> 16) & 0xff; -#if 0 - printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", - dst_node, dst_link, bus_base, - reg, config_map); -#endif - if ((dst_node == node) && (dst_link == link)) - { - return bus_base; - } - } - return 0; -} +#define AVAILABLE_IRQS 0xdef8 +#define IRQ_SLOT(slot, bus, dev, fn, linka, linkb, linkc, linkd) \ + { bus, (dev<<3)|fn, {{ linka, AVAILABLE_IRQS}, { linkb, AVAILABLE_IRQS}, \ + {linkc, AVAILABLE_IRQS}, {linkd, AVAILABLE_IRQS}}, slot, 0} -static void write_pirq_info(struct irq_info *pirq_info, uint8_t bus, uint8_t devfn, uint8_t link0, uint16_t bitmap0, - uint8_t link1, uint16_t bitmap1, uint8_t link2, uint16_t bitmap2,uint8_t link3, uint16_t bitmap3, - uint8_t slot, uint8_t rfu) -{ - pirq_info->bus = bus; - pirq_info->devfn = devfn; - pirq_info->irq[0].link = link0; - pirq_info->irq[0].bitmap = bitmap0; - pirq_info->irq[1].link = link1; - pirq_info->irq[1].bitmap = bitmap1; - pirq_info->irq[2].link = link2; - pirq_info->irq[2].bitmap = bitmap2; - pirq_info->irq[3].link = link3; - pirq_info->irq[3].bitmap = bitmap3; - pirq_info->slot = slot; - pirq_info->rfu = rfu; -} +/* Each IRQ_SLOT entry consists of: + * bus, devfn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu + */ +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32+16*IRQ_SLOT_COUNT, /* there can be total IRQ_SLOT_COUNT table entries */ + IRQ_ROUTER_BUS, /* Where the interrupt router lies (bus) */ + IRQ_ROUTER_DEVFN, /* Where the interrupt router lies (dev) */ + 0x00, /* IRQs devoted exclusively to PCI usage */ + IRQ_ROUTER_VENDOR, /* Vendor */ + IRQ_ROUTER_DEVICE, /* Device */ + 0x00, /* Crap (miniport) */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xb0, /* u8 checksum , mod 256 checksum must give zero */ + { /* slot(0=onboard), devfn, irqlinks (line id, 0=not routed) */ + /* PCI Slot 1-6 */ + IRQ_SLOT(1, 3,1,0, 2,3,4,1 ), + IRQ_SLOT(2, 3,2,0, 3,4,1,2 ), + IRQ_SLOT(3, 2,1,0, 2,3,4,1 ), + IRQ_SLOT(4, 2,2,0, 3,4,1,2 ), + IRQ_SLOT(5, 4,5,0, 2,3,4,1 ), + IRQ_SLOT(6, 4,4,0, 1,2,3,4 ), + /* Onboard NICs */ + IRQ_SLOT(0, 2,3,0, 4,0,0,0 ), + IRQ_SLOT(0, 2,4,0, 4,0,0,0 ), + /* Let Linux know about bus 1 */ + IRQ_SLOT(0, 1,4,3, 0,0,0,0 ), + } +}; unsigned long write_pirq_routing_table(unsigned long addr) { - - struct irq_routing_table *pirq; - struct irq_info *pirq_info; - unsigned slot_num; - uint8_t *v; - - uint8_t sum=0; - int i; - - unsigned char bus_chain_0; - unsigned char bus_8131_1; - unsigned char bus_8131_2; - unsigned char bus_8111_1; - { - device_t dev; - - /* HT chain 0 */ - bus_chain_0 = node_link_to_bus(0, 0); - if (bus_chain_0 == 0) { - printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); - bus_chain_0 = 1; - } - - /* 8111 */ - dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0)); - if (dev) { - bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); - } - else { - printk_debug("ERROR - could not find PCI 1:03.0, using defaults\n"); - - bus_8111_1 = 4; - } - /* 8131-1 */ - dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0)); - if (dev) { - bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); - - } - else { - printk_debug("ERROR - could not find PCI 1:01.0, using defaults\n"); - - bus_8131_1 = 2; - } - /* 8131-2 */ - dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0)); - if (dev) { - bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); - - } - else { - printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n"); - - bus_8131_2 = 3; - } - } - - /* Align the table to be 16 byte aligned. */ - addr += 15; - addr &= ~15; - - /* This table must be betweeen 0xf0000 & 0x100000 */ - printk_info("Writing IRQ routing tables to 0x%x...", addr); - - pirq = (void *)(addr); - v = (uint8_t *)(addr); - - pirq->signature = PIRQ_SIGNATURE; - pirq->version = PIRQ_VERSION; - - pirq->rtr_bus = bus_chain_0; - pirq->rtr_devfn = (4<<3)|3; - - pirq->exclusive_irqs = 0; - - pirq->rtr_vendor = 0x1022; - pirq->rtr_device = 0x746b; - - pirq->miniport_data = 0; - - memset(pirq->rfu, 0, sizeof(pirq->rfu)); - - pirq_info = (void *) ( &pirq->checksum + 1); - slot_num = 0; - - { - device_t dev; - dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x04,3)); - if (dev) { - /* initialize PCI interupts - these assignments depend - on the PCB routing of PINTA-D - - PINTA = IRQ5 - PINTB = IRQ9 - PINTC = IRQ11 - PINTD = IRQ10 - */ - pci_write_config16(dev, 0x56, 0xab95); - } - } - - printk_info("setting Onboard AMD Southbridge \n"); - static const unsigned char slotIrqs_1_4[4] = { 5, 9, 11, 10 }; - pci_assign_irqs(bus_chain_0, 4, slotIrqs_1_4); - write_pirq_info(pirq_info, bus_chain_0,(4<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0, 0); - pirq_info++; slot_num++; - - printk_info("setting Onboard AMD USB \n"); - static const unsigned char slotIrqs_8111_1_0[4] = { 0, 0, 0, 10 }; - pci_assign_irqs(bus_8111_1, 0, slotIrqs_8111_1_0); - write_pirq_info(pirq_info, bus_8111_1,0, 0, 0, 0, 0, 0, 0, 0x4, 0xdef8, 0, 0); - pirq_info++; slot_num++; - - printk_info("setting Onboard ATI Display Adapter\n"); - static const unsigned char slotIrqs_8111_1_6[4] = { 11, 0, 0, 0 }; - pci_assign_irqs(bus_8111_1, 6, slotIrqs_8111_1_6); - write_pirq_info(pirq_info, bus_8111_1,(6<<3)|0, 0x3, 0xdef8, 0, 0, 0, 0, 0, 0, 0, 0); - pirq_info++; slot_num++; - - printk_info("setting Slot 1\n"); - static const unsigned char slotIrqs_8131_2_3[4] = { 5, 9, 11, 10 }; - pci_assign_irqs(bus_8131_2, 3, slotIrqs_8131_2_3); - write_pirq_info(pirq_info, bus_8131_2,(3<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0); - pirq_info++; slot_num++; - - printk_info("setting Slot 2\n"); - static const unsigned char slotIrqs_8131_2_1[4] = { 9, 11, 10, 5 }; - pci_assign_irqs(bus_8131_2, 1, slotIrqs_8131_2_1); - write_pirq_info(pirq_info, bus_8131_2,(1<<3)|0, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0); - pirq_info++; slot_num++; - - printk_info("setting Slot 3\n"); - static const unsigned char slotIrqs_8131_1_3[4] = { 10, 5, 9, 11 }; - pci_assign_irqs(bus_8131_1, 3, slotIrqs_8131_1_3); - write_pirq_info(pirq_info, bus_8131_1,(3<<3)|0, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x3, 0); - pirq_info++; slot_num++; - - printk_info("setting Slot 4\n"); - static const unsigned char slotIrqs_8131_1_2[4] = { 11, 10, 5, 9 }; - pci_assign_irqs(bus_8131_1, 2, slotIrqs_8131_1_2); - write_pirq_info(pirq_info, bus_8131_1,(2<<3)|0, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0x4, 0); - pirq_info++; slot_num++; - - printk_info("setting Slot 5 \n"); - static const unsigned char slotIrqs_8111_1_4[4] = { 5, 9, 11, 10 }; - pci_assign_irqs(bus_8111_1, 4, slotIrqs_8111_1_4); - write_pirq_info(pirq_info, bus_8111_1,(4<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x5, 0); - pirq_info++; slot_num++; - - printk_info("setting Onboard SI Serail ATA\n"); - static const unsigned char slotIrqs_8111_1_5[4] = { 10, 0, 0, 0 }; - pci_assign_irqs(bus_8111_1, 5, slotIrqs_8111_1_5); - write_pirq_info(pirq_info, bus_8111_1,(5<<3)|0, 0x4, 0xdef8, 0, 0, 0, 0, 0, 0, 0, 0); - pirq_info++; slot_num++; - - printk_info("setting Onboard Intel NIC\n"); - static const unsigned char slotIrqs_8111_1_8[4] = { 11, 0, 0, 0 }; - pci_assign_irqs(bus_8111_1, 8, slotIrqs_8111_1_8); - write_pirq_info(pirq_info, bus_8111_1,(8<<3)|0, 0x3, 0xdef8, 0, 0, 0, 0, 0, 0, 0, 0); - pirq_info++; slot_num++; - - printk_info("setting Onboard Adaptec SCSI\n"); - static const unsigned char slotIrqs_8131_1_6[4] = { 5, 9, 0, 0 }; - pci_assign_irqs(bus_8131_1, 6, slotIrqs_8131_1_6); - write_pirq_info(pirq_info, bus_8131_1,(6<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0, 0, 0, 0, 0, 0); - pirq_info++; slot_num++; -#if 0 - //?? - write_pirq_info(pirq_info, bus_8131_1,(5<<3)|0, 0x3, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0, 0, 0, 0); - pirq_info++; slot_num++; -#endif - - printk_info("setting Onboard Broadcom NIC\n"); - static const unsigned char slotIrqs_8131_1_9[4] = { 5, 9, 0, 0 }; - pci_assign_irqs(bus_8131_1, 9, slotIrqs_8131_1_9); - write_pirq_info(pirq_info, bus_8131_1,(9<<3)|0, 0x1, 0xdef8, 0x2, 0xdef8, 0, 0, 0, 0, 0, 0); - pirq_info++; slot_num++; -#if 0 - //?? what's this? - write_pirq_info(pirq_info, bus_8131_2,(4<<3)|0, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x6, 0); - pirq_info++; slot_num++; -#endif - -#if 0 - //?? what's this? - write_pirq_info(pirq_info, bus_8131_2,(5<<3)|0, 0x3, 0xdef8, 0x4, 0xdef8, 0x1, 0xdef8, 0x2, 0xdef8, 0x7, 0); - pirq_info++; slot_num++; -#endif - - pirq->size = 32 + 16 * slot_num; - - for (i = 0; i < pirq->size; i++) - sum += v[i]; - - sum = pirq->checksum - sum; - - if (sum != pirq->checksum) { - pirq->checksum = sum; - } - - return (unsigned long) pirq_info; - + return copy_pirq_routing_table(addr); } diff --git a/src/mainboard/tyan/s2882/reset.c b/src/mainboard/tyan/s2882/reset.c new file mode 100644 index 0000000000..3db3956ec6 --- /dev/null +++ b/src/mainboard/tyan/s2882/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 0); +} diff --git a/src/mainboard/tyan/s2885/Config.lb b/src/mainboard/tyan/s2885/Config.lb index a29c713ac6..f6ea627f8b 100644 --- a/src/mainboard/tyan/s2885/Config.lb +++ b/src/mainboard/tyan/s2885/Config.lb @@ -44,7 +44,7 @@ driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o if USE_DCACHE_RAM @@ -66,7 +66,7 @@ end end else - + ## ## Romcc output ## diff --git a/src/mainboard/tyan/s2885/Options.lb b/src/mainboard/tyan/s2885/Options.lb index 7bc324e606..79d60a3e3b 100644 --- a/src/mainboard/tyan/s2885/Options.lb +++ b/src/mainboard/tyan/s2885/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -87,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=3 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/tyan/s2885/auto.c b/src/mainboard/tyan/s2885/auto.c index cff103b9cc..8275f6d5d7 100644 --- a/src/mainboard/tyan/s2885/auto.c +++ b/src/mainboard/tyan/s2885/auto.c @@ -26,20 +26,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { - set_bios_reset(); + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3); + + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -192,7 +224,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } @@ -223,4 +255,5 @@ static void main(unsigned long bist) sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); + } diff --git a/src/mainboard/tyan/s2885/cache_as_ram_auto.c b/src/mainboard/tyan/s2885/cache_as_ram_auto.c index 3d27071031..85d4da9227 100644 --- a/src/mainboard/tyan/s2885/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s2885/cache_as_ram_auto.c @@ -13,7 +13,6 @@ #include "arch/i386/lib/console.c" #include "ram/ramtest.c" - #include "northbridge/amd/amdk8/cpu_rev.c" #define K8_HT_FREQ_1G_SUPPORT 0 #include "northbridge/amd/amdk8/incoherent_ht.c" @@ -38,20 +37,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 2), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -103,6 +134,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 @@ -159,6 +192,7 @@ void amd64_main(unsigned long bist) enumerate_ht_chain(); + /* Setup the ck804 */ amd8111_enable_rom(); /* Is this a deliberate reset by the bios */ @@ -296,15 +330,10 @@ void amd64_main(unsigned long bist) uart_init(); console_init(); - /* Halt if there was a built in self test failure */ report_bist_failure(bist); setup_s2885_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif needs_reset = setup_coherent_ht_domain(); @@ -319,17 +348,10 @@ void amd64_main(unsigned long bist) } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif -#if 0 - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); - #if 1 { /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ diff --git a/src/mainboard/tyan/s2885/mptable.c b/src/mainboard/tyan/s2885/mptable.c index 2396ade53e..a9683d577c 100644 --- a/src/mainboard/tyan/s2885/mptable.c +++ b/src/mainboard/tyan/s2885/mptable.c @@ -7,6 +7,42 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -51,9 +87,14 @@ void *smp_write_config_table(void *v) { device_t dev; + /* HT chain 0 */ + bus_8151_0 = node_link_to_bus(0, 0); + if (bus_8151_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_8151_0 = 1; + } /* 8151 */ - bus_8151_0 = 1; - dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); + dev = dev_find_slot(bus_8151_0, PCI_DEVFN(0x02,0)); if (dev) { bus_8151_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); // printk_debug("bus_8151_1=%d\n",bus_8151_1); diff --git a/src/mainboard/tyan/s2885/reset.c b/src/mainboard/tyan/s2885/reset.c new file mode 100644 index 0000000000..63958185f6 --- /dev/null +++ b/src/mainboard/tyan/s2885/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 2); +} diff --git a/src/mainboard/tyan/s2891/Config.lb b/src/mainboard/tyan/s2891/Config.lb index 53a7fee36e..6341926115 100644 --- a/src/mainboard/tyan/s2891/Config.lb +++ b/src/mainboard/tyan/s2891/Config.lb @@ -346,12 +346,13 @@ chip northbridge/amd/amdk8/root_complex end # pci_domain # chip drivers/generic/debug # device pnp 0.0 off end # chip name -# device pnp 0.1 on end # pci_regs_all +# device pnp 0.1 off end # pci_regs_all # device pnp 0.2 off end # mem # device pnp 0.3 off end # cpuid -# device pnp 0.4 on end # smbus_regs_all +# device pnp 0.4 off end # smbus_regs_all # device pnp 0.5 off end # dual core msr # device pnp 0.6 off end # cache size # device pnp 0.7 off end # tsc +# device pnp 0.8 on end # hard_reset # end end # root_complex diff --git a/src/mainboard/tyan/s2891/Options.lb b/src/mainboard/tyan/s2891/Options.lb index 7147c69d76..58b052e33d 100644 --- a/src/mainboard/tyan/s2891/Options.lb +++ b/src/mainboard/tyan/s2891/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -92,10 +89,6 @@ default HAVE_FALLBACK_BOOT=1 ## default HAVE_HARD_RESET=1 -#default HARD_RESET_BUS=1 -#default HARD_RESET_DEVICE=4 -#default HARD_RESET_FUNCTION=0 - ## ## Build code to export a programmable irq routing table ## @@ -134,7 +127,7 @@ default K8_E0_MEM_HOLE_SIZEK=0x100000 #CK804 setting -default CK804_DEVN_BASE=0 +#default CK804_DEVN_BASE=0 #BTEXT Console #default CONFIG_CONSOLE_BTEXT=1 diff --git a/src/mainboard/tyan/s2891/auto.c b/src/mainboard/tyan/s2891/auto.c index 4a8ef3f952..4637b4e9c6 100644 --- a/src/mainboard/tyan/s2891/auto.c +++ b/src/mainboard/tyan/s2891/auto.c @@ -87,7 +87,6 @@ static inline int spd_read_byte(unsigned device, unsigned address) #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) #define CK804_NUM 1 -#include "southbridge/nvidia/ck804/ck804_early_setup.h" #include "southbridge/nvidia/ck804/ck804_early_setup_ss.h" #include "southbridge/nvidia/ck804/ck804_early_setup.c" @@ -136,6 +135,7 @@ static void main(unsigned long bist) enable_lapic(); init_timer(); + #if CONFIG_LOGICAL_CPUS==1 id = get_node_core_id_x(); if(id.coreid == 0) { @@ -152,16 +152,19 @@ static void main(unsigned long bist) distinguish_cpu_resets(nodeid); #endif + post_code(0x31); if (!boot_cpu() #if CONFIG_LOGICAL_CPUS==1 || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } + post_code(0x32); + w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); @@ -174,6 +177,7 @@ static void main(unsigned long bist) needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif needs_reset |= ht_setup_chains_x(); @@ -190,5 +194,4 @@ static void main(unsigned long bist) memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); - } diff --git a/src/mainboard/tyan/s2891/cache_as_ram_auto.c b/src/mainboard/tyan/s2891/cache_as_ram_auto.c index ba2dfc1f8c..b78a899764 100644 --- a/src/mainboard/tyan/s2891/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s2891/cache_as_ram_auto.c @@ -15,6 +15,7 @@ #include "northbridge/amd/amdk8/cpu_rev.c" //#define K8_HT_FREQ_1G_SUPPORT 1 +//#define K8_SCAN_PCI_BUS 1 #include "northbridge/amd/amdk8/incoherent_ht.c" #include "southbridge/nvidia/ck804/ck804_early_smbus.c" #include "northbridge/amd/amdk8/raminit.h" @@ -84,6 +85,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 @@ -259,6 +262,7 @@ void amd64_main(unsigned long bist) goto cpu_reset_x; } distinguish_cpu_resets(id.nodeid); +// start_other_core(id.nodeid); } #else if (cpu_init_detected(nodeid)) { @@ -292,16 +296,14 @@ void amd64_main(unsigned long bist) report_bist_failure(bist); setup_s2891_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif + // automatically set that for you, but you might meet tight space needs_reset |= ht_setup_chains_x(); needs_reset |= ck804_early_setup_x(); @@ -312,20 +314,10 @@ void amd64_main(unsigned long bist) } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif -#if 0 - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif - #if 1 { /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ @@ -342,6 +334,7 @@ void amd64_main(unsigned long bist) } #endif +#if 1 cpu_reset_x: @@ -386,7 +379,7 @@ cpu_reset_x: "movl %%ebx, %0\n\t" :"=a" (new_cpu_reset) ); - + /* We can not go back any more, we lost old stack data in cache as ram*/ if(new_cpu_reset==0) { print_debug("Use Ram as Stack now - done\r\n"); @@ -404,6 +397,7 @@ cpu_reset_x: copy_and_run(new_cpu_reset); /* We will not return */ } +#endif print_debug("should not be here -\r\n"); diff --git a/src/mainboard/tyan/s2891/irq_tables.c b/src/mainboard/tyan/s2891/irq_tables.c index d6f75a0950..0d880a23f6 100644 --- a/src/mainboard/tyan/s2891/irq_tables.c +++ b/src/mainboard/tyan/s2891/irq_tables.c @@ -18,7 +18,11 @@ const struct irq_routing_table intel_irq_routing_table = { 0x005c, /* Device */ 0, /* Crap (miniport) */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ +#if CK804_DEVN_BASE==0 0x5a, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */ +#else + 0x4a, +#endif { {1,((CK804_DEVN_BASE+9)<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0}, {0x5,(1<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0, 0}, diff --git a/src/mainboard/tyan/s2891/mptable.c b/src/mainboard/tyan/s2891/mptable.c index e8d5f4ccc9..e62ec6eef1 100644 --- a/src/mainboard/tyan/s2891/mptable.c +++ b/src/mainboard/tyan/s2891/mptable.c @@ -7,6 +7,41 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -52,22 +87,60 @@ void *smp_write_config_table(void *v) { device_t dev; + bus_ck804_0 = node_link_to_bus(0, 0); + if (bus_ck804_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_ck804_0 = 1; + } /* CK804 */ - bus_ck804_0 = 1; dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0)); if (dev) { bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); +#if 0 + bus_ck804_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_2++; +#else bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); bus_ck804_4++; +#endif } else { printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09); bus_ck804_1 = 2; +#if 0 + bus_ck804_2 = 3; +#else bus_ck804_4 = 3; +#endif } +#if 0 + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0)); + if (dev) { + bus_ck804_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_3++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0b); + + bus_ck804_3 = bus_ck804_2+1; + } + + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0)); + if (dev) { + bus_ck804_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_4++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0c); + + bus_ck804_4 = bus_ck804_3+1; + } +#endif dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0)); if (dev) { bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -157,12 +230,9 @@ void *smp_write_config_table(void *v) pci_write_config32(dev, 0x7c, dword); dword = 0x12008a00; - - pci_write_config32(dev, 0x80, dword); dword = 0x0000007d; - pci_write_config32(dev, 0x84, dword); } @@ -199,40 +269,51 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_ck804, 0xf); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa); +// 10 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); // 21 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); // 20 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); // 23 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); // 22 -#if 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // +#if CK804_DEVN_BASE == 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 18 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // +#else + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x11); // 17 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x10); // #endif -#if 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // +#if CK804_DEVN_BASE == 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // 17 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x12); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x13); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x10); // +#else + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x10); // 16 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x11); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x13); // #endif - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); // 19 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0); //24+4+0 = 28 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x0); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x0); // 24 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x1);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x2);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x2); // 26 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, apicid_8131_1, 0x3);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|2, apicid_8131_1, 0x0);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|3, apicid_8131_1, 0x1);// diff --git a/src/mainboard/tyan/s2892/Options.lb b/src/mainboard/tyan/s2892/Options.lb index 20b58bce85..8a229a1269 100644 --- a/src/mainboard/tyan/s2892/Options.lb +++ b/src/mainboard/tyan/s2892/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -92,10 +89,6 @@ default HAVE_FALLBACK_BOOT=1 ## default HAVE_HARD_RESET=1 -#default HARD_RESET_BUS=1 -#default HARD_RESET_DEVICE=4 -#default HARD_RESET_FUNCTION=0 - ## ## Build code to export a programmable irq routing table ## diff --git a/src/mainboard/tyan/s2892/auto.c b/src/mainboard/tyan/s2892/auto.c index d2512e9f61..25967056de 100644 --- a/src/mainboard/tyan/s2892/auto.c +++ b/src/mainboard/tyan/s2892/auto.c @@ -142,7 +142,6 @@ static void main(unsigned long bist) enable_lapic(); init_timer(); - #if CONFIG_LOGICAL_CPUS==1 id = get_node_core_id_x(); if(id.coreid == 0) { @@ -150,6 +149,7 @@ static void main(unsigned long bist) asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(id.nodeid); +// start_other_core(id.nodeid); } #else nodeid = lapicid(); @@ -164,7 +164,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } @@ -174,13 +174,14 @@ static void main(unsigned long bist) console_init(); /* Halt if there was a built in self test failure */ - report_bist_failure(bist); +// report_bist_failure(bist); setup_s2892_resource_map(); needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif needs_reset |= ht_setup_chains_x(); diff --git a/src/mainboard/tyan/s2892/cache_as_ram_auto.c b/src/mainboard/tyan/s2892/cache_as_ram_auto.c index 30a78f5a96..5158bccf55 100644 --- a/src/mainboard/tyan/s2892/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s2892/cache_as_ram_auto.c @@ -86,6 +86,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 @@ -295,15 +297,10 @@ void amd64_main(unsigned long bist) report_bist_failure(bist); setup_s2892_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 - // It is said that we should start core1 after all core0 launched start_other_cores(); #endif needs_reset |= ht_setup_chains_x(); @@ -316,19 +313,10 @@ void amd64_main(unsigned long bist) } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif -#if 0 - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif #if 1 { @@ -346,6 +334,7 @@ void amd64_main(unsigned long bist) } #endif +#if 1 cpu_reset_x: @@ -408,6 +397,7 @@ cpu_reset_x: copy_and_run(new_cpu_reset); /* We will not return */ } +#endif print_debug("should not be here -\r\n"); diff --git a/src/mainboard/tyan/s2892/mptable.c b/src/mainboard/tyan/s2892/mptable.c index b4f26aaeba..02754a1b34 100644 --- a/src/mainboard/tyan/s2892/mptable.c +++ b/src/mainboard/tyan/s2892/mptable.c @@ -7,6 +7,41 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -52,22 +87,60 @@ void *smp_write_config_table(void *v) { device_t dev; + bus_ck804_0 = node_link_to_bus(0, 0); + if (bus_ck804_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_ck804_0 = 1; + } /* CK804 */ - bus_ck804_0 = 1; dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0)); if (dev) { bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); +#if 0 + bus_ck804_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_2++; +#else bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); bus_ck804_4++; +#endif } else { printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09); bus_ck804_1 = 2; +#if 0 + bus_ck804_2 = 3; +#else bus_ck804_4 = 3; +#endif } +#if 0 + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0)); + if (dev) { + bus_ck804_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_3++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0b); + + bus_ck804_3 = bus_ck804_2+1; + } + + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0)); + if (dev) { + bus_ck804_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_4++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0c); + + bus_ck804_4 = bus_ck804_3+1; + } +#endif dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0)); if (dev) { bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -152,6 +225,8 @@ void *smp_write_config_table(void *v) smp_write_ioapic(mc, apicid_ck804, 0x11, res->base); } + /* Initialize interrupt mapping*/ + dword = 0x0000d218; pci_write_config32(dev, 0x7c, dword); @@ -195,57 +270,77 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_ck804, 0xf); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa); +// 10 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); // 21 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); // 20 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); // 23 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); // 22 -#if 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // +#if CK804_DEVN_BASE == 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 18 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // +#else + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x11); // 17 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x10); // #endif -#if 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // +#if CK804_DEVN_BASE == 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); // 17 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x12); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x13); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x10); // +#else + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x10); // 16 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x11); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x13); // #endif - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (6<<2)|0, apicid_ck804, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (8<<2)|0, apicid_ck804, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // 16 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // 17 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // 18 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // 19 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (6<<2)|0, apicid_ck804, 0x12); // 18 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (8<<2)|0, apicid_ck804, 0x12); // 18 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0);// +//Channel B of 8131 + + +//Onboard Broadcom NIC + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0);//24+4= 28 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (7<<2)|0, apicid_8131_2, 0x0);// +//SO DIMM PCI-X + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (7<<2)|0, apicid_8131_2, 0x0);//28 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (7<<2)|1, apicid_8131_2, 0x1); - - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x2); // +//Slot 4 PCIX 133/100/66 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x2); // 30 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, apicid_8131_2, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, apicid_8131_2, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, apicid_8131_2, 0x0);// 28 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, apicid_8131_1, 0x3); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, apicid_8131_1, 0x0);// +//Channel A of 8131 + +//Slot 5 PCIX 133/100/66 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, apicid_8131_1, 0x3); //28 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, apicid_8131_1, 0x0);//24 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|2, apicid_8131_1, 0x1);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|3, apicid_8131_1, 0x2);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); // +//Slot 6 PCIX 133/100/66 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); // 27 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|1, apicid_8131_1, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, apicid_8131_1, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, apicid_8131_1, 0x0);// 24 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|3, apicid_8131_1, 0x1);// diff --git a/src/mainboard/tyan/s2895/Options.lb b/src/mainboard/tyan/s2895/Options.lb index e2d220201b..fc63823480 100644 --- a/src/mainboard/tyan/s2895/Options.lb +++ b/src/mainboard/tyan/s2895/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -90,10 +87,6 @@ default HAVE_FALLBACK_BOOT=1 ## default HAVE_HARD_RESET=1 -#default HARD_RESET_BUS=1 -#default HARD_RESET_DEVICE=4 -#default HARD_RESET_FUNCTION=0 - ## ## Build code to export a programmable irq routing table ## @@ -134,7 +127,7 @@ default CONFIG_LOGICAL_CPUS=1 default K8_E0_MEM_HOLE_SIZEK=0x100000 #CK804 setting -default CK804_DEVN_BASE=0 +#default CK804_DEVN_BASE=0 #VGA default CONFIG_CONSOLE_VGA=1 diff --git a/src/mainboard/tyan/s2895/auto.c b/src/mainboard/tyan/s2895/auto.c index b6f121e6e8..0a26f21735 100644 --- a/src/mainboard/tyan/s2895/auto.c +++ b/src/mainboard/tyan/s2895/auto.c @@ -14,7 +14,7 @@ #include "ram/ramtest.c" #include "northbridge/amd/amdk8/cpu_rev.c" -#define K8_HT_FREQ_1G_SUPPORT 1 +//#define K8_HT_FREQ_1G_SUPPORT 1 #include "northbridge/amd/amdk8/incoherent_ht.c" #include "southbridge/nvidia/ck804/ck804_early_smbus.c" #include "northbridge/amd/amdk8/raminit.h" @@ -70,8 +70,9 @@ static void sio_gpio_setup(void){ unsigned value; +// lpc47b397_enable_serial(SUPERIO_GPIO_DEV, SUPERIO_GPIO_IO_BASE); // Already enable in failover.c + #if 1 - /*Enable onboard scsi*/ lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x2c, (1<<7)|(0<<2)|(0<<1)|(0<<0)); // GP21, offset 0x2c, DISABLE_SCSI_L value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x4c); lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x4c, (value|(1<<1))); @@ -117,10 +118,9 @@ static inline int spd_read_byte(unsigned device, unsigned address) #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) #define CK804_NUM 2 -#define CK804B_BUSN 0xc +#define CK804B_BUSN 0x80 #define CK804_USE_NIC 1 #define CK804_USE_ACI 1 -#include "southbridge/nvidia/ck804/ck804_early_setup.h" #include "southbridge/nvidia/ck804/ck804_early_setup_ss.h" //set GPIO to input mode @@ -192,11 +192,12 @@ static void main(unsigned long bist) enable_lapic(); init_timer(); + post_code(0x30); #if CONFIG_LOGICAL_CPUS==1 #if ENABLE_APIC_EXT_ID == 1 #if LIFT_BSP_APIC_ID == 0 - if( id.nodeid != 0 ) + if( id.nodeid != 0 ) //all except cores in node0 #endif lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); #endif @@ -213,7 +214,7 @@ static void main(unsigned long bist) #if LIFT_BSP_APIC_ID == 0 if(nodeid != 0) #endif - lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10 #endif @@ -223,16 +224,18 @@ static void main(unsigned long bist) distinguish_cpu_resets(nodeid); #endif + post_code(0x31); if (!boot_cpu() #if CONFIG_LOGICAL_CPUS==1 || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } + post_code(0x32); lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); @@ -247,6 +250,7 @@ static void main(unsigned long bist) needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif diff --git a/src/mainboard/tyan/s2895/cache_as_ram_auto.c b/src/mainboard/tyan/s2895/cache_as_ram_auto.c index fde94cc780..2cf73c333f 100644 --- a/src/mainboard/tyan/s2895/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s2895/cache_as_ram_auto.c @@ -13,9 +13,10 @@ #include "arch/i386/lib/console.c" #include "ram/ramtest.c" - #include "northbridge/amd/amdk8/cpu_rev.c" -#define K8_HT_FREQ_1G_SUPPORT 0 +#define K8_HT_FREQ_1G_SUPPORT 1 +#define K8_ALLOCATE_IO_RANGE 1 +//#define K8_SCAN_PCI_BUS 1 #include "northbridge/amd/amdk8/incoherent_ht.c" #include "southbridge/nvidia/ck804/ck804_early_smbus.c" #include "northbridge/amd/amdk8/raminit.h" @@ -75,13 +76,11 @@ static void sio_gpio_setup(void){ unsigned value; +// lpc47b397_enable_serial(SUPERIO_GPIO_DEV, SUPERIO_GPIO_IO_BASE); // Already enable in failover.c -#if 1 - /*Enable onboard scsi*/ lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x2c, (1<<7)|(0<<2)|(0<<1)|(0<<0)); // GP21, offset 0x2c, DISABLE_SCSI_L value = lpc47b397_gpio_offset_in(SUPERIO_GPIO_IO_BASE, 0x4c); lpc47b397_gpio_offset_out(SUPERIO_GPIO_IO_BASE, 0x4c, (value|(1<<1))); -#endif } @@ -114,6 +113,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 @@ -121,8 +122,7 @@ static inline int spd_read_byte(unsigned device, unsigned address) #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) #define CK804_NUM 2 -//#define CK804B_BUSN 0x80 -#define CK804B_BUSN 0xc +#define CK804B_BUSN 0x80 #define CK804_USE_NIC 1 #define CK804_USE_ACI 1 @@ -155,13 +155,18 @@ static void sio_setup(void) uint8_t byte; + /* LPC Variable Range Decode 1 0x400-0x47f */ + /* to make sure lpc47b397 gpio on device work */ pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1, 0), 0xac, 0x047f0400); + /* subject decoding*/ byte = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b); byte |= 0x20; pci_write_config8(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0x7b, byte); + /* LPC Positive Decode 0 */ dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0); + /*decode VAR1, serial 0 */ dword |= (1<<29)|(1<<0); pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0, dword); @@ -311,7 +316,7 @@ void amd64_main(unsigned long bist) enable_lapic(); - init_timer(); +// init_timer(); #if CONFIG_LOGICAL_CPUS==1 @@ -323,10 +328,12 @@ void amd64_main(unsigned long bist) #endif if(id.coreid == 0) { if (cpu_init_detected(id.nodeid)) { +// __asm__ volatile ("jmp __cpu_reset"); cpu_reset = 1; goto cpu_reset_x; } distinguish_cpu_resets(id.nodeid); +// start_other_core(id.nodeid); } #else #if ENABLE_APIC_EXT_ID == 1 @@ -337,6 +344,7 @@ void amd64_main(unsigned long bist) #endif if (cpu_init_detected(nodeid)) { +// __asm__ volatile ("jmp __cpu_reset"); cpu_reset = 1; goto cpu_reset_x; } @@ -355,6 +363,8 @@ void amd64_main(unsigned long bist) } } + init_timer(); // only do it it first CPU + lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); @@ -364,10 +374,6 @@ void amd64_main(unsigned long bist) report_bist_failure(bist); setup_s2895_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif needs_reset = setup_coherent_ht_domain(); @@ -376,15 +382,7 @@ void amd64_main(unsigned long bist) start_other_cores(); #endif -#if CK804B_BUSN == 0x80 - // You need to preset bus num in PCI_DEV(0, 0x18,1) 0xe0, 0xe4, 0xe8, 0xec - needs_reset |= ht_setup_chains(3); -#else - // automatically set that for you, but you might meet tight space - // Bcause it has two Ck804, we need to set CK804B_BUSN to 0xc (ht_setup_chains_x will let second CK804 use that bus num. - // otherwise ck804_eary_setup can not work rightly. needs_reset |= ht_setup_chains_x(); -#endif needs_reset |= ck804_early_setup_x(); @@ -394,20 +392,10 @@ void amd64_main(unsigned long bist) } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif -#if 0 - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif - #if 1 { /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ @@ -424,6 +412,7 @@ void amd64_main(unsigned long bist) } #endif +#if 1 cpu_reset_x: @@ -486,6 +475,7 @@ cpu_reset_x: copy_and_run(new_cpu_reset); /* We will not return */ } +#endif print_err("should not be here -\r\n"); diff --git a/src/mainboard/tyan/s2895/irq_tables.c b/src/mainboard/tyan/s2895/irq_tables.c index cf1a438dc1..aa16866763 100644 --- a/src/mainboard/tyan/s2895/irq_tables.c +++ b/src/mainboard/tyan/s2895/irq_tables.c @@ -403,6 +403,8 @@ unsigned long write_pirq_routing_table(unsigned long addr) pirq->checksum = sum; } + printk_info("done.\n"); + return (unsigned long) pirq_info; } diff --git a/src/mainboard/tyan/s2895/mptable.c b/src/mainboard/tyan/s2895/mptable.c index f6b534d866..810e234af6 100644 --- a/src/mainboard/tyan/s2895/mptable.c +++ b/src/mainboard/tyan/s2895/mptable.c @@ -8,6 +8,41 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -62,21 +97,71 @@ void *smp_write_config_table(void *v) device_t dev; + bus_ck804_0 = node_link_to_bus(0, 0); + if (bus_ck804_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_ck804_0 = 1; + } /* CK804 */ - bus_ck804_0 = 1; dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0)); if (dev) { bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); +#if 0 + bus_ck804_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_2++; +#else bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); bus_ck804_5++; +#endif } else { printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09); bus_ck804_1 = 2; +#if 0 + bus_ck804_2 = 3; +#else bus_ck804_5 = 3; +#endif + + } +#if 0 + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0)); + if (dev) { + bus_ck804_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_3++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0b); + + bus_ck804_3 = bus_ck804_2+1; + } + + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0)); + if (dev) { + bus_ck804_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_4++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x0c); + + bus_ck804_4 = bus_ck804_3+1; + } + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0)); + if (dev) { + bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804_5++; } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0d); + + bus_ck804_5 = bus_ck804_4+1; + } +#endif dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0)); if (dev) { @@ -119,6 +204,59 @@ void *smp_write_config_table(void *v) /* CK804b */ +#if 0 + dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0)); + if (dev) { + bus_ck804b_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804b_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804b_2++; + } + else { + printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x09); + + bus_ck804b_1 = bus_ck804b_0+1; + bus_ck804b_2 = bus_ck804b_0+2; + } + + dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0b,0)); + if (dev) { + bus_ck804b_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804b_3 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804b_3++; + } + else { + printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0b); + + bus_ck804b_2 = bus_ck804b_0+1; + bus_ck804b_3 = bus_ck804b_0+2; + } + + dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0c,0)); + if (dev) { + bus_ck804b_3 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804b_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804b_4++; + } + else { + printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0c); + + bus_ck804b_4 = bus_ck804b_3+1; + } + + dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0)); + if (dev) { + bus_ck804b_4 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_ck804b_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_ck804b_5++; + } + else { + printk_debug("ERROR - could not find PCI %02x:%02x.0, using defaults\n", bus_ck804b_0,CK804_DEVN_BASE+0x0d); + + bus_ck804b_5 = bus_ck804b_4+1; + } + +#endif + dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0)); if (dev) { bus_ck804b_5 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -168,7 +306,7 @@ void *smp_write_config_table(void *v) smp_write_ioapic(mc, apicid_ck804, 0x11, res->base); } - dword = 0x0120d218; + dword = 0x0000d218; pci_write_config32(dev, 0x7c, dword); dword = 0x12008a00; @@ -229,58 +367,77 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_ck804, 0xf); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa); +// 10 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x15); // 21 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x14); // 20 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+4)<<2)|0, apicid_ck804, 0x14); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+4)<<2)|0, apicid_ck804, 0x14); // 20 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x17); // 23 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x16); // 22 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +0x0a)<<2)|0, apicid_ck804, 0x15); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +0x0a)<<2)|0, apicid_ck804, 0x15); // 21 -#if 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // +#if CK804_DEVN_BASE == 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); // 18 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); // 19 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); // 16 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); // 17 +#else + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x11); // 17 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x12); // 18 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x13); // 19 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x10); // 16 #endif - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x05<<2)|0, apicid_ck804, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x05<<2)|0, apicid_ck804, 0x13); // 19 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|0, apicid_ck804, 0x10); // 16 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|1, apicid_ck804, 0x11); // 17 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|2, apicid_ck804, 0x12); // 18 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|3, apicid_ck804, 0x13); // 19 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_0, ((CK804_DEVN_BASE+0x0a)<<2)|0, apicid_ck804b, 0x15);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_0, ((CK804_DEVN_BASE+0x0a)<<2)|0, apicid_ck804b, 0x15);//24+4+4+21=53 -#if 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x12);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x13); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x10); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x11); // +#if CK804_DEVN_BASE == 0 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x12);//18+24+4+4=50 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x13); // 19 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x10); // 16 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x11); // 17 +#else + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|0, apicid_ck804b, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|1, apicid_ck804b, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|2, apicid_ck804b, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|3, apicid_ck804b, 0x10); #endif - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|0, apicid_8131_2, 0x0); // +//Channel B of 8131 + +//Slot 4 PCI-X 100/66 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|0, apicid_8131_2, 0x0); //24+4 = 28 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|1, apicid_8131_2, 0x1); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|2, apicid_8131_2, 0x2); // smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|3, apicid_8131_2, 0x3); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x1); // +//Slot 5 PCIX 100/66 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x1); //24+4+1 = 29 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x2); smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|2, apicid_8131_2, 0x3);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|3, apicid_8131_2, 0x0);// +//OnBoard LSI SCSI + + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x2); // 24+4+2 = 30 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x3); // 31 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x3); +//Channel A of 8131 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); // +//Slot 6 PCIX 133/100/66 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); // 24 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|1, apicid_8131_1, 0x1);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|2, apicid_8131_1, 0x2);// smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|3, apicid_8131_1, 0x3);// diff --git a/src/mainboard/tyan/s4880/Config.lb b/src/mainboard/tyan/s4880/Config.lb index 3b3806f6ac..e3c5b03b40 100644 --- a/src/mainboard/tyan/s4880/Config.lb +++ b/src/mainboard/tyan/s4880/Config.lb @@ -43,7 +43,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -##object reset.o +object reset.o if USE_DCACHE_RAM if CONFIG_USE_INIT diff --git a/src/mainboard/tyan/s4880/Options.lb b/src/mainboard/tyan/s4880/Options.lb index f3d73515ee..fc98b83255 100644 --- a/src/mainboard/tyan/s4880/Options.lb +++ b/src/mainboard/tyan/s4880/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -87,14 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=3 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 diff --git a/src/mainboard/tyan/s4880/auto.c b/src/mainboard/tyan/s4880/auto.c index fc1bf58e91..3e0d4825df 100644 --- a/src/mainboard/tyan/s4880/auto.c +++ b/src/mainboard/tyan/s4880/auto.c @@ -95,65 +95,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -#if 0 -static unsigned int generate_row(uint8_t node, uint8_t row, uint8_t maxnodes) -{ - /* Routing Table Node i - * - * F0: 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c - * i: 0, 1, 2, 3, 4, 5, 6, 7 - * - * [ 0: 3] Request Route - * [0] Route to this node - * [1] Route to Link 0 - * [2] Route to Link 1 - * [3] Route to Link 2 - * [11: 8] Response Route - * [0] Route to this node - * [1] Route to Link 0 - * [2] Route to Link 1 - * [3] Route to Link 2 - * [19:16] Broadcast route - * [0] Route to this node - * [1] Route to Link 0 - * [2] Route to Link 1 - * [3] Route to Link 2 - */ - uint32_t ret=0x00010101; /* default row entry */ - -/* - (L1) (L2) - CPU3-------------CPU1 - (L0)| |(L0) - | | - | | - | | - | | - (L0)| |(L0) - CPU2-------------CPU0---------8131----------8111 - (L2) (L1) (L2) -*/ - - /* Link0 of CPU0 to Link0 of CPU1 */ - /* Link1 of CPU0 to Link2 of CPU2 */ - /* Link2 of CPU1 to Link1 of CPU3 */ - /* Link0 of CPU2 to Link0 of CPU3 */ - - static const unsigned int rows_4p[4][4] = { - { 0x00070101, 0x00010202, 0x00030404, 0x00010204 }, - { 0x00010202, 0x000b0101, 0x00010208, 0x00030808 }, - { 0x00030808, 0x00010208, 0x000b0101, 0x00010202 }, - { 0x00010204, 0x00030404, 0x00010202, 0x00070101 } - }; - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_4p[node][row]; - } - - return ret; -} -#endif - static inline void activate_spd_rom(const struct mem_controller *ctrl) { #define SMBUS_HUB 0x18 @@ -161,6 +102,14 @@ static inline void activate_spd_rom(const struct mem_controller *ctrl) smbus_write_byte(SMBUS_HUB , 0x01, device); smbus_write_byte(SMBUS_HUB , 0x03, 0); } +#if 0 +static inline void change_i2c_mux(unsigned device) +{ +#define SMBUS_HUB 0x18 + smbus_write_byte(SMBUS_HUB , 0x01, device); + smbus_write_byte(SMBUS_HUB , 0x03, 0); +} +#endif static inline int spd_read_byte(unsigned device, unsigned address) { @@ -308,22 +257,19 @@ static void main(unsigned long bist) needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 - // It is said that we should start core1 after all core0 launched start_other_cores(); #endif -#if 0 - needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0); -#else - // automatically set that for you, but you might meet tight space needs_reset |= ht_setup_chains_x(); -#endif if (needs_reset) { print_info("ht reset -\r\n"); soft_reset(); } +#if 0 + dump_pci_devices(); +#endif enable_smbus(); memreset_setup(); diff --git a/src/mainboard/tyan/s4880/cache_as_ram_auto.c b/src/mainboard/tyan/s4880/cache_as_ram_auto.c index f39ff15b4d..bddcd08820 100644 --- a/src/mainboard/tyan/s4880/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s4880/cache_as_ram_auto.c @@ -325,6 +325,7 @@ void amd64_main(unsigned long bist) enable_lapic(); init_timer(); +// post_code(0x30); #if CONFIG_LOGICAL_CPUS==1 #if ENABLE_APIC_EXT_ID == 1 @@ -355,7 +356,6 @@ void amd64_main(unsigned long bist) distinguish_cpu_resets(nodeid); #endif - if (!boot_cpu() #if CONFIG_LOGICAL_CPUS==1 || (id.coreid != 0) @@ -380,9 +380,9 @@ void amd64_main(unsigned long bist) needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif - needs_reset |= ht_setup_chains_x(); if (needs_reset) { diff --git a/src/mainboard/tyan/s4880/reset.c b/src/mainboard/tyan/s4880/reset.c new file mode 100644 index 0000000000..63958185f6 --- /dev/null +++ b/src/mainboard/tyan/s4880/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 2); +} diff --git a/src/mainboard/tyan/s4882/Config.lb b/src/mainboard/tyan/s4882/Config.lb index 95ef0464fe..18fec090cf 100644 --- a/src/mainboard/tyan/s4882/Config.lb +++ b/src/mainboard/tyan/s4882/Config.lb @@ -43,7 +43,7 @@ arch i386 end driver mainboard.o if HAVE_MP_TABLE object mptable.o end if HAVE_PIRQ_TABLE object irq_tables.o end -#object reset.o +object reset.o if USE_DCACHE_RAM if CONFIG_USE_INIT diff --git a/src/mainboard/tyan/s4882/Options.lb b/src/mainboard/tyan/s4882/Options.lb index 56a2548228..0c5571aa07 100644 --- a/src/mainboard/tyan/s4882/Options.lb +++ b/src/mainboard/tyan/s4882/Options.lb @@ -3,9 +3,6 @@ uses HAVE_PIRQ_TABLE uses USE_FALLBACK_IMAGE uses HAVE_FALLBACK_BOOT uses HAVE_HARD_RESET -uses HARD_RESET_BUS -uses HARD_RESET_DEVICE -uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS @@ -31,9 +28,9 @@ uses USE_OPTION_TABLE uses LB_CKS_RANGE_START uses LB_CKS_RANGE_END uses LB_CKS_LOC +uses MAINBOARD uses MAINBOARD_PART_NUMBER uses MAINBOARD_VENDOR -uses MAINBOARD uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID uses LINUXBIOS_EXTRA_VERSION @@ -87,13 +84,6 @@ default HAVE_FALLBACK_BOOT=1 default HAVE_HARD_RESET=1 ## -## Funky hard reset implementation -## -default HARD_RESET_BUS=3 -default HARD_RESET_DEVICE=4 -default HARD_RESET_FUNCTION=0 - -## ## Build code to export a programmable irq routing table ## default HAVE_PIRQ_TABLE=1 @@ -153,8 +143,8 @@ default CONFIG_IOAPIC=1 ## ## Clean up the motherboard id strings ## -default MAINBOARD_PART_NUMBER="s4882" default MAINBOARD_VENDOR="Tyan" +default MAINBOARD_PART_NUMBER="s4882" default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1 default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x4882 diff --git a/src/mainboard/tyan/s4882/auto.c b/src/mainboard/tyan/s4882/auto.c index 21d459b6e4..e8d46e7961 100644 --- a/src/mainboard/tyan/s4882/auto.c +++ b/src/mainboard/tyan/s4882/auto.c @@ -26,26 +26,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { - set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); -} + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 0); -static void soft2_reset(void) -{ set_bios_reset(); - pci_write_config8(PCI_DEV(3, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -73,6 +99,7 @@ static inline void activate_spd_rom(const struct mem_controller *ctrl) #define SMBUS_HUB 0x18 int ret,i; unsigned device=(ctrl->channel0[0])>>8; + /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/ i=2; do { ret = smbus_write_byte(SMBUS_HUB, 0x01, device); @@ -194,7 +221,7 @@ static void main(unsigned long bist) #if CONFIG_LOGICAL_CPUS==1 set_apicid_cpuid_lo(); - id = get_node_core_id_x(); + id = get_node_core_id_x(); // that is initid #if ENABLE_APIC_EXT_ID == 1 if(id.coreid == 0) { enable_apic_ext_id(id.nodeid); @@ -213,7 +240,7 @@ static void main(unsigned long bist) #if CONFIG_LOGICAL_CPUS==1 #if ENABLE_APIC_EXT_ID == 1 #if LIFT_BSP_APIC_ID == 0 - if( id.nodeid != 0 ) + if( id.nodeid != 0 ) //all except cores in node0 #endif lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); #endif @@ -241,7 +268,7 @@ static void main(unsigned long bist) || (id.coreid != 0) #endif ) { - stop_this_cpu(); + stop_this_cpu(); // it will stop all cores except core0 of cpu0 } } @@ -257,10 +284,10 @@ static void main(unsigned long bist) needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 + // It is said that we should start core1 after all core0 launched start_other_cores(); #endif - // automatically set that for you, but you might meet tight space needs_reset |= ht_setup_chains_x(); if (needs_reset) { print_info("ht reset -\r\n"); diff --git a/src/mainboard/tyan/s4882/cache_as_ram_auto.c b/src/mainboard/tyan/s4882/cache_as_ram_auto.c index bbcc49a9cf..234e3a0a58 100644 --- a/src/mainboard/tyan/s4882/cache_as_ram_auto.c +++ b/src/mainboard/tyan/s4882/cache_as_ram_auto.c @@ -37,20 +37,52 @@ #define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) +/* Look up a which bus a given node/link combination is on. + * return 0 when we can't find the answer. + */ +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + static void hard_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 3); + set_bios_reset(); /* enable cf9 */ - pci_write_config8(PCI_DEV(0, 0x04, 3), 0x41, 0xf1); + pci_write_config8(dev, 0x41, 0xf1); /* reset */ outb(0x0e, 0x0cf9); } static void soft_reset(void) { + device_t dev; + + /* Find the device */ + dev = PCI_DEV(node_link_to_bus(0, 1), 0x04, 0); + set_bios_reset(); - pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); + pci_write_config8(dev, 0x47, 1); } static void memreset_setup(void) @@ -77,6 +109,7 @@ static inline void activate_spd_rom(const struct mem_controller *ctrl) #define SMBUS_HUB 0x18 int ret,i; unsigned device=(ctrl->channel0[0])>>8; + /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/ i=2; do { ret = smbus_write_byte(SMBUS_HUB, 0x01, device); @@ -109,6 +142,8 @@ static inline int spd_read_byte(unsigned device, unsigned address) #if CONFIG_LOGICAL_CPUS==1 #define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" +#else +#include "cpu/amd/model_fxx/node_id.c" #endif #define FIRST_CPU 1 #define SECOND_CPU 1 @@ -325,7 +360,6 @@ void amd64_main(unsigned long bist) distinguish_cpu_resets(nodeid); #endif - if (!boot_cpu() #if CONFIG_LOGICAL_CPUS==1 || (id.coreid != 0) @@ -337,22 +371,15 @@ void amd64_main(unsigned long bist) } } - w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); - dump_mem(DCACHE_RAM_BASE+DCACHE_RAM_SIZE-0x200, DCACHE_RAM_BASE+DCACHE_RAM_SIZE); - /* Halt if there was a built in self test failure */ report_bist_failure(bist); setup_s4882_resource_map(); -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 0)); - dump_pci_device(PCI_DEV(0, 0x19, 0)); -#endif - + needs_reset = setup_coherent_ht_domain(); #if CONFIG_LOGICAL_CPUS==1 @@ -387,6 +414,7 @@ void amd64_main(unsigned long bist) } #endif +#if 1 cpu_reset_x: @@ -450,6 +478,7 @@ cpu_reset_x: copy_and_run(new_cpu_reset); /* We will not return */ } +#endif print_debug("should not be here -\r\n"); diff --git a/src/mainboard/tyan/s4882/reset.c b/src/mainboard/tyan/s4882/reset.c new file mode 100644 index 0000000000..7f58d01410 --- /dev/null +++ b/src/mainboard/tyan/s4882/reset.c @@ -0,0 +1,6 @@ +#include "../../../southbridge/amd/amd8111/amd8111_reset.c" + +void hard_reset(void) +{ + amd8111_hard_reset(0, 1); +} diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c index d7be557d37..c79a432ab5 100644 --- a/src/northbridge/amd/amdk8/coherent_ht.c +++ b/src/northbridge/amd/amdk8/coherent_ht.c @@ -145,15 +145,16 @@ static void disable_probes(void) print_spew("Disabling read/write/fill probes for UP... "); - val=pci_read_config32(NODE_HT(0), 0x68); - val |= (1<<10)|(1<<9)|(1<<8)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1 << 0); - pci_write_config32(NODE_HT(0), 0x68, val); + val=pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL); + val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C | + HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P | + HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P; + pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val); print_spew("done.\r\n"); } - #ifndef ENABLE_APIC_EXT_ID #define ENABLE_APIC_EXT_ID 0 #endif @@ -163,7 +164,7 @@ static void enable_apic_ext_id(u8 node) #if ENABLE_APIC_EXT_ID==1 #warning "FIXME Is the right place to enable apic ext id here?" - u32 val; + u32 val; val = pci_read_config32(NODE_HT(node), 0x68); val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST); @@ -171,8 +172,6 @@ static void enable_apic_ext_id(u8 node) #endif } - - static void enable_routing(u8 node) { u32 val; @@ -277,11 +276,11 @@ static void wait_ht_stable(uint8_t node) } #endif -static int check_connection(u8 dest) +static int verify_connection(u8 dest) { /* See if we have a valid connection to dest */ u32 val; - + /* Verify that the coherent hypertransport link is * established and actually working by reading the * remode node's vendor/device id @@ -289,10 +288,6 @@ static int check_connection(u8 dest) val = pci_read_config32(NODE_HT(dest),0); if(val != 0x11001022) return 0; -// needed? -#if K8_HT_CHECK_PENDING_LINK == 1 - wait_ht_stable(dest); -#endif return 1; } @@ -306,11 +301,11 @@ static uint16_t read_freq_cap(device_t dev, uint8_t pos) freq_cap = pci_read_config16(dev, pos); freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */ - - #if K8_HT_FREQ_1G_SUPPORT == 1 - if (!is_cpu_pre_e0()) +#if K8_HT_FREQ_1G_SUPPORT == 1 + if (!is_cpu_pre_e0()) { return freq_cap; - #endif + } +#endif id = pci_read_config32(dev, 0); @@ -726,8 +721,8 @@ static struct setup_smp_result setup_smp2(void) print_linkn("(0,1) link=", byte); setup_row_direct(0,1, byte); setup_temp_row(0, 1); - - check_connection(7); + + verify_connection(7); /* We found 2 nodes so far */ val = pci_read_config32(NODE_HT(7), 0x6c); @@ -751,8 +746,8 @@ static struct setup_smp_result setup_smp2(void) print_linkn("\t-->(0,1) link=", byte); setup_row_direct(0,1, byte); setup_temp_row(0, 1); - - check_connection(7); + + verify_connection(7); /* We found 2 nodes so far */ val = pci_read_config32(NODE_HT(7), 0x6c); @@ -832,7 +827,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0])); setup_temp_row(0,2); - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 0*/ print_linkn("(2,0) link=", byte); @@ -846,7 +841,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) setup_temp_row(0,1); setup_temp_row(1,3); - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 1*/ @@ -865,7 +860,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) setup_row_direct(2,3, byte & 0x3); setup_temp_row(0,2); setup_temp_row(2,3); - check_connection(7); /* to 3*/ + verify_connection(7); /* to 3*/ #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1) /* We need to find out which link is to node3 */ @@ -878,7 +873,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) print_linkn("\t-->(2,3) link=", byte); setup_row_direct(2,3,byte); setup_temp_row(2,3); - check_connection(7); /* to 3*/ + verify_connection(7); /* to 3*/ } } #endif @@ -1016,7 +1011,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) for(byte=0; byte<4; byte+=2) { setup_temp_row(byte,byte+2); } - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /*get default link on 7 to 2*/ print_linkn("(4,2) link=", byte); @@ -1044,7 +1039,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) for(byte=0; byte<4; byte+=2) { setup_temp_row(byte+1,byte+3); } - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 3*/ @@ -1064,7 +1059,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) setup_temp_row(0,2); setup_temp_row(2,4); setup_temp_row(4,5); - check_connection(7); /* to 5*/ + verify_connection(7); /* to 5*/ #if CONFIG_MAX_PHYSICAL_CPUS > 6 /* We need to find out which link is to node5 */ @@ -1078,7 +1073,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) print_linkn("\t-->(4,5) link=", byte); setup_row_direct(4,5,byte); setup_temp_row(4,5); - check_connection(7); /* to 5*/ + verify_connection(7); /* to 5*/ } } #endif @@ -1254,7 +1249,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) for(byte=0; byte<6; byte+=2) { setup_temp_row(byte,byte+2); } - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 4*/ print_linkn("(6,4) link=", byte); @@ -1294,7 +1289,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) } setup_temp_row(5,6); - check_connection(7); + verify_connection(7); val = get_row(7,6); // to chect it if it is node6 before renaming if( (val>>16) == 1) { // it is real node 7 so swap it @@ -1316,7 +1311,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) #endif setup_temp_row(5,6); - check_connection(7); + verify_connection(7); } val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 5*/ @@ -1334,7 +1329,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) setup_temp_row(byte+1,byte+3); } - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 5*/ @@ -1354,7 +1349,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) setup_temp_row(byte,byte+2); } - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 4*/ @@ -1379,7 +1374,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) setup_temp_row(byte+1,byte+3); } - check_connection(7); + verify_connection(7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 5*/ @@ -1568,7 +1563,6 @@ static struct setup_smp_result setup_smp(void) #endif return result; - } static unsigned verify_mp_capabilities(unsigned nodes) @@ -1663,10 +1657,10 @@ static void coherent_ht_finalize(unsigned nodes) #endif /* set up cpu count and node count and enable Limit - * Config Space Range for all available CPUs. - * Also clear non coherent hypertransport bus range - * registers on Hammer A0 revision. - */ + * Config Space Range for all available CPUs. + * Also clear non coherent hypertransport bus range + * registers on Hammer A0 revision. + */ print_spew("coherent_ht_finalize\r\n"); rev_a0 = is_cpu_rev_a0(); @@ -1686,21 +1680,19 @@ static void coherent_ht_finalize(unsigned nodes) pci_write_config32(dev, 0x60, val); /* Only respond to real cpu pci configuration cycles - * and optimize the HT settings - */ - val=pci_read_config32(dev, 0x68); + * and optimize the HT settings + */ + val=pci_read_config32(dev, HT_TRANSACTION_CONTROL); val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) | (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) | (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT)); val |= HTTC_LIMIT_CLDT_CFG | (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) | - HTTC_RSP_PASS_PW | (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) | (3 << HTTC_HI_PRI_BYP_CNT_SHIFT); - pci_write_config32(dev, 0x68, val); + pci_write_config32(dev, HT_TRANSACTION_CONTROL, val); if (rev_a0) { - print_spew("shit it is an old cup\n"); pci_write_config32(dev, 0x94, 0); pci_write_config32(dev, 0xb4, 0); pci_write_config32(dev, 0xd4, 0); @@ -1720,8 +1712,8 @@ static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset) if (is_cpu_pre_c0()) { /* Errata 66 - * Limit the number of downstream posted requests to 1 - */ + * Limit the number of downstream posted requests to 1 + */ cmd = pci_read_config32(dev, 0x70); if ((cmd & (3 << 0)) != 2) { cmd &= ~(3<<0); @@ -1745,12 +1737,12 @@ static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset) } } - else if(is_cpu_pre_d0()) { // d0 later don't need it + else if (is_cpu_pre_d0()) { // d0 later don't need it uint32_t cmd_ref; /* Errata 98 - * Set Clk Ramp Hystersis to 7 - * Clock Power/Timing Low - */ + * Set Clk Ramp Hystersis to 7 + * Clock Power/Timing Low + */ cmd_ref = 0x04e20707; /* Registered */ cmd = pci_read_config32(dev, 0xd4); if(cmd != cmd_ref) { @@ -1778,7 +1770,10 @@ static int optimize_link_read_pointers(unsigned nodes, int needs_reset) /* This works on an Athlon64 because unimplemented links return 0 */ reg = 0x98 + (link * 0x20); link_type = pci_read_config32(f0_dev, reg); - if ((link_type & 7) == 3) { /* only handle coherent link here*/ + /* Only handle coherent links */ + if ((link_type & (LinkConnected | InitComplete|NonCoherent)) == + (LinkConnected|InitComplete)) + { cmd &= ~(0xff << (link *8)); cmd |= 0x25 << (link *8); } @@ -1794,6 +1789,8 @@ static int optimize_link_read_pointers(unsigned nodes, int needs_reset) static int setup_coherent_ht_domain(void) { struct setup_smp_result result; + result.nodes = 1; + result.needs_reset = 0; #if K8_HT_CHECK_PENDING_LINK == 1 //needed? @@ -1802,17 +1799,14 @@ static int setup_coherent_ht_domain(void) enable_bsp_routing(); #if CONFIG_MAX_PHYSICAL_CPUS > 1 - result = setup_smp(); - result.nodes = verify_mp_capabilities(result.nodes); - clear_dead_routes(result.nodes); -#else - result.nodes = 1; - result.needs_reset = 0; + result = setup_smp(); + result.nodes = verify_mp_capabilities(result.nodes); + clear_dead_routes(result.nodes); #endif if (result.nodes == 1) { setup_uniprocessor(); - } + } coherent_ht_finalize(result.nodes); result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset); result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset); diff --git a/src/northbridge/amd/amdk8/debug.c b/src/northbridge/amd/amdk8/debug.c index 861ad8c38a..d0841e878e 100644 --- a/src/northbridge/amd/amdk8/debug.c +++ b/src/northbridge/amd/amdk8/debug.c @@ -5,12 +5,16 @@ #if 1 static void print_debug_pci_dev(unsigned dev) { +#if CONFIG_USE_INIT + printk_debug("PCI: %02x:%02x.%02x", (dev>>16) & 0xff, (dev>>11) & 0x1f, (dev>>8) & 0x7); +#else print_debug("PCI: "); print_debug_hex8((dev >> 16) & 0xff); print_debug_char(':'); print_debug_hex8((dev >> 11) & 0x1f); print_debug_char('.'); print_debug_hex8((dev >> 8) & 7); +#endif } static void print_pci_devices(void) @@ -27,7 +31,19 @@ static void print_pci_devices(void) continue; } print_debug_pci_dev(dev); +#if CONFIG_USE_INIT + printk_debug(" %04x:%04x\r\n", (id & 0xffff), (id>>16)); +#else + print_debug_hex32(id); print_debug("\r\n"); +#endif + if(((dev>>8) & 0x07) == 0) { + uint8_t hdr_type; + hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + if((hdr_type & 0x80) != 0x80) { + dev += PCI_DEV(0,0,7); + } + } } } @@ -72,6 +88,14 @@ static void dump_pci_devices(void) continue; } dump_pci_device(dev); + + if(((dev>>8) & 0x07) == 0) { + uint8_t hdr_type; + hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + if((hdr_type & 0x80) != 0x80) { + dev += PCI_DEV(0,0,7); + } + } } } @@ -89,6 +113,14 @@ static void dump_pci_devices_on_bus(unsigned busn) continue; } dump_pci_device(dev); + + if(((dev>>8) & 0x07) == 0) { + uint8_t hdr_type; + hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + if((hdr_type & 0x80) != 0x80) { + dev += PCI_DEV(0,0,7); + } + } } } diff --git a/src/northbridge/amd/amdk8/early_ht.c b/src/northbridge/amd/amdk8/early_ht.c index ab9d4592dd..2711657455 100644 --- a/src/northbridge/amd/amdk8/early_ht.c +++ b/src/northbridge/amd/amdk8/early_ht.c @@ -17,8 +17,9 @@ static int enumerate_ht_chain(void) id = pci_read_config32(PCI_DEV(0,0,0), PCI_VENDOR_ID); /* If the chain is enumerated quit */ if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || - (((id >> 16) & 0xffff) == 0xffff) || - (((id >> 16) & 0xffff) == 0x0000)) { + (((id >> 16) & 0xffff) == 0xffff) || + (((id >> 16) & 0xffff) == 0x0000)) + { break; } @@ -35,7 +36,8 @@ static int enumerate_ht_chain(void) hdr_type &= 0x7f; if ((hdr_type == PCI_HEADER_TYPE_NORMAL) || - (hdr_type == PCI_HEADER_TYPE_BRIDGE)) { + (hdr_type == PCI_HEADER_TYPE_BRIDGE)) + { pos = pci_read_config8(PCI_DEV(0,0,0), PCI_CAPABILITY_LIST); } while(pos != 0) { @@ -43,24 +45,39 @@ static int enumerate_ht_chain(void) cap = pci_read_config8(PCI_DEV(0,0,0), pos + PCI_CAP_LIST_ID); if (cap == PCI_CAP_ID_HT) { uint16_t flags; + /* Read and write and reread flags so the link + * direction bit is valid. + */ + flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS); + pci_write_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS, flags); flags = pci_read_config16(PCI_DEV(0,0,0), pos + PCI_CAP_FLAGS); if ((flags >> 13) == 0) { unsigned count; + unsigned ctrl, ctrl_off; flags &= ~0x1f; flags |= next_unitid & 0x1f; count = (flags >> 5) & 0x1f; + next_unitid += count; + + /* Test for end of chain */ + ctrl_off = ((flags >> 10) & 1)? + PCI_HT_CAP_SLAVE_CTRL1 : PCI_HT_CAP_SLAVE_CTRL0; + ctrl = pci_read_config16(PCI_DEV(0,0,0), pos + ctrl_off); + /* Is this the end of the hypertransport chain. + * or has the link failed? + */ + if (ctrl & ((1 << 6)|(1 << 4))) { + next_unitid = 0x20; + } pci_write_config16(PCI_DEV(0, 0, 0), pos + PCI_CAP_FLAGS, flags); - - next_unitid += count; break; } } pos = pci_read_config8(PCI_DEV(0, 0, 0), pos + PCI_CAP_LIST_NEXT); } - } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); - + } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); return reset_needed; } diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c index 7bb315d687..d4271efbda 100644 --- a/src/northbridge/amd/amdk8/incoherent_ht.c +++ b/src/northbridge/amd/amdk8/incoherent_ht.c @@ -10,6 +10,10 @@ #define K8_HT_FREQ_1G_SUPPORT 0 #endif +#ifndef K8_SCAN_PCI_BUS + #define K8_SCAN_PCI_BUS 0 +#endif + static inline void print_linkn_in (const char *strval, uint8_t byteval) { #if 1 @@ -21,7 +25,7 @@ static inline void print_linkn_in (const char *strval, uint8_t byteval) #endif } -static uint8_t ht_lookup_slave_capability(device_t dev) +static uint8_t ht_lookup_capability(device_t dev, uint16_t val) { uint8_t pos; uint8_t hdr_type; @@ -44,8 +48,8 @@ static uint8_t ht_lookup_slave_capability(device_t dev) uint16_t flags; flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); - if ((flags >> 13) == 0) { - /* Entry is a Slave secondary, success... */ + if ((flags >> 13) == val) { + /* Entry is a slave or host , success... */ break; } } @@ -54,6 +58,16 @@ static uint8_t ht_lookup_slave_capability(device_t dev) return pos; } +static uint8_t ht_lookup_slave_capability(device_t dev) +{ + return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format +} + +static uint8_t ht_lookup_host_capability(device_t dev) +{ + return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format +} + static void ht_collapse_previous_enumeration(uint8_t bus) { device_t dev; @@ -135,25 +149,28 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos) return freq_cap; } +#define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \ + (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF)) -#define LINK_OFFS(WIDTH,FREQ,FREQ_CAP) \ - (((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF)) - +#define LINK_CTRL(OFFS) ((OFFS >> 24) & 0xFF) #define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF) #define LINK_FREQ(OFFS) ((OFFS >> 8) & 0xFF) #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF) #define PCI_HT_HOST_OFFS LINK_OFFS( \ + PCI_HT_CAP_HOST_CTRL, \ PCI_HT_CAP_HOST_WIDTH, \ PCI_HT_CAP_HOST_FREQ, \ PCI_HT_CAP_HOST_FREQ_CAP) #define PCI_HT_SLAVE0_OFFS LINK_OFFS( \ + PCI_HT_CAP_SLAVE_CTRL0, \ PCI_HT_CAP_SLAVE_WIDTH0, \ PCI_HT_CAP_SLAVE_FREQ0, \ PCI_HT_CAP_SLAVE_FREQ_CAP0) #define PCI_HT_SLAVE1_OFFS LINK_OFFS( \ + PCI_HT_CAP_SLAVE_CTRL1, \ PCI_HT_CAP_SLAVE_WIDTH1, \ PCI_HT_CAP_SLAVE_FREQ1, \ PCI_HT_CAP_SLAVE_FREQ_CAP1) @@ -164,8 +181,8 @@ static int ht_optimize_link( { static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 }; static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 }; - uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask; - uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2; + uint16_t freq_cap1, freq_cap2; + uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2; uint8_t freq, old_freq; int needs_reset; /* Set link width and frequency */ @@ -228,94 +245,123 @@ static int ht_optimize_link( return needs_reset; } -static int ht_setup_chain(device_t udev, uint8_t upos) +#if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1) +static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus); +static int scan_pci_bus( unsigned bus) { - /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. - * On most boards this just happens. If a cpu has multiple - * non Coherent links the appropriate bus registers for the - * links needs to be programed to point at bus 0. - */ - uint8_t next_unitid, last_unitid; - int reset_needed; - unsigned uoffs; - - /* Make certain the HT bus is not enumerated */ - ht_collapse_previous_enumeration(0); + /* + here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7) + So We can scan these devices to find out if they are bridge + If it is pci bridge, We need to set busn in bridge, and go on + For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus + */ + unsigned int devfn; + unsigned new_bus; + unsigned max_bus; + + new_bus = (bus & 0xff); // mask out the reset_needed + + if(new_bus<0x40) { + max_bus = 0x3f; + } else if (new_bus<0x80) { + max_bus = 0x7f; + } else if (new_bus<0xc0) { + max_bus = 0xbf; + } else { + max_bus = 0xff; + } - reset_needed = 0; - uoffs = PCI_HT_HOST_OFFS; - next_unitid = 1; - do { - uint32_t id; - uint8_t pos; - uint16_t flags; - uint8_t count; - unsigned offs; + new_bus = bus; - device_t dev = PCI_DEV(0, 0, 0); - last_unitid = next_unitid; +#if 0 +#if CONFIG_USE_INIT == 1 + printk_debug("bus_num=%02x\r\n", bus); +#endif +#endif - id = pci_read_config32(dev, PCI_VENDOR_ID); - /* If the chain is enumerated quit */ - if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || - (((id >> 16) & 0xffff) == 0xffff) || - (((id >> 16) & 0xffff) == 0x0000)) { - break; - } + for (devfn = 0; devfn <= 0xff; devfn++) { + uint8_t hdr_type; + uint16_t class; + uint32_t buses; + device_t dev; + uint16_t cr; + dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7)); + hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + class = pci_read_config16(dev, PCI_CLASS_DEVICE); - pos = ht_lookup_slave_capability(dev); - if (!pos) { - print_err("HT link capability not found\r\n"); - break; +#if 0 +#if CONFIG_USE_INIT == 1 + if(hdr_type !=0xff ) { + printk_debug("dev=%02x fn=%02x hdr_type=%02x class=%04x\r\n", + (devfn>>3)& 0x1f, (devfn & 0x7), hdr_type, class); } -#if CK804_DEVN_BASE==0 - //CK804 workaround: - // CK804 UnitID changes not use - id = pci_read_config32(dev, PCI_VENDOR_ID); - if(id != 0x005e10de) { #endif - - /* Update the Unitid of the current device */ - flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); - flags &= ~0x1f; /* mask out the bse Unit ID */ - flags |= next_unitid & 0x1f; - pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); - - dev = PCI_DEV(0, next_unitid, 0); -#if CK804_DEVN_BASE==0 - } - else { - dev = PCI_DEV(0, 0, 0); - } #endif - - /* Compute the number of unitids consumed */ - count = (flags >> 5) & 0x1f; - next_unitid += count; - - /* get ht direction */ - flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ?? - - offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS; - - /* Setup the Hypertransport link */ - reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs); - -#if CK804_DEVN_BASE==0 - if(id == 0x005e10de) { - break; + switch(hdr_type & 0x7f) { /* header type */ + case PCI_HEADER_TYPE_BRIDGE: + if (class != PCI_CLASS_BRIDGE_PCI) goto bad; + /* set the bus range dev */ + + /* Clear all status bits and turn off memory, I/O and master enables. */ + cr = pci_read_config16(dev, PCI_COMMAND); + pci_write_config16(dev, PCI_COMMAND, 0x0000); + pci_write_config16(dev, PCI_STATUS, 0xffff); + + buses = pci_read_config32(dev, PCI_PRIMARY_BUS); + + buses &= 0xff000000; + new_bus++; + buses |= (((unsigned int) (bus & 0xff) << 0) | + ((unsigned int) (new_bus & 0xff) << 8) | + ((unsigned int) max_bus << 16)); + pci_write_config32(dev, PCI_PRIMARY_BUS, buses); + + { + /* here we need to figure out if dev is a ht bridge + if it is ht bridge, we need to call ht_setup_chainx at first + Not verified --- yhlu + */ + uint8_t upos; + upos = ht_lookup_host_capability(dev); // one func one ht sub + if (upos) { // sub ht chain + uint8_t busn; + busn = (new_bus & 0xff); + /* Make certain the HT bus is not enumerated */ + ht_collapse_previous_enumeration(busn); + /* scan the ht chain */ + new_bus |= (ht_setup_chainx(dev,upos,busn)<<16); // store reset_needed to upword + } + } + + new_bus = scan_pci_bus(new_bus); + /* set real max bus num in that */ + + buses = (buses & 0xff00ffff) | + ((unsigned int) (new_bus & 0xff) << 16); + pci_write_config32(dev, PCI_PRIMARY_BUS, buses); + + pci_write_config16(dev, PCI_COMMAND, cr); + + break; + default: + bad: + ; + } + + /* if this is not a multi function device, + * or the device is not present don't waste + * time probing another function. + * Skip to next device. + */ + if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80)) + { + devfn += 0x07; } -#endif - - /* Remeber the location of the last device */ - udev = dev; - upos = pos; - uoffs = (offs != PCI_HT_SLAVE0_OFFS) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS; - - } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); - return reset_needed; + } + + return new_bus; } - +#endif static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus) { uint8_t next_unitid, last_unitid; @@ -328,25 +374,38 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus) do { uint32_t id; uint8_t pos; - uint16_t flags; + uint16_t flags, ctrl; uint8_t count; unsigned offs; - + + /* Wait until the link initialization is complete */ + do { + ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs)); + /* Is this the end of the hypertransport chain? */ + if (ctrl & (1 << 6)) { + break; + } + /* Has the link failed */ + if (ctrl & (1 << 4)) { + break; + } + } while((ctrl & (1 << 5)) == 0); + device_t dev = PCI_DEV(bus, 0, 0); last_unitid = next_unitid; id = pci_read_config32(dev, PCI_VENDOR_ID); /* If the chain is enumerated quit */ - if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) || - (((id >> 16) & 0xffff) == 0xffff) || - (((id >> 16) & 0xffff) == 0x0000)) { + if ( (id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000)) + { break; } pos = ht_lookup_slave_capability(dev); if (!pos) { - print_err(" HT link capability not found\r\n"); + print_err("HT link capability not found\r\n"); break; } @@ -363,6 +422,7 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus) flags |= next_unitid & 0x1f; pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); + /* Note the change in device number */ dev = PCI_DEV(bus, next_unitid, 0); #if CK804_DEVN_BASE==0 } @@ -375,9 +435,11 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus) count = (flags >> 5) & 0x1f; next_unitid += count; - /* get ht direction */ - flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); // double read ?? - + /* Find which side of the ht link we are on, + * by reading which direction our last write to PCI_CAP_FLAGS + * came from. + */ + flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS; /* Setup the Hypertransport link */ @@ -395,9 +457,23 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus) uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS; } while((last_unitid != next_unitid) && (next_unitid <= 0x1f)); + return reset_needed; } +static int ht_setup_chain(device_t udev, unsigned upos) +{ + /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. + * On most boards this just happens. If a cpu has multiple + * non Coherent links the appropriate bus registers for the + * links needs to be programed to point at bus 0. + */ + + /* Make certain the HT bus is not enumerated */ + ht_collapse_previous_enumeration(0); + + return ht_setup_chainx(udev, upos, 0); +} static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val) { uint32_t dword, dword_old; @@ -444,7 +520,7 @@ static int optimize_link_in_coherent(uint8_t ht_c_num) reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID); if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) { val = 0x25; - } else if ( (reg & 0xffff) == 0x10de ) { + } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) { val = 0x25;//??? } else { continue; @@ -477,6 +553,9 @@ static int ht_setup_chains(uint8_t ht_c_num) unsigned regpos; uint32_t dword; uint8_t busn; + #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1) + unsigned bus; + #endif reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4); @@ -498,7 +577,11 @@ static int ht_setup_chains(uint8_t ht_c_num) reset_needed |= ht_setup_chainx(udev,upos,busn); - + #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1) + /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */ + bus = busn; // we need 32 bit + reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword + #endif } reset_needed |= optimize_link_in_coherent(ht_c_num); @@ -506,6 +589,10 @@ static int ht_setup_chains(uint8_t ht_c_num) return reset_needed; } +#ifndef K8_ALLOCATE_IO_RANGE + #define K8_ALLOCATE_IO_RANGE 0 +#endif + static int ht_setup_chains_x(void) { uint8_t nodeid; @@ -514,18 +601,34 @@ static int ht_setup_chains_x(void) uint8_t next_busn; uint8_t ht_c_num; uint8_t nodes; +#if K8_ALLOCATE_IO_RANGE == 1 + unsigned next_io_base; +#endif /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */ reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64); - /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=5+1 */ + /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */ print_linkn_in("SBLink=", ((reg>>8) & 3) ); - tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (5<<24); + tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24); pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg); - next_busn=5+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/ + next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/ + +#if K8_ALLOCATE_IO_RANGE == 1 + /* io range allocation */ + tempreg = 0 | (((reg>>8) & 0x3) << 4 )| (0x3<<12); //limit + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg); + tempreg = 3 | ( 3<<4) | (0<<12); //base + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg); + next_io_base = 0x3+0x1; +#endif + /* clean others */ for(ht_c_num=1;ht_c_num<4; ht_c_num++) { pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0); + /* io range allocation */ + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0); + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0); } nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1; @@ -548,13 +651,23 @@ static int ht_setup_chains_x(void) break; } } - if(ht_c_num == 4) break; /*used up onle 4 non conherent allowed*/ + if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/ /*update to 0xe0...*/ if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */ print_linkn_in("\tbusn=", next_busn); - tempreg |= (next_busn<<16)|((next_busn+5)<<24); + tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24); pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg); - next_busn+=5+1; + next_busn+=0x3f+1; + +#if K8_ALLOCATE_IO_RANGE == 1 + /* io range allocation */ + tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg); + tempreg = 3 | ( 3<<4) | (next_io_base<<12); //base + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg); + next_io_base += 0x3+0x1; +#endif + } } /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/ @@ -568,8 +681,23 @@ static int ht_setup_chains_x(void) regpos = 0xe0 + i * 4; reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); pci_write_config32(dev, regpos, reg); + } +#if K8_ALLOCATE_IO_RANGE == 1 + /* io range allocation */ + for(i = 0; i< 4; i++) { + unsigned regpos; + regpos = 0xc4 + i * 8; + reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); + pci_write_config32(dev, regpos, reg); } + for(i = 0; i< 4; i++) { + unsigned regpos; + regpos = 0xc0 + i * 8; + reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); + pci_write_config32(dev, regpos, reg); + } +#endif } /* recount ht_c_num*/ diff --git a/src/northbridge/amd/amdk8/misc_control.c b/src/northbridge/amd/amdk8/misc_control.c index 4ac6ef473d..4cd3d0d42d 100644 --- a/src/northbridge/amd/amdk8/misc_control.c +++ b/src/northbridge/amd/amdk8/misc_control.c @@ -187,7 +187,10 @@ static void misc_control_init(struct device *dev) /* This works on an Athlon64 because unimplemented links return 0 */ reg = 0x98 + (link * 0x20); link_type = pci_read_config32(f0_dev, reg); - if ((link_type & 7) == 3) { /* Only handle coherent link here */ + /* Only handle coherent link here please */ + if ((link_type & (LinkConnected|InitComplete|NonCoherent)) + == (LinkConnected|InitComplete)) + { cmd &= ~(0xff << (link *8)); /* FIXME this assumes the device on the other side is an AMD device */ cmd |= 0x25 << (link *8); diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index 89602f37a6..e45aff8242 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -40,7 +40,7 @@ static device_t __f1_dev[FX_DEVS]; static void debug_fx_devs(void) { int i; - for (i = 0; i < FX_DEVS; i++) { + for(i = 0; i < FX_DEVS; i++) { device_t dev; dev = __f0_dev[i]; if (dev) { @@ -62,7 +62,7 @@ static void get_fx_devs(void) if (__f1_dev[0]) { return; } - for (i = 0; i < FX_DEVS; i++) { + for(i = 0; i < FX_DEVS; i++) { __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0)); __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1)); } @@ -81,7 +81,7 @@ static void f1_write_config32(unsigned reg, uint32_t value) { int i; get_fx_devs(); - for (i = 0; i < FX_DEVS; i++) { + for(i = 0; i < FX_DEVS; i++) { device_t dev; dev = __f1_dev[i]; if (dev && dev->enabled) { @@ -102,9 +102,9 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) nodeid = amdk8_nodeid(dev); #if 0 printk_debug("%s amdk8_scan_chains max: %d starting...\n", - dev_path(dev), max); + dev_path(dev), max); #endif - for (link = 0; link < dev->links; link++) { + for(link = 0; link < dev->links; link++) { uint32_t link_type; uint32_t busses, config_busses; unsigned free_reg, config_reg; @@ -122,9 +122,10 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) continue; } /* See if there is an available configuration space mapping - * register in function 1. */ + * register in function 1. + */ free_reg = 0; - for (config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) { + for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) { uint32_t config; config = f1_read_config32(config_reg); if (!free_reg && ((config & 3) == 0)) { @@ -132,8 +133,8 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) continue; } if (((config & 3) == 3) && - (((config >> 4) & 7) == nodeid) && - (((config >> 8) & 3) == link)) { + (((config >> 4) & 7) == nodeid) && + (((config >> 8) & 3) == link)) { break; } } @@ -141,7 +142,8 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) config_reg = free_reg; } /* If we can't find an available configuration space mapping - * register skip this bus */ + * register skip this bus + */ if (config_reg > 0xec) { continue; } @@ -158,15 +160,15 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) */ busses = pci_read_config32(dev, dev->link[link].cap + 0x14); config_busses = f1_read_config32(config_reg); - + /* Configure the bus numbers for this bridge: the configuration * transactions will not be propagates by the bridge if it is * not correctly configured */ busses &= 0xff000000; busses |= (((unsigned int)(dev->bus->secondary) << 0) | - ((unsigned int)(dev->link[link].secondary) << 8) | - ((unsigned int)(dev->link[link].subordinate) << 16)); + ((unsigned int)(dev->link[link].secondary) << 8) | + ((unsigned int)(dev->link[link].subordinate) << 16)); pci_write_config32(dev, dev->link[link].cap + 0x14, busses); config_busses &= 0x000fc88; @@ -183,13 +185,14 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) dev_path(dev), link, max); #endif /* Now we can scan all of the subordinate busses i.e. the - * chain on the hypertranport link */ - max = hypertransport_scan_chain(&dev->link[link], max); + * chain on the hypertranport link + */ + max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max); #if 0 printk_debug("%s Hyper transport scan link: %d new max: %d\n", dev_path(dev), link, max); -#endif +#endif /* We know the number of busses behind this bridge. Set the * subordinate bus number to it's real value @@ -202,6 +205,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) config_busses = (config_busses & 0x00ffffff) | (dev->link[link].subordinate << 24); f1_write_config32(config_reg, config_busses); + #if 0 printk_debug("%s Hypertransport scan link: %d done\n", dev_path(dev), link); @@ -214,32 +218,34 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max) return max; } -static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid, - unsigned goal_link) +static int reg_useable(unsigned reg, + device_t goal_dev, unsigned goal_nodeid, unsigned goal_link) { struct resource *res; unsigned nodeid, link; int result; res = 0; - for (nodeid = 0; !res && (nodeid < 8); nodeid++) { + for(nodeid = 0; !res && (nodeid < 8); nodeid++) { device_t dev; dev = __f0_dev[nodeid]; - for (link = 0; !res && (link < 3); link++) { + for(link = 0; !res && (link < 3); link++) { res = probe_resource(dev, 0x100 + (reg | link)); } } result = 2; if (res) { result = 0; - if ((goal_link == (link - 1)) && - (goal_nodeid == (nodeid - 1)) && - (res->flags <= 1)) { + if ( (goal_link == (link - 1)) && + (goal_nodeid == (nodeid - 1)) && + (res->flags <= 1)) { result = 1; } } #if 0 printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n", - reg, result, goal_nodeid, goal_link, nodeid, link); + reg, result, + goal_nodeid, goal_link, + nodeid, link); #endif return result; } @@ -250,7 +256,7 @@ static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigne unsigned free_reg, reg; resource = 0; free_reg = 0; - for (reg = 0xc0; reg <= 0xd8; reg += 0x8) { + for(reg = 0xc0; reg <= 0xd8; reg += 0x8) { int result; result = reg_useable(reg, dev, nodeid, link); if (result == 1) { @@ -277,7 +283,7 @@ static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsign unsigned free_reg, reg; resource = 0; free_reg = 0; - for (reg = 0x80; reg <= 0xb8; reg += 0x8) { + for(reg = 0x80; reg <= 0xb8; reg += 0x8) { int result; result = reg_useable(reg, dev, nodeid, link); if (result == 1) { @@ -348,7 +354,7 @@ static void amdk8_read_resources(device_t dev) { unsigned nodeid, link; nodeid = amdk8_nodeid(dev); - for (link = 0; link < dev->links; link++) { + for(link = 0; link < dev->links; link++) { if (dev->link[link].children) { amdk8_link_read_bases(dev, nodeid, link); } @@ -499,11 +505,11 @@ static void amdk8_set_resources(device_t dev) amdk8_create_vga_resource(dev, nodeid); /* Set each resource we have found */ - for (i = 0; i < dev->resources; i++) { + for(i = 0; i < dev->resources; i++) { amdk8_set_resource(dev, &dev->resource[i], nodeid); } - for (link = 0; link < dev->links; link++) { + for(link = 0; link < dev->links; link++) { struct bus *bus; bus = &dev->link[link]; if (bus->children) { @@ -520,26 +526,9 @@ static void amdk8_enable_resources(device_t dev) static void mcf0_control_init(struct device *dev) { - uint32_t cmd; - #if 0 printk_debug("NB: Function 0 Misc Control.. "); #endif -#if 1 - /* improve latency and bandwith on HT */ - cmd = pci_read_config32(dev, 0x68); - cmd &= 0xffff80ff; - cmd |= 0x00004800; - pci_write_config32(dev, 0x68, cmd ); -#endif - -#if 0 - /* over drive the ht port to 1000 Mhz */ - cmd = pci_read_config32(dev, 0xa8); - cmd &= 0xfffff0ff; - cmd |= 0x00000600; - pci_write_config32(dev, 0xdc, cmd ); -#endif #if 0 printk_debug("done.\n"); #endif @@ -578,7 +567,7 @@ static void pci_domain_read_resources(device_t dev) /* Find the already assigned resource pairs */ get_fx_devs(); - for (reg = 0x80; reg <= 0xd8; reg+= 0x08) { + for(reg = 0x80; reg <= 0xd8; reg+= 0x08) { uint32_t base, limit; base = f1_read_config32(reg); limit = f1_read_config32(reg + 0x04); @@ -612,8 +601,8 @@ static void pci_domain_read_resources(device_t dev) resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; } -static void ram_resource(device_t dev, unsigned long index, - unsigned long basek, unsigned long sizek) +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) { struct resource *resource; @@ -691,7 +680,7 @@ static void pci_domain_set_resources(device_t dev) #endif idx = 10; - for (i = 0; i < 8; i++) { + for(i = 0; i < 8; i++) { uint32_t base, limit; unsigned basek, limitk, sizek; base = f1_read_config32(0x40 + (i << 3)); @@ -737,11 +726,35 @@ static void pci_domain_set_resources(device_t dev) static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) { unsigned reg; + int i; /* Unmap all of the HT chains */ - for (reg = 0xe0; reg <= 0xec; reg += 4) { + for(reg = 0xe0; reg <= 0xec; reg += 4) { f1_write_config32(reg, 0); } max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max); + + /* Tune the hypertransport transaction for best performance. + * Including enabling relaxed ordering if it is safe. + */ + get_fx_devs(); + for(i = 0; i < FX_DEVS; i++) { + device_t f0_dev; + f0_dev = __f0_dev[i]; + if (f0_dev && f0_dev->enabled) { + uint32_t httc; + int j; + httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL); + httc &= ~HTTC_RSP_PASS_PW; + if (!dev->link[0].disable_relaxed_ordering) { + httc |= HTTC_RSP_PASS_PW; + } + printk_spew("%s passpw: %s\n", + dev_path(dev), + (!dev->link[0].disable_relaxed_ordering)? + "enabled":"disabled"); + pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc); + } + } return max; } @@ -755,20 +768,34 @@ static struct device_operations pci_domain_ops = { }; #define APIC_ID_OFFSET 0x10 + static unsigned int cpu_bus_scan(device_t dev, unsigned int max) { struct bus *cpu_bus; device_t dev_mc; + int bsp_apic_id; + int apic_id_offset; int i,j; - unsigned nb_cfg_54 = 0; - unsigned siblings = 0; - int enable_apic_ext_id = 0; - int bsp_apic_id = lapicid(); // bsp apicid - int apic_id_offset = bsp_apic_id; + unsigned nb_cfg_54; + int enable_apic_ext_id; + unsigned siblings; +#if CONFIG_LOGICAL_CPUS == 1 + int e0_later_single_core; + int disable_siblings; +#endif -#if CONFIG_LOGICAL_CPUS==1 - int e0_later_single_core; - int disable_siblings = !CONFIG_LOGICAL_CPUS; + nb_cfg_54 = 0; + enable_apic_ext_id = 0; + siblings = 0; + + /* Find the bootstrap processors apicid */ + bsp_apic_id = lapicid(); + + /* See if I will enable extended ids' */ + apic_id_offset = bsp_apic_id; + +#if CONFIG_LOGICAL_CPUS == 1 + disable_siblings = !CONFIG_LOGICAL_CPUS; get_option(&disable_siblings, "dual_core"); // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it still be 0) @@ -776,45 +803,42 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max) nb_cfg_54 = read_nb_cfg_54(); #endif - dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0)); - if(pci_read_config32(dev_mc, 0x68) & ( HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST)) { + if (!dev_mc) { + die("0:18.0 not found?"); + } + if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST)) + { enable_apic_ext_id = 1; - if(apic_id_offset==0) { //bsp apic id is not changed + if (apic_id_offset == 0) { + /* bsp apic id is not changed */ apic_id_offset = APIC_ID_OFFSET; } } - /* Find which cpus are present */ cpu_bus = &dev->link[0]; - for (i = 0; i < 8; i++) { + for(i = 0; i < 8; i++) { device_t dev, cpu; struct device_path cpu_path; - /* Find the cpu's memory controller */ + /* Find the cpu's pci device */ dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3)); - if(!dev) { // in case we move apic cluser before pci_domain and not set that for second CPU - for(j=0; j<4; j++) { - struct device dummy; - uint32_t id; - dummy.bus = dev_mc->bus; - dummy.path.type = DEVICE_PATH_PCI; - dummy.path.u.pci.devfn = PCI_DEVFN(0x18 + i, j); - id = pci_read_config32(&dummy, PCI_VENDOR_ID); - if (id != 0xffffffff && id != 0x00000000 && - id != 0x0000ffff && id != 0xffff0000) { - //create that for it - dev = alloc_dev(dev_mc->bus, &dummy.path); - } + if (!dev) { + /* If I am probing things in a weird order + * ensure all of the cpu's pci devices are found. + */ + int j; + for(j = 0; j <= 3; j++) { + dev = pci_probe_dev(NULL, dev_mc->bus, + PCI_DEVFN(0x18 + i, j)); } } -#if CONFIG_LOGICAL_CPUS==1 +#if CONFIG_LOGICAL_CPUS == 1 e0_later_single_core = 0; - if((!disable_siblings) && dev && dev->enabled) { - j = (pci_read_config32(dev, 0xe8) >> 12) & 3; //dev is func 3 - + if ((!disable_siblings) && dev && dev->enabled) { + j = (pci_read_config32(dev, 0xe8) >> 12) & 3; // dev is func 3 printk_debug(" %s siblings=%d\r\n", dev_path(dev), j); if(nb_cfg_54) { @@ -843,51 +867,49 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max) } } else { siblings = j; - } + } } #endif - #if CONFIG_LOGICAL_CPUS==1 for (j = 0; j <= (e0_later_single_core?0:siblings); j++ ) { #else - for (j = 0; j <= siblings; j++ ) { + for (j = 0; j <= siblings; j++ ) { #endif - /* Build the cpu device path */ - cpu_path.type = DEVICE_PATH_APIC; - cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8); - - /* See if I can find the cpu */ - cpu = find_dev_path(cpu_bus, &cpu_path); - - /* Enable the cpu if I have the processor */ - if (dev && dev->enabled) { - if (!cpu) { - cpu = alloc_dev(cpu_bus, &cpu_path); - } - if (cpu) { - cpu->enabled = 1; - } - } - - /* Disable the cpu if I don't have the processor */ - if (cpu && (!dev || !dev->enabled)) { - cpu->enabled = 0; - } - - /* Report what I have done */ - if (cpu) { - if(enable_apic_ext_id) { - if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0 - if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) ) - cpu->path.u.apic.apic_id += apic_id_offset; - } + /* Build the cpu device path */ + cpu_path.type = DEVICE_PATH_APIC; + cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8); + + /* See if I can find the cpu */ + cpu = find_dev_path(cpu_bus, &cpu_path); + + /* Enable the cpu if I have the processor */ + if (dev && dev->enabled) { + if (!cpu) { + cpu = alloc_dev(cpu_bus, &cpu_path); } - printk_debug("CPU: %s %s\n", - dev_path(cpu), cpu->enabled?"enabled":"disabled"); - } - } //j + if (cpu) { + cpu->enabled = 1; + } + } + + /* Disable the cpu if I don't have the processor */ + if (cpu && (!dev || !dev->enabled)) { + cpu->enabled = 0; + } + + /* Report what I have done */ + if (cpu) { + if(enable_apic_ext_id) { + if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0 + if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) ) + cpu->path.u.apic.apic_id += apic_id_offset; + } + } + printk_debug("CPU: %s %s\n", + dev_path(cpu), cpu->enabled?"enabled":"disabled"); + } + } //j } - return max; } diff --git a/src/northbridge/amd/amdk8/setup_resource_map.c b/src/northbridge/amd/amdk8/setup_resource_map.c index ebd1978a7c..27da719409 100644 --- a/src/northbridge/amd/amdk8/setup_resource_map.c +++ b/src/northbridge/amd/amdk8/setup_resource_map.c @@ -1,16 +1,53 @@ #define RES_DEBUG 0 +static void setup_resource_map_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base) +{ + int i; +// print_debug("setting up resource map offset...."); +#if 0 + print_debug("\r\n"); +#endif + for(i = 0; i < max; i += 3) { + device_t dev; + unsigned where; + unsigned long reg; +#if 0 + #if CONFIG_USE_INIT + prink_debug("%08x <- %08x\r\n", register_values[i] + offset_pci_dev, register_values[i+2]); + #else + print_debug_hex32(register_values[i] + offset_pci_dev); + print_debug(" <-"); + print_debug_hex32(register_values[i+2]); + print_debug("\r\n"); + #endif +#endif + dev = (register_values[i] & ~0xff) + offset_pci_dev; + where = register_values[i] & 0xff; + reg = pci_read_config32(dev, where); + reg &= register_values[i+1]; + reg |= register_values[i+2] + offset_io_base; + pci_write_config32(dev, where, reg); +#if 0 + reg = pci_read_config32(register_values[i]); + reg &= register_values[i+1]; + reg |= register_values[i+2] & ~register_values[i+1]; + pci_write_config32(register_values[i], reg); +#endif + } +// print_debug("done.\r\n"); +} + #define RES_PCI_IO 0x10 #define RES_PORT_IO_8 0x22 #define RES_PORT_IO_32 0x20 -#define RES_MEM_IO 0x30 +#define RES_MEM_IO 0x40 -static void setup_resource_map_x(const unsigned int *register_values, int max) +static void setup_resource_map_x_offset(const unsigned int *register_values, int max, unsigned offset_pci_dev, unsigned offset_io_base) { int i; #if RES_DEBUG - print_debug("setting up resource map ex...."); + print_debug("setting up resource map ex offset...."); #endif @@ -21,17 +58,23 @@ static void setup_resource_map_x(const unsigned int *register_values, int max) #if RES_DEBUG #if CONFIG_USE_INIT printk_debug("%04x: %02x %08x <- & %08x | %08x\r\n", - i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]); + i/4, register_values[i], + register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0), + register_values[i+2], + register_values[i+3] + ( ( (register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0) + ); #else print_debug_hex16(i/4); print_debug(": "); print_debug_hex8(register_values[i]); print_debug(" "); - print_debug_hex32(register_values[i+1]); + print_debug_hex32(register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0) ); print_debug(" <- & "); print_debug_hex32(register_values[i+2]); print_debug(" | "); - print_debug_hex32(register_values[i+3]); + print_debug_hex32(register_values[i+3] + + (((register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0) + ); print_debug("\r\n"); #endif #endif @@ -41,7 +84,7 @@ static void setup_resource_map_x(const unsigned int *register_values, int max) device_t dev; unsigned where; unsigned long reg; - dev = register_values[i+1] & ~0xff; + dev = (register_values[i+1] & ~0xff) + offset_pci_dev; where = register_values[i+1] & 0xff; reg = pci_read_config32(dev, where); reg &= register_values[i+2]; @@ -53,7 +96,7 @@ static void setup_resource_map_x(const unsigned int *register_values, int max) { unsigned where; unsigned reg; - where = register_values[i+1]; + where = register_values[i+1] + offset_io_base; reg = inb(where); reg &= register_values[i+2]; reg |= register_values[i+3]; @@ -64,7 +107,7 @@ static void setup_resource_map_x(const unsigned int *register_values, int max) { unsigned where; unsigned long reg; - where = register_values[i+1]; + where = register_values[i+1] + offset_io_base; reg = inl(where); reg &= register_values[i+2]; reg |= register_values[i+3]; @@ -94,7 +137,95 @@ static void setup_resource_map_x(const unsigned int *register_values, int max) print_debug("done.\r\n"); #endif } +static void setup_resource_map_x(const unsigned int *register_values, int max) +{ + int i; +#if RES_DEBUG + print_debug("setting up resource map ex offset...."); + +#endif + +#if RES_DEBUG + print_debug("\r\n"); +#endif + for(i = 0; i < max; i += 4) { +#if RES_DEBUG + #if CONFIG_USE_INIT + printk_debug("%04x: %02x %08x <- & %08x | %08x\r\n", + i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]); + #else + print_debug_hex16(i/4); + print_debug(": "); + print_debug_hex8(register_values[i]); + print_debug(" "); + print_debug_hex32(register_values[i+1]); + print_debug(" <- & "); + print_debug_hex32(register_values[i+2]); + print_debug(" | "); + print_debug_hex32(register_values[i+3]); + print_debug("\r\n"); + #endif +#endif + switch (register_values[i]) { + case RES_PCI_IO: //PCI + { + device_t dev; + unsigned where; + unsigned long reg; + dev = register_values[i+1] & ~0xff; + where = register_values[i+1] & 0xff; + reg = pci_read_config32(dev, where); + reg &= register_values[i+2]; + reg |= register_values[i+3]; + pci_write_config32(dev, where, reg); + } + break; + case RES_PORT_IO_8: // io 8 + { + unsigned where; + unsigned reg; + where = register_values[i+1]; + reg = inb(where); + reg &= register_values[i+2]; + reg |= register_values[i+3]; + outb(reg, where); + } + break; + case RES_PORT_IO_32: //io32 + { + unsigned where; + unsigned long reg; + where = register_values[i+1]; + reg = inl(where); + reg &= register_values[i+2]; + reg |= register_values[i+3]; + outl(reg, where); + } + break; +#if 0 + case RES_MEM_IO: //mem + { + unsigned where; + unsigned long reg; + where = register_values[i+1]; + reg = read32(where); + reg &= register_values[i+2]; + reg |= register_values[i+3]; + write32( where, reg); + } + break; +#endif + + } // switch + + + } + +#if RES_DEBUG + print_debug("done.\r\n"); +#endif +} static void setup_iob_resource_map(const unsigned int *register_values, int max) { diff --git a/src/northbridge/intel/E7520/Config.lb b/src/northbridge/intel/E7520/Config.lb new file mode 100644 index 0000000000..064c867618 --- /dev/null +++ b/src/northbridge/intel/E7520/Config.lb @@ -0,0 +1,12 @@ +config chip.h +driver northbridge.o +driver pciexp_porta.o +driver pciexp_porta1.o +driver pciexp_portb.o +driver pciexp_portc.o + +makerule raminit_test + depends "$(TOP)/src/northbridge/intel/e7520/raminit_test.c" + depends "$(TOP)/src/northbridge/intel/e7520/raminit.c" + action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g $< -o $@" +end diff --git a/src/northbridge/intel/E7520/chip.h b/src/northbridge/intel/E7520/chip.h new file mode 100644 index 0000000000..e9ee0a2e10 --- /dev/null +++ b/src/northbridge/intel/E7520/chip.h @@ -0,0 +1,7 @@ +struct northbridge_intel_E7520_config +{ + /* Interrupt line connect */ + unsigned int intrline; +}; + +extern struct chip_operations northbridge_intel_E7520_ops; diff --git a/src/northbridge/intel/E7520/e7520.h b/src/northbridge/intel/E7520/e7520.h new file mode 100644 index 0000000000..be76303d4f --- /dev/null +++ b/src/northbridge/intel/E7520/e7520.h @@ -0,0 +1,44 @@ +#define VID 0X00 +#define DID 0X02 +#define PCICMD 0X04 +#define PCISTS 0X06 +#define RID 0X08 +#define IURBASE 0X14 +#define MCHCFG0 0X50 +#define MCHSCRB 0X52 +#define FDHC 0X58 +#define PAM 0X59 +#define DRB 0X60 +#define DRA 0X70 +#define DRT 0X78 +#define DRC 0X7C +#define DRM 0X80 +#define DRORC 0X82 +#define ECCDIAG 0X84 +#define SDRC 0X88 +#define CKDIS 0X8C +#define CKEDIS 0X8D +#define DDRCSR 0X9A +#define DEVPRES 0X9C +#define DEVPRES_D0F0 (1 << 0) +#define DEVPRES_D1F0 (1 << 1) +#define DEVPRES_D2F0 (1 << 2) +#define DEVPRES_D3F0 (1 << 3) +#define DEVPRES_D4F0 (1 << 4) +#define DEVPRES_D5F0 (1 << 5) +#define DEVPRES_D6F0 (1 << 6) +#define DEVPRES_D7F0 (1 << 7) +#define ESMRC 0X9D +#define SMRC 0X9E +#define EXSMRC 0X9F +#define DDR2ODTC 0XB0 +#define TOLM 0XC4 +#define REMAPBASE 0XC6 +#define REMAPLIMIT 0XC8 +#define REMAPOFFSET 0XCA +#define TOM 0XCC +#define EXPECBASE 0XCE +#define DEVPRES1 0XF4 +#define DEVPRES1_D0F1 (1 << 5) +#define DEVPRES1_D8F0 (1 << 1) +#define MSCFG 0XF6 diff --git a/src/northbridge/intel/E7520/memory_initialized.c b/src/northbridge/intel/E7520/memory_initialized.c new file mode 100644 index 0000000000..3b9b696a21 --- /dev/null +++ b/src/northbridge/intel/E7520/memory_initialized.c @@ -0,0 +1,13 @@ +#include "e7520.h" +#define NB_DEV PCI_DEV(0, 0, 0) + +static inline int memory_initialized(void) +{ + uint32_t drc; + drc = pci_read_config32(NB_DEV, DRC); + //print_debug("memory_initialized: DRC: "); + //print_debug_hex32(drc); + //print_debug("\r\n"); + + return (drc & (1<<29)); +} diff --git a/src/northbridge/intel/E7520/northbridge.c b/src/northbridge/intel/E7520/northbridge.c new file mode 100644 index 0000000000..44490861f8 --- /dev/null +++ b/src/northbridge/intel/E7520/northbridge.c @@ -0,0 +1,270 @@ +#include <console/console.h> +#include <arch/io.h> +#include <stdint.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/hypertransport.h> +#include <stdlib.h> +#include <string.h> +#include <bitops.h> +#include <cpu/cpu.h> +#include "chip.h" +#include "northbridge.h" +#include "e7520.h" + + +static unsigned int max_bus; + +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + + +static void pci_domain_read_resources(device_t dev) +{ + struct resource *resource; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0,0)); + resource->base = 0; + resource->size = 0; + resource->align = 0; + resource->gran = 0; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1,0)); + resource->base = 0; + resource->size = 0; + resource->align = 0; + resource->gran = 0; + resource->limit = 0xffffffffUL; + resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; +} + +static void tolm_test(void *gp, struct device *dev, struct resource *new) +{ + struct resource **best_p = gp; + struct resource *best; + best = *best_p; + if (!best || (best->base > new->base)) { + best = new; + } + *best_p = best; +} + +static uint32_t find_pci_tolm(struct bus *bus) +{ + struct resource *min; + uint32_t tolm; + min = 0; + search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min); + tolm = 0xffffffffUL; + if (min && tolm > min->base) { + tolm = min->base; + } + return tolm; +} + + +static void pci_domain_set_resources(device_t dev) +{ + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = find_pci_tolm(&dev->link[0]); + +#if 1 + printk_debug("PCI mem marker = %x\n", pci_tolm); +#endif + /* FIXME Me temporary hack */ + if(pci_tolm > 0xe0000000) + pci_tolm = 0xe0000000; + /* Ensure pci_tolm is 128M aligned */ + pci_tolm &= 0xf8000000; + mc_dev = dev->link[0].children; + if (mc_dev) { + /* Figure out which areas are/should be occupied by RAM. + * This is all computed in kilobytes and converted to/from + * the memory controller right at the edges. + * Having different variables in different units is + * too confusing to get right. Kilobytes are good up to + * 4 Terabytes of RAM... + */ + uint16_t tolm_r, remapbase_r, remaplimit_r, remapoffset_r; + unsigned long tomk, tolmk; + unsigned long remapbasek, remaplimitk, remapoffsetk; + + /* Get the Top of Memory address, units are 128M */ + tomk = ((unsigned long)pci_read_config16(mc_dev, TOM)) << 17; + /* Compute the Top of Low Memory */ + tolmk = (pci_tolm & 0xf8000000) >> 10; + + if (tolmk >= tomk) { + /* The PCI hole does not overlap memory + * we won't use the remap window. + */ + tolmk = tomk; + remapbasek = 0x3ff << 16; + remaplimitk = 0 << 16; + remapoffsetk = 0 << 16; + } + else { + /* The PCI memory hole overlaps memory + * setup the remap window. + */ + /* Find the bottom of the remap window + * is it above 4G? + */ + remapbasek = 4*1024*1024; + if (tomk > remapbasek) { + remapbasek = tomk; + } + /* Find the limit of the remap window */ + remaplimitk = (remapbasek + (4*1024*1024 - tolmk) - (1 << 16)); + /* Find the offset of the remap window from tolm */ + remapoffsetk = remapbasek - tolmk; + } + /* Write the ram configruation registers, + * preserving the reserved bits. + */ + tolm_r = pci_read_config16(mc_dev, 0xc4); + tolm_r = ((tolmk >> 17) << 11) | (tolm_r & 0x7ff); + pci_write_config16(mc_dev, 0xc4, tolm_r); + + remapbase_r = pci_read_config16(mc_dev, 0xc6); + remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00); + pci_write_config16(mc_dev, 0xc6, remapbase_r); + + remaplimit_r = pci_read_config16(mc_dev, 0xc8); + remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00); + pci_write_config16(mc_dev, 0xc8, remaplimit_r); + + remapoffset_r = pci_read_config16(mc_dev, 0xca); + remapoffset_r = (remapoffsetk >> 16) | (remapoffset_r & 0xfc00); + pci_write_config16(mc_dev, 0xca, remapoffset_r); + + /* Report the memory regions */ + ram_resource(dev, 3, 0, 640); + ram_resource(dev, 4, 768, (tolmk - 768)); + if (tomk > 4*1024*1024) { + ram_resource(dev, 5, 4096*1024, tomk - 4*1024*1024); + } + if (remaplimitk >= remapbasek) { + ram_resource(dev, 6, remapbasek, + (remaplimitk + 64*1024) - remapbasek); + } + } + assign_resources(&dev->link[0]); +} + +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], 0, 0xff, max); + if (max > max_bus) { + max_bus = max; + } + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, + .ops_pci_bus = &pci_cf8_conf1, /* Do we want to use the memory mapped space here? */ +}; + +static void mc_read_resources(device_t dev) +{ + struct resource *resource; + + pci_dev_read_resources(dev); + + resource = new_resource(dev, 0xcf); + resource->base = 0xe0000000; + resource->size = max_bus * 4096*256; + resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static void mc_set_resources(device_t dev) +{ + struct resource *resource, *last; + + last = &dev->resource[dev->resources]; + resource = find_resource(dev, 0xcf); + if (resource) { + report_resource_stored(dev, resource, "<mmconfig>"); + } + pci_dev_set_resources(dev); +} + +static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations intel_pci_ops = { + .set_subsystem = intel_set_subsystem, +}; + +static struct device_operations mc_ops = { + .read_resources = mc_read_resources, + .set_resources = mc_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .ops_pci = &intel_pci_ops, +}; + +static struct pci_driver mc_driver __pci_driver = { + .ops = &mc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x3590, +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); +} + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + + +static void enable_dev(device_t dev) +{ + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { + dev->ops = &cpu_bus_ops; + } +} + +struct chip_operations northbridge_intel_E7520_ops = { + CHIP_NAME("Intel E7520 Northbridge") + .enable_dev = enable_dev, +}; diff --git a/src/northbridge/intel/E7520/northbridge.h b/src/northbridge/intel/E7520/northbridge.h new file mode 100644 index 0000000000..516834f23a --- /dev/null +++ b/src/northbridge/intel/E7520/northbridge.h @@ -0,0 +1,8 @@ +#ifndef NORTHBRIDGE_INTEL_E7520_H +#define NORTHBRIDGE_INTEL_E7520_H + +extern unsigned int e7520_scan_root_bus(device_t root, unsigned int max); + + +#endif /* NORTHBRIDGE_INTEL_E7520_H */ + diff --git a/src/northbridge/intel/E7520/pciexp_porta.c b/src/northbridge/intel/E7520/pciexp_porta.c new file mode 100644 index 0000000000..5443d66174 --- /dev/null +++ b/src/northbridge/intel/E7520/pciexp_porta.c @@ -0,0 +1,62 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" +#include <part/hard_reset.h> + +typedef struct northbridge_intel_E7520_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static unsigned int pcie_scan_bridge(struct device *dev, unsigned int max) +{ + uint16_t val; + uint16_t ctl; + int flag = 0; + do { + val = pci_read_config16(dev, 0x76); + printk_debug("pcie porta 0x76: %02x\n", val); + if((val & (1<<10) )&&(!flag)) { /* training error */ + ctl = pci_read_config16(dev, 0x74); + pci_write_config16(dev, 0x74, (ctl | (1<<5))); + val = pci_read_config16(dev, 0x76); + printk_debug("pcie porta reset 0x76: %02x\n", val); + flag=1; + hard_reset(); + } + } while ( val & (3<<10) ); + return pciexp_scan_bridge(dev, max); +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pcie_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PA, +}; + + diff --git a/src/northbridge/intel/E7520/pciexp_porta1.c b/src/northbridge/intel/E7520/pciexp_porta1.c new file mode 100644 index 0000000000..b4dcb2fe15 --- /dev/null +++ b/src/northbridge/intel/E7520/pciexp_porta1.c @@ -0,0 +1,41 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7520_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PA1, +}; + + diff --git a/src/northbridge/intel/E7520/pciexp_portb.c b/src/northbridge/intel/E7520/pciexp_portb.c new file mode 100644 index 0000000000..7f17925212 --- /dev/null +++ b/src/northbridge/intel/E7520/pciexp_portb.c @@ -0,0 +1,42 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7520_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PB, +}; + + diff --git a/src/northbridge/intel/E7520/pciexp_portc.c b/src/northbridge/intel/E7520/pciexp_portc.c new file mode 100644 index 0000000000..c46610b069 --- /dev/null +++ b/src/northbridge/intel/E7520/pciexp_portc.c @@ -0,0 +1,41 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7520_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PC, +}; + + diff --git a/src/northbridge/intel/E7520/raminit.c b/src/northbridge/intel/E7520/raminit.c new file mode 100644 index 0000000000..22ac115d6b --- /dev/null +++ b/src/northbridge/intel/E7520/raminit.c @@ -0,0 +1,1333 @@ +#include <cpu/x86/mem.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/cache.h> +#include "raminit.h" +#include "e7520.h" + +#define BAR 0x40000000 + +static void sdram_set_registers(const struct mem_controller *ctrl) +{ + static const unsigned int register_values[] = { + + /* CKDIS 0x8c disable clocks */ + PCI_ADDR(0, 0x00, 0, CKDIS), 0xffff0000, 0x0000ffff, + + /* 0x9c Device present and extended RAM control + * DEVPRES is very touchy, hard code the initialization + * of PCI-E ports here. + */ + PCI_ADDR(0, 0x00, 0, DEVPRES), 0x00000000, 0x07020801 | DEVPRES_CONFIG, + + /* 0xc8 Remap RAM base and limit off */ + PCI_ADDR(0, 0x00, 0, REMAPLIMIT), 0x00000000, 0x03df0000, + + /* ??? */ + PCI_ADDR(0, 0x00, 0, 0xd8), 0x00000000, 0xb5930000, + PCI_ADDR(0, 0x00, 0, 0xe8), 0x00000000, 0x00004a2a, + + /* 0x50 scrub */ + PCI_ADDR(0, 0x00, 0, MCHCFG0), 0xfce0ffff, 0x00006000, /* 6000 */ + + /* 0x58 0x5c PAM */ + PCI_ADDR(0, 0x00, 0, PAM-1), 0xcccccc7f, 0x33333000, + PCI_ADDR(0, 0x00, 0, PAM+3), 0xcccccccc, 0x33333333, + + /* 0xf4 */ + PCI_ADDR(0, 0x00, 0, DEVPRES1), 0xffbffff, (1<<22)|(6<<2) | DEVPRES1_CONFIG, + + /* 0x14 */ + PCI_ADDR(0, 0x00, 0, IURBASE), 0x00000fff, BAR |0, + }; + int i; + int max; + + max = sizeof(register_values)/sizeof(register_values[0]); + for(i = 0; i < max; i += 3) { + device_t dev; + unsigned where; + unsigned long reg; + dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x00, 0) + ctrl->f0; + where = register_values[i] & 0xff; + reg = pci_read_config32(dev, where); + reg &= register_values[i+1]; + reg |= register_values[i+2]; + pci_write_config32(dev, where, reg); + } + print_spew("done.\r\n"); +} + + + +struct dimm_size { + unsigned long side1; + unsigned long side2; +}; + +static struct dimm_size spd_get_dimm_size(unsigned device) +{ + /* Calculate the log base 2 size of a DIMM in bits */ + struct dimm_size sz; + int value, low, ddr2; + sz.side1 = 0; + sz.side2 = 0; + + /* test for ddr2 */ + ddr2=0; + value = spd_read_byte(device, 2); /* type */ + if (value < 0) goto hw_err; + if (value == 8) ddr2 = 1; + + /* Note it might be easier to use byte 31 here, it has the DIMM size as + * a multiple of 4MB. The way we do it now we can size both + * sides of an assymetric dimm. + */ + value = spd_read_byte(device, 3); /* rows */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + sz.side1 += value & 0xf; + + value = spd_read_byte(device, 4); /* columns */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + sz.side1 += value & 0xf; + + value = spd_read_byte(device, 17); /* banks */ + if (value < 0) goto hw_err; + if ((value & 0xff) == 0) goto val_err; + sz.side1 += log2(value & 0xff); + + /* Get the module data width and convert it to a power of two */ + value = spd_read_byte(device, 7); /* (high byte) */ + if (value < 0) goto hw_err; + value &= 0xff; + value <<= 8; + + low = spd_read_byte(device, 6); /* (low byte) */ + if (low < 0) goto hw_err; + value = value | (low & 0xff); + if ((value != 72) && (value != 64)) goto val_err; + sz.side1 += log2(value); + + /* side 2 */ + value = spd_read_byte(device, 5); /* number of physical banks */ + + if (value < 0) goto hw_err; + value &= 7; + if(ddr2) value++; + if (value == 1) goto out; + if (value != 2) goto val_err; + + /* Start with the symmetrical case */ + sz.side2 = sz.side1; + + value = spd_read_byte(device, 3); /* rows */ + if (value < 0) goto hw_err; + if ((value & 0xf0) == 0) goto out; /* If symmetrical we are done */ + sz.side2 -= (value & 0x0f); /* Subtract out rows on side 1 */ + sz.side2 += ((value >> 4) & 0x0f); /* Add in rows on side 2 */ + + value = spd_read_byte(device, 4); /* columns */ + if (value < 0) goto hw_err; + if ((value & 0xff) == 0) goto val_err; + sz.side2 -= (value & 0x0f); /* Subtract out columns on side 1 */ + sz.side2 += ((value >> 4) & 0x0f); /* Add in columsn on side 2 */ + goto out; + + val_err: + die("Bad SPD value\r\n"); + /* If an hw_error occurs report that I have no memory */ +hw_err: + sz.side1 = 0; + sz.side2 = 0; + out: + return sz; + +} + +static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask) +{ + int i; + int cum; + + for(i = cum = 0; i < DIMM_SOCKETS; i++) { + struct dimm_size sz; + if (dimm_mask & (1 << i)) { + sz = spd_get_dimm_size(ctrl->channel0[i]); + if (sz.side1 < 29) { + return -1; /* Report SPD error */ + } + /* convert bits to multiples of 64MB */ + sz.side1 -= 29; + cum += (1 << sz.side1); + /* DRB = 0x60 */ + pci_write_config8(ctrl->f0, DRB + (i*2), cum); + if( sz.side2 > 28) { + sz.side2 -= 29; + cum += (1 << sz.side2); + } + pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum); + } + else { + pci_write_config8(ctrl->f0, DRB + (i*2), cum); + pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum); + } + } + /* set TOM top of memory 0xcc */ + pci_write_config16(ctrl->f0, TOM, cum); + /* set TOLM top of low memory */ + if(cum > 0x18) { + cum = 0x18; + } + cum <<= 11; + /* 0xc4 TOLM */ + pci_write_config16(ctrl->f0, TOLM, cum); + return 0; +} + + +static unsigned int spd_detect_dimms(const struct mem_controller *ctrl) +{ + unsigned dimm_mask; + int i; + dimm_mask = 0; + for(i = 0; i < DIMM_SOCKETS; i++) { + int byte; + unsigned device; + device = ctrl->channel0[i]; + if (device) { + byte = spd_read_byte(device, 2); /* Type */ + if ((byte == 7) || (byte == 8)) { + dimm_mask |= (1 << i); + } + } + device = ctrl->channel1[i]; + if (device) { + byte = spd_read_byte(device, 2); + if ((byte == 7) || (byte == 8)) { + dimm_mask |= (1 << (i + DIMM_SOCKETS)); + } + } + } + return dimm_mask; +} + + +static int spd_set_row_attributes(const struct mem_controller *ctrl, + long dimm_mask) +{ + + int value; + int reg; + int dra; + int cnt; + + dra = 0; + for(cnt=0; cnt < 4; cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + reg =0; + value = spd_read_byte(ctrl->channel0[cnt], 3); /* rows */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + reg += value & 0xf; + + value = spd_read_byte(ctrl->channel0[cnt], 4); /* columns */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + reg += value & 0xf; + + value = spd_read_byte(ctrl->channel0[cnt], 17); /* banks */ + if (value < 0) goto hw_err; + if ((value & 0xff) == 0) goto val_err; + reg += log2(value & 0xff); + + /* Get the device width and convert it to a power of two */ + value = spd_read_byte(ctrl->channel0[cnt], 13); + if (value < 0) goto hw_err; + value = log2(value & 0xff); + reg += value; + if(reg < 27) goto hw_err; + reg -= 27; + reg += (value << 2); + + dra += reg << (cnt*8); + value = spd_read_byte(ctrl->channel0[cnt], 5); + if (value & 2) + dra += reg << ((cnt*8)+4); + } + + /* 0x70 DRA */ + pci_write_config32(ctrl->f0, DRA, dra); + goto out; + + val_err: + die("Bad SPD value\r\n"); + /* If an hw_error occurs report that I have no memory */ +hw_err: + dra = 0; + out: + return dra; + +} + + +static int spd_set_drt_attributes(const struct mem_controller *ctrl, + long dimm_mask, uint32_t drc) +{ + int value; + int reg; + uint32_t drt; + int cnt; + int first_dimm; + int cas_latency=0; + int latency; + uint32_t index = 0; + uint32_t index2 = 0; + static const unsigned char cycle_time[3] = {0x75,0x60,0x50}; + static const int latency_indicies[] = { 26, 23, 9 }; + + /* 0x78 DRT */ + drt = pci_read_config32(ctrl->f0, DRT); + drt &= 3; /* save bits 1:0 */ + + for(first_dimm = 0; first_dimm < 4; first_dimm++) { + if (dimm_mask & (1 << first_dimm)) + break; + } + + /* get dimm type */ + value = spd_read_byte(ctrl->channel0[first_dimm], 2); + if(value == 8) { + drt |= (3<<5); /* back to bark write turn around & cycle add */ + } + + drt |= (3<<18); /* Trasmax */ + + for(cnt=0; cnt < 4; cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + reg = spd_read_byte(ctrl->channel0[cnt], 18); /* CAS Latency */ + /* Compute the lowest cas latency supported */ + latency = log2(reg) -2; + + /* Loop through and find a fast clock with a low latency */ + for(index = 0; index < 3; index++, latency++) { + if ((latency < 2) || (latency > 4) || + (!(reg & (1 << latency)))) { + continue; + } + value = spd_read_byte(ctrl->channel0[cnt], + latency_indicies[index]); + + if(value <= cycle_time[drc&3]) { + if( latency > cas_latency) { + cas_latency = latency; + } + break; + } + } + } + index = (cas_latency-2); + if((index)==0) cas_latency = 20; + else if((index)==1) cas_latency = 25; + else cas_latency = 30; + + for(cnt=0;cnt<4;cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + reg = spd_read_byte(ctrl->channel0[cnt], 27)&0x0ff; + if(((index>>8)&0x0ff)<reg) { + index &= ~(0x0ff << 8); + index |= (reg << 8); + } + reg = spd_read_byte(ctrl->channel0[cnt], 28)&0x0ff; + if(((index>>16)&0x0ff)<reg) { + index &= ~(0x0ff << 16); + index |= (reg<<16); + } + reg = spd_read_byte(ctrl->channel0[cnt], 29)&0x0ff; + if(((index2>>0)&0x0ff)<reg) { + index2 &= ~(0x0ff << 0); + index2 |= (reg<<0); + } + reg = spd_read_byte(ctrl->channel0[cnt], 41)&0x0ff; + if(((index2>>8)&0x0ff)<reg) { + index2 &= ~(0x0ff << 8); + index2 |= (reg<<8); + } + reg = spd_read_byte(ctrl->channel0[cnt], 42)&0x0ff; + if(((index2>>16)&0x0ff)<reg) { + index2 &= ~(0x0ff << 16); + index2 |= (reg<<16); + } + } + + /* get dimm speed */ + value = cycle_time[drc&3]; + if(value <= 0x50) { /* 200 MHz */ + if((index&7) > 2) { + drt |= (2<<2); /* CAS latency 4 */ + cas_latency = 40; + } else { + drt |= (1<<2); /* CAS latency 3 */ + cas_latency = 30; + } + if((index&0x0ff00)<=0x03c00) { + drt |= (1<<8); /* Trp RAS Precharg */ + } else { + drt |= (2<<8); /* Trp RAS Precharg */ + } + + /* Trcd RAS to CAS delay */ + if((index2&0x0ff)<=0x03c) { + drt |= (0<<10); + } else { + drt |= (1<<10); + } + + /* Tdal Write auto precharge recovery delay */ + drt |= (1<<12); + + /* Trc TRS min */ + if((index2&0x0ff00)<=0x03700) + drt |= (0<<14); + else if((index2&0xff00)<=0x03c00) + drt |= (1<<14); + else + drt |= (2<<14); /* spd 41 */ + + drt |= (2<<16); /* Twr not defined for DDR docs say use 2 */ + + /* Trrd Row Delay */ + if((index&0x0ff0000)<=0x0140000) { + drt |= (0<<20); + } else if((index&0x0ff0000)<=0x0280000) { + drt |= (1<<20); + } else if((index&0x0ff0000)<=0x03c0000) { + drt |= (2<<20); + } else { + drt |= (3<<20); + } + + /* Trfc Auto refresh cycle time */ + if((index2&0x0ff0000)<=0x04b0000) { + drt |= (0<<22); + } else if((index2&0x0ff0000)<=0x0690000) { + drt |= (1<<22); + } else { + drt |= (2<<22); + } + /* Docs say use 55 for all 200Mhz */ + drt |= (0x055<<24); + } + else if(value <= 0x60) { /* 167 Mhz */ + /* according to new documentation CAS latency is 00 + * for bits 3:2 for all 167 Mhz + drt |= ((index&3)<<2); */ /* set CAS latency */ + if((index&0x0ff00)<=0x03000) { + drt |= (1<<8); /* Trp RAS Precharg */ + } else { + drt |= (2<<8); /* Trp RAS Precharg */ + } + + /* Trcd RAS to CAS delay */ + if((index2&0x0ff)<=0x030) { + drt |= (0<<10); + } else { + drt |= (1<<10); + } + + /* Tdal Write auto precharge recovery delay */ + drt |= (2<<12); + + /* Trc TRS min */ + drt |= (2<<14); /* spd 41, but only one choice */ + + drt |= (2<<16); /* Twr not defined for DDR docs say 2 */ + + /* Trrd Row Delay */ + if((index&0x0ff0000)<=0x0180000) { + drt |= (0<<20); + } else if((index&0x0ff0000)<=0x0300000) { + drt |= (1<<20); + } else { + drt |= (2<<20); + } + + /* Trfc Auto refresh cycle time */ + if((index2&0x0ff0000)<=0x0480000) { + drt |= (0<<22); + } else if((index2&0x0ff0000)<=0x0780000) { + drt |= (2<<22); + } else { + drt |= (2<<22); + } + /* Docs state to use 99 for all 167 Mhz */ + drt |= (0x099<<24); + } + else if(value <= 0x75) { /* 133 Mhz */ + drt |= ((index&3)<<2); /* set CAS latency */ + if((index&0x0ff00)<=0x03c00) { + drt |= (1<<8); /* Trp RAS Precharg */ + } else { + drt |= (2<<8); /* Trp RAS Precharg */ + } + + /* Trcd RAS to CAS delay */ + if((index2&0x0ff)<=0x03c) { + drt |= (0<<10); + } else { + drt |= (1<<10); + } + + /* Tdal Write auto precharge recovery delay */ + drt |= (1<<12); + + /* Trc TRS min */ + drt |= (2<<14); /* spd 41, but only one choice */ + + drt |= (1<<16); /* Twr not defined for DDR docs say 1 */ + + /* Trrd Row Delay */ + if((index&0x0ff0000)<=0x01e0000) { + drt |= (0<<20); + } else if((index&0x0ff0000)<=0x03c0000) { + drt |= (1<<20); + } else { + drt |= (2<<20); + } + + /* Trfc Auto refresh cycle time */ + if((index2&0x0ff0000)<=0x04b0000) { + drt |= (0<<22); + } else if((index2&0x0ff0000)<=0x0780000) { + drt |= (2<<22); + } else { + drt |= (2<<22); + } + + /* Based on CAS latency */ + if(index&7) + drt |= (0x099<<24); + else + drt |= (0x055<<24); + + } + else { + die("Invalid SPD 9 bus speed.\r\n"); + } + + /* 0x78 DRT */ + pci_write_config32(ctrl->f0, DRT, drt); + + return(cas_latency); +} + +static int spd_set_dram_controller_mode(const struct mem_controller *ctrl, + long dimm_mask) +{ + int value; + int reg; + int drc; + int cnt; + msr_t msr; + unsigned char dram_type = 0xff; + unsigned char ecc = 0xff; + unsigned char rate = 62; + static const unsigned char spd_rates[6] = {15,3,7,7,62,62}; + static const unsigned char drc_rates[5] = {0,15,7,62,3}; + static const unsigned char fsb_conversion[4] = {3,1,3,2}; + + /* 0x7c DRC */ + drc = pci_read_config32(ctrl->f0, DRC); + for(cnt=0; cnt < 4; cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + value = spd_read_byte(ctrl->channel0[cnt], 11); /* ECC */ + reg = spd_read_byte(ctrl->channel0[cnt], 2); /* Type */ + if (value == 2) { /* RAM is ECC capable */ + if (reg == 8) { + if ( ecc == 0xff ) { + ecc = 2; + } + else if (ecc == 1) { + die("ERROR - Mixed DDR & DDR2 RAM\r\n"); + } + } + else if ( reg == 7 ) { + if ( ecc == 0xff) { + ecc = 1; + } + else if ( ecc > 1 ) { + die("ERROR - Mixed DDR & DDR2 RAM\r\n"); + } + } + else { + die("ERROR - RAM not DDR\r\n"); + } + } + else { + die("ERROR - Non ECC memory dimm\r\n"); + } + + value = spd_read_byte(ctrl->channel0[cnt], 12); /*refresh rate*/ + value &= 0x0f; /* clip self refresh bit */ + if (value > 5) goto hw_err; + if (rate > spd_rates[value]) + rate = spd_rates[value]; + + value = spd_read_byte(ctrl->channel0[cnt], 9); /* cycle time */ + if (value > 0x75) goto hw_err; + if (value <= 0x50) { + if (dram_type >= 2) { + if (reg == 8) { /*speed is good, is this ddr2?*/ + dram_type = 2; + } else { /* not ddr2 so use ddr333 */ + dram_type = 1; + } + } + } + else if (value <= 0x60) { + if (dram_type >= 1) dram_type = 1; + } + else dram_type = 0; /* ddr266 */ + + } + ecc = 2; + if (read_option(CMOS_VSTART_ECC_memory,CMOS_VLEN_ECC_memory,1) == 0) { + ecc = 0; /* ECC off in CMOS so disable it */ + print_debug("ECC off\r\n"); + } + else { + print_debug("ECC on\r\n"); + } + drc &= ~(3 << 20); /* clear the ecc bits */ + drc |= (ecc << 20); /* or in the calculated ecc bits */ + for ( cnt = 1; cnt < 5; cnt++) + if (drc_rates[cnt] == rate) + break; + if (cnt < 5) { + drc &= ~(7 << 8); /* clear the rate bits */ + drc |= (cnt << 8); + } + + if (reg == 8) { /* independant clocks */ + drc |= (1 << 4); + } + + drc |= (1 << 26); /* set the overlap bit - the factory BIOS does */ + drc |= (1 << 27); /* set DED retry enable - the factory BIOS does */ + /* front side bus */ + msr = rdmsr(0x2c); + value = msr.lo >> 16; + value &= 0x03; + drc &= ~(3 << 2); /* set the front side bus */ + drc |= (fsb_conversion[value] << 2); + drc &= ~(3 << 0); /* set the dram type */ + drc |= (dram_type << 0); + + goto out; + + val_err: + die("Bad SPD value\r\n"); + /* If an hw_error occurs report that I have no memory */ +hw_err: + drc = 0; + out: + return drc; +} + +static void sdram_set_spd_registers(const struct mem_controller *ctrl) +{ + long dimm_mask; + + /* Test if we can read the spd and if ram is ddr or ddr2 */ + dimm_mask = spd_detect_dimms(ctrl); + if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) { + print_err("No memory for this cpu\r\n"); + return; + } + return; +} + +static void do_delay(void) +{ + int i; + unsigned char b; + for(i=0;i<16;i++) + b=inb(0x80); +} + +static void pll_setup(uint32_t drc) +{ + unsigned pins; + if(drc&3) { /* DDR 333 or DDR 400 */ + if((drc&0x0c) == 0x0c) { /* FSB 200 */ + pins = 2 | 1; + } + else if((drc&0x0c) == 0x08) { /* FSB 167 */ + pins = 0 | 1; + } + else if(drc&1){ /* FSB 133 DDR 333 */ + pins = 2 | 1; + } + else { /* FSB 133 DDR 400 */ + pins = 0 | 1; + } + } + else { /* DDR 266 */ + if((drc&0x08) == 0x08) { /* FSB 200 or 167 */ + pins = 0 | 0; + } + else { /* FSB 133 */ + pins = 0 | 1; + } + } + mainboard_set_e7520_pll(pins); + return; +} + +#define TIMEOUT_LOOPS 300000 + +#define DCALCSR 0x100 +#define DCALADDR 0x104 +#define DCALDATA 0x108 + +static void set_on_dimm_termination_enable(const struct mem_controller *ctrl) +{ + unsigned char c1,c2; + unsigned int dimm,i; + unsigned int data32; + unsigned int t4; + + /* Set up northbridge values */ + /* ODT enable */ + pci_write_config32(ctrl->f0, 0x88, 0xf0000180); + /* Figure out which slots are Empty, Single, or Double sided */ + for(i=0,t4=0,c2=0;i<8;i+=2) { + c1 = pci_read_config8(ctrl->f0, DRB+i); + if(c1 == c2) continue; + c2 = pci_read_config8(ctrl->f0, DRB+1+i); + if(c1 == c2) + t4 |= (1 << (i*4)); + else + t4 |= (2 << (i*4)); + } + for(i=0;i<1;i++) { + if((t4&0x0f) == 1) { + if( ((t4>>8)&0x0f) == 0 ) { + data32 = 0x00000010; /* EEES */ + break; + } + if ( ((t4>>16)&0x0f) == 0 ) { + data32 = 0x00003132; /* EESS */ + break; + } + if ( ((t4>>24)&0x0f) == 0 ) { + data32 = 0x00335566; /* ESSS */ + break; + } + data32 = 0x77bbddee; /* SSSS */ + break; + } + if((t4&0x0f) == 2) { + if( ((t4>>8)&0x0f) == 0 ) { + data32 = 0x00003132; /* EEED */ + break; + } + if ( ((t4>>8)&0x0f) == 2 ) { + data32 = 0xb373ecdc; /* EEDD */ + break; + } + if ( ((t4>>16)&0x0f) == 0 ) { + data32 = 0x00b3a898; /* EESD */ + break; + } + data32 = 0x777becdc; /* ESSD */ + break; + } + die("Error - First dimm slot empty\r\n"); + } + + print_debug("ODT Value = "); + print_debug_hex32(data32); + print_debug("\r\n"); + + pci_write_config32(ctrl->f0, 0xb0, data32); + + for(dimm=0;dimm<8;dimm+=1) { + + write32(BAR+DCALADDR, 0x0b840001); + write32(BAR+DCALCSR, 0x83000003 | (dimm << 20)); + + for(i=0;i<1001;i++) { + data32 = read32(BAR+DCALCSR); + if(!(data32 & (1<<31))) + break; + } + } +} +static void set_receive_enable(const struct mem_controller *ctrl) +{ + unsigned int i; + unsigned int cnt; + uint32_t recena=0; + uint32_t recenb=0; + + { + unsigned int dimm; + unsigned int edge; + int32_t data32; + uint32_t data32_dram; + uint32_t dcal_data32_0; + uint32_t dcal_data32_1; + uint32_t dcal_data32_2; + uint32_t dcal_data32_3; + uint32_t work32l; + uint32_t work32h; + uint32_t data32r; + int32_t recen; + for(dimm=0;dimm<8;dimm+=1) { + + if(!(dimm&1)) { + write32(BAR+DCALDATA+(17*4), 0x04020000); + write32(BAR+DCALCSR, 0x83800004 | (dimm << 20)); + + for(i=0;i<1001;i++) { + data32 = read32(BAR+DCALCSR); + if(!(data32 & (1<<31))) + break; + } + if(i>=1000) + continue; + + dcal_data32_0 = read32(BAR+DCALDATA + 0); + dcal_data32_1 = read32(BAR+DCALDATA + 4); + dcal_data32_2 = read32(BAR+DCALDATA + 8); + dcal_data32_3 = read32(BAR+DCALDATA + 12); + } + else { + dcal_data32_0 = read32(BAR+DCALDATA + 16); + dcal_data32_1 = read32(BAR+DCALDATA + 20); + dcal_data32_2 = read32(BAR+DCALDATA + 24); + dcal_data32_3 = read32(BAR+DCALDATA + 28); + } + + /* check if bank is installed */ + if((dcal_data32_0 == 0) && (dcal_data32_2 == 0)) + continue; + /* Calculate the timing value */ + { + unsigned int bit; + for(i=0,edge=0,bit=63,cnt=31,data32r=0, + work32l=dcal_data32_1,work32h=dcal_data32_3; + (i<4) && bit; i++) { + for(;;bit--,cnt--) { + if(work32l & (1<<cnt)) + break; + if(!cnt) { + work32l = dcal_data32_0; + work32h = dcal_data32_2; + cnt = 32; + } + if(!bit) break; + } + for(;;bit--,cnt--) { + if(!(work32l & (1<<cnt))) + break; + if(!cnt) { + work32l = dcal_data32_0; + work32h = dcal_data32_2; + cnt = 32; + } + if(!bit) break; + } + if(!bit) { + break; + } + data32 = ((bit%8) << 1); + if(work32h & (1<<cnt)) + data32 += 1; + if(data32 < 4) { + if(!edge) { + edge = 1; + } + else { + if(edge != 1) { + data32 = 0x0f; + } + } + } + if(data32 > 12) { + if(!edge) { + edge = 2; + } + else { + if(edge != 2) { + data32 = 0x00; + } + } + } + data32r += data32; + } + } + work32l = dcal_data32_0; + work32h = dcal_data32_2; + recen = data32r; + recen += 3; + recen = recen>>2; + for(cnt=5;cnt<24;) { + for(;;cnt++) + if(!(work32l & (1<<cnt))) + break; + for(;;cnt++) { + if(work32l & (1<<cnt)) + break; + } + data32 = (((cnt-1)%8)<<1); + if(work32h & (1<<(cnt-1))) { + data32++; + } + /* test for frame edge cross overs */ + if((edge == 1) && (data32 > 12) && + (((recen+16)-data32) < 3)) { + data32 = 0; + cnt += 2; + } + if((edge == 2) && (data32 < 4) && + ((recen - data32) > 12)) { + data32 = 0x0f; + cnt -= 2; + } + if(((recen+3) >= data32) && ((recen-3) <= data32)) + break; + } + cnt--; + cnt /= 8; + cnt--; + if(recen&1) + recen+=2; + recen >>= 1; + recen += (cnt*8); + recen+=2; /* this is not in the spec, but matches + the factory output, and has less failure */ + recen <<= (dimm/2) * 8; + if(!(dimm&1)) { + recena |= recen; + } + else { + recenb |= recen; + } + } + } + /* Check for Eratta problem */ + for(i=cnt=0;i<32;i+=8) { + if (((recena>>i)&0x0f)>7) { + cnt+= 0x101; + } + else { + if((recena>>i)&0x0f) { + cnt++; + } + } + } + if(cnt&0x0f00) { + cnt = (cnt&0x0f) - (cnt>>16); + if(cnt>1) { + for(i=0;i<32;i+=8) { + if(((recena>>i)&0x0f)>7) { + recena &= ~(0x0f<<i); + recena |= (7<<i); + } + } + } + else { + for(i=0;i<32;i+=8) { + if(((recena>>i)&0x0f)<8) { + recena &= ~(0x0f<<i); + recena |= (8<<i); + } + } + } + } + for(i=cnt=0;i<32;i+=8) { + if (((recenb>>i)&0x0f)>7) { + cnt+= 0x101; + } + else { + if((recenb>>i)&0x0f) { + cnt++; + } + } + } + if(cnt & 0x0f00) { + cnt = (cnt&0x0f) - (cnt>>16); + if(cnt>1) { + for(i=0;i<32;i+=8) { + if(((recenb>>i)&0x0f)>7) { + recenb &= ~(0x0f<<i); + recenb |= (7<<i); + } + } + } + else { + for(i=0;i<32;i+=8) { + if(((recenb>>8)&0x0f)<8) { + recenb &= ~(0x0f<<i); + recenb |= (8<<i); + } + } + } + } + + print_debug("Receive enable A = "); + print_debug_hex32(recena); + print_debug(", Receive enable B = "); + print_debug_hex32(recenb); + print_debug("\r\n"); + + /* clear out the calibration area */ + write32(BAR+DCALDATA+(16*4), 0x00000000); + write32(BAR+DCALDATA+(17*4), 0x00000000); + write32(BAR+DCALDATA+(18*4), 0x00000000); + write32(BAR+DCALDATA+(19*4), 0x00000000); + + /* No command */ + write32(BAR+DCALCSR, 0x0000000f); + + write32(BAR+0x150, recena); + write32(BAR+0x154, recenb); +} + + +static void sdram_enable(int controllers, const struct mem_controller *ctrl) +{ + int i; + int cs; + int cnt; + int cas_latency; + long mask; + uint32_t drc; + uint32_t data32; + uint32_t mode_reg; + uint32_t *iptr; + volatile unsigned long *iptrv; + msr_t msr; + uint32_t scratch; + uint8_t byte; + uint16_t data16; + static const struct { + uint32_t clkgr[4]; + } gearing [] = { + /* FSB 133 DIMM 266 */ + {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}}, + /* FSB 133 DIMM 333 */ + {{ 0x00000000, 0x00000000, 0x00000000, 0x00000000}}, + /* FSB 133 DIMM 400 */ + {{ 0x00000120, 0x00000000, 0x00000032, 0x00000010}}, + /* FSB 167 DIMM 266 */ + {{ 0x00005432, 0x00001000, 0x00004325, 0x00000000}}, + /* FSB 167 DIMM 333 */ + {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}}, + /* FSB 167 DIMM 400 */ + {{ 0x00154320, 0x00000000, 0x00065432, 0x00010000}}, + /* FSB 200 DIMM 266 */ + {{ 0x00000032, 0x00000010, 0x00000120, 0x00000000}}, + /* FSB 200 DIMM 333 */ + {{ 0x00065432, 0x00010000, 0x00154320, 0x00000000}}, + /* FSB 200 DIMM 400 */ + {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}}, + }; + + static const uint32_t dqs_data[] = { + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff}; + + mask = spd_detect_dimms(ctrl); + print_debug("Starting SDRAM Enable\r\n"); + + /* 0x80 */ +#ifdef DIMM_MAP_LOGICAL + pci_write_config32(ctrl->f0, DRM, + 0x00210000 | DIMM_MAP_LOGICAL); +#else + pci_write_config32(ctrl->f0, DRM, 0x00211248); +#endif + /* set dram type and Front Side Bus freq. */ + drc = spd_set_dram_controller_mode(ctrl, mask); + if( drc == 0) { + die("Error calculating DRC\r\n"); + } + pll_setup(drc); + data32 = drc & ~(3 << 20); /* clear ECC mode */ + data32 = data32 & ~(7 << 8); /* clear refresh rates */ + data32 = data32 | (1 << 5); /* temp turn off of ODT */ + /* Set gearing, then dram controller mode */ + /* drc bits 1:0 = DIMM speed, bits 3:2 = FSB speed */ + for(iptr = gearing[(drc&3)+((((drc>>2)&3)-1)*3)].clkgr,cnt=0; + cnt<4;cnt++) { + pci_write_config32(ctrl->f0, 0xa0+(cnt*4), iptr[cnt]); + } + /* 0x7c DRC */ + pci_write_config32(ctrl->f0, DRC, data32); + + /* turn the clocks on */ + /* 0x8c CKDIS */ + pci_write_config16(ctrl->f0, CKDIS, 0x0000); + + /* 0x9a DDRCSR Take subsystem out of idle */ + data16 = pci_read_config16(ctrl->f0, DDRCSR); + data16 &= ~(7 << 12); + data16 |= (3 << 12); /* use dual channel lock step */ + pci_write_config16(ctrl->f0, DDRCSR, data16); + + /* program row size DRB */ + spd_set_ram_size(ctrl, mask); + + /* program page size DRA */ + spd_set_row_attributes(ctrl, mask); + + /* program DRT timing values */ + cas_latency = spd_set_drt_attributes(ctrl, mask, drc); + + for(i=0;i<8;i++) { /* loop throught each dimm to test for row */ + print_debug("DIMM "); + print_debug_hex8(i); + print_debug("\r\n"); + /* Apply NOP */ + do_delay(); + + write32(BAR + 0x100, (0x03000000 | (i<<20))); + + write32(BAR+0x100, (0x83000000 | (i<<20))); + + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + + } + + /* Apply NOP */ + do_delay(); + + for(cs=0;cs<8;cs++) { + write32(BAR + DCALCSR, (0x83000000 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Precharg all banks */ + do_delay(); + for(cs=0;cs<8;cs++) { + if ((drc & 3) == 2) /* DDR2 */ + write32(BAR+DCALADDR, 0x04000000); + else /* DDR1 */ + write32(BAR+DCALADDR, 0x00000000); + write32(BAR+DCALCSR, (0x83000002 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* EMRS dll's enabled */ + do_delay(); + for(cs=0;cs<8;cs++) { + if ((drc & 3) == 2) /* DDR2 */ + /* fixme hard code AL additive latency */ + write32(BAR+DCALADDR, 0x0b940001); + else /* DDR1 */ + write32(BAR+DCALADDR, 0x00000001); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + /* MRS reset dll's */ + do_delay(); + if ((drc & 3) == 2) { /* DDR2 */ + if(cas_latency == 30) + mode_reg = 0x053a0000; + else + mode_reg = 0x054a0000; + } + else { /* DDR1 */ + if(cas_latency == 20) + mode_reg = 0x012a0000; + else /* CAS Latency 2.5 */ + mode_reg = 0x016a0000; + } + for(cs=0;cs<8;cs++) { + write32(BAR+DCALADDR, mode_reg); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Precharg all banks */ + do_delay(); + do_delay(); + do_delay(); + for(cs=0;cs<8;cs++) { + if ((drc & 3) == 2) /* DDR2 */ + write32(BAR+DCALADDR, 0x04000000); + else /* DDR1 */ + write32(BAR+DCALADDR, 0x00000000); + write32(BAR+DCALCSR, (0x83000002 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Do 2 refreshes */ + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + do_delay(); + /* for good luck do 6 more */ + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + /* MRS reset dll's normal */ + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALADDR, (mode_reg & ~(1<<24))); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Do only if DDR2 EMRS dll's enabled */ + if ((drc & 3) == 2) { /* DDR2 */ + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALADDR, (0x0b940001)); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + } + + do_delay(); + /* No command */ + write32(BAR+DCALCSR, 0x0000000f); + + /* DDR1 This is test code to copy some codes in the factory setup */ + + write32(BAR, 0x00100000); + + if ((drc & 3) == 2) { /* DDR2 */ + /* enable on dimm termination */ + set_on_dimm_termination_enable(ctrl); + } + else { /* ddr */ + pci_write_config32(ctrl->f0, 0x88, 0xa0000000 ); + } + + /* receive enable calibration */ + set_receive_enable(ctrl); + + /* DQS */ + pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); + for(i = 0, cnt = (BAR+0x200); i < 24; i++, cnt+=4) { + write32(cnt, dqs_data[i]); + } + pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); + + /* Enable refresh */ + /* 0x7c DRC */ + data32 = drc & ~(3 << 20); /* clear ECC mode */ + pci_write_config32(ctrl->f0, DRC, data32); + write32(BAR+DCALCSR, 0x0008000f); + + /* clear memory and init ECC */ + print_debug("Clearing memory\r\n"); + for(i=0;i<64;i+=4) { + write32(BAR+DCALDATA+i, 0x00000000); + } + + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x830831d8 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Bring memory subsystem on line */ + data32 = pci_read_config32(ctrl->f0, 0x98); + data32 |= (1 << 31); + pci_write_config32(ctrl->f0, 0x98, data32); + /* wait for completion */ + print_debug("Waiting for mem complete\r\n"); + while(1) { + data32 = pci_read_config32(ctrl->f0, 0x98); + if( (data32 & (1<<31)) == 0) + break; + } + print_debug("Done\r\n"); + + /* Set initialization complete */ + /* 0x7c DRC */ + drc |= (1 << 29); + data32 = drc & ~(3 << 20); /* clear ECC mode */ + pci_write_config32(ctrl->f0, DRC, data32); + + /* Set the ecc mode */ + pci_write_config32(ctrl->f0, DRC, drc); + + /* Enable memory scrubbing */ + /* 0x52 MCHSCRB */ + data16 = pci_read_config16(ctrl->f0, MCHSCRB); + data16 &= ~0x0f; + data16 |= ((2 << 2) | (2 << 0)); + pci_write_config16(ctrl->f0, MCHSCRB, data16); + + /* The memory is now setup, use it */ + cache_lbmem(MTRR_TYPE_WRBACK); +} diff --git a/src/northbridge/intel/E7520/raminit.h b/src/northbridge/intel/E7520/raminit.h new file mode 100644 index 0000000000..183ace8385 --- /dev/null +++ b/src/northbridge/intel/E7520/raminit.h @@ -0,0 +1,12 @@ +#ifndef RAMINIT_H +#define RAMINIT_H + +#define DIMM_SOCKETS 4 +struct mem_controller { + unsigned node_id; + device_t f0, f1, f2, f3; + uint16_t channel0[DIMM_SOCKETS]; + uint16_t channel1[DIMM_SOCKETS]; +}; + +#endif /* RAMINIT_H */ diff --git a/src/northbridge/intel/E7520/raminit_test.c b/src/northbridge/intel/E7520/raminit_test.c new file mode 100644 index 0000000000..a69bafdac9 --- /dev/null +++ b/src/northbridge/intel/E7520/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 "e7520.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; +} diff --git a/src/northbridge/intel/E7525/Config.lb b/src/northbridge/intel/E7525/Config.lb new file mode 100644 index 0000000000..919e0f8adf --- /dev/null +++ b/src/northbridge/intel/E7525/Config.lb @@ -0,0 +1,12 @@ +config chip.h +driver northbridge.o +driver pciexp_porta.o +driver pciexp_porta1.o +driver pciexp_portb.o +driver pciexp_portc.o + +makerule raminit_test + depends "$(TOP)/src/northbridge/intel/e7525/raminit_test.c" + depends "$(TOP)/src/northbridge/intel/e7525/raminit.c" + action "$(HOSTCC) $(HOSTCFLAGS) $(CPUFLAGS) -Wno-unused-function -I$(TOP)/src/include -g $< -o $@" +end diff --git a/src/northbridge/intel/E7525/chip.h b/src/northbridge/intel/E7525/chip.h new file mode 100644 index 0000000000..19d8c4e54c --- /dev/null +++ b/src/northbridge/intel/E7525/chip.h @@ -0,0 +1,7 @@ +struct northbridge_intel_E7525_config +{ + /* Interrupt line connect */ + unsigned int intrline; +}; + +extern struct chip_operations northbridge_intel_E7525_ops; diff --git a/src/northbridge/intel/E7525/e7525.h b/src/northbridge/intel/E7525/e7525.h new file mode 100644 index 0000000000..be76303d4f --- /dev/null +++ b/src/northbridge/intel/E7525/e7525.h @@ -0,0 +1,44 @@ +#define VID 0X00 +#define DID 0X02 +#define PCICMD 0X04 +#define PCISTS 0X06 +#define RID 0X08 +#define IURBASE 0X14 +#define MCHCFG0 0X50 +#define MCHSCRB 0X52 +#define FDHC 0X58 +#define PAM 0X59 +#define DRB 0X60 +#define DRA 0X70 +#define DRT 0X78 +#define DRC 0X7C +#define DRM 0X80 +#define DRORC 0X82 +#define ECCDIAG 0X84 +#define SDRC 0X88 +#define CKDIS 0X8C +#define CKEDIS 0X8D +#define DDRCSR 0X9A +#define DEVPRES 0X9C +#define DEVPRES_D0F0 (1 << 0) +#define DEVPRES_D1F0 (1 << 1) +#define DEVPRES_D2F0 (1 << 2) +#define DEVPRES_D3F0 (1 << 3) +#define DEVPRES_D4F0 (1 << 4) +#define DEVPRES_D5F0 (1 << 5) +#define DEVPRES_D6F0 (1 << 6) +#define DEVPRES_D7F0 (1 << 7) +#define ESMRC 0X9D +#define SMRC 0X9E +#define EXSMRC 0X9F +#define DDR2ODTC 0XB0 +#define TOLM 0XC4 +#define REMAPBASE 0XC6 +#define REMAPLIMIT 0XC8 +#define REMAPOFFSET 0XCA +#define TOM 0XCC +#define EXPECBASE 0XCE +#define DEVPRES1 0XF4 +#define DEVPRES1_D0F1 (1 << 5) +#define DEVPRES1_D8F0 (1 << 1) +#define MSCFG 0XF6 diff --git a/src/northbridge/intel/E7525/memory_initialized.c b/src/northbridge/intel/E7525/memory_initialized.c new file mode 100644 index 0000000000..6eb31a8ca3 --- /dev/null +++ b/src/northbridge/intel/E7525/memory_initialized.c @@ -0,0 +1,9 @@ +#include "e7525.h" +#define NB_DEV PCI_DEV(0, 0, 0) + +static inline int memory_initialized(void) +{ + uint32_t drc; + drc = pci_read_config32(NB_DEV, DRC); + return (drc & (1<<29)); +} diff --git a/src/northbridge/intel/E7525/northbridge.c b/src/northbridge/intel/E7525/northbridge.c new file mode 100644 index 0000000000..71f17224df --- /dev/null +++ b/src/northbridge/intel/E7525/northbridge.c @@ -0,0 +1,270 @@ +#include <console/console.h> +#include <arch/io.h> +#include <stdint.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/hypertransport.h> +#include <stdlib.h> +#include <string.h> +#include <bitops.h> +#include <cpu/cpu.h> +#include "chip.h" +#include "northbridge.h" +#include "e7525.h" + + +static unsigned int max_bus; + +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + + +static void pci_domain_read_resources(device_t dev) +{ + struct resource *resource; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0,0)); + resource->base = 0; + resource->size = 0; + resource->align = 0; + resource->gran = 0; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1,0)); + resource->base = 0; + resource->size = 0; + resource->align = 0; + resource->gran = 0; + resource->limit = 0xffffffffUL; + resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; +} + +static void tolm_test(void *gp, struct device *dev, struct resource *new) +{ + struct resource **best_p = gp; + struct resource *best; + best = *best_p; + if (!best || (best->base > new->base)) { + best = new; + } + *best_p = best; +} + +static uint32_t find_pci_tolm(struct bus *bus) +{ + struct resource *min; + uint32_t tolm; + min = 0; + search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min); + tolm = 0xffffffffUL; + if (min && tolm > min->base) { + tolm = min->base; + } + return tolm; +} + + +static void pci_domain_set_resources(device_t dev) +{ + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = find_pci_tolm(&dev->link[0]); + +#if 1 + printk_debug("PCI mem marker = %x\n", pci_tolm); +#endif + /* FIXME Me temporary hack */ + if(pci_tolm > 0xe0000000) + pci_tolm = 0xe0000000; + /* Ensure pci_tolm is 128M aligned */ + pci_tolm &= 0xf8000000; + mc_dev = dev->link[0].children; + if (mc_dev) { + /* Figure out which areas are/should be occupied by RAM. + * This is all computed in kilobytes and converted to/from + * the memory controller right at the edges. + * Having different variables in different units is + * too confusing to get right. Kilobytes are good up to + * 4 Terabytes of RAM... + */ + uint16_t tolm_r, remapbase_r, remaplimit_r, remapoffset_r; + unsigned long tomk, tolmk; + unsigned long remapbasek, remaplimitk, remapoffsetk; + + /* Get the Top of Memory address, units are 128M */ + tomk = ((unsigned long)pci_read_config16(mc_dev, TOM)) << 17; + /* Compute the Top of Low Memory */ + tolmk = (pci_tolm & 0xf8000000) >> 10; + + if (tolmk >= tomk) { + /* The PCI hole does not overlap memory + * we won't use the remap window. + */ + tolmk = tomk; + remapbasek = 0x3ff << 16; + remaplimitk = 0 << 16; + remapoffsetk = 0 << 16; + } + else { + /* The PCI memory hole overlaps memory + * setup the remap window. + */ + /* Find the bottom of the remap window + * is it above 4G? + */ + remapbasek = 4*1024*1024; + if (tomk > remapbasek) { + remapbasek = tomk; + } + /* Find the limit of the remap window */ + remaplimitk = (remapbasek + (4*1024*1024 - tolmk) - (1 << 16)); + /* Find the offset of the remap window from tolm */ + remapoffsetk = remapbasek - tolmk; + } + /* Write the ram configruation registers, + * preserving the reserved bits. + */ + tolm_r = pci_read_config16(mc_dev, 0xc4); + tolm_r = ((tolmk >> 17) << 11) | (tolm_r & 0x7ff); + pci_write_config16(mc_dev, 0xc4, tolm_r); + + remapbase_r = pci_read_config16(mc_dev, 0xc6); + remapbase_r = (remapbasek >> 16) | (remapbase_r & 0xfc00); + pci_write_config16(mc_dev, 0xc6, remapbase_r); + + remaplimit_r = pci_read_config16(mc_dev, 0xc8); + remaplimit_r = (remaplimitk >> 16) | (remaplimit_r & 0xfc00); + pci_write_config16(mc_dev, 0xc8, remaplimit_r); + + remapoffset_r = pci_read_config16(mc_dev, 0xca); + remapoffset_r = (remapoffsetk >> 16) | (remapoffset_r & 0xfc00); + pci_write_config16(mc_dev, 0xca, remapoffset_r); + + /* Report the memory regions */ + ram_resource(dev, 3, 0, 640); + ram_resource(dev, 4, 768, tolmk - 768); + if (tomk > 4*1024*1024) { + ram_resource(dev, 5, 4096*1024, tomk - 4*1024*1024); + } + if (remaplimitk >= remapbasek) { + ram_resource(dev, 6, remapbasek, + (remaplimitk + 64*1024) - remapbasek); + } + } + assign_resources(&dev->link[0]); +} + +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], 0, 0xff, max); + if (max > max_bus) { + max_bus = max; + } + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, + .ops_pci_bus = &pci_cf8_conf1, /* Do we want to use the memory mapped space here? */ +}; + +static void mc_read_resources(device_t dev) +{ + struct resource *resource; + + pci_dev_read_resources(dev); + + resource = new_resource(dev, 0xcf); + resource->base = 0xe0000000; + resource->size = max_bus * 4096*256; + resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static void mc_set_resources(device_t dev) +{ + struct resource *resource, *last; + + last = &dev->resource[dev->resources]; + resource = find_resource(dev, 0xcf); + if (resource) { + report_resource_stored(dev, resource, "<mmconfig>"); + } + pci_dev_set_resources(dev); +} + +static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations intel_pci_ops = { + .set_subsystem = intel_set_subsystem, +}; + +static struct device_operations mc_ops = { + .read_resources = mc_read_resources, + .set_resources = mc_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .ops_pci = &intel_pci_ops, +}; + +static struct pci_driver mc_driver __pci_driver = { + .ops = &mc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x359e, +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); +} + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + + +static void enable_dev(device_t dev) +{ + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { + dev->ops = &cpu_bus_ops; + } +} + +struct chip_operations northbridge_intel_E7525_ops = { + CHIP_NAME("Intel E7525 Northbridge") + .enable_dev = enable_dev, +}; diff --git a/src/northbridge/intel/E7525/northbridge.h b/src/northbridge/intel/E7525/northbridge.h new file mode 100644 index 0000000000..0ee533f011 --- /dev/null +++ b/src/northbridge/intel/E7525/northbridge.h @@ -0,0 +1,8 @@ +#ifndef NORTHBRIDGE_INTEL_E7525_H +#define NORTHBRIDGE_INTEL_E7525_H + +extern unsigned int e7525_scan_root_bus(device_t root, unsigned int max); + + +#endif /* NORTHBRIDGE_INTEL_E7525_H */ + diff --git a/src/northbridge/intel/E7525/pciexp_porta.c b/src/northbridge/intel/E7525/pciexp_porta.c new file mode 100644 index 0000000000..093edec38f --- /dev/null +++ b/src/northbridge/intel/E7525/pciexp_porta.c @@ -0,0 +1,41 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7525_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PA, +}; + + diff --git a/src/northbridge/intel/E7525/pciexp_porta1.c b/src/northbridge/intel/E7525/pciexp_porta1.c new file mode 100644 index 0000000000..7118caa72f --- /dev/null +++ b/src/northbridge/intel/E7525/pciexp_porta1.c @@ -0,0 +1,41 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7525_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PA1, +}; + + diff --git a/src/northbridge/intel/E7525/pciexp_portb.c b/src/northbridge/intel/E7525/pciexp_portb.c new file mode 100644 index 0000000000..f623a54416 --- /dev/null +++ b/src/northbridge/intel/E7525/pciexp_portb.c @@ -0,0 +1,41 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7525_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PB, +}; + + diff --git a/src/northbridge/intel/E7525/pciexp_portc.c b/src/northbridge/intel/E7525/pciexp_portc.c new file mode 100644 index 0000000000..05e0b68863 --- /dev/null +++ b/src/northbridge/intel/E7525/pciexp_portc.c @@ -0,0 +1,41 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <arch/io.h> +#include "chip.h" + +typedef struct northbridge_intel_E7525_config config_t; + +static void pcie_init(struct device *dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->intrline) { + pci_write_config32(dev, 0x3c, config->intrline); + } + +} + +static struct device_operations pcie_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcie_init, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pcie_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_PCIE_PC, +}; + + diff --git a/src/northbridge/intel/E7525/raminit.c b/src/northbridge/intel/E7525/raminit.c new file mode 100644 index 0000000000..c0e6b4291e --- /dev/null +++ b/src/northbridge/intel/E7525/raminit.c @@ -0,0 +1,1300 @@ +#include <cpu/x86/mem.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/cache.h> +#include "raminit.h" +#include "e7525.h" + +#define BAR 0x40000000 + +static void sdram_set_registers(const struct mem_controller *ctrl) +{ + static const unsigned int register_values[] = { + + /* CKDIS 0x8c disable clocks */ + PCI_ADDR(0, 0x00, 0, CKDIS), 0xffff0000, 0x0000ffff, + + /* 0x9c Device present and extended RAM control + * DEVPRES is very touchy, hard code the initialization + * of PCI-E ports here. + */ + PCI_ADDR(0, 0x00, 0, DEVPRES), 0x00000000, 0x07020801 | DEVPRES_CONFIG, + + /* 0xc8 Remap RAM base and limit off */ + PCI_ADDR(0, 0x00, 0, REMAPLIMIT), 0x00000000, 0x03df0000, + + /* ??? */ + PCI_ADDR(0, 0x00, 0, 0xd8), 0x00000000, 0xb5930000, + PCI_ADDR(0, 0x00, 0, 0xe8), 0x00000000, 0x00004a2a, + + /* 0x50 scrub */ + PCI_ADDR(0, 0x00, 0, MCHCFG0), 0xfce0ffff, 0x00006000, /* 6000 */ + + /* 0x58 0x5c PAM */ + PCI_ADDR(0, 0x00, 0, PAM-1), 0xcccccc7f, 0x33333000, + PCI_ADDR(0, 0x00, 0, PAM+3), 0xcccccccc, 0x33333333, + + /* 0xf4 */ + PCI_ADDR(0, 0x00, 0, DEVPRES1), 0xffbffff, (1<<22)|(6<<2) | DEVPRES1_CONFIG, + + /* 0x14 */ + PCI_ADDR(0, 0x00, 0, IURBASE), 0x00000fff, BAR |0, + }; + int i; + int max; + + max = sizeof(register_values)/sizeof(register_values[0]); + for(i = 0; i < max; i += 3) { + device_t dev; + unsigned where; + unsigned long reg; + dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x00, 0) + ctrl->f0; + where = register_values[i] & 0xff; + reg = pci_read_config32(dev, where); + reg &= register_values[i+1]; + reg |= register_values[i+2]; + pci_write_config32(dev, where, reg); + } + print_spew("done.\r\n"); +} + + + +struct dimm_size { + unsigned long side1; + unsigned long side2; +}; + +static struct dimm_size spd_get_dimm_size(unsigned device) +{ + /* Calculate the log base 2 size of a DIMM in bits */ + struct dimm_size sz; + int value, low, ddr2; + sz.side1 = 0; + sz.side2 = 0; + + /* test for ddr2 */ + ddr2=0; + value = spd_read_byte(device, 2); /* type */ + if (value < 0) goto hw_err; + if (value == 8) ddr2 = 1; + + /* Note it might be easier to use byte 31 here, it has the DIMM size as + * a multiple of 4MB. The way we do it now we can size both + * sides of an assymetric dimm. + */ + value = spd_read_byte(device, 3); /* rows */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + sz.side1 += value & 0xf; + + value = spd_read_byte(device, 4); /* columns */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + sz.side1 += value & 0xf; + + value = spd_read_byte(device, 17); /* banks */ + if (value < 0) goto hw_err; + if ((value & 0xff) == 0) goto val_err; + sz.side1 += log2(value & 0xff); + + /* Get the module data width and convert it to a power of two */ + value = spd_read_byte(device, 7); /* (high byte) */ + if (value < 0) goto hw_err; + value &= 0xff; + value <<= 8; + + low = spd_read_byte(device, 6); /* (low byte) */ + if (low < 0) goto hw_err; + value = value | (low & 0xff); + if ((value != 72) && (value != 64)) goto val_err; + sz.side1 += log2(value); + + /* side 2 */ + value = spd_read_byte(device, 5); /* number of physical banks */ + + if (value < 0) goto hw_err; + value &= 7; + if(ddr2) value++; + if (value == 1) goto out; + if (value != 2) goto val_err; + + /* Start with the symmetrical case */ + sz.side2 = sz.side1; + + value = spd_read_byte(device, 3); /* rows */ + if (value < 0) goto hw_err; + if ((value & 0xf0) == 0) goto out; /* If symmetrical we are done */ + sz.side2 -= (value & 0x0f); /* Subtract out rows on side 1 */ + sz.side2 += ((value >> 4) & 0x0f); /* Add in rows on side 2 */ + + value = spd_read_byte(device, 4); /* columns */ + if (value < 0) goto hw_err; + if ((value & 0xff) == 0) goto val_err; + sz.side2 -= (value & 0x0f); /* Subtract out columns on side 1 */ + sz.side2 += ((value >> 4) & 0x0f); /* Add in columsn on side 2 */ + goto out; + + val_err: + die("Bad SPD value\r\n"); + /* If an hw_error occurs report that I have no memory */ +hw_err: + sz.side1 = 0; + sz.side2 = 0; + out: + return sz; + +} + +static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask) +{ + int i; + int cum; + + for(i = cum = 0; i < DIMM_SOCKETS; i++) { + struct dimm_size sz; + if (dimm_mask & (1 << i)) { + sz = spd_get_dimm_size(ctrl->channel0[i]); + if (sz.side1 < 29) { + return -1; /* Report SPD error */ + } + /* convert bits to multiples of 64MB */ + sz.side1 -= 29; + cum += (1 << sz.side1); + /* DRB = 0x60 */ + pci_write_config8(ctrl->f0, DRB + (i*2), cum); + if( sz.side2 > 28) { + sz.side2 -= 29; + cum += (1 << sz.side2); + } + pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum); + } + else { + pci_write_config8(ctrl->f0, DRB + (i*2), cum); + pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum); + } + } + /* set TOM top of memory 0xcc */ + pci_write_config16(ctrl->f0, TOM, cum); + /* set TOLM top of low memory */ + if(cum > 0x18) { + cum = 0x18; + } + cum <<= 11; + /* 0xc4 TOLM */ + pci_write_config16(ctrl->f0, TOLM, cum); + return 0; +} + + +static unsigned int spd_detect_dimms(const struct mem_controller *ctrl) +{ + unsigned dimm_mask; + int i; + dimm_mask = 0; + for(i = 0; i < DIMM_SOCKETS; i++) { + int byte; + unsigned device; + device = ctrl->channel0[i]; + if (device) { + byte = spd_read_byte(device, 2); /* Type */ + if ((byte == 7) || (byte == 8)) { + dimm_mask |= (1 << i); + } + } + device = ctrl->channel1[i]; + if (device) { + byte = spd_read_byte(device, 2); + if ((byte == 7) || (byte == 8)) { + dimm_mask |= (1 << (i + DIMM_SOCKETS)); + } + } + } + return dimm_mask; +} + + +static int spd_set_row_attributes(const struct mem_controller *ctrl, + long dimm_mask) +{ + + int value; + int reg; + int dra; + int cnt; + + dra = 0; + for(cnt=0; cnt < 4; cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + reg =0; + value = spd_read_byte(ctrl->channel0[cnt], 3); /* rows */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + reg += value & 0xf; + + value = spd_read_byte(ctrl->channel0[cnt], 4); /* columns */ + if (value < 0) goto hw_err; + if ((value & 0xf) == 0) goto val_err; + reg += value & 0xf; + + value = spd_read_byte(ctrl->channel0[cnt], 17); /* banks */ + if (value < 0) goto hw_err; + if ((value & 0xff) == 0) goto val_err; + reg += log2(value & 0xff); + + /* Get the device width and convert it to a power of two */ + value = spd_read_byte(ctrl->channel0[cnt], 13); + if (value < 0) goto hw_err; + value = log2(value & 0xff); + reg += value; + if(reg < 27) goto hw_err; + reg -= 27; + reg += (value << 2); + + dra += reg << (cnt*8); + value = spd_read_byte(ctrl->channel0[cnt], 5); + if (value & 2) + dra += reg << ((cnt*8)+4); + } + + /* 0x70 DRA */ + pci_write_config32(ctrl->f0, DRA, dra); + goto out; + + val_err: + die("Bad SPD value\r\n"); + /* If an hw_error occurs report that I have no memory */ +hw_err: + dra = 0; + out: + return dra; + +} + + +static int spd_set_drt_attributes(const struct mem_controller *ctrl, + long dimm_mask, uint32_t drc) +{ + int value; + int reg; + uint32_t drt; + int cnt; + int first_dimm; + int cas_latency=0; + int latency; + uint32_t index = 0; + uint32_t index2 = 0; + static const unsigned char cycle_time[3] = {0x75,0x60,0x50}; + static const int latency_indicies[] = { 26, 23, 9 }; + + /* 0x78 DRT */ + drt = pci_read_config32(ctrl->f0, DRT); + drt &= 3; /* save bits 1:0 */ + + for(first_dimm = 0; first_dimm < 4; first_dimm++) { + if (dimm_mask & (1 << first_dimm)) + break; + } + + /* get dimm type */ + value = spd_read_byte(ctrl->channel0[first_dimm], 2); + if(value == 8) { + drt |= (3<<5); /* back to bark write turn around & cycle add */ + } + + drt |= (3<<18); /* Trasmax */ + + for(cnt=0; cnt < 4; cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + reg = spd_read_byte(ctrl->channel0[cnt], 18); /* CAS Latency */ + /* Compute the lowest cas latency supported */ + latency = log2(reg) -2; + + /* Loop through and find a fast clock with a low latency */ + for(index = 0; index < 3; index++, latency++) { + if ((latency < 2) || (latency > 4) || + (!(reg & (1 << latency)))) { + continue; + } + value = spd_read_byte(ctrl->channel0[cnt], + latency_indicies[index]); + + if(value <= cycle_time[drc&3]) { + if( latency > cas_latency) { + cas_latency = latency; + } + break; + } + } + } + index = (cas_latency-2); + if((index)==0) cas_latency = 20; + else if((index)==1) cas_latency = 25; + else cas_latency = 30; + + for(cnt=0;cnt<4;cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + reg = spd_read_byte(ctrl->channel0[cnt], 27)&0x0ff; + if(((index>>8)&0x0ff)<reg) { + index &= ~(0x0ff << 8); + index |= (reg << 8); + } + reg = spd_read_byte(ctrl->channel0[cnt], 28)&0x0ff; + if(((index>>16)&0x0ff)<reg) { + index &= ~(0x0ff << 16); + index |= (reg<<16); + } + reg = spd_read_byte(ctrl->channel0[cnt], 29)&0x0ff; + if(((index2>>0)&0x0ff)<reg) { + index2 &= ~(0x0ff << 0); + index2 |= (reg<<0); + } + reg = spd_read_byte(ctrl->channel0[cnt], 41)&0x0ff; + if(((index2>>8)&0x0ff)<reg) { + index2 &= ~(0x0ff << 8); + index2 |= (reg<<8); + } + reg = spd_read_byte(ctrl->channel0[cnt], 42)&0x0ff; + if(((index2>>16)&0x0ff)<reg) { + index2 &= ~(0x0ff << 16); + index2 |= (reg<<16); + } + } + + /* get dimm speed */ + value = cycle_time[drc&3]; + if(value <= 0x50) { /* 200 MHz */ + if((index&7) > 2) { + drt |= (2<<2); /* CAS latency 4 */ + cas_latency = 40; + } else { + drt |= (1<<2); /* CAS latency 3 */ + cas_latency = 30; + } + if((index&0x0ff00)<=0x03c00) { + drt |= (1<<8); /* Trp RAS Precharg */ + } else { + drt |= (2<<8); /* Trp RAS Precharg */ + } + + /* Trcd RAS to CAS delay */ + if((index2&0x0ff)<=0x03c) { + drt |= (0<<10); + } else { + drt |= (1<<10); + } + + /* Tdal Write auto precharge recovery delay */ + drt |= (1<<12); + + /* Trc TRS min */ + if((index2&0x0ff00)<=0x03700) + drt |= (0<<14); + else if((index2&0xff00)<=0x03c00) + drt |= (1<<14); + else + drt |= (2<<14); /* spd 41 */ + + drt |= (2<<16); /* Twr not defined for DDR docs say use 2 */ + + /* Trrd Row Delay */ + if((index&0x0ff0000)<=0x0140000) { + drt |= (0<<20); + } else if((index&0x0ff0000)<=0x0280000) { + drt |= (1<<20); + } else if((index&0x0ff0000)<=0x03c0000) { + drt |= (2<<20); + } else { + drt |= (3<<20); + } + + /* Trfc Auto refresh cycle time */ + if((index2&0x0ff0000)<=0x04b0000) { + drt |= (0<<22); + } else if((index2&0x0ff0000)<=0x0690000) { + drt |= (1<<22); + } else { + drt |= (2<<22); + } + /* Docs say use 55 for all 200Mhz */ + drt |= (0x055<<24); + } + else if(value <= 0x60) { /* 167 Mhz */ + /* according to new documentation CAS latency is 00 + * for bits 3:2 for all 167 Mhz + drt |= ((index&3)<<2); */ /* set CAS latency */ + if((index&0x0ff00)<=0x03000) { + drt |= (1<<8); /* Trp RAS Precharg */ + } else { + drt |= (2<<8); /* Trp RAS Precharg */ + } + + /* Trcd RAS to CAS delay */ + if((index2&0x0ff)<=0x030) { + drt |= (0<<10); + } else { + drt |= (1<<10); + } + + /* Tdal Write auto precharge recovery delay */ + drt |= (2<<12); + + /* Trc TRS min */ + drt |= (2<<14); /* spd 41, but only one choice */ + + drt |= (2<<16); /* Twr not defined for DDR docs say 2 */ + + /* Trrd Row Delay */ + if((index&0x0ff0000)<=0x0180000) { + drt |= (0<<20); + } else if((index&0x0ff0000)<=0x0300000) { + drt |= (1<<20); + } else { + drt |= (2<<20); + } + + /* Trfc Auto refresh cycle time */ + if((index2&0x0ff0000)<=0x0480000) { + drt |= (0<<22); + } else if((index2&0x0ff0000)<=0x0780000) { + drt |= (2<<22); + } else { + drt |= (2<<22); + } + /* Docs state to use 99 for all 167 Mhz */ + drt |= (0x099<<24); + } + else if(value <= 0x75) { /* 133 Mhz */ + drt |= ((index&3)<<2); /* set CAS latency */ + if((index&0x0ff00)<=0x03c00) { + drt |= (1<<8); /* Trp RAS Precharg */ + } else { + drt |= (2<<8); /* Trp RAS Precharg */ + } + + /* Trcd RAS to CAS delay */ + if((index2&0x0ff)<=0x03c) { + drt |= (0<<10); + } else { + drt |= (1<<10); + } + + /* Tdal Write auto precharge recovery delay */ + drt |= (1<<12); + + /* Trc TRS min */ + drt |= (2<<14); /* spd 41, but only one choice */ + + drt |= (1<<16); /* Twr not defined for DDR docs say 1 */ + + /* Trrd Row Delay */ + if((index&0x0ff0000)<=0x01e0000) { + drt |= (0<<20); + } else if((index&0x0ff0000)<=0x03c0000) { + drt |= (1<<20); + } else { + drt |= (2<<20); + } + + /* Trfc Auto refresh cycle time */ + if((index2&0x0ff0000)<=0x04b0000) { + drt |= (0<<22); + } else if((index2&0x0ff0000)<=0x0780000) { + drt |= (2<<22); + } else { + drt |= (2<<22); + } + + /* Based on CAS latency */ + if(index&7) + drt |= (0x099<<24); + else + drt |= (0x055<<24); + + } + else { + die("Invalid SPD 9 bus speed.\r\n"); + } + + /* 0x78 DRT */ + pci_write_config32(ctrl->f0, DRT, drt); + + return(cas_latency); +} + +static int spd_set_dram_controller_mode(const struct mem_controller *ctrl, + long dimm_mask) +{ + int value; + int reg; + int drc; + int cnt; + msr_t msr; + unsigned char dram_type = 0xff; + unsigned char ecc = 0xff; + unsigned char rate = 62; + static const unsigned char spd_rates[6] = {15,3,7,7,62,62}; + static const unsigned char drc_rates[5] = {0,15,7,62,3}; + static const unsigned char fsb_conversion[4] = {3,1,3,2}; + + /* 0x7c DRC */ + drc = pci_read_config32(ctrl->f0, DRC); + for(cnt=0; cnt < 4; cnt++) { + if (!(dimm_mask & (1 << cnt))) { + continue; + } + value = spd_read_byte(ctrl->channel0[cnt], 11); /* ECC */ + reg = spd_read_byte(ctrl->channel0[cnt], 2); /* Type */ + if (value == 2) { /* RAM is ECC capable */ + if (reg == 8) { + if ( ecc == 0xff ) { + ecc = 2; + } + else if (ecc == 1) { + die("ERROR - Mixed DDR & DDR2 RAM\r\n"); + } + } + else if ( reg == 7 ) { + if ( ecc == 0xff) { + ecc = 1; + } + else if ( ecc > 1 ) { + die("ERROR - Mixed DDR & DDR2 RAM\r\n"); + } + } + else { + die("ERROR - RAM not DDR\r\n"); + } + } + else { + die("ERROR - Non ECC memory dimm\r\n"); + } + + value = spd_read_byte(ctrl->channel0[cnt], 12); /*refresh rate*/ + value &= 0x0f; /* clip self refresh bit */ + if (value > 5) goto hw_err; + if (rate > spd_rates[value]) + rate = spd_rates[value]; + + value = spd_read_byte(ctrl->channel0[cnt], 9); /* cycle time */ + if (value > 0x75) goto hw_err; + if (value <= 0x50) { + if (dram_type >= 2) { + if (reg == 8) { /*speed is good, is this ddr2?*/ + dram_type = 2; + } else { /* not ddr2 so use ddr333 */ + dram_type = 1; + } + } + } + else if (value <= 0x60) { + if (dram_type >= 1) dram_type = 1; + } + else dram_type = 0; /* ddr266 */ + + } + ecc = 2; + if (read_option(CMOS_VSTART_ECC_memory,CMOS_VLEN_ECC_memory,1) == 0) { + ecc = 0; /* ECC off in CMOS so disable it */ + print_debug("ECC off\r\n"); + } + else { + print_debug("ECC on\r\n"); + } + drc &= ~(3 << 20); /* clear the ecc bits */ + drc |= (ecc << 20); /* or in the calculated ecc bits */ + for ( cnt = 1; cnt < 5; cnt++) + if (drc_rates[cnt] == rate) + break; + if (cnt < 5) { + drc &= ~(7 << 8); /* clear the rate bits */ + drc |= (cnt << 8); + } + + if (reg == 8) { /* independant clocks */ + drc |= (1 << 4); + } + + drc |= (1 << 26); /* set the overlap bit - the factory BIOS does */ + drc |= (1 << 27); /* set DED retry enable - the factory BIOS does */ + /* front side bus */ + msr = rdmsr(0x2c); + value = msr.lo >> 16; + value &= 0x03; + drc &= ~(3 << 2); /* set the front side bus */ + drc |= (fsb_conversion[value] << 2); + drc &= ~(3 << 0); /* set the dram type */ + drc |= (dram_type << 0); + + goto out; + + val_err: + die("Bad SPD value\r\n"); + /* If an hw_error occurs report that I have no memory */ +hw_err: + drc = 0; + out: + return drc; +} + +static void sdram_set_spd_registers(const struct mem_controller *ctrl) +{ + long dimm_mask; + + /* Test if we can read the spd and if ram is ddr or ddr2 */ + dimm_mask = spd_detect_dimms(ctrl); + if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) { + print_err("No memory for this cpu\r\n"); + return; + } + return; +} + +static void do_delay(void) +{ + int i; + unsigned char b; + for(i=0;i<16;i++) + b=inb(0x80); +} + +#define TIMEOUT_LOOPS 300000 + +#define DCALCSR 0x100 +#define DCALADDR 0x104 +#define DCALDATA 0x108 + +static void set_on_dimm_termination_enable(const struct mem_controller *ctrl) +{ + unsigned char c1,c2; + unsigned int dimm,i; + unsigned int data32; + unsigned int t4; + + /* Set up northbridge values */ + /* ODT enable */ + pci_write_config32(ctrl->f0, 0x88, 0xf0000180); + /* Figure out which slots are Empty, Single, or Double sided */ + for(i=0,t4=0,c2=0;i<8;i+=2) { + c1 = pci_read_config8(ctrl->f0, DRB+i); + if(c1 == c2) continue; + c2 = pci_read_config8(ctrl->f0, DRB+1+i); + if(c1 == c2) + t4 |= (1 << (i*4)); + else + t4 |= (2 << (i*4)); + } + for(i=0;i<1;i++) { + if((t4&0x0f) == 1) { + if( ((t4>>8)&0x0f) == 0 ) { + data32 = 0x00000010; /* EEES */ + break; + } + if ( ((t4>>16)&0x0f) == 0 ) { + data32 = 0x00003132; /* EESS */ + break; + } + if ( ((t4>>24)&0x0f) == 0 ) { + data32 = 0x00335566; /* ESSS */ + break; + } + data32 = 0x77bbddee; /* SSSS */ + break; + } + if((t4&0x0f) == 2) { + if( ((t4>>8)&0x0f) == 0 ) { + data32 = 0x00003132; /* EEED */ + break; + } + if ( ((t4>>8)&0x0f) == 2 ) { + data32 = 0xb373ecdc; /* EEDD */ + break; + } + if ( ((t4>>16)&0x0f) == 0 ) { + data32 = 0x00b3a898; /* EESD */ + break; + } + data32 = 0x777becdc; /* ESSD */ + break; + } + die("Error - First dimm slot empty\r\n"); + } + + print_debug("ODT Value = "); + print_debug_hex32(data32); + print_debug("\r\n"); + + pci_write_config32(ctrl->f0, 0xb0, data32); + + for(dimm=0;dimm<8;dimm+=1) { + + write32(BAR+DCALADDR, 0x0b840001); + write32(BAR+DCALCSR, 0x83000003 | (dimm << 20)); + + for(i=0;i<1001;i++) { + data32 = read32(BAR+DCALCSR); + if(!(data32 & (1<<31))) + break; + } + } +} +static void set_receive_enable(const struct mem_controller *ctrl) +{ + unsigned int i; + unsigned int cnt,bit; + uint32_t recena=0; + uint32_t recenb=0; + + { + unsigned int dimm; + unsigned int edge; + int32_t data32; + uint32_t data32_dram; + uint32_t dcal_data32_0; + uint32_t dcal_data32_1; + uint32_t dcal_data32_2; + uint32_t dcal_data32_3; + uint32_t work32l; + uint32_t work32h; + uint32_t data32r; + int32_t recen; + for(dimm=0;dimm<8;dimm+=1) { + + if(!(dimm&1)) { + write32(BAR+DCALDATA+(17*4), 0x04020000); + write32(BAR+DCALCSR, 0x83800004 | (dimm << 20)); + + for(i=0;i<1001;i++) { + data32 = read32(BAR+DCALCSR); + if(!(data32 & (1<<31))) + break; + } + if(i>=1000) + continue; + + dcal_data32_0 = read32(BAR+DCALDATA + 0); + dcal_data32_1 = read32(BAR+DCALDATA + 4); + dcal_data32_2 = read32(BAR+DCALDATA + 8); + dcal_data32_3 = read32(BAR+DCALDATA + 12); + } + else { + dcal_data32_0 = read32(BAR+DCALDATA + 16); + dcal_data32_1 = read32(BAR+DCALDATA + 20); + dcal_data32_2 = read32(BAR+DCALDATA + 24); + dcal_data32_3 = read32(BAR+DCALDATA + 28); + } + + /* check if bank is installed */ + if((dcal_data32_0 == 0) && (dcal_data32_2 == 0)) + continue; + /* Calculate the timing value */ + for(i=0,edge=0,bit=63,cnt=31,data32r=0, + work32l=dcal_data32_1,work32h=dcal_data32_3; + (i<4) && bit; i++) { + for(;;bit--,cnt--) { + if(work32l & (1<<cnt)) + break; + if(!cnt) { + work32l = dcal_data32_0; + work32h = dcal_data32_2; + cnt = 32; + } + if(!bit) break; + } + for(;;bit--,cnt--) { + if(!(work32l & (1<<cnt))) + break; + if(!cnt) { + work32l = dcal_data32_0; + work32h = dcal_data32_2; + cnt = 32; + } + if(!bit) break; + } + if(!bit) { + break; + } + data32 = ((bit%8) << 1); + if(work32h & (1<<cnt)) + data32 += 1; + if(data32 < 4) { + if(!edge) { + edge = 1; + } + else { + if(edge != 1) { + data32 = 0x0f; + } + } + } + if(data32 > 12) { + if(!edge) { + edge = 2; + } + else { + if(edge != 2) { + data32 = 0x00; + } + } + } + data32r += data32; + } + + work32l = dcal_data32_0; + work32h = dcal_data32_2; + recen = data32r; + recen += 3; + recen = recen>>2; + for(cnt=5;cnt<24;) { + for(;;cnt++) + if(!(work32l & (1<<cnt))) + break; + for(;;cnt++) { + if(work32l & (1<<cnt)) + break; + } + data32 = (((cnt-1)%8)<<1); + if(work32h & (1<<(cnt-1))) { + data32++; + } + /* test for frame edge cross overs */ + if((edge == 1) && (data32 > 12) && + (((recen+16)-data32) < 3)) { + data32 = 0; + cnt += 2; + } + if((edge == 2) && (data32 < 4) && + ((recen - data32) > 12)) { + data32 = 0x0f; + cnt -= 2; + } + if(((recen+3) >= data32) && ((recen-3) <= data32)) + break; + } + cnt--; + cnt /= 8; + cnt--; + if(recen&1) + recen+=2; + recen >>= 1; + recen += (cnt*8); + recen+=2; + recen <<= (dimm/2) * 8; + if(!(dimm&1)) { + recena |= recen; + } + else { + recenb |= recen; + } + } + } + /* Check for Eratta problem */ + for(i=cnt=bit=0;i<4;i++) { + if (((recena>>(i*8))&0x0f)>7) { + cnt++; bit++; + } + else { + if((recena>>(i*8))&0x0f) { + cnt++; + } + } + } + if(bit) { + cnt-=bit; + if(cnt>1) { + for(i=0;i<4;i++) { + if(((recena>>(i*8))&0x0f)>7) { + recena &= ~(0x0f<<(i*8)); + recena |= (7<<(i*8)); + } + } + } + else { + for(i=0;i<4;i++) { + if(((recena>>(i*8))&0x0f)<8) { + recena &= ~(0x0f<<(i*8)); + recena |= (8<<(i*8)); + } + } + } + } + for(i=cnt=bit=0;i<4;i++) { + if (((recenb>>(i*8))&0x0f)>7) { + cnt++; bit++; + } + else { + if((recenb>>(i*8))&0x0f) { + cnt++; + } + } + } + if(bit) { + cnt-=bit; + if(cnt>1) { + for(i=0;i<4;i++) { + if(((recenb>>(i*8))&0x0f)>7) { + recenb &= ~(0x0f<<(i*8)); + recenb |= (7<<(i*8)); + } + } + } + else { + for(i=0;i<4;i++) { + if(((recenb>>(i*8))&0x0f)<8) { + recenb &= ~(0x0f<<(i*8)); + recenb |= (8<<(i*8)); + } + } + } + } + +// recena = 0x0000090a; +// recenb = 0x0000090a; + + print_debug("Receive enable A = "); + print_debug_hex32(recena); + print_debug(", Receive enable B = "); + print_debug_hex32(recenb); + print_debug("\r\n"); + + /* clear out the calibration area */ + write32(BAR+DCALDATA+(16*4), 0x00000000); + write32(BAR+DCALDATA+(17*4), 0x00000000); + write32(BAR+DCALDATA+(18*4), 0x00000000); + write32(BAR+DCALDATA+(19*4), 0x00000000); + + /* No command */ + write32(BAR+DCALCSR, 0x0000000f); + + write32(BAR+0x150, recena); + write32(BAR+0x154, recenb); +} + + +static void sdram_enable(int controllers, const struct mem_controller *ctrl) +{ + int i; + int cs; + int cnt; + int cas_latency; + long mask; + uint32_t drc; + uint32_t data32; + uint32_t mode_reg; + uint32_t *iptr; + volatile unsigned long *iptrv; + msr_t msr; + uint32_t scratch; + uint8_t byte; + uint16_t data16; + static const struct { + uint32_t clkgr[4]; + } gearing [] = { + /* FSB 133 DIMM 266 */ + {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}}, + /* FSB 133 DIMM 333 */ + {{ 0x00000000, 0x00000000, 0x00000000, 0x00000000}}, + /* FSB 133 DIMM 400 */ + {{ 0x00000120, 0x00000000, 0x00000032, 0x00000010}}, + /* FSB 167 DIMM 266 */ + {{ 0x00005432, 0x00001000, 0x00004325, 0x00000000}}, + /* FSB 167 DIMM 333 */ + {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}}, + /* FSB 167 DIMM 400 */ + {{ 0x00154320, 0x00000000, 0x00065432, 0x00010000}}, + /* FSB 200 DIMM 266 */ + {{ 0x00000032, 0x00000010, 0x00000120, 0x00000000}}, + /* FSB 200 DIMM 333 */ + {{ 0x00065432, 0x00010000, 0x00054326, 0x00000000}}, + /* FSB 200 DIMM 400 */ + {{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}}, + }; + + static const uint32_t dqs_data[] = { + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff, + 0xffffffff, 0xffffffff, 0x000000ff}; + + mask = spd_detect_dimms(ctrl); + print_debug("Starting SDRAM Enable\r\n"); + + /* 0x80 */ +#ifdef DIMM_MAP_LOGICAL + pci_write_config32(ctrl->f0, DRM, + 0x00210000 | DIMM_MAP_LOGICAL); +#else + pci_write_config32(ctrl->f0, DRM, 0x00211248); +#endif + /* set dram type and Front Side Bus freq. */ + drc = spd_set_dram_controller_mode(ctrl, mask); + if( drc == 0) { + die("Error calculating DRC\r\n"); + } + data32 = drc & ~(3 << 20); /* clear ECC mode */ + data32 = data32 & ~(7 << 8); /* clear refresh rates */ + data32 = data32 | (1 << 5); /* temp turn off of ODT */ + /* Set gearing, then dram controller mode */ + /* drc bits 1:0 = DIMM speed, bits 3:2 = FSB speed */ + for(iptr = gearing[(drc&3)+((((drc>>2)&3)-1)*3)].clkgr,cnt=0; + cnt<4;cnt++) { + pci_write_config32(ctrl->f0, 0xa0+(cnt*4), iptr[cnt]); + } + /* 0x7c DRC */ + pci_write_config32(ctrl->f0, DRC, data32); + + /* turn the clocks on */ + /* 0x8c CKDIS */ + pci_write_config16(ctrl->f0, CKDIS, 0x0000); + + /* 0x9a DDRCSR Take subsystem out of idle */ + data16 = pci_read_config16(ctrl->f0, DDRCSR); + data16 &= ~(7 << 12); + data16 |= (3 << 12); /* use dual channel lock step */ + pci_write_config16(ctrl->f0, DDRCSR, data16); + + /* program row size DRB */ + spd_set_ram_size(ctrl, mask); + + /* program page size DRA */ + spd_set_row_attributes(ctrl, mask); + + /* program DRT timing values */ + cas_latency = spd_set_drt_attributes(ctrl, mask, drc); + + for(i=0;i<8;i++) { /* loop throught each dimm to test for row */ + print_debug("DIMM "); + print_debug_hex8(i); + print_debug("\r\n"); + /* Apply NOP */ + do_delay(); + + write32(BAR + 0x100, (0x03000000 | (i<<20))); + + write32(BAR+0x100, (0x83000000 | (i<<20))); + + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + + } + + /* Apply NOP */ + do_delay(); + + for(cs=0;cs<8;cs++) { + write32(BAR + DCALCSR, (0x83000000 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Precharg all banks */ + do_delay(); + for(cs=0;cs<8;cs++) { + if ((drc & 3) == 2) /* DDR2 */ + write32(BAR+DCALADDR, 0x04000000); + else /* DDR1 */ + write32(BAR+DCALADDR, 0x00000000); + write32(BAR+DCALCSR, (0x83000002 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* EMRS dll's enabled */ + do_delay(); + for(cs=0;cs<8;cs++) { + if ((drc & 3) == 2) /* DDR2 */ + /* fixme hard code AL additive latency */ + write32(BAR+DCALADDR, 0x0b940001); + else /* DDR1 */ + write32(BAR+DCALADDR, 0x00000001); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + /* MRS reset dll's */ + do_delay(); + if ((drc & 3) == 2) { /* DDR2 */ + if(cas_latency == 30) + mode_reg = 0x053a0000; + else + mode_reg = 0x054a0000; + } + else { /* DDR1 */ + if(cas_latency == 20) + mode_reg = 0x012a0000; + else /* CAS Latency 2.5 */ + mode_reg = 0x016a0000; + } + for(cs=0;cs<8;cs++) { + write32(BAR+DCALADDR, mode_reg); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Precharg all banks */ + do_delay(); + do_delay(); + do_delay(); + for(cs=0;cs<8;cs++) { + if ((drc & 3) == 2) /* DDR2 */ + write32(BAR+DCALADDR, 0x04000000); + else /* DDR1 */ + write32(BAR+DCALADDR, 0x00000000); + write32(BAR+DCALCSR, (0x83000002 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Do 2 refreshes */ + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + do_delay(); + /* for good luck do 6 more */ + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x83000001 | (cs<<20))); + } + do_delay(); + /* MRS reset dll's normal */ + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALADDR, (mode_reg & ~(1<<24))); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Do only if DDR2 EMRS dll's enabled */ + if ((drc & 3) == 2) { /* DDR2 */ + do_delay(); + for(cs=0;cs<8;cs++) { + write32(BAR+DCALADDR, (0x0b940001)); + write32(BAR+DCALCSR, (0x83000003 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + } + + do_delay(); + /* No command */ + write32(BAR+DCALCSR, 0x0000000f); + + /* DDR1 This is test code to copy some codes in the factory setup */ + + write32(BAR, 0x00100000); + + if ((drc & 3) == 2) { /* DDR2 */ + /* enable on dimm termination */ + set_on_dimm_termination_enable(ctrl); + } + + /* receive enable calibration */ + set_receive_enable(ctrl); + + /* DQS */ + pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); + for(i = 0, cnt = (BAR+0x200); i < 24; i++, cnt+=4) { + write32(cnt, dqs_data[i]); + } + pci_write_config32(ctrl->f0, 0x94, 0x3904a100 ); + + /* Enable refresh */ + /* 0x7c DRC */ + data32 = drc & ~(3 << 20); /* clear ECC mode */ + pci_write_config32(ctrl->f0, DRC, data32); + write32(BAR+DCALCSR, 0x0008000f); + + /* clear memory and init ECC */ + print_debug("Clearing memory\r\n"); + for(i=0;i<64;i+=4) { + write32(BAR+DCALDATA+i, 0x00000000); + } + + for(cs=0;cs<8;cs++) { + write32(BAR+DCALCSR, (0x830831d8 | (cs<<20))); + data32 = read32(BAR+DCALCSR); + while(data32 & 0x80000000) + data32 = read32(BAR+DCALCSR); + } + + /* Bring memory subsystem on line */ + data32 = pci_read_config32(ctrl->f0, 0x98); + data32 |= (1 << 31); + pci_write_config32(ctrl->f0, 0x98, data32); + /* wait for completion */ + print_debug("Waiting for mem complete\r\n"); + while(1) { + data32 = pci_read_config32(ctrl->f0, 0x98); + if( (data32 & (1<<31)) == 0) + break; + } + print_debug("Done\r\n"); + + /* Set initialization complete */ + /* 0x7c DRC */ + drc |= (1 << 29); + data32 = drc & ~(3 << 20); /* clear ECC mode */ + pci_write_config32(ctrl->f0, DRC, data32); + + /* Set the ecc mode */ + pci_write_config32(ctrl->f0, DRC, drc); + + /* Enable memory scrubbing */ + /* 0x52 MCHSCRB */ + data16 = pci_read_config16(ctrl->f0, MCHSCRB); + data16 &= ~0x0f; + data16 |= ((2 << 2) | (2 << 0)); + pci_write_config16(ctrl->f0, MCHSCRB, data16); + + /* The memory is now setup, use it */ + cache_lbmem(MTRR_TYPE_WRBACK); +} diff --git a/src/northbridge/intel/E7525/raminit.h b/src/northbridge/intel/E7525/raminit.h new file mode 100644 index 0000000000..183ace8385 --- /dev/null +++ b/src/northbridge/intel/E7525/raminit.h @@ -0,0 +1,12 @@ +#ifndef RAMINIT_H +#define RAMINIT_H + +#define DIMM_SOCKETS 4 +struct mem_controller { + unsigned node_id; + device_t f0, f1, f2, f3; + uint16_t channel0[DIMM_SOCKETS]; + uint16_t channel1[DIMM_SOCKETS]; +}; + +#endif /* RAMINIT_H */ diff --git a/src/northbridge/intel/E7525/raminit_test.c b/src/northbridge/intel/E7525/raminit_test.c new file mode 100644 index 0000000000..2d44d25403 --- /dev/null +++ b/src/northbridge/intel/E7525/raminit_test.c @@ -0,0 +1,393 @@ +#include <unistd.h> +#include <limits.h> +#include <stdint.h> +#include <string.h> +#include <setjmp.h> +#include <device/pci_def.h> +#include "e7525.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); + + 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; +} + +#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 (spd_count >= spd_fail_count) { + result = -1; + } + return result; +} + +#include "raminit.c" +#include "../../../sdram/generic_sdram.c" + +#define FIRST_CPU 1 +#define SECOND_CPU 1 +#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) +#if 0 +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); + +} +#endif +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); +} + +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); +// raminit_main(); +} + + +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; +} diff --git a/src/southbridge/amd/amd8111/amd8111_reset.c b/src/southbridge/amd/amd8111/amd8111_reset.c index 822a1e378f..435904aabd 100644 --- a/src/southbridge/amd/amd8111/amd8111_reset.c +++ b/src/southbridge/amd/amd8111/amd8111_reset.c @@ -1,14 +1,15 @@ +/* Include this file in the mainboards reset.c + */ #include <arch/io.h> +#include <device/pci_ids.h> #define PCI_DEV(BUS, DEV, FN) ( \ (((BUS) & 0xFF) << 16) | \ (((DEV) & 0x1f) << 11) | \ (((FN) & 0x7) << 8)) -#define AMD8111_RESET PCI_DEV( \ - HARD_RESET_BUS, \ - HARD_RESET_DEVICE, \ - HARD_RESET_FUNCTION) +#define PCI_ID(VENDOR_ID, DEVICE_ID) \ + ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF)) typedef unsigned device_t; @@ -36,10 +37,57 @@ static unsigned pci_read_config32(device_t dev, unsigned where) return inl(0xCFC); } +#define PCI_DEV_INVALID (0xffffffffU) +static device_t pci_locate_device(unsigned pci_id, unsigned bus) +{ + device_t dev, last; + dev = PCI_DEV(bus, 0, 0); + last = PCI_DEV(bus, 31, 7); + for(; dev <= last; 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; +} + #include "../../../northbridge/amd/amdk8/reset_test.c" -void hard_reset(void) +static unsigned node_link_to_bus(unsigned node, unsigned link) { + unsigned reg; + + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + unsigned config_map; + config_map = pci_read_config32(PCI_DEV(0, 0x18, 1), reg); + if ((config_map & 3) != 3) { + continue; + } + if ((((config_map >> 4) & 7) == node) && + (((config_map >> 8) & 3) == link)) + { + return (config_map >> 16) & 0xff; + } + } + return 0; +} + +static void amd8111_hard_reset(unsigned node, unsigned link) +{ + device_t dev; + unsigned bus; + + /* Find the device. + * There can only be one 8111 on a hypertransport chain/bus. + */ + bus = node_link_to_bus(node, link); + dev = pci_locate_device( + PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_ISA), + bus); + + /* Reset */ set_bios_reset(); - pci_write_config8(AMD8111_RESET, 0x47, 1); + pci_write_config8(dev, 0x47, 1); } diff --git a/src/southbridge/amd/amd8131-disable/Config.lb b/src/southbridge/amd/amd8131-disable/Config.lb new file mode 100644 index 0000000000..9968e9ad1d --- /dev/null +++ b/src/southbridge/amd/amd8131-disable/Config.lb @@ -0,0 +1 @@ +driver amd8131_bridge.o diff --git a/src/southbridge/amd/amd8131-disable/amd8131_bridge.c b/src/southbridge/amd/amd8131-disable/amd8131_bridge.c new file mode 100644 index 0000000000..648dbba250 --- /dev/null +++ b/src/southbridge/amd/amd8131-disable/amd8131_bridge.c @@ -0,0 +1,116 @@ +/* + * (C) 2004 Linux Networx + */ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <pc80/mc146818rtc.h> + +static void amd8131_bus_read_resources(device_t dev) +{ + return; +} + +static void amd8131_bus_set_resources(device_t dev) +{ +#if 0 + pci_bus_read_resources(dev); +#endif + return; +} + +static void amd8131_bus_enable_resources(device_t dev) +{ +#if 0 + pci_dev_set_resources(dev); +#endif + return; +} + +static void amd8131_bus_init(device_t dev) +{ +#if 0 + pcix_init(dev); +#endif + return; +} + +static unsigned int amd8131_scan_bus(device_t bus, unsigned int max) +{ +#if 0 + max = pcix_scan_bridge(bus, max); +#endif + return max; +} + +static void amd8131_enable(device_t dev) +{ + uint32_t buses; + uint16_t cr; + + /* Clear all status bits and turn off memory, I/O and master enables. */ + pci_write_config16(dev, PCI_COMMAND, 0x0000); + pci_write_config16(dev, PCI_STATUS, 0xffff); + + /* + * Read the existing primary/secondary/subordinate bus + * number configuration. + */ + buses = pci_read_config32(dev, PCI_PRIMARY_BUS); + + /* Configure the bus numbers for this bridge: the configuration + * transactions will not be propagated by the bridge if it is not + * correctly configured. + */ + buses &= 0xff000000; + buses |= (((unsigned int) (dev->bus->secondary) << 0) | + ((unsigned int) (dev->bus->secondary) << 8) | + ((unsigned int) (dev->bus->secondary) << 16)); + pci_write_config32(dev, PCI_PRIMARY_BUS, buses); +} + +static struct device_operations pcix_ops = { + .read_resources = amd8131_bus_read_resources, + .set_resources = amd8131_bus_set_resources, + .enable_resources = amd8131_bus_enable_resources, + .init = amd8131_bus_init, + .scan_bus = 0, + .enable = amd8131_enable, +}; + +static struct pci_driver pcix_driver __pci_driver = { + .ops = &pcix_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = 0x7450, +}; + + +static void ioapic_enable(device_t dev) +{ + uint32_t value; + value = pci_read_config32(dev, 0x44); + if (dev->enabled) { + value |= ((1 << 1) | (1 << 0)); + } else { + value &= ~((1 << 1) | (1 << 0)); + } + pci_write_config32(dev, 0x44, value); +} + +static struct device_operations ioapic_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .enable = ioapic_enable, +}; + +static struct pci_driver ioapic_driver __pci_driver = { + .ops = &ioapic_ops, + .vendor = PCI_VENDOR_ID_AMD, + .device = 0x7451, + +}; diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c index 357059d347..828b083f2e 100644 --- a/src/southbridge/amd/amd8131/amd8131_bridge.c +++ b/src/southbridge/amd/amd8131/amd8131_bridge.c @@ -7,10 +7,273 @@ #include <device/pci_ids.h> #include <device/pci_ops.h> #include <pc80/mc146818rtc.h> +#include <device/pci_def.h> +#include <device/pcix.h> #define NMI_OFF 0 -static void pcix_init(device_t dev) +#define NPUML 0xD9 /* Non prefetchable upper memory limit */ +#define NPUMB 0xD8 /* Non prefetchable upper memory base */ + +static void amd8131_walk_children(struct bus *bus, + void (*visit)(device_t dev, void *ptr), void *ptr) +{ + device_t child; + for(child = bus->children; child; child = child->sibling) + { + if (child->path.type != DEVICE_PATH_PCI) { + continue; + } + if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) { + amd8131_walk_children(&child->link[0], visit, ptr); + } + visit(child, ptr); + } +} + +struct amd8131_bus_info { + unsigned sstatus; + unsigned rev; + int errata_56; + int master_devices; + int max_func; +}; + +static void amd8131_count_dev(device_t dev, void *ptr) +{ + struct amd8131_bus_info *info = ptr; + /* Don't count pci bridges */ + if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { + info->master_devices++; + } + if (PCI_FUNC(dev->path.u.pci.devfn) > info->max_func) { + info->max_func = PCI_FUNC(dev->path.u.pci.devfn); + } +} + + +static void amd8131_pcix_tune_dev(device_t dev, void *ptr) +{ + struct amd8131_bus_info *info = ptr; + unsigned cap; + unsigned status, cmd, orig_cmd; + unsigned max_read, max_tran; + int sib_funcs, sibs; + device_t sib; + + if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) { + return; + } + cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); + if (!cap) { + return; + } + /* How many siblings does this device have? */ + sibs = info->master_devices - 1; + /* Count how many sibling functions this device has */ + sib_funcs = 0; + for(sib = dev->bus->children; sib; sib = sib->sibling) { + if (sib == dev) { + continue; + } + if (PCI_SLOT(sib->path.u.pci.devfn) != PCI_SLOT(dev->path.u.pci.devfn)) { + continue; + } + sib_funcs++; + } + + + printk_debug("%s AMD8131 PCI-X tuning\n", dev_path(dev)); + status = pci_read_config32(dev, cap + PCI_X_STATUS); + orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD); + + max_read = (status & PCI_X_STATUS_MAX_READ) >> 21; + max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23; + + /* Errata #49 don't allow 4K transactions */ + if (max_read >= 2) { + max_read = 2; + } + + /* Errata #37 Limit the number of split transactions to avoid starvation */ + if (sibs >= 2) { + /* At most 2 outstanding split transactions when we have + * 3 or more bus master devices on the bus. + */ + if (max_tran > 1) { + max_tran = 1; + } + } + else if (sibs == 1) { + /* At most 4 outstanding split transactions when we have + * 2 bus master devices on the bus. + */ + if (max_tran > 3) { + max_tran = 3; + } + } + else { + /* At most 8 outstanding split transactions when we have + * only one bus master device on the bus. + */ + if (max_tran > 4) { + max_tran = 4; + } + } + /* Errata #56 additional limits when the bus runs at 133Mhz */ + if (info->errata_56 && + (PCI_X_SSTATUS_MFREQ(info->sstatus) == PCI_X_SSTATUS_MODE1_133MHZ)) + { + unsigned limit_read; + /* Look at the number of siblings and compute the + * largest legal read size. + */ + if (sib_funcs == 0) { + /* 2k reads */ + limit_read = 2; + } + else if (sib_funcs <= 1) { + /* 1k reads */ + limit_read = 1; + } + else { + /* 512 byte reads */ + limit_read = 0; + } + if (max_read > limit_read) { + max_read = limit_read; + } + /* Look at the read size and the nubmer of siblings + * and compute how many outstanding transactions I can have. + */ + if (max_read == 2) { + /* 2K reads */ + if (max_tran > 0) { + /* Only 1 outstanding transaction allowed */ + max_tran = 0; + } + } + else if (max_read == 1) { + /* 1K reads */ + if (max_tran > (1 - sib_funcs)) { + /* At most 2 outstanding transactions */ + max_tran = 1 - sib_funcs; + } + } + else { + /* 512 byte reads */ + max_read = 0; + if (max_tran > (2 - sib_funcs)) { + /* At most 3 outstanding transactions */ + max_tran = 2 - sib_funcs; + } + } + } +#if 0 + printk_debug("%s max_read: %d max_tran: %d sibs: %d sib_funcs: %d\n", + dev_path(dev), max_read, max_tran, sibs, sib_funcs, sib_funcs); +#endif + if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) { + cmd &= ~PCI_X_CMD_MAX_READ; + cmd |= max_read << 2; + } + if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) { + cmd &= ~PCI_X_CMD_MAX_SPLIT; + cmd |= max_tran << 4; + } + + /* Don't attempt to handle PCI-X errors */ + cmd &= ~PCI_X_CMD_DPERR_E; + /* The 8131 does not work properly with relax ordering enabled. + * Errata #58 + */ + cmd &= ~PCI_X_CMD_ERO; + if (orig_cmd != cmd) { + pci_write_config16(dev, cap + PCI_X_CMD, cmd); + } +} +static unsigned int amd8131_scan_bus(struct bus *bus, + unsigned min_devfn, unsigned max_devfn, unsigned int max) +{ + struct amd8131_bus_info info; + struct bus *pbus; + unsigned pos; + + + /* Find the children on the bus */ + max = pci_scan_bus(bus, min_devfn, max_devfn, max); + + /* Find the revision of the 8131 */ + info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION); + + /* See which errata apply */ + info.errata_56 = info.rev <= 0x12; + + /* Find the pcix capability and get the secondary bus status */ + pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX); + info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS); + + /* Print the PCI-X bus speed */ + printk_debug("PCI: %02x: %s\n", bus->secondary, pcix_speed(info.sstatus)); + + + /* Examine the bus and find out how loaded it is */ + info.max_func = 0; + info.master_devices = 0; + amd8131_walk_children(bus, amd8131_count_dev, &info); + + /* Disable the bus if there are no devices on it or + * we are running at 133Mhz and have a 4 function device. + * see errata #56 + */ + if (!bus->children || + (info.errata_56 && + (info.max_func >= 3) && + (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_MODE1_133MHZ))) + { + unsigned pcix_misc; + /* Disable all of my children */ + disable_children(bus); + + /* Remember the device is disabled */ + bus->dev->enabled = 0; + + /* Disable the PCI-X clocks */ + pcix_misc = pci_read_config32(bus->dev, 0x40); + pcix_misc &= ~(0x1f << 16); + pci_write_config32(bus->dev, 0x40, pcix_misc); + + return max; + } + + /* If we are in conventional PCI mode nothing more is necessary. + */ + if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) { + return max; + } + + + /* Tune the devices on the bus */ + amd8131_walk_children(bus, amd8131_pcix_tune_dev, &info); + + /* Don't allow the 8131 or any of it's parent busses to + * implement relaxed ordering. Errata #58 + */ + for(pbus = bus; !pbus->disable_relaxed_ordering; pbus = pbus->dev->bus) { + printk_spew("%s disabling relaxed ordering\n", + bus_path(pbus)); + pbus->disable_relaxed_ordering = 1; + } + return max; +} + +static unsigned int amd8131_scan_bridge(device_t dev, unsigned int max) +{ + return do_pci_scan_bridge(dev, max, amd8131_scan_bus); +} + + +static void amd8131_pcix_init(device_t dev) { uint32_t dword; uint16_t word; @@ -24,18 +287,19 @@ static void pcix_init(device_t dev) /* Set drive strength */ word = pci_read_config16(dev, 0xe0); - word = 0x0808; + word = 0x0404; pci_write_config16(dev, 0xe0, word); word = pci_read_config16(dev, 0xe4); - word = 0x0808; + word = 0x0404; pci_write_config16(dev, 0xe4, word); /* Set impedance */ word = pci_read_config16(dev, 0xe8); - word = 0x0f0f; + word = 0x0404; pci_write_config16(dev, 0xe8, word); /* Set discard unrequested prefetch data */ + /* Errata #51 */ word = pci_read_config16(dev, 0x4c); word |= 1; pci_write_config16(dev, 0x4c, word); @@ -76,16 +340,58 @@ static void pcix_init(device_t dev) dword |= (1<<1); pci_write_config32(dev, 0xc8, dword); } - return; } +#define BRIDGE_40_BIT_SUPPORT 0 +#if BRIDGE_40_BIT_SUPPORT +static void bridge_read_resources(struct device *dev) +{ + struct resource *res; + pci_bus_read_resources(dev); + res = find_resource(dev, PCI_MEMORY_BASE); + if (res) { + res->limit = 0xffffffffffULL; + } +} + +static void bridge_set_resources(struct device *dev) +{ + struct resource *res; + res = find_resource(dev, PCI_MEMORY_BASE); + if (res) { + resource_t base, end; + /* set the memory range */ + dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + res->flags |= IORESOURCE_STORED; + compute_allocate_resource(&dev->link[0], res, + IORESOURCE_MEM | IORESOURCE_PREFETCH, + IORESOURCE_MEM); + base = res->base; + end = resource_end(res); + pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16); + pci_write_config8(dev, NPUML, (base >> 32) & 0xff); + pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16); + pci_write_config8(dev, NPUMB, (end >> 32) & 0xff); + + report_resource_stored(dev, res, ""); + } + pci_dev_set_resources(dev); +} +#endif /* BRIDGE_40_BIT_SUPPORT */ + static struct device_operations pcix_ops = { +#if BRIDGE_40_BIT_SUPPORT + .read_resources = bridge_read_resources, + .set_resources = bridge_set_resources, +#else .read_resources = pci_bus_read_resources, .set_resources = pci_dev_set_resources, +#endif .enable_resources = pci_bus_enable_resources, - .init = pcix_init, - .scan_bus = pci_scan_bridge, + .init = amd8131_pcix_init, + .scan_bus = amd8131_scan_bridge, + .reset_bus = pci_bus_reset, }; static struct pci_driver pcix_driver __pci_driver = { diff --git a/src/southbridge/intel/esb6300/Config.lb b/src/southbridge/intel/esb6300/Config.lb new file mode 100644 index 0000000000..9674c1f818 --- /dev/null +++ b/src/southbridge/intel/esb6300/Config.lb @@ -0,0 +1,12 @@ +config chip.h +driver esb6300.o +driver esb6300_uhci.o +driver esb6300_lpc.o +driver esb6300_ide.o +driver esb6300_sata.o +driver esb6300_ehci.o +driver esb6300_smbus.o +driver esb6300_pci.o +driver esb6300_pic.o +driver esb6300_bridge1c.o +driver esb6300_ac97.o diff --git a/src/southbridge/intel/esb6300/chip.h b/src/southbridge/intel/esb6300/chip.h new file mode 100644 index 0000000000..ff74e615fd --- /dev/null +++ b/src/southbridge/intel/esb6300/chip.h @@ -0,0 +1,30 @@ +struct southbridge_intel_esb6300_config +{ +#define ESB6300_GPIO_USE_MASK 0x03 +#define ESB6300_GPIO_USE_DEFAULT 0x00 +#define ESB6300_GPIO_USE_AS_NATIVE 0x01 +#define ESB6300_GPIO_USE_AS_GPIO 0x02 + +#define ESB6300_GPIO_SEL_MASK 0x0c +#define ESB6300_GPIO_SEL_DEFAULT 0x00 +#define ESB6300_GPIO_SEL_OUTPUT 0x04 +#define ESB6300_GPIO_SEL_INPUT 0x08 + +#define ESB6300_GPIO_LVL_MASK 0x30 +#define ESB6300_GPIO_LVL_DEFAULT 0x00 +#define ESB6300_GPIO_LVL_LOW 0x10 +#define ESB6300_GPIO_LVL_HIGH 0x20 +#define ESB6300_GPIO_LVL_BLINK 0x30 + +#define ESB6300_GPIO_INV_MASK 0xc0 +#define ESB6300_GPIO_INV_DEFAULT 0x00 +#define ESB6300_GPIO_INV_OFF 0x40 +#define ESB6300_GPIO_INV_ON 0x80 + + /* GPIO use select */ + unsigned char gpio[64]; + unsigned int pirq_a_d; + unsigned int pirq_e_h; +}; +extern struct chip_operations southbridge_intel_esb6300_ops; + diff --git a/src/southbridge/intel/esb6300/esb6300.c b/src/southbridge/intel/esb6300/esb6300.c new file mode 100644 index 0000000000..3551a59ea6 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300.c @@ -0,0 +1,48 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include "esb6300.h" + +void esb6300_enable(device_t dev) +{ + device_t lpc_dev; + unsigned index = 0; + uint16_t reg_old, reg; + + /* See if we are on the behind the 6300 pci bridge */ + lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0)); + if((dev->path.u.pci.devfn &0xf8)== 0xf8) { + index = dev->path.u.pci.devfn & 7; + } + else if((dev->path.u.pci.devfn &0xf8)== 0xe8) { + index = (dev->path.u.pci.devfn & 7) +8; + } + if ((!lpc_dev) || (index >= 16) || ((1<<index)&0x3091)) { + return; + } + if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) || + (lpc_dev->device != PCI_DEVICE_ID_INTEL_6300ESB_ISA)) { + uint32_t id; + id = pci_read_config32(lpc_dev, PCI_VENDOR_ID); + if (id != (PCI_VENDOR_ID_INTEL | + (PCI_DEVICE_ID_INTEL_6300ESB_ISA << 16))) { + return; + } + } + + reg = reg_old = pci_read_config16(lpc_dev, 0xf2); + reg &= ~(1 << index); + if (!dev->enabled) { + reg |= (1 << index); + } + if (reg != reg_old) { + pci_write_config16(lpc_dev, 0xf2, reg); + } + +} + +struct chip_operations southbridge_intel_esb6300_ops = { + CHIP_NAME("INTEL 6300ESB") + .enable_dev = esb6300_enable, +}; diff --git a/src/southbridge/intel/esb6300/esb6300.h b/src/southbridge/intel/esb6300/esb6300.h new file mode 100644 index 0000000000..2c91fcba98 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300.h @@ -0,0 +1,7 @@ +#ifndef ESB6300_H +#define ESB6300_H +#include "chip.h" + +void esb6300_enable(device_t dev); + +#endif /* ESB6300 */ diff --git a/src/southbridge/intel/esb6300/esb6300_ac97.c b/src/southbridge/intel/esb6300/esb6300_ac97.c new file mode 100644 index 0000000000..cc221f6e64 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_ac97.c @@ -0,0 +1,37 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + /* Write the subsystem vendor and device id */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = ac97_set_subsystem, +}; +static struct device_operations ac97_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .enable = esb6300_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ac97_audio_driver __pci_driver = { + .ops = &ac97_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_AUDIO, +}; +static struct pci_driver ac97_modem_driver __pci_driver = { + .ops = &ac97_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_MODEM, +}; diff --git a/src/southbridge/intel/esb6300/esb6300_bridge1c.c b/src/southbridge/intel/esb6300/esb6300_bridge1c.c new file mode 100644 index 0000000000..49e3b056a0 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_bridge1c.c @@ -0,0 +1,51 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void bridge1c_init(struct device *dev) +{ + + uint16_t word; + + /* configuration */ + pci_write_config8(dev, 0x1b, 0x30); +// pci_write_config8(dev, 0x3e, 0x07); + pci_write_config8(dev, 0x3e, 0x04); /* parity ignore */ + pci_write_config8(dev, 0x6c, 0x0c); /* undocumented */ + pci_write_config8(dev, 0xe0, 0x20); + + /* SRB enable */ + pci_write_config16(dev, 0xe4, 0x0232); + + /* Burst size */ + pci_write_config8(dev, 0xf0, 0x02); + + /* prefetch threshold size */ + pci_write_config16(dev, 0xf8, 0x2121); + + /* primary latency */ + pci_write_config8(dev, 0x0d, 0x28); + + /* multi transaction timer */ + pci_write_config8(dev, 0x42, 0x08); + +} + +static struct device_operations pci_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = bridge1c_init, + .scan_bus = pci_scan_bridge, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_BRIDGE1C, +}; + diff --git a/src/southbridge/intel/esb6300/esb6300_early_smbus.c b/src/southbridge/intel/esb6300/esb6300_early_smbus.c new file mode 100644 index 0000000000..e115e3a2fa --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_early_smbus.c @@ -0,0 +1,107 @@ +#include "esb6300_smbus.h" + +#define SMBUS_IO_BASE 0x0f00 + +static void enable_smbus(void) +{ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x25a4), 0); + if (dev == PCI_DEV_INVALID) { + die("SMBUS controller not found\r\n"); + } + uint8_t enable; + print_spew("SMBus controller enabled\r\n"); + pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1); + pci_write_config8(dev, 0x40, 1); + pci_write_config8(dev, 0x4, 1); + /* SMBALERT_DIS */ + pci_write_config8(dev, 0x11, 4); + + /* Disable interrupt generation */ + outb(0, SMBUS_IO_BASE + SMBHSTCTL); + + dev = pci_locate_device(PCI_ID(0x8086, 0x25a1), 0); + if (dev == PCI_DEV_INVALID) { + die("ISA bridge not found\r\n"); + } +} + +static int smbus_read_byte(unsigned device, unsigned address) +{ + return do_smbus_read_byte(SMBUS_IO_BASE, device, address); +} + +static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) +{ + if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { + return; + } + return; +} + +static int smbus_write_block(unsigned device, unsigned length, unsigned cmd, + unsigned data1, unsigned data2) +{ + unsigned char global_control_register; + unsigned char global_status_register; + unsigned char byte; + unsigned char stat; + int i; + + /* chear the PM timeout flags, SECOND_TO_STS */ + outw(inw(0x0400 + 0x66), 0x0400 + 0x66); + + if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { + return -2; + } + + /* setup transaction */ + /* Obtain ownership */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); + for(stat=0;(stat&0x40)==0;) { + stat = inb(SMBUS_IO_BASE + SMBHSTSTAT); + } + /* clear the done bit */ + outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT); + /* disable interrupts */ + outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD); + + /* set the command address */ + outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); + + /* set the block length */ + outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0); + + /* try sending out the first byte of data here */ + byte=(data1>>(0))&0x0ff; + outb(byte,SMBUS_IO_BASE + SMBBLKDAT); + /* issue a block write command */ + outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40, + SMBUS_IO_BASE + SMBHSTCTL); + + for(i=0;i<length;i++) { + + /* poll for transaction completion */ + if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) { + return -3; + } + + /* load the next byte */ + if(i>3) + byte=(data2>>(i%4))&0x0ff; + else + byte=(data1>>(i))&0x0ff; + outb(byte,SMBUS_IO_BASE + SMBBLKDAT); + + /* clear the done bit */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), + SMBUS_IO_BASE + SMBHSTSTAT); + } + + print_debug("SMBUS Block complete\r\n"); + return 0; +} + diff --git a/src/southbridge/intel/esb6300/esb6300_ehci.c b/src/southbridge/intel/esb6300/esb6300_ehci.c new file mode 100644 index 0000000000..58dcd9593c --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_ehci.c @@ -0,0 +1,50 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void ehci_init(struct device *dev) +{ + uint32_t cmd; + + printk_debug("EHCI: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_MASTER); + + printk_debug("done.\n"); +} + +static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + uint8_t access_cntl; + access_cntl = pci_read_config8(dev, 0x80); + /* Enable writes to protected registers */ + pci_write_config8(dev, 0x80, access_cntl | 1); + /* Write the subsystem vendor and device id */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + /* Restore protection */ + pci_write_config8(dev, 0x80, access_cntl); +} + +static struct pci_operations lops_pci = { + .set_subsystem = &ehci_set_subsystem, +}; +static struct device_operations ehci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ehci_init, + .scan_bus = 0, + .enable = esb6300_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ehci_driver __pci_driver = { + .ops = &ehci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_EHCI, +}; diff --git a/src/southbridge/intel/esb6300/esb6300_ide.c b/src/southbridge/intel/esb6300/esb6300_ide.c new file mode 100644 index 0000000000..bb77ad7726 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_ide.c @@ -0,0 +1,56 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void ide_init(struct device *dev) +{ + + /* Enable ide devices so the linux ide driver will work */ + uint16_t word; + + /* Enable IDE devices */ + pci_write_config16(dev, 0x40, 0x0a307); + pci_write_config16(dev, 0x42, 0x0a307); + pci_write_config8(dev, 0x48, 0x05); + pci_write_config16(dev, 0x4a, 0x0101); + pci_write_config16(dev, 0x54, 0x5055); + +#if 0 + word = pci_read_config16(dev, 0x40); + word |= (1 << 15); + pci_write_config16(dev, 0x40, word); + word = pci_read_config16(dev, 0x42); + word |= (1 << 15); + pci_write_config16(dev, 0x42, word); +#endif + printk_debug("IDE Enabled\n"); +} + +static void esb6300_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + /* This value is also visible in uchi[0-2] and smbus functions */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = esb6300_ide_set_subsystem, +}; +static struct device_operations ide_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ide_init, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ide_driver __pci_driver = { + .ops = &ide_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_IDE, +}; + diff --git a/src/southbridge/intel/esb6300/esb6300_lpc.c b/src/southbridge/intel/esb6300/esb6300_lpc.c new file mode 100644 index 0000000000..caef888d2a --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_lpc.c @@ -0,0 +1,410 @@ +/* + * (C) 2004 Linux Networx + */ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <pc80/mc146818rtc.h> +#include <pc80/isa-dma.h> +#include <arch/io.h> +#include "esb6300.h" + +#define ACPI_BAR 0x40 +#define GPIO_BAR 0x58 + +#define NMI_OFF 0 +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_FAIL +#define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON +#endif + +#define ALL (0xff << 24) +#define NONE (0) +#define DISABLED (1 << 16) +#define ENABLED (0 << 16) +#define TRIGGER_EDGE (0 << 15) +#define TRIGGER_LEVEL (1 << 15) +#define POLARITY_HIGH (0 << 13) +#define POLARITY_LOW (1 << 13) +#define PHYSICAL_DEST (0 << 11) +#define LOGICAL_DEST (1 << 11) +#define ExtINT (7 << 8) +#define NMI (4 << 8) +#define SMI (2 << 8) +#define INT (1 << 8) + +static void setup_ioapic(device_t dev) +{ + int i; + unsigned long value_low, value_high; + unsigned long ioapic_base = 0xfec00000; + volatile unsigned long *l; + unsigned interrupts; + + l = (unsigned long *) ioapic_base; + + l[0] = 0x01; + interrupts = (l[04] >> 16) & 0xff; + for (i = 0; i < interrupts; i++) { + l[0] = (i * 2) + 0x10; + l[4] = DISABLED; + value_low = l[4]; + l[0] = (i * 2) + 0x11; + l[4] = NONE; /* Should this be an address? */ + value_high = l[4]; + if (value_low == 0xffffffff) { + printk_warning("%d IO APIC not responding.\n", + dev_path(dev)); + return; + } + } + + /* Put the ioapic in virtual wire mode */ + l[0] = 0 + 0x10; + l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT; +} + +#define SERIRQ_CNTL 0x64 +static void esb6300_enable_serial_irqs(device_t dev) +{ + /* set packet length and toggle silent mode bit */ + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0)); + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0)); +} + +#define PCI_DMA_CFG 0x90 +static void esb6300_pci_dma_cfg(device_t dev) +{ + /* Set PCI DMA CFG to lpc I/F DMA */ + pci_write_config16(dev, PCI_DMA_CFG, 0xfcff); +} + +#define LPC_EN 0xe6 +static void esb6300_enable_lpc(device_t dev) +{ + /* lpc i/f enable */ + pci_write_config8(dev, LPC_EN, 0x0d); +} + +typedef struct southbridge_intel_esb6300_config config_t; + +static void set_esb6300_gpio_use_sel( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_use_sel, gpio_use_sel2; + int i; + +// gpio_use_sel = 0x1B003100; +// gpio_use_sel2 = 0x03000000; + gpio_use_sel = 0x1BBC31C0; + gpio_use_sel2 = 0x03000FE1; +#if 0 + for(i = 0; i < 64; i++) { + int val; + switch(config->gpio[i] & ESB6300_GPIO_USE_MASK) { + case ESB6300_GPIO_USE_AS_NATIVE: val = 0; break; + case ESB6300_GPIO_USE_AS_GPIO: val = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_use_sel &= ~( 1 << i); + gpio_use_sel |= (val << i); + } else { + gpio_use_sel2 &= ~( 1 << (i - 32)); + gpio_use_sel2 |= (val << (i - 32)); + } + } +#endif + outl(gpio_use_sel, res->base + 0x00); + outl(gpio_use_sel2, res->base + 0x30); +} + +static void set_esb6300_gpio_direction( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_io_sel, gpio_io_sel2; + int i; + +// gpio_io_sel = 0x0000ffff; +// gpio_io_sel2 = 0x00000000; + gpio_io_sel = 0x1900ffff; + gpio_io_sel2 = 0x00000fe1; +#if 0 + for(i = 0; i < 64; i++) { + int val; + switch(config->gpio[i] & ESB6300_GPIO_SEL_MASK) { + case ESB6300_GPIO_SEL_OUTPUT: val = 0; break; + case ESB6300_GPIO_SEL_INPUT: val = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_io_sel &= ~( 1 << i); + gpio_io_sel |= (val << i); + } else { + gpio_io_sel2 &= ~( 1 << (i - 32)); + gpio_io_sel2 |= (val << (i - 32)); + } + } +#endif + outl(gpio_io_sel, res->base + 0x04); + outl(gpio_io_sel2, res->base + 0x34); +} + +static void set_esb6300_gpio_level( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_lvl, gpio_lvl2; + uint32_t gpio_blink; + int i; + +// gpio_lvl = 0x1b3f0000; +// gpio_blink = 0x00040000; +// gpio_lvl2 = 0x00000fff; + gpio_lvl = 0x19370000; + gpio_blink = 0x00000000; + gpio_lvl2 = 0x00000fff; +#if 0 + for(i = 0; i < 64; i++) { + int val, blink; + switch(config->gpio[i] & ESB6300_GPIO_LVL_MASK) { + case ESB6300_GPIO_LVL_LOW: val = 0; blink = 0; break; + case ESB6300_GPIO_LVL_HIGH: val = 1; blink = 0; break; + case ESB6300_GPIO_LVL_BLINK: val = 1; blink = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_lvl &= ~( 1 << i); + gpio_blink &= ~( 1 << i); + gpio_lvl |= ( val << i); + gpio_blink |= (blink << i); + } else { + gpio_lvl2 &= ~( 1 << (i - 32)); + gpio_lvl2 |= (val << (i - 32)); + } + } +#endif + outl(gpio_lvl, res->base + 0x0c); + outl(gpio_blink, res->base + 0x18); + outl(gpio_lvl2, res->base + 0x38); +} + +static void set_esb6300_gpio_inv( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_inv; + int i; + + gpio_inv = 0x00003100; +#if 0 + for(i = 0; i < 32; i++) { + int val; + switch(config->gpio[i] & ESB6300_GPIO_INV_MASK) { + case ESB6300_GPIO_INV_OFF: val = 0; break; + case ESB6300_GPIO_INV_ON: val = 1; break; + default: + continue; + } + gpio_inv &= ~( 1 << i); + gpio_inv |= (val << i); + } +#endif + outl(gpio_inv, res->base + 0x2c); +} + +static void esb6300_pirq_init(device_t dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->pirq_a_d) { + pci_write_config32(dev, 0x60, config->pirq_a_d); + } + if(config->pirq_e_h) { + pci_write_config32(dev, 0x68, config->pirq_e_h); + } +} + + +static void esb6300_gpio_init(device_t dev) +{ + struct resource *res; + config_t *config; + + /* Skip if I don't have any configuration */ + if (!dev->chip_info) { + return; + } + /* The programmer is responsible for ensuring + * a valid gpio configuration. + */ + + /* Get the chip configuration */ + config = dev->chip_info; + /* Find the GPIO bar */ + res = find_resource(dev, GPIO_BAR); + if (!res) { + return; + } + + /* Set the use selects */ + set_esb6300_gpio_use_sel(dev, res, config); + + /* Set the IO direction */ + set_esb6300_gpio_direction(dev, res, config); + + /* Setup the input inverters */ + set_esb6300_gpio_inv(dev, res, config); + + /* Set the value on the GPIO output pins */ + set_esb6300_gpio_level(dev, res, config); + +} + + +static void lpc_init(struct device *dev) +{ + uint8_t byte; + uint32_t value; + int pwr_on=MAINBOARD_POWER_ON_AFTER_FAIL; + + /* sata settings */ + pci_write_config32(dev, 0x58, 0x00001181); + + /* IO APIC initialization */ + value = pci_read_config32(dev, 0xd0); + value |= (1 << 8)|(1<<7); + value |= (6 << 0)|(1<<13)|(1<<11); + pci_write_config32(dev, 0xd0, value); + setup_ioapic(dev); + + /* disable reset timer */ + pci_write_config8(dev, 0xd4, 0x02); + + /* cmos ram 2nd 128 */ + pci_write_config8(dev, 0xd8, 0x04); + + /* comm 2 */ + pci_write_config8(dev, 0xe0, 0x10); + + /* fwh sellect */ + pci_write_config32(dev, 0xe8, 0x00112233); + + /* fwh decode */ + pci_write_config8(dev, 0xf0, 0x0f); + + /* av disable, sata controller */ + pci_write_config8(dev, 0xf2, 0xc0); + + /* undocumented */ + pci_write_config8(dev, 0xa0, 0x20); + pci_write_config8(dev, 0xad, 0x03); + pci_write_config8(dev, 0xbb, 0x09); + + /* apic1 rout */ + pci_write_config8(dev, 0xf4, 0x40); + + /* undocumented */ + pci_write_config8(dev, 0xa0, 0x20); + pci_write_config8(dev, 0xad, 0x03); + pci_write_config8(dev, 0xbb, 0x09); + + esb6300_enable_serial_irqs(dev); + + esb6300_pci_dma_cfg(dev); + + esb6300_enable_lpc(dev); + + get_option(&pwr_on, "power_on_after_fail"); + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + if (!pwr_on) { + byte |= 1; + } + pci_write_config8(dev, 0xa4, byte); + printk_info("set power %s after power fail\n", pwr_on?"on":"off"); + + /* Set up the PIRQ */ + esb6300_pirq_init(dev); + + /* Set the state of the gpio lines */ + esb6300_gpio_init(dev); + + /* Initialize the real time clock */ + rtc_init(0); + + /* Initialize isa dma */ + isa_dma_init(); +} + +static void esb6300_lpc_read_resources(device_t dev) +{ + struct resource *res; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); + + /* Add the ACPI BAR */ + res = pci_get_resource(dev, ACPI_BAR); + + /* Add the GPIO BAR */ + res = pci_get_resource(dev, GPIO_BAR); + + /* Add an extra subtractive resource for both memory and I/O */ + res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + + res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; +} + +static void esb6300_lpc_enable_resources(device_t dev) +{ + uint8_t acpi_cntl, gpio_cntl; + + /* Enable the normal pci resources */ + pci_dev_enable_resources(dev); + + /* Enable the ACPI bar */ + acpi_cntl = pci_read_config8(dev, 0x44); + acpi_cntl |= (1 << 4); + pci_write_config8(dev, 0x44, acpi_cntl); + + /* Enable the GPIO bar */ + gpio_cntl = pci_read_config8(dev, 0x5c); + gpio_cntl |= (1 << 4); + pci_write_config8(dev, 0x5c, gpio_cntl); + + enable_childrens_resources(dev); +} + +static struct pci_operations lops_pci = { + .set_subsystem = 0, +}; + +static struct device_operations lpc_ops = { + .read_resources = esb6300_lpc_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = esb6300_lpc_enable_resources, + .init = lpc_init, + .scan_bus = scan_static_bus, + .enable = esb6300_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver lpc_driver __pci_driver = { + .ops = &lpc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_ISA, +}; diff --git a/src/southbridge/intel/esb6300/esb6300_pci.c b/src/southbridge/intel/esb6300/esb6300_pci.c new file mode 100644 index 0000000000..1131941728 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_pci.c @@ -0,0 +1,37 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void pci_init(struct device *dev) +{ + + uint16_t word; + + /* Clear system errors */ + word = pci_read_config16(dev, 0x06); + word |= 0xf900; /* Clear possible errors */ + pci_write_config16(dev, 0x06, word); + + word = pci_read_config16(dev, 0x1e); + word |= 0xf800; /* Clear possible errors */ + pci_write_config16(dev, 0x1e, word); +} + +static struct device_operations pci_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pci_init, + .scan_bus = pci_scan_bridge, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_PCI, +}; + diff --git a/src/southbridge/intel/esb6300/esb6300_pic.c b/src/southbridge/intel/esb6300/esb6300_pic.c new file mode 100644 index 0000000000..024c7e2980 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_pic.c @@ -0,0 +1,109 @@ +/* + * (C) 2004 Linux Networx + */ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +#define ALL (0xff << 24) +#define NONE (0) +#define DISABLED (1 << 16) +#define ENABLED (0 << 16) +#define TRIGGER_EDGE (0 << 15) +#define TRIGGER_LEVEL (1 << 15) +#define POLARITY_HIGH (0 << 13) +#define POLARITY_LOW (1 << 13) +#define PHYSICAL_DEST (0 << 11) +#define LOGICAL_DEST (1 << 11) +#define ExtINT (7 << 8) +#define NMI (4 << 8) +#define SMI (2 << 8) +#define INT (1 << 8) + +static void setup_ioapic(device_t dev) +{ + int i; + unsigned long value_low, value_high; + unsigned long ioapic_base = 0xfec10000; + volatile unsigned long *l; + unsigned interrupts; + + l = (unsigned long *) ioapic_base; + + l[0] = 0x01; + interrupts = (l[04] >> 16) & 0xff; + for (i = 0; i < interrupts; i++) { + l[0] = (i * 2) + 0x10; + l[4] = DISABLED; + value_low = l[4]; + l[0] = (i * 2) + 0x11; + l[4] = NONE; /* Should this be an address? */ + value_high = l[4]; + if (value_low == 0xffffffff) { + printk_warning("%s IO APIC not responding.\n", + dev_path(dev)); + return; + } + } +} + +static void pic_init(struct device *dev) +{ + + uint16_t word; + + /* Clear system errors */ + word = pci_read_config16(dev, 0x06); + word |= 0xf900; /* Clear possible errors */ + pci_write_config16(dev, 0x06, word); + + /* enable interrupt lines */ + pci_write_config8(dev, 0x3c, 0xff); + + /* Setup the ioapic */ + setup_ioapic(dev); +} + +static void pic_read_resources(device_t dev) +{ + struct resource *res; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); + + /* Report the pic1 mbar resource */ + res = new_resource(dev, 0x44); + res->base = 0xfec10000; + res->size = 256; + res->limit = res->base + res->size -1; + res->align = 8; + res->gran = 8; + res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | + IORESOURCE_STORED | IORESOURCE_ASSIGNED; + dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; +} + +static struct pci_operations lops_pci = { + /* Can we set the pci subsystem and device id? */ + .set_subsystem = 0, +}; + +static struct device_operations pci_ops = { + .read_resources = pic_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pic_init, + .scan_bus = 0, + .enable = esb6300_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_PIC1, +}; + diff --git a/src/southbridge/intel/esb6300/esb6300_sata.c b/src/southbridge/intel/esb6300/esb6300_sata.c new file mode 100644 index 0000000000..9d8fb759fc --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_sata.c @@ -0,0 +1,77 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void sata_init(struct device *dev) +{ + + /* Enable sata devices so the linux sata driver will work */ + uint16_t word; + + /* Enable SATA devices */ + + printk_debug("SATA init\n"); + /* SATA configuration */ + pci_write_config8(dev, 0x04, 0x07); + pci_write_config8(dev, 0x09, 0x8f); + + /* Set timmings */ + pci_write_config16(dev, 0x40, 0x0a307); + pci_write_config16(dev, 0x42, 0x0a307); + + /* Sync DMA */ + pci_write_config16(dev, 0x48, 0x000f); + pci_write_config16(dev, 0x4a, 0x1111); + + /* 66 mhz */ + pci_write_config16(dev, 0x54, 0xf00f); + + /* Combine ide - sata configuration */ + pci_write_config8(dev, 0x90, 0x0); + + /* port 0 & 1 enable */ + pci_write_config8(dev, 0x92, 0x33); + + /* initialize SATA */ + pci_write_config16(dev, 0xa0, 0x0018); + pci_write_config32(dev, 0xa4, 0x00000264); + pci_write_config16(dev, 0xa0, 0x0040); + pci_write_config32(dev, 0xa4, 0x00220043); + + printk_debug("SATA Enabled\n"); +} + +static void esb6300_sata_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + /* This value is also visible in usb1, usb2 and smbus functions */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = esb6300_sata_set_subsystem, +}; +static struct device_operations sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sata_init, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver sata_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA, +}; + +static struct pci_driver sata_driver_nr __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA_R, +}; + diff --git a/src/southbridge/intel/esb6300/esb6300_smbus.c b/src/southbridge/intel/esb6300/esb6300_smbus.c new file mode 100644 index 0000000000..6cb6f2d9bb --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_smbus.c @@ -0,0 +1,45 @@ +#include <device/device.h> +#include <device/path.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/smbus.h> +#include <arch/io.h> +#include "esb6300.h" +#include "esb6300_smbus.h" + +static int lsmbus_read_byte(struct bus *bus, device_t dev, uint8_t address) +{ + unsigned device; + struct resource *res; + + device = dev->path.u.i2c.device; + res = find_resource(bus->dev, 0x20); + + return do_smbus_read_byte(res->base, device, address); +} + +static struct smbus_bus_operations lops_smbus_bus = { + .read_byte = lsmbus_read_byte, +}; +static struct pci_operations lops_pci = { + /* The subsystem id follows the ide controller */ + .set_subsystem = 0, +}; +static struct device_operations smbus_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = scan_static_bus, + .enable = esb6300_enable, + .ops_pci = &lops_pci, + .ops_smbus_bus = &lops_smbus_bus, +}; + +static struct pci_driver smbus_driver __pci_driver = { + .ops = &smbus_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_SMB, +}; + diff --git a/src/southbridge/intel/esb6300/esb6300_smbus.h b/src/southbridge/intel/esb6300/esb6300_smbus.h new file mode 100644 index 0000000000..861230e130 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_smbus.h @@ -0,0 +1,105 @@ +#include <device/smbus_def.h> + +#define SMBHSTSTAT 0x0 +#define SMBHSTCTL 0x2 +#define SMBHSTCMD 0x3 +#define SMBXMITADD 0x4 +#define SMBHSTDAT0 0x5 +#define SMBHSTDAT1 0x6 +#define SMBBLKDAT 0x7 +#define SMBTRNSADD 0x9 +#define SMBSLVDATA 0xa +#define SMLINK_PIN_CTL 0xe +#define SMBUS_PIN_CTL 0xf + +#define SMBUS_TIMEOUT (100*1000*10) + + +static void smbus_delay(void) +{ + outb(0x80, 0x80); +} + +static int smbus_wait_until_ready(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while(byte & 1); + return loops?0:-1; +} + +static int smbus_wait_until_done(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0); + return loops?0:-1; +} + +static int smbus_wait_until_blk_done(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while((byte&(1<<7)) == 0); + return loops?0:-1; +} + +static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address) +{ + unsigned char global_status_register; + unsigned char byte; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + /* setup transaction */ + /* disable interrupts */ + outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL); + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD); + /* set the command/address... */ + outb(address & 0xFF, smbus_io_base + SMBHSTCMD); + /* set up for a byte data read */ + outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL); + /* clear any lingering errors, so the transaction will run */ + outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT); + + /* clear the data byte...*/ + outb(0, smbus_io_base + SMBHSTDAT0); + + /* start the command */ + outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + + global_status_register = inb(smbus_io_base + SMBHSTSTAT); + + /* Ignore the In Use Status... */ + global_status_register &= ~(3 << 5); + + /* read results of transaction */ + byte = inb(smbus_io_base + SMBHSTDAT0); + if (global_status_register != (1 << 1)) { + return SMBUS_ERROR; + } + return byte; +} + diff --git a/src/southbridge/intel/esb6300/esb6300_uhci.c b/src/southbridge/intel/esb6300/esb6300_uhci.c new file mode 100644 index 0000000000..835a39c2e4 --- /dev/null +++ b/src/southbridge/intel/esb6300/esb6300_uhci.c @@ -0,0 +1,56 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "esb6300.h" + +static void uhci_init(struct device *dev) +{ + uint32_t cmd; + +#if 1 + printk_debug("UHCI: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_MASTER); + + + printk_debug("done.\n"); +#endif + +} + +static struct pci_operations lops_pci = { + /* The subsystem id follows the ide controller */ + .set_subsystem = 0, +}; + +static struct device_operations uhci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = uhci_init, + .scan_bus = 0, + .enable = esb6300_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver uhci_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_USB, +}; + +static struct pci_driver usb2_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_USB2, +}; + +static struct pci_driver usb3_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_6300ESB_USB3, +}; + diff --git a/src/southbridge/intel/i82801er/i82801er_reset.c b/src/southbridge/intel/i82801er/i82801er_reset.c index 3d7a4b79b6..fa41756557 100644 --- a/src/southbridge/intel/i82801er/i82801er_reset.c +++ b/src/southbridge/intel/i82801er/i82801er_reset.c @@ -1,6 +1,6 @@ #include <arch/io.h> -void hard_reset(void) +void i82801er_hard_reset(void) { /* Try rebooting through port 0xcf9 */ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9); diff --git a/src/southbridge/intel/i82870/p64h2_pcibridge.c b/src/southbridge/intel/i82870/p64h2_pcibridge.c index 6f161e900b..01f871766d 100644 --- a/src/southbridge/intel/i82870/p64h2_pcibridge.c +++ b/src/southbridge/intel/i82870/p64h2_pcibridge.c @@ -29,6 +29,7 @@ static struct device_operations pcix_ops = { .enable_resources = pci_bus_enable_resources, .init = p64h2_pcix_init, .scan_bus = pci_scan_bridge, + .reset_bus = pci_bus_reset, }; static struct pci_driver pcix_driver __pci_driver = { diff --git a/src/southbridge/intel/ich5r/Config.lb b/src/southbridge/intel/ich5r/Config.lb new file mode 100644 index 0000000000..0bad3f0bf5 --- /dev/null +++ b/src/southbridge/intel/ich5r/Config.lb @@ -0,0 +1,11 @@ +config chip.h +driver ich5r.o +driver ich5r_uhci.o +driver ich5r_lpc.o +driver ich5r_ide.o +driver ich5r_sata.o +driver ich5r_ehci.o +driver ich5r_smbus.o +driver ich5r_pci.o +driver ich5r_ac97.o +object ich5r_watchdog.o diff --git a/src/southbridge/intel/ich5r/chip.h b/src/southbridge/intel/ich5r/chip.h new file mode 100644 index 0000000000..b3abeabca7 --- /dev/null +++ b/src/southbridge/intel/ich5r/chip.h @@ -0,0 +1,30 @@ +struct southbridge_intel_ich5r_config +{ + +#define ICH5R_GPIO_USE_MASK 0x03 +#define ICH5R_GPIO_USE_DEFAULT 0x00 +#define ICH5R_GPIO_USE_AS_NATIVE 0x01 +#define ICH5R_GPIO_USE_AS_GPIO 0x02 + +#define ICH5R_GPIO_SEL_MASK 0x0c +#define ICH5R_GPIO_SEL_DEFAULT 0x00 +#define ICH5R_GPIO_SEL_OUTPUT 0x04 +#define ICH5R_GPIO_SEL_INPUT 0x08 + +#define ICH5R_GPIO_LVL_MASK 0x30 +#define ICH5R_GPIO_LVL_DEFAULT 0x00 +#define ICH5R_GPIO_LVL_LOW 0x10 +#define ICH5R_GPIO_LVL_HIGH 0x20 +#define ICH5R_GPIO_LVL_BLINK 0x30 + +#define ICH5R_GPIO_INV_MASK 0xc0 +#define ICH5R_GPIO_INV_DEFAULT 0x00 +#define ICH5R_GPIO_INV_OFF 0x40 +#define ICH5R_GPIO_INV_ON 0x80 + + /* GPIO use select */ + unsigned char gpio[64]; + unsigned int pirq_a_d; + unsigned int pirq_e_h; +}; +extern struct chip_operations southbridge_intel_ich5r_ops; diff --git a/src/southbridge/intel/ich5r/ich5r.c b/src/southbridge/intel/ich5r/ich5r.c new file mode 100644 index 0000000000..1b65465234 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r.c @@ -0,0 +1,48 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include "ich5r.h" + +void ich5r_enable(device_t dev) +{ + device_t lpc_dev; + unsigned index = 0; + uint16_t reg_old, reg; + + /* See if we are on the behind the ich5r pci bridge */ + lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0)); + if((dev->path.u.pci.devfn &0xf8)== 0xf8) { + index = dev->path.u.pci.devfn & 7; + } + else if((dev->path.u.pci.devfn &0xf8)== 0xe8) { + index = (dev->path.u.pci.devfn & 7) +8; + } + if ((!lpc_dev) || (index >= 16) || ((1<<index)&0x3091)) { + return; + } + if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) || + (lpc_dev->device != PCI_DEVICE_ID_INTEL_82801ER_ISA)) { + uint32_t id; + id = pci_read_config32(lpc_dev, PCI_VENDOR_ID); + if (id != (PCI_VENDOR_ID_INTEL | + (PCI_DEVICE_ID_INTEL_82801ER_ISA << 16))) { + return; + } + } + + reg = reg_old = pci_read_config16(lpc_dev, 0xf2); + reg &= ~(1 << index); + if (!dev->enabled) { + reg |= (1 << index); + } + if (reg != reg_old) { + pci_write_config16(lpc_dev, 0xf2, reg); + } + +} + +struct chip_operations southbridge_intel_ich5r_ops = { + CHIP_NAME("INTEL 82801ER") + .enable_dev = ich5r_enable, +}; diff --git a/src/southbridge/intel/ich5r/ich5r.h b/src/southbridge/intel/ich5r/ich5r.h new file mode 100644 index 0000000000..28572c9c27 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r.h @@ -0,0 +1,7 @@ +#ifndef ICH5R_H +#define ICH5R_H + +#include "chip.h" +void ich5r_enable(device_t dev); + +#endif /* ICH5R_H */ diff --git a/src/southbridge/intel/ich5r/ich5r_ac97.c b/src/southbridge/intel/ich5r/ich5r_ac97.c new file mode 100644 index 0000000000..17d924b196 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_ac97.c @@ -0,0 +1,37 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "ich5r.h" + +static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + /* Write the subsystem vendor and device id */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = ac97_set_subsystem, +}; +static struct device_operations ac97_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = 0, + .enable = ich5r_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ac97_audio_driver __pci_driver = { + .ops = &ac97_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_AC97_AUDIO, +}; +static struct pci_driver ac97_modem_driver __pci_driver = { + .ops = &ac97_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_AC97_MODEM, +}; diff --git a/src/southbridge/intel/ich5r/ich5r_early_smbus.c b/src/southbridge/intel/ich5r/ich5r_early_smbus.c new file mode 100644 index 0000000000..6880fde126 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_early_smbus.c @@ -0,0 +1,130 @@ +#include "ich5r_smbus.h" + +#define SMBUS_IO_BASE 0x0f00 + +static void enable_smbus(void) +{ + device_t dev; + dev = pci_locate_device(PCI_ID(0x8086, 0x24d3), 0); + if (dev == PCI_DEV_INVALID) { + die("SMBUS controller not found\r\n"); + } + uint8_t enable; + print_spew("SMBus controller enabled\r\n"); + pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1); + pci_write_config8(dev, 0x40, 1); + pci_write_config8(dev, 0x4, 1); + /* SMBALERT_DIS */ + pci_write_config8(dev, 0x11, 4); + + /* Disable interrupt generation */ + outb(0, SMBUS_IO_BASE + SMBHSTCTL); + + dev = pci_locate_device(PCI_ID(0x8086, 0x24d0), 0); + if (dev == PCI_DEV_INVALID) { + die("ISA bridge not found\r\n"); + } +} + +static int smbus_read_byte(unsigned device, unsigned address) +{ + return do_smbus_read_byte(SMBUS_IO_BASE, device, address); +} + +static void smbus_write_byte(unsigned device, unsigned address, unsigned char val) +{ + if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { + return; + } +#if 0 + /* setup transaction */ + /* disable interrupts */ + outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), + SMBUS_IO_BASE + SMBGCTL); + /* set the device I'm talking too */ + outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR); + outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); + /* set up for a byte data write */ /* FIXME */ + outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x1), SMBUS_IO_BASE + SMBGCTL); + /* clear any lingering errors, so the transaction will run */ + /* Do I need to write the bits to a 1 to clear an error? */ + outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS); + + /* clear the data word...*/ + outw(val, SMBUS_IO_BASE + SMBHSTDAT); + + /* start the command */ + outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL); + + /* poll for transaction completion */ + smbus_wait_until_done(SMBUS_IO_BASE); +#endif + return; +} + +static int smbus_write_block(unsigned device, unsigned length, unsigned cmd, + unsigned data1, unsigned data2) +{ + unsigned char global_control_register; + unsigned char global_status_register; + unsigned char byte; + unsigned char stat; + int i; + + /* chear the PM timeout flags, SECOND_TO_STS */ + outw(inw(0x0400 + 0x66), 0x0400 + 0x66); + + if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) { + return -2; + } + + /* setup transaction */ + /* Obtain ownership */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT); + for(stat=0;(stat&0x40)==0;) { + stat = inb(SMBUS_IO_BASE + SMBHSTSTAT); + } + /* clear the done bit */ + outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT); + /* disable interrupts */ + outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL); + + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD); + + /* set the command address */ + outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD); + + /* set the block length */ + outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0); + + /* try sending out the first byte of data here */ + byte=(data1>>(0))&0x0ff; + outb(byte,SMBUS_IO_BASE + SMBBLKDAT); + /* issue a block write command */ + outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40, + SMBUS_IO_BASE + SMBHSTCTL); + + for(i=0;i<length;i++) { + + /* poll for transaction completion */ + if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) { + return -3; + } + + /* load the next byte */ + if(i>3) + byte=(data2>>(i%4))&0x0ff; + else + byte=(data1>>(i))&0x0ff; + outb(byte,SMBUS_IO_BASE + SMBBLKDAT); + + /* clear the done bit */ + outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), + SMBUS_IO_BASE + SMBHSTSTAT); + } + + print_debug("SMBUS Block complete\r\n"); + return 0; +} + diff --git a/src/southbridge/intel/ich5r/ich5r_ehci.c b/src/southbridge/intel/ich5r/ich5r_ehci.c new file mode 100644 index 0000000000..d1650c1385 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_ehci.c @@ -0,0 +1,50 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "ich5r.h" + +static void ehci_init(struct device *dev) +{ + uint32_t cmd; + + printk_debug("EHCI: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_MASTER); + + printk_debug("done.\n"); +} + +static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + uint8_t access_cntl; + access_cntl = pci_read_config8(dev, 0x80); + /* Enable writes to protected registers */ + pci_write_config8(dev, 0x80, access_cntl | 1); + /* Write the subsystem vendor and device id */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); + /* Restore protection */ + pci_write_config8(dev, 0x80, access_cntl); +} + +static struct pci_operations lops_pci = { + .set_subsystem = &ehci_set_subsystem, +}; +static struct device_operations ehci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ehci_init, + .scan_bus = 0, + .enable = ich5r_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ehci_driver __pci_driver = { + .ops = &ehci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_EHCI, +}; diff --git a/src/southbridge/intel/ich5r/ich5r_ide.c b/src/southbridge/intel/ich5r/ich5r_ide.c new file mode 100644 index 0000000000..7bfd92555c --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_ide.c @@ -0,0 +1,44 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "ich5r.h" + +static void ide_init(struct device *dev) +{ + + /* Enable IDE devices and timmings */ + pci_write_config16(dev, 0x40, 0x0a307); + pci_write_config16(dev, 0x42, 0x0a307); + pci_write_config8(dev, 0x48, 0x05); + pci_write_config16(dev, 0x4a, 0x0101); + pci_write_config16(dev, 0x54, 0x5055); + printk_debug("IDE Enabled\n"); +} + +static void ich5r_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + /* This value is also visible in uchi[0-2] and smbus functions */ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations lops_pci = { + .set_subsystem = ich5r_ide_set_subsystem, +}; +static struct device_operations ide_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ide_init, + .scan_bus = 0, + .ops_pci = &lops_pci, +}; + +static struct pci_driver ide_driver __pci_driver = { + .ops = &ide_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_IDE, +}; + diff --git a/src/southbridge/intel/ich5r/ich5r_lpc.c b/src/southbridge/intel/ich5r/ich5r_lpc.c new file mode 100644 index 0000000000..d9d98891ad --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_lpc.c @@ -0,0 +1,369 @@ +/* + * (C) 2004 Linux Networx + */ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <pc80/mc146818rtc.h> +#include <pc80/isa-dma.h> +#include <arch/io.h> +#include "ich5r.h" + +#define ACPI_BAR 0x40 +#define GPIO_BAR 0x58 + +#define NMI_OFF 0 +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 + +#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL +#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON +#endif + +#define ALL (0xff << 24) +#define NONE (0) +#define DISABLED (1 << 16) +#define ENABLED (0 << 16) +#define TRIGGER_EDGE (0 << 15) +#define TRIGGER_LEVEL (1 << 15) +#define POLARITY_HIGH (0 << 13) +#define POLARITY_LOW (1 << 13) +#define PHYSICAL_DEST (0 << 11) +#define LOGICAL_DEST (1 << 11) +#define ExtINT (7 << 8) +#define NMI (4 << 8) +#define SMI (2 << 8) +#define INT (1 << 8) + +static void setup_ioapic(void) +{ + int i; + unsigned long value_low, value_high; + unsigned long ioapic_base = 0xfec00000; + volatile unsigned long *l; + unsigned interrupts; + + l = (unsigned long *) ioapic_base; + + l[0] = 0x01; + interrupts = (l[04] >> 16) & 0xff; + for (i = 0; i < interrupts; i++) { + l[0] = (i * 2) + 0x10; + l[4] = DISABLED; + value_low = l[4]; + l[0] = (i * 2) + 0x11; + l[4] = NONE; /* Should this be an address? */ + value_high = l[4]; + if (value_low == 0xffffffff) { + printk_warning("IO APIC not responding.\n"); + return; + } + } + + /* Put the ioapic in virtual wire mode */ + l[0] = 0 + 0x10; + l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT; +} + +#define SERIRQ_CNTL 0x64 +static void ich5r_enable_serial_irqs(device_t dev) +{ + /* set packet length and toggle silent mode bit */ + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0)); + pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0)); +} + +#define PCI_DMA_CFG 0x90 +static void ich5r_pci_dma_cfg(device_t dev) +{ + /* Set PCI DMA CFG to lpc I/F DMA */ + pci_write_config16(dev, PCI_DMA_CFG, 0xfcff); +} + +#define LPC_EN 0xe6 +static void ich5r_enable_lpc(device_t dev) +{ + /* lpc i/f enable */ + pci_write_config8(dev, LPC_EN, 0x0d); +} + +typedef struct southbridge_intel_ich5r_config config_t; + +static void set_ich5r_gpio_use_sel( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_use_sel, gpio_use_sel2; + int i; + + gpio_use_sel = 0x1A003180; + gpio_use_sel2 = 0x00000007; + for(i = 0; i < 64; i++) { + int val; + switch(config->gpio[i] & ICH5R_GPIO_USE_MASK) { + case ICH5R_GPIO_USE_AS_NATIVE: val = 0; break; + case ICH5R_GPIO_USE_AS_GPIO: val = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_use_sel &= ~( 1 << i); + gpio_use_sel |= (val << i); + } else { + gpio_use_sel2 &= ~( 1 << (i - 32)); + gpio_use_sel2 |= (val << (i - 32)); + } + } + outl(gpio_use_sel, res->base + 0x00); + outl(gpio_use_sel2, res->base + 0x30); +} + +static void set_ich5r_gpio_direction( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_io_sel, gpio_io_sel2; + int i; + + gpio_io_sel = 0x0000ffff; + gpio_io_sel2 = 0x00000300; + for(i = 0; i < 64; i++) { + int val; + switch(config->gpio[i] & ICH5R_GPIO_SEL_MASK) { + case ICH5R_GPIO_SEL_OUTPUT: val = 0; break; + case ICH5R_GPIO_SEL_INPUT: val = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_io_sel &= ~( 1 << i); + gpio_io_sel |= (val << i); + } else { + gpio_io_sel2 &= ~( 1 << (i - 32)); + gpio_io_sel2 |= (val << (i - 32)); + } + } + outl(gpio_io_sel, res->base + 0x04); + outl(gpio_io_sel2, res->base + 0x34); +} + +static void set_ich5r_gpio_level( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_lvl, gpio_lvl2; + uint32_t gpio_blink; + int i; + + gpio_lvl = 0x1b3f0000; + gpio_blink = 0x00040000; + gpio_lvl2 = 0x00030207; + for(i = 0; i < 64; i++) { + int val, blink; + switch(config->gpio[i] & ICH5R_GPIO_LVL_MASK) { + case ICH5R_GPIO_LVL_LOW: val = 0; blink = 0; break; + case ICH5R_GPIO_LVL_HIGH: val = 1; blink = 0; break; + case ICH5R_GPIO_LVL_BLINK: val = 1; blink = 1; break; + default: + continue; + } + /* The caller is responsible for not playing with unimplemented bits */ + if (i < 32) { + gpio_lvl &= ~( 1 << i); + gpio_blink &= ~( 1 << i); + gpio_lvl |= ( val << i); + gpio_blink |= (blink << i); + } else { + gpio_lvl2 &= ~( 1 << (i - 32)); + gpio_lvl2 |= (val << (i - 32)); + } + } + outl(gpio_lvl, res->base + 0x0c); + outl(gpio_blink, res->base + 0x18); + outl(gpio_lvl2, res->base + 0x38); +} + +static void set_ich5r_gpio_inv( + device_t dev, struct resource *res, config_t *config) +{ + uint32_t gpio_inv; + int i; + + gpio_inv = 0x00000000; + for(i = 0; i < 32; i++) { + int val; + switch(config->gpio[i] & ICH5R_GPIO_INV_MASK) { + case ICH5R_GPIO_INV_OFF: val = 0; break; + case ICH5R_GPIO_INV_ON: val = 1; break; + default: + continue; + } + gpio_inv &= ~( 1 << i); + gpio_inv |= (val << i); + } + outl(gpio_inv, res->base + 0x2c); +} + +static void ich5r_pirq_init(device_t dev) +{ + config_t *config; + + /* Get the chip configuration */ + config = dev->chip_info; + + if(config->pirq_a_d) { + pci_write_config32(dev, 0x60, config->pirq_a_d); + } + if(config->pirq_e_h) { + pci_write_config32(dev, 0x68, config->pirq_e_h); + } +} + + +static void ich5r_gpio_init(device_t dev) +{ + struct resource *res; + config_t *config; + + /* Skip if I don't have any configuration */ + if (!dev->chip_info) { + return; + } + /* The programmer is responsible for ensuring + * a valid gpio configuration. + */ + + /* Get the chip configuration */ + config = dev->chip_info; + /* Find the GPIO bar */ + res = find_resource(dev, GPIO_BAR); + if (!res) { + return; + } + + /* Set the use selects */ + set_ich5r_gpio_use_sel(dev, res, config); + + /* Set the IO direction */ + set_ich5r_gpio_direction(dev, res, config); + + /* Setup the input inverters */ + set_ich5r_gpio_inv(dev, res, config); + + /* Set the value on the GPIO output pins */ + set_ich5r_gpio_level(dev, res, config); + +} + + +static void lpc_init(struct device *dev) +{ + uint8_t byte; + uint32_t value; + int pwr_on=MAINBOARD_POWER_ON_AFTER_POWER_FAIL; + + /* IO APIC initialization */ + value = pci_read_config32(dev, 0xd0); + value |= (1 << 8)|(1<<7)|(1<<1); + pci_write_config32(dev, 0xd0, value); + value = pci_read_config32(dev, 0xd4); + value |= (1<<1); + pci_write_config32(dev, 0xd4, value); + setup_ioapic(); + + ich5r_enable_serial_irqs(dev); + + ich5r_pci_dma_cfg(dev); + + ich5r_enable_lpc(dev); + + /* Clear SATA to non raid */ + pci_write_config8(dev, 0xae, 0x00); + + get_option(&pwr_on, "power_on_after_fail"); + byte = pci_read_config8(dev, 0xa4); + byte &= 0xfe; + if (!pwr_on) { + byte |= 1; + } + pci_write_config8(dev, 0xa4, byte); + printk_info("set power %s after power fail\n", pwr_on?"on":"off"); + + /* Set up the PIRQ */ + ich5r_pirq_init(dev); + + /* Set the state of the gpio lines */ + ich5r_gpio_init(dev); + + /* Initialize the real time clock */ + rtc_init(0); + + /* Initialize isa dma */ + isa_dma_init(); + + /* Disable IDE (needed when sata is enabled) */ + pci_write_config8(dev, 0xf2, 0x60); + +} + +static void ich5r_lpc_read_resources(device_t dev) +{ + struct resource *res; + + /* Get the normal pci resources of this device */ + pci_dev_read_resources(dev); + + /* Add the ACPI BAR */ + res = pci_get_resource(dev, ACPI_BAR); + + /* Add the GPIO BAR */ + res = pci_get_resource(dev, GPIO_BAR); + + /* Add an extra subtractive resource for both memory and I/O */ + res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + + res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; +} + +static void ich5r_lpc_enable_resources(device_t dev) +{ + uint8_t acpi_cntl, gpio_cntl; + + /* Enable the normal pci resources */ + pci_dev_enable_resources(dev); + + /* Enable the ACPI bar */ + acpi_cntl = pci_read_config8(dev, 0x44); + acpi_cntl |= (1 << 4); + pci_write_config8(dev, 0x44, acpi_cntl); + + /* Enable the GPIO bar */ + gpio_cntl = pci_read_config8(dev, 0x5c); + gpio_cntl |= (1 << 4); + pci_write_config8(dev, 0x5c, gpio_cntl); + + enable_childrens_resources(dev); +} + +static struct pci_operations lops_pci = { + .set_subsystem = 0, +}; + +static struct device_operations lpc_ops = { + .read_resources = ich5r_lpc_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = ich5r_lpc_enable_resources, + .init = lpc_init, + .scan_bus = scan_static_bus, + .enable = ich5r_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver lpc_driver __pci_driver = { + .ops = &lpc_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_ISA, +}; diff --git a/src/southbridge/intel/ich5r/ich5r_pci.c b/src/southbridge/intel/ich5r/ich5r_pci.c new file mode 100644 index 0000000000..d2c94c778e --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_pci.c @@ -0,0 +1,37 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "ich5r.h" + +static void pci_init(struct device *dev) +{ + + uint16_t word; + + /* Clear system errors */ + word = pci_read_config16(dev, 0x06); + word |= 0xf900; /* Clear possible errors */ + pci_write_config16(dev, 0x06, word); + + word = pci_read_config16(dev, 0x1e); + word |= 0xf800; /* Clear possible errors */ + pci_write_config16(dev, 0x1e, word); +} + +static struct device_operations pci_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pci_init, + .scan_bus = pci_scan_bridge, + .ops_pci = 0, +}; + +static struct pci_driver pci_driver __pci_driver = { + .ops = &pci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_PCI, +}; + diff --git a/src/southbridge/intel/ich5r/ich5r_sata.c b/src/southbridge/intel/ich5r/ich5r_sata.c new file mode 100644 index 0000000000..803d8789cf --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_sata.c @@ -0,0 +1,63 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "ich5r.h" + +static void sata_init(struct device *dev) +{ + + uint16_t word; + + printk_debug("SATA init\n"); + /* SATA configuration */ + pci_write_config8(dev, 0x04, 0x07); + pci_write_config8(dev, 0x09, 0x8f); + + /* Set timmings */ + pci_write_config16(dev, 0x40, 0x0a307); + pci_write_config16(dev, 0x42, 0x0a307); + + /* Sync DMA */ + pci_write_config16(dev, 0x48, 0x000f); + pci_write_config16(dev, 0x4a, 0x1111); + + /* 66 mhz */ + pci_write_config16(dev, 0x54, 0xf00f); + + /* Combine ide - sata configuration */ + pci_write_config8(dev, 0x90, 0x0); + + /* port 0 & 1 enable */ + pci_write_config8(dev, 0x92, 0x33); + + /* initialize SATA */ + pci_write_config16(dev, 0xa0, 0x0018); + pci_write_config32(dev, 0xa4, 0x00000264); + pci_write_config16(dev, 0xa0, 0x0040); + pci_write_config32(dev, 0xa4, 0x00220043); + +} + +static struct device_operations sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sata_init, + .scan_bus = 0, + .ops_pci = 0, +}; + +static struct pci_driver sata_driver __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F2_R, +}; + +static struct pci_driver sata_driver_nr __pci_driver = { + .ops = &sata_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_1F2, +}; + diff --git a/src/southbridge/intel/ich5r/ich5r_smbus.c b/src/southbridge/intel/ich5r/ich5r_smbus.c new file mode 100644 index 0000000000..3337a65b15 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_smbus.c @@ -0,0 +1,45 @@ +#include <device/device.h> +#include <device/path.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/smbus.h> +#include <arch/io.h> +#include "ich5r.h" +#include "ich5r_smbus.h" + +static int lsmbus_read_byte(struct bus *bus, device_t dev, uint8_t address) +{ + unsigned device; + struct resource *res; + + device = dev->path.u.i2c.device; + res = find_resource(bus->dev, 0x20); + + return do_smbus_read_byte(res->base, device, address); +} + +static struct smbus_bus_operations lops_smbus_bus = { + .read_byte = lsmbus_read_byte, +}; +static struct pci_operations lops_pci = { + /* The subsystem id follows the ide controller */ + .set_subsystem = 0, +}; +static struct device_operations smbus_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = 0, + .scan_bus = scan_static_bus, + .enable = ich5r_enable, + .ops_pci = &lops_pci, + .ops_smbus_bus = &lops_smbus_bus, +}; + +static struct pci_driver smbus_driver __pci_driver = { + .ops = &smbus_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_SMB, +}; + diff --git a/src/southbridge/intel/ich5r/ich5r_smbus.h b/src/southbridge/intel/ich5r/ich5r_smbus.h new file mode 100644 index 0000000000..861230e130 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_smbus.h @@ -0,0 +1,105 @@ +#include <device/smbus_def.h> + +#define SMBHSTSTAT 0x0 +#define SMBHSTCTL 0x2 +#define SMBHSTCMD 0x3 +#define SMBXMITADD 0x4 +#define SMBHSTDAT0 0x5 +#define SMBHSTDAT1 0x6 +#define SMBBLKDAT 0x7 +#define SMBTRNSADD 0x9 +#define SMBSLVDATA 0xa +#define SMLINK_PIN_CTL 0xe +#define SMBUS_PIN_CTL 0xf + +#define SMBUS_TIMEOUT (100*1000*10) + + +static void smbus_delay(void) +{ + outb(0x80, 0x80); +} + +static int smbus_wait_until_ready(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while(byte & 1); + return loops?0:-1; +} + +static int smbus_wait_until_done(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0); + return loops?0:-1; +} + +static int smbus_wait_until_blk_done(unsigned smbus_io_base) +{ + unsigned loops = SMBUS_TIMEOUT; + unsigned char byte; + do { + smbus_delay(); + if (--loops == 0) + break; + byte = inb(smbus_io_base + SMBHSTSTAT); + } while((byte&(1<<7)) == 0); + return loops?0:-1; +} + +static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address) +{ + unsigned char global_status_register; + unsigned char byte; + + if (smbus_wait_until_ready(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_READY_TIMEOUT; + } + /* setup transaction */ + /* disable interrupts */ + outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL); + /* set the device I'm talking too */ + outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD); + /* set the command/address... */ + outb(address & 0xFF, smbus_io_base + SMBHSTCMD); + /* set up for a byte data read */ + outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL); + /* clear any lingering errors, so the transaction will run */ + outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT); + + /* clear the data byte...*/ + outb(0, smbus_io_base + SMBHSTDAT0); + + /* start the command */ + outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL); + + /* poll for transaction completion */ + if (smbus_wait_until_done(smbus_io_base) < 0) { + return SMBUS_WAIT_UNTIL_DONE_TIMEOUT; + } + + global_status_register = inb(smbus_io_base + SMBHSTSTAT); + + /* Ignore the In Use Status... */ + global_status_register &= ~(3 << 5); + + /* read results of transaction */ + byte = inb(smbus_io_base + SMBHSTDAT0); + if (global_status_register != (1 << 1)) { + return SMBUS_ERROR; + } + return byte; +} + diff --git a/src/southbridge/intel/ich5r/ich5r_uhci.c b/src/southbridge/intel/ich5r/ich5r_uhci.c new file mode 100644 index 0000000000..ad4ae978cf --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_uhci.c @@ -0,0 +1,56 @@ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include "ich5r.h" + +static void uhci_init(struct device *dev) +{ + uint32_t cmd; + +#if 1 + printk_debug("UHCI: Setting up controller.. "); + cmd = pci_read_config32(dev, PCI_COMMAND); + pci_write_config32(dev, PCI_COMMAND, + cmd | PCI_COMMAND_MASTER); + + + printk_debug("done.\n"); +#endif + +} + +static struct pci_operations lops_pci = { + /* The subsystem id follows the ide controller */ + .set_subsystem = 0, +}; + +static struct device_operations uhci_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = uhci_init, + .scan_bus = 0, + .enable = ich5r_enable, + .ops_pci = &lops_pci, +}; + +static struct pci_driver uhci_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_USB, +}; + +static struct pci_driver usb2_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_USB2, +}; + +static struct pci_driver usb3_driver __pci_driver = { + .ops = &uhci_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801ER_USB3, +}; + diff --git a/src/southbridge/intel/ich5r/ich5r_watchdog.c b/src/southbridge/intel/ich5r/ich5r_watchdog.c new file mode 100644 index 0000000000..c9c09f5896 --- /dev/null +++ b/src/southbridge/intel/ich5r/ich5r_watchdog.c @@ -0,0 +1,28 @@ +#include <console/console.h> +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> + +void watchdog_off(void) +{ + device_t dev; + unsigned long value,base; + + /* turn off the ICH5 watchdog */ + dev = dev_find_slot(0, PCI_DEVFN(0x1f,0)); + /* Enable I/O space */ + value = pci_read_config16(dev, 0x04); + value |= (1 << 10); + pci_write_config16(dev, 0x04, value); + /* Get TCO base */ + base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60; + /* Disable the watchdog timer */ + value = inw(base + 0x08); + value |= 1 << 11; + outw(value, base + 0x08); + /* Clear TCO timeout status */ + outw(0x0008, base + 0x04); + outw(0x0002, base + 0x06); + printk_debug("Watchdog ICH5 disabled\r\n"); +} + diff --git a/src/southbridge/intel/pxhd/Config.lb b/src/southbridge/intel/pxhd/Config.lb new file mode 100644 index 0000000000..349b8dd624 --- /dev/null +++ b/src/southbridge/intel/pxhd/Config.lb @@ -0,0 +1,2 @@ +config chip.h +driver pxhd_bridge.o diff --git a/src/southbridge/intel/pxhd/chip.h b/src/southbridge/intel/pxhd/chip.h new file mode 100644 index 0000000000..516f1df7d2 --- /dev/null +++ b/src/southbridge/intel/pxhd/chip.h @@ -0,0 +1,5 @@ +struct southbridge_intel_pxhd_config +{ + /* nothing */ +}; +struct chip_operations southbridge_intel_pxhd_ops; diff --git a/src/southbridge/intel/pxhd/pxhd.h b/src/southbridge/intel/pxhd/pxhd.h new file mode 100644 index 0000000000..c3e6ce5cd7 --- /dev/null +++ b/src/southbridge/intel/pxhd/pxhd.h @@ -0,0 +1,6 @@ +#ifndef PXHD_H +#define PXHD_H + +#include "chip.h" + +#endif /* PXHD_H */ diff --git a/src/southbridge/intel/pxhd/pxhd_bridge.c b/src/southbridge/intel/pxhd/pxhd_bridge.c new file mode 100644 index 0000000000..bceca29db9 --- /dev/null +++ b/src/southbridge/intel/pxhd/pxhd_bridge.c @@ -0,0 +1,258 @@ +/* + * (C) 2003-2004 Linux Networx + */ +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pcix.h> +#include <pc80/mc146818rtc.h> +#include <delay.h> +#include "pxhd.h" + +static void pxhd_enable(device_t dev) +{ + device_t bridge; + uint16_t value; + if ((dev->path.u.pci.devfn & 1) == 0) { + /* Can we enable/disable the bridges? */ + return; + } + bridge = dev_find_slot(dev->bus->secondary, dev->path.u.pci.devfn & ~1); + if (!bridge) { + printk_err("Cannot find bridge for ioapic: %s\n", + dev_path(dev)); + return; + } + value = pci_read_config16(bridge, 0x40); + value &= ~(1 << 13); + if (!dev->enabled) { + value |= (1 << 13); + } + pci_write_config16(bridge, 0x40, value); +} + + +#define NMI_OFF 0 + +static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max) +{ + int bus_100Mhz = 0; + + dev->link[0].dev = dev; + dev->links = 1; + + get_option(&bus_100Mhz, "pxhd_bus_speed_100"); + if(bus_100Mhz) { + uint16_t word; + + printk_debug("setting pxhd bus to 100 Mhz\n"); + /* set to pcix 100 mhz */ + word = pci_read_config16(dev, 0x40); + word &= ~(3 << 14); + word |= (1 << 14); + word &= ~(3 << 9); + word |= (2 << 9); + pci_write_config16(dev, 0x40, word); + + /* reset the bus to make the new frequencies effective */ + pci_bus_reset(&dev->link[0]); + } + return pcix_scan_bridge(dev, max); +} +static void pcix_init(device_t dev) +{ + uint32_t dword; + uint16_t word; + uint8_t byte; + int nmi_option; + + /* Bridge control ISA enable */ + pci_write_config8(dev, 0x3e, 0x07); + +#if 0 + + /* Enable memory write and invalidate ??? */ + byte = pci_read_config8(dev, 0x04); + byte |= 0x10; + pci_write_config8(dev, 0x04, byte); + + /* Set drive strength */ + word = pci_read_config16(dev, 0xe0); + word = 0x0404; + pci_write_config16(dev, 0xe0, word); + word = pci_read_config16(dev, 0xe4); + word = 0x0404; + pci_write_config16(dev, 0xe4, word); + + /* Set impedance */ + word = pci_read_config16(dev, 0xe8); + word = 0x0404; + pci_write_config16(dev, 0xe8, word); + + /* Set discard unrequested prefetch data */ + word = pci_read_config16(dev, 0x4c); + word |= 1; + pci_write_config16(dev, 0x4c, word); + + /* Set split transaction limits */ + word = pci_read_config16(dev, 0xa8); + pci_write_config16(dev, 0xaa, word); + word = pci_read_config16(dev, 0xac); + pci_write_config16(dev, 0xae, word); + + /* Set up error reporting, enable all */ + /* system error enable */ + dword = pci_read_config32(dev, 0x04); + dword |= (1<<8); + pci_write_config32(dev, 0x04, dword); + + /* system and error parity enable */ + dword = pci_read_config32(dev, 0x3c); + dword |= (3<<16); + pci_write_config32(dev, 0x3c, dword); + + /* NMI enable */ + nmi_option = NMI_OFF; + get_option(&nmi_option, "nmi"); + if(nmi_option) { + dword = pci_read_config32(dev, 0x44); + dword |= (1<<0); + pci_write_config32(dev, 0x44, dword); + } + + /* Set up CRC flood enable */ + dword = pci_read_config32(dev, 0xc0); + if(dword) { /* do device A only */ + dword = pci_read_config32(dev, 0xc4); + dword |= (1<<1); + pci_write_config32(dev, 0xc4, dword); + dword = pci_read_config32(dev, 0xc8); + dword |= (1<<1); + pci_write_config32(dev, 0xc8, dword); + } + + return; +#endif +} + +static struct device_operations pcix_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = pcix_init, + .scan_bus = pxhd_scan_bridge, + .reset_bus = pci_bus_reset, + .ops_pci = 0, +}; + +static struct pci_driver pcix_driver __pci_driver = { + .ops = &pcix_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x0329, +}; + +static struct pci_driver pcix_driver2 __pci_driver = { + .ops = &pcix_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x032a, +}; + +#define ALL (0xff << 24) +#define NONE (0) +#define DISABLED (1 << 16) +#define ENABLED (0 << 16) +#define TRIGGER_EDGE (0 << 15) +#define TRIGGER_LEVEL (1 << 15) +#define POLARITY_HIGH (0 << 13) +#define POLARITY_LOW (1 << 13) +#define PHYSICAL_DEST (0 << 11) +#define LOGICAL_DEST (1 << 11) +#define ExtINT (7 << 8) +#define NMI (4 << 8) +#define SMI (2 << 8) +#define INT (1 << 8) + /* IO-APIC virtual wire mode configuration */ + /* mask, trigger, polarity, destination, delivery, vector */ + +static void setup_ioapic(device_t dev) +{ + int i; + unsigned long value_low, value_high; + unsigned long ioapic_base; + volatile unsigned long *l; + unsigned interrupts; + + ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0); + l = (unsigned long *) ioapic_base; + + /* Enable front side bus delivery */ + l[0] = 0x03; + l[4] = 1; + + l[0] = 0x01; + interrupts = (l[04] >> 16) & 0xff; + for (i = 0; i < interrupts; i++) { + l[0] = (i * 2) + 0x10; + l[4] = DISABLED; + value_low = l[4]; + l[0] = (i * 2) + 0x11; + l[4] = NONE; /* Should this be an address? */ + value_high = l[4]; + if (value_low == 0xffffffff) { + printk_warning("IO APIC not responding.\n"); + return; + } + } +} + +static void ioapic_init(device_t dev) +{ + uint32_t value; + /* Enable bus mastering so IOAPICs work */ + value = pci_read_config16(dev, PCI_COMMAND); + value |= PCI_COMMAND_MASTER; + pci_write_config16(dev, PCI_COMMAND, value); + + setup_ioapic(dev); +} + +static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) +{ + pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations intel_ops_pci = { + .set_subsystem = intel_set_subsystem, +}; + +static struct device_operations ioapic_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = ioapic_init, + .scan_bus = 0, + .enable = pxhd_enable, + .ops_pci = &intel_ops_pci, +}; + +static struct pci_driver ioapic_driver __pci_driver = { + .ops = &ioapic_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x0326, + +}; + +static struct pci_driver ioapic2_driver __pci_driver = { + .ops = &ioapic_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x0327, + +}; + +struct chip_operations southbridge_intel_pxhd_ops = { + CHIP_NAME("PXHD") + .enable_dev = pxhd_enable, +}; diff --git a/src/superio/NSC/pc87427/Config.lb b/src/superio/NSC/pc87427/Config.lb new file mode 100644 index 0000000000..f62a567d61 --- /dev/null +++ b/src/superio/NSC/pc87427/Config.lb @@ -0,0 +1,2 @@ +config chip.h +object superio.o diff --git a/src/superio/NSC/pc87427/chip.h b/src/superio/NSC/pc87427/chip.h new file mode 100644 index 0000000000..ae46971590 --- /dev/null +++ b/src/superio/NSC/pc87427/chip.h @@ -0,0 +1,16 @@ +#ifndef SIO_COM1 +#define SIO_COM1_BASE 0x3F8 +#endif +#ifndef SIO_COM2 +#define SIO_COM2_BASE 0x2F8 +#endif + +extern struct chip_operations superio_NSC_pc87427_ops; + +#include <pc80/keyboard.h> +#include <uart8250.h> + +struct superio_NSC_pc87427_config { + struct uart8250 com1, com2; + struct pc_keyboard keyboard; +}; diff --git a/src/superio/NSC/pc87427/pc87427.h b/src/superio/NSC/pc87427/pc87427.h new file mode 100644 index 0000000000..d998bd6c20 --- /dev/null +++ b/src/superio/NSC/pc87427/pc87427.h @@ -0,0 +1,94 @@ +#define PC87427_FDC 0x00 /* Floppy */ +#define PC87427_SP2 0x02 /* Com2 */ +#define PC87427_SP1 0x03 /* Com1 */ +#define PC87427_SWC 0x04 +#define PC87427_KBCM 0x05 /* Mouse */ +#define PC87427_KBCK 0x06 /* Keyboard */ +#define PC87427_GPIO 0x07 +#define PC87427_FMC 0x09 +#define PC87427_WDT 0x0A +#define PC87427_XBUS 0x0F +#define PC87427_RTC 0x10 +#define PC87427_MHC 0x14 + +#define PC87427_GPIO_DEV PNP_DEV(0x2e, PC87427_GPIO) +/* This is to get around a romcc bug */ +//#define PC87427_XBUS_DEV PNP_DEV(0x2e, PC87427_XBUS) +#define PC87427_XBUS_DEV PNP_DEV(0x2e, 0x0f) + +#define PC87427_GPSEL 0xf0 +#define PC87427_GPCFG1 0xf1 +#define PC87427_GPEVR 0xf2 +#define PC87427_GPCFG2 0xf3 +#define PC87427_EXTCFG 0xf4 +#define PC87427_IOEXT1A 0xf5 +#define PC87427_IOEXT1B 0xf6 +#define PC87427_IOEXT2A 0xf7 +#define PC87427_IOEXT2B 0xf8 + +#define PC87427_GPDO_0 0x00 +#define PC87427_GPDI_0 0x01 +#define PC87427_GPDO_1 0x02 +#define PC87427_GPDI_1 0x03 +#define PC87427_GPEVEN_1 0x04 +#define PC87427_GPEVST_1 0x05 +#define PC87427_GPDO_2 0x06 +#define PC87427_GPDI_2 0x07 +#define PC87427_GPDO_3 0x08 +#define PC87427_GPDI_3 0x09 +#define PC87427_GPDO_4 0x0a +#define PC87427_GPDI_4 0x0b +#define PC87427_GPEVEN_4 0x0c +#define PC87427_GPEVST_4 0x0d +#define PC87427_GPDO_5 0x0e +#define PC87427_GPDI_5 0x0f +#define PC87427_GPDO_6 0x10 +#define PC87427_GPDO_7A 0x11 +#define PC87427_GPDO_7B 0x12 +#define PC87427_GPDO_7C 0x13 +#define PC87427_GPDO_7D 0x14 +#define PC87427_GPDI_7A 0x15 +#define PC87427_GPDI_7B 0x16 +#define PC87427_GPDI_7C 0x17 +#define PC87427_GPDI_7D 0x18 + +#define PC87427_XIOCNF 0xf0 +#define PC87427_XIOBA1H 0xf1 +#define PC87427_XIOBA1L 0xf2 +#define PC87427_XIOSIZE1 0xf3 +#define PC87427_XIOBA2H 0xf4 +#define PC87427_XIOBA2L 0xf5 +#define PC87427_XIOSIZE2 0xf6 +#define PC87427_XMEMCNF1 0xf7 +#define PC87427_XMEMCNF2 0xf8 +#define PC87427_XMEMBAH 0xf9 +#define PC87427_XMEMBAL 0xfa +#define PC87427_XMEMSIZE 0xfb +#define PC87427_XIRQMAP1 0xfc +#define PC87427_XIRQMAP2 0xfd +#define PC87427_XBIMM 0xfe +#define PC87427_XBBSL 0xff + +#define PC87427_XBCNF 0x00 +#define PC87427_XZCNF0 0x01 +#define PC87427_XZCNF1 0x02 +#define PC87427_XIRQC0 0x04 +#define PC87427_XIRQC1 0x05 +#define PC87427_XIRQC2 0x06 +#define PC87427_XIMA0 0x08 +#define PC87427_XIMA1 0x09 +#define PC87427_XIMA2 0x0a +#define PC87427_XIMA3 0x0b +#define PC87427_XIMD 0x0c +#define PC87427_XZCNF2 0x0d +#define PC87427_XZCNF3 0x0e +#define PC87427_XZM0 0x0f +#define PC87427_XZM1 0x10 +#define PC87427_XZM2 0x11 +#define PC87427_XZM3 0x12 +#define PC87427_HAP0 0x13 +#define PC87427_HAP1 0x14 +#define PC87427_XSCNF 0x15 +#define PC87427_XWBCNF 0x16 + + diff --git a/src/superio/NSC/pc87427/pc87427_early_init.c b/src/superio/NSC/pc87427/pc87427_early_init.c new file mode 100644 index 0000000000..71f702f11f --- /dev/null +++ b/src/superio/NSC/pc87427/pc87427_early_init.c @@ -0,0 +1,31 @@ +#include <arch/romcc_io.h> +#include "pc87427.h" + +static void pc87427_disable_dev(device_t dev) +{ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); +} +static void pc87427_enable_dev(device_t dev, unsigned iobase) +{ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); + pnp_set_iobase(dev, PNP_IDX_IO0, iobase); + pnp_set_enable(dev, 1); +} +static void xbus_cfg(device_t dev) +{ + uint8_t i, data; + uint16_t xbus_index; + + pnp_set_logical_device(dev); + /* select proper BIOS size (4MB) */ + pnp_write_config(dev, PC87427_XMEMCNF2, (pnp_read_config(dev, PC87427_XMEMCNF2)) | 0x04); + xbus_index = pnp_read_iobase(dev, 0x60); + + /* enable writes to devices attached to XCS0 (XBUS Chip Select 0) */ + for (i=0; i<= 0xf; i++) { + outb((i<<4), xbus_index + PC87427_HAP0); + } + return; +} diff --git a/src/superio/NSC/pc87427/superio.c b/src/superio/NSC/pc87427/superio.c new file mode 100644 index 0000000000..84c6ecb628 --- /dev/null +++ b/src/superio/NSC/pc87427/superio.c @@ -0,0 +1,77 @@ +/* Copyright 2000 AG Electronics Ltd. */ +/* Copyright 2003-2004 Linux Networx */ +/* This code is distributed without warranty under the GPL v2 (see COPYING) */ + +#include <arch/io.h> +#include <device/device.h> +#include <device/pnp.h> +#include <console/console.h> +#include <string.h> +#include <bitops.h> +#include "chip.h" +#include "pc87427.h" + + +static void init(device_t dev) +{ + struct superio_NSC_pc87427_config *conf; + struct resource *res0, *res1; + /* Wishlist handle well known programming interfaces more + * generically. + */ + if (!dev->enabled) { + return; + } + conf = dev->chip_info; + switch(dev->path.u.pnp.device) { + case PC87427_SP1: + res0 = find_resource(dev, PNP_IDX_IO0); + init_uart8250(res0->base, &conf->com1); + break; + case PC87427_SP2: + res0 = find_resource(dev, PNP_IDX_IO0); + init_uart8250(res0->base, &conf->com2); + break; + case PC87427_KBCK: + res0 = find_resource(dev, PNP_IDX_IO0); + res1 = find_resource(dev, PNP_IDX_IO1); + init_pc_keyboard(res0->base, res1->base, &conf->keyboard); + break; + } +} + +static struct device_operations ops = { + .read_resources = pnp_read_resources, + .set_resources = pnp_set_resources, + .enable_resources = pnp_enable_resources, + .enable = pnp_enable, + .init = init, +}; + +static struct pnp_info pnp_dev_info[] = { + { &ops, PC87427_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, }, + { &ops, PC87427_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, }, + { &ops, PC87427_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, }, + { &ops, PC87427_SWC, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0, + { 0xfff0, 0 }, { 0xfffc, 0 }, { 0xfffc, 0 }, { 0xfff8, 0 } }, + { &ops, PC87427_KBCM, PNP_IRQ0 }, + { &ops, PC87427_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, }, + { &ops, PC87427_GPIO, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } }, + { &ops, PC87427_WDT, PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 } }, + { &ops, PC87427_FMC, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } }, + { &ops, PC87427_XBUS, PNP_IO0 | PNP_IRQ0, { 0xffe0, 0 } }, + { &ops, PC87427_RTC, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0xfffe, 0 }, { 0xfffe, 0 } }, + { &ops, PC87427_MHC, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0xffe0, 0 }, { 0xffe0, 0 } }, +}; + + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &ops, + sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info); +} + +struct chip_operations superio_NSC_pc87427_ops = { + CHIP_NAME("NSC 87427") + .enable_dev = enable_dev, +}; diff --git a/src/superio/smsc/lpc47b397/superio.c b/src/superio/smsc/lpc47b397/superio.c index 5a456099c8..ab9da13e93 100644 --- a/src/superio/smsc/lpc47b397/superio.c +++ b/src/superio/smsc/lpc47b397/superio.c @@ -45,33 +45,6 @@ static void enable_hwm_smbus(device_t dev) { value |= 0x01; pnp_write_config(dev, reg, value); } -#if 0 -static void dump_pnp_device(device_t dev) -{ - int i; - print_debug("\r\n"); - - for(i = 0; i <= 255; i++) { - uint8_t reg, val; - if ((i & 0x0f) == 0) { - print_debug_hex8(i); - print_debug_char(':'); - } - reg = i; - if(i!=0xaa) { - val = pnp_read_config(dev, reg); - } - else { - val = 0xaa; - } - print_debug_char(' '); - print_debug_hex8(val); - if ((i & 0x0f) == 0x0f) { - print_debug("\r\n"); - } - } -} -#endif static void lpc47b397_init(device_t dev) diff --git a/src/superio/winbond/w83627hf/superio.c b/src/superio/winbond/w83627hf/superio.c index 57d475b00f..559bdf1189 100644 --- a/src/superio/winbond/w83627hf/superio.c +++ b/src/superio/winbond/w83627hf/superio.c @@ -12,6 +12,7 @@ #include <bitops.h> #include <uart8250.h> #include <pc80/keyboard.h> +#include <pc80/mc146818rtc.h> #include "chip.h" #include "w83627hf.h" @@ -47,33 +48,22 @@ static void enable_hwm_smbus(device_t dev) { pnp_write_config(dev, reg, value); } -#if 0 -static void dump_pnp_device(device_t dev) +static void init_acpi(device_t dev) { - int i; - print_debug("\r\n"); - - for(i = 0; i <= 255; i++) { - uint8_t reg, val; - if ((i & 0x0f) == 0) { - print_debug_hex8(i); - print_debug_char(':'); - } - reg = i; - if(i!=0xaa) { - val = pnp_read_config(dev, reg); - } - else { - val = 0xaa; - } - print_debug_char(' '); - print_debug_hex8(val); - if ((i & 0x0f) == 0x0f) { - print_debug("\r\n"); - } - } + uint8_t value = 0x20; + int power_on = 1; + + get_option(&power_on, "power_on_after_fail"); + pnp_enter_ext_func_mode(dev); + pnp_write_index(dev->path.u.pnp.port,7,0x0a); + value = pnp_read_config(dev, 0xE4); + value &= ~(3<<5); + if(power_on) { + value |= (1<<5); + } + pnp_write_config(dev, 0xE4, value); + pnp_exit_ext_func_mode(dev); } -#endif static void init_hwm(unsigned long base) { @@ -105,7 +95,6 @@ static void init_hwm(unsigned long base) } } - static void w83627hf_init(device_t dev) { struct superio_winbond_w83627hf_config *conf; @@ -133,21 +122,16 @@ static void w83627hf_init(device_t dev) #define HWM_INDEX_PORT 5 init_hwm(res0->base + HWM_INDEX_PORT); break; + case W83627HF_ACPI: + init_acpi(dev); + break; } - } void w83627hf_pnp_set_resources(device_t dev) { - pnp_enter_ext_func_mode(dev); - pnp_set_resources(dev); - -#if 0 - dump_pnp_device(dev); -#endif - pnp_exit_ext_func_mode(dev); } @@ -155,20 +139,13 @@ void w83627hf_pnp_set_resources(device_t dev) void w83627hf_pnp_enable_resources(device_t dev) { pnp_enter_ext_func_mode(dev); - pnp_enable_resources(dev); - switch(dev->path.u.pnp.device) { case W83627HF_HWM: printk_debug("w83627hf hwm smbus enabled\n"); enable_hwm_smbus(dev); break; } - -#if 0 - dump_pnp_device(dev); -#endif - pnp_exit_ext_func_mode(dev); } @@ -219,4 +196,3 @@ struct chip_operations superio_winbond_w83627hf_ops = { CHIP_NAME("Winbond w83627hf") .enable_dev = enable_dev, }; - diff --git a/src/superio/winbond/w83627hf/w83627hf.h b/src/superio/winbond/w83627hf/w83627hf.h index 0cf16310c3..7cd664cd16 100644 --- a/src/superio/winbond/w83627hf/w83627hf.h +++ b/src/superio/winbond/w83627hf/w83627hf.h @@ -9,3 +9,83 @@ #define W83627HF_GPIO3 9 #define W83627HF_ACPI 10 #define W83627HF_HWM 11 /* Hardware Monitor */ + +//#define W83627HF_GPIO_DEV PNP_DEV(0x2e, W83627HF_GPIO) +//#define W83627HF_XBUS_DEV PNP_DEV(0x2e, W83627HF_XBUS) + +#define W83627HF_GPSEL 0xf0 +#define W83627HF_GPCFG1 0xf1 +#define W83627HF_GPEVR 0xf2 +#define W83627HF_GPCFG2 0xf3 +#define W83627HF_EXTCFG 0xf4 +#define W83627HF_IOEXT1A 0xf5 +#define W83627HF_IOEXT1B 0xf6 +#define W83627HF_IOEXT2A 0xf7 +#define W83627HF_IOEXT2B 0xf8 + +#define W83627HF_GPDO_0 0x00 +#define W83627HF_GPDI_0 0x01 +#define W83627HF_GPDO_1 0x02 +#define W83627HF_GPDI_1 0x03 +#define W83627HF_GPEVEN_1 0x04 +#define W83627HF_GPEVST_1 0x05 +#define W83627HF_GPDO_2 0x06 +#define W83627HF_GPDI_2 0x07 +#define W83627HF_GPDO_3 0x08 +#define W83627HF_GPDI_3 0x09 +#define W83627HF_GPDO_4 0x0a +#define W83627HF_GPDI_4 0x0b +#define W83627HF_GPEVEN_4 0x0c +#define W83627HF_GPEVST_4 0x0d +#define W83627HF_GPDO_5 0x0e +#define W83627HF_GPDI_5 0x0f +#define W83627HF_GPDO_6 0x10 +#define W83627HF_GPDO_7A 0x11 +#define W83627HF_GPDO_7B 0x12 +#define W83627HF_GPDO_7C 0x13 +#define W83627HF_GPDO_7D 0x14 +#define W83627HF_GPDI_7A 0x15 +#define W83627HF_GPDI_7B 0x16 +#define W83627HF_GPDI_7C 0x17 +#define W83627HF_GPDI_7D 0x18 + +#define W83627HF_XIOCNF 0xf0 +#define W83627HF_XIOBA1H 0xf1 +#define W83627HF_XIOBA1L 0xf2 +#define W83627HF_XIOSIZE1 0xf3 +#define W83627HF_XIOBA2H 0xf4 +#define W83627HF_XIOBA2L 0xf5 +#define W83627HF_XIOSIZE2 0xf6 +#define W83627HF_XMEMCNF1 0xf7 +#define W83627HF_XMEMCNF2 0xf8 +#define W83627HF_XMEMBAH 0xf9 +#define W83627HF_XMEMBAL 0xfa +#define W83627HF_XMEMSIZE 0xfb +#define W83627HF_XIRQMAP1 0xfc +#define W83627HF_XIRQMAP2 0xfd +#define W83627HF_XBIMM 0xfe +#define W83627HF_XBBSL 0xff + +#define W83627HF_XBCNF 0x00 +#define W83627HF_XZCNF0 0x01 +#define W83627HF_XZCNF1 0x02 +#define W83627HF_XIRQC0 0x04 +#define W83627HF_XIRQC1 0x05 +#define W83627HF_XIRQC2 0x06 +#define W83627HF_XIMA0 0x08 +#define W83627HF_XIMA1 0x09 +#define W83627HF_XIMA2 0x0a +#define W83627HF_XIMA3 0x0b +#define W83627HF_XIMD 0x0c +#define W83627HF_XZCNF2 0x0d +#define W83627HF_XZCNF3 0x0e +#define W83627HF_XZM0 0x0f +#define W83627HF_XZM1 0x10 +#define W83627HF_XZM2 0x11 +#define W83627HF_XZM3 0x12 +#define W83627HF_HAP0 0x13 +#define W83627HF_HAP1 0x14 +#define W83627HF_XSCNF 0x15 +#define W83627HF_XWBCNF 0x16 + + diff --git a/src/superio/winbond/w83627hf/w83627hf_early_init.c b/src/superio/winbond/w83627hf/w83627hf_early_init.c new file mode 100644 index 0000000000..e449c4ae9c --- /dev/null +++ b/src/superio/winbond/w83627hf/w83627hf_early_init.c @@ -0,0 +1,15 @@ +#include <arch/romcc_io.h> +#include "w83627hf.h" + +static void w83627hf_disable_dev(device_t dev) +{ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); +} +static void w83627hf_enable_dev(device_t dev, unsigned iobase) +{ + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); + pnp_set_iobase(dev, PNP_IDX_IO0, iobase); + pnp_set_enable(dev, 1); +} |