diff options
author | Yinghai Lu <yinghailu@gmail.com> | 2005-07-08 02:49:49 +0000 |
---|---|---|
committer | Yinghai Lu <yinghailu@gmail.com> | 2005-07-08 02:49:49 +0000 |
commit | 13f1c2af8be2cd7f7e99a678f5d428a65b771811 (patch) | |
tree | 27cad5581f1fa150f573149d48e82f70ba1b1d9f | |
parent | 14cde9e96a777f9d75016a13b23fab0480515f58 (diff) | |
download | coreboot-13f1c2af8be2cd7f7e99a678f5d428a65b771811.tar.xz |
eric patch
1. x86_setup_mtrr take address bit.
2. generic ht, pcix, pcie beidge...
3. scan bus and reset_bus
4. ht read ctrl to decide if the ht chain
is ready
5. Intel e7520 and e7525 support
6. new ich5r support
7. intel sb 6300 support.
yhlu patch
1. split x86_setup_mtrrs to fixed and var
2. if (resource->flags & IORESOURCE_FIXED ) return; in device.c pick_largest_resource
3. in_conherent.c K8_SCAN_PCI_BUS
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1982 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
315 files changed, 30257 insertions, 1955 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); +} diff --git a/targets/tyan/s2850/Config.lb b/targets/tyan/s2850/Config.lb index 3b52fcc772..a2258c8a92 100644 --- a/targets/tyan/s2850/Config.lb +++ b/targets/tyan/s2850/Config.lb @@ -15,9 +15,9 @@ romimage "normal" # option ROM_SIZE = 458752 option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x11800 -# option ROM_IMAGE_SIZE=0x16000 + option ROM_IMAGE_SIZE=0x16000 # option ROM_IMAGE_SIZE=0x17800 - option ROM_IMAGE_SIZE=0x13c00 +# option ROM_IMAGE_SIZE=0x13c00 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" # payload ../../../payloads/tg3--ide_disk.zelf @@ -26,8 +26,8 @@ romimage "normal" # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3.zelf # payload ../../../payloads/tg3_vga.zelf -# payload ../../../payloads/tg3--filo_hda2_vga.zelf - payload ../../../payloads/tg3--filo_u_hda2_vga.zelf + payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_u_hda2_vga.zelf # payload ../../../payloads/tg3--filo_hda2_com2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf @@ -37,9 +37,9 @@ end romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x11800 -# option ROM_IMAGE_SIZE=0x16000 + option ROM_IMAGE_SIZE=0x16000 # option ROM_IMAGE_SIZE=0x17800 - option ROM_IMAGE_SIZE=0x13c00 +# option ROM_IMAGE_SIZE=0x13c00 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" # payload ../../../payloads/tg3--ide_disk.zelf @@ -48,8 +48,8 @@ romimage "fallback" # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3.zelf # payload ../../../payloads/tg3_vga.zelf -# payload ../../../payloads/tg3--filo_hda2_vga.zelf - payload ../../../payloads/tg3--filo_u_hda2_vga.zelf + payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_u_hda2_vga.zelf # payload ../../../payloads/tg3--filo_hda2_com2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf diff --git a/targets/tyan/s2880/Config.lb b/targets/tyan/s2880/Config.lb index 6dbde5768e..72b7152e8f 100644 --- a/targets/tyan/s2880/Config.lb +++ b/targets/tyan/s2880/Config.lb @@ -8,9 +8,9 @@ mainboard tyan/s2880 # Tyan s2880 romimage "normal" # 48K for SCSI FW or ATI ROM - option ROM_SIZE = 475136 +# option ROM_SIZE = 475136 # 48K for SCSI FW and 48K for ATI ROM -# option ROM_SIZE = 425984 + option ROM_SIZE = 425984 # 64K for Etherboot # option ROM_SIZE = 458752 option USE_FALLBACK_IMAGE=0 diff --git a/targets/tyan/s2881/Config.lb b/targets/tyan/s2881/Config.lb index 1caa8e524b..332fc24d3b 100644 --- a/targets/tyan/s2881/Config.lb +++ b/targets/tyan/s2881/Config.lb @@ -16,7 +16,7 @@ romimage "normal" option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13000 - option ROM_IMAGE_SIZE=0x16200 + option ROM_IMAGE_SIZE=0x16000 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" # payload ../../../payloads/tg3--ide_disk.zelf @@ -24,7 +24,8 @@ romimage "normal" # payload ../../../payloads/filo_mem.elf # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3--filo.zelf - payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_vga.zelf + payload ../../../payloads/tg3--filo_hda1_vga_md1.zelf # payload ../../../payloads/tg3--filo_btext_hda2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf @@ -35,7 +36,7 @@ romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13000 - option ROM_IMAGE_SIZE=0x16200 + option ROM_IMAGE_SIZE=0x16000 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" # payload ../../../payloads/tg3--ide_disk.zelf @@ -43,7 +44,8 @@ romimage "fallback" # payload ../../../payloads/filo_mem.elf # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3--filo.zelf - payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_vga.zelf + payload ../../../payloads/tg3--filo_hda1_vga_md1.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--filo_btext_hda2.zelf # payload ../../../payloads/tg3--e1000--filo.zelf diff --git a/targets/tyan/s2882/Config.lb b/targets/tyan/s2882/Config.lb index 7118d47299..2913109e00 100644 --- a/targets/tyan/s2882/Config.lb +++ b/targets/tyan/s2882/Config.lb @@ -15,7 +15,7 @@ romimage "normal" # option ROM_SIZE = 458752 option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x11800 - option ROM_IMAGE_SIZE=0x16300 + option ROM_IMAGE_SIZE=0x16000 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" # payload ../../../payloads/tg3--ide_disk.zelf @@ -32,7 +32,7 @@ end romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x11800 - option ROM_IMAGE_SIZE=0x16300 + option ROM_IMAGE_SIZE=0x16000 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" # payload ../../../payloads/tg3--ide_disk.zelf diff --git a/targets/tyan/s2885/Config.lb b/targets/tyan/s2885/Config.lb index 98e00826d5..1ec013be7a 100644 --- a/targets/tyan/s2885/Config.lb +++ b/targets/tyan/s2885/Config.lb @@ -15,8 +15,8 @@ romimage "normal" # option ROM_SIZE = 458752 option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x13800 - option ROM_IMAGE_SIZE=0x17800 -# option ROM_IMAGE_SIZE=0x16000 +# option ROM_IMAGE_SIZE=0x17800 + option ROM_IMAGE_SIZE=0x16200 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" # payload ../../../payloads/tg3--ide_disk.zelf @@ -25,8 +25,8 @@ romimage "normal" # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3--filo_hda2.zelf # payload ../../../payloads/tg3.zelf - payload ../../../payloads/tg3_vga.zelf -# payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3_vga.zelf + payload ../../../payloads/tg3--filo_hda2_vga.zelf # payload ../../../payloads/tg3_com2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf @@ -38,8 +38,8 @@ end romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x13800 - option ROM_IMAGE_SIZE=0x17800 -# option ROM_IMAGE_SIZE=0x16000 +# option ROM_IMAGE_SIZE=0x17800 + option ROM_IMAGE_SIZE=0x16200 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" # payload ../../../payloads/tg3--ide_disk.zelf @@ -48,8 +48,8 @@ romimage "fallback" # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3--filo_hda2.zelf # payload ../../../payloads/tg3.zelf - payload ../../../payloads/tg3_vga.zelf -# payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3_vga.zelf + payload ../../../payloads/tg3--filo_hda2_vga.zelf # payload ../../../payloads/tg3_com2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf diff --git a/targets/tyan/s2891/Config.lb b/targets/tyan/s2891/Config.lb index 24f9046de2..2b80499e6f 100644 --- a/targets/tyan/s2891/Config.lb +++ b/targets/tyan/s2891/Config.lb @@ -7,6 +7,8 @@ mainboard tyan/s2891 # Tyan s2891 romimage "normal" +# 48K for ATI ROM in 1M +# option ROM_SIZE = 999424 # 48K for SCSI FW or ATI ROM option ROM_SIZE = 475136 # 48K for SCSI FW and 48K for ATI ROM @@ -16,7 +18,7 @@ romimage "normal" option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13000 - option ROM_IMAGE_SIZE=0x15800 + option ROM_IMAGE_SIZE=0x16000 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" # payload ../../../payloads/tg3--ide_disk.zelf @@ -37,7 +39,7 @@ romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13000 - option ROM_IMAGE_SIZE=0x15800 + option ROM_IMAGE_SIZE=0x16000 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" # payload ../../../payloads/tg3--ide_disk.zelf diff --git a/targets/tyan/s2892/Config.lb b/targets/tyan/s2892/Config.lb index dd5a70b519..20d6c8765e 100644 --- a/targets/tyan/s2892/Config.lb +++ b/targets/tyan/s2892/Config.lb @@ -16,7 +16,7 @@ romimage "normal" option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13800 - option ROM_IMAGE_SIZE=0x16000 + option ROM_IMAGE_SIZE=0x16380 # option ROM_IMAGE_SIZE=0x17800 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" @@ -37,7 +37,7 @@ romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13800 - option ROM_IMAGE_SIZE=0x16000 + option ROM_IMAGE_SIZE=0x16380 # option ROM_IMAGE_SIZE=0x17800 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" diff --git a/targets/tyan/s2895/Config.lb b/targets/tyan/s2895/Config.lb index 58a0d150e8..53b17f3f1c 100644 --- a/targets/tyan/s2895/Config.lb +++ b/targets/tyan/s2895/Config.lb @@ -18,7 +18,7 @@ romimage "normal" option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13800 - option ROM_IMAGE_SIZE=0x16000 + option ROM_IMAGE_SIZE=0x15000 # option ROM_IMAGE_SIZE=0x17800 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" @@ -27,7 +27,13 @@ romimage "normal" # payload ../../../payloads/filo_mem.elf # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3.zelf +# payload ../../../payloads/tg3--filo_hda2_vga.zelf payload ../../../payloads/forcedeth--filo_hda2_vga.zelf +# payload ../../../payloads/forcedeth_vga.zelf +# payload ../../../payloads/forcedeth--filo_hda2_vga_5_4.zelf +# payload ../../../../../../elf/ram0_2.5_2.6.11.tiny.elf +# payload ../../../../../../elf/ram0_2.5_2.6.12.tiny.elf +# payload ../../../payloads/tg3--filo_hda2_vga_5_4.zelf # payload ../../../payloads/tg3_vga.zelf # payload ../../../payloads/tg3--filo_hda2_vgax.zelf # payload ../../../payloads/tg3--filo_hda2_com2.zelf @@ -40,7 +46,7 @@ romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x11800 # option ROM_IMAGE_SIZE=0x13800 - option ROM_IMAGE_SIZE=0x16000 + option ROM_IMAGE_SIZE=0x15000 # option ROM_IMAGE_SIZE=0x17800 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" @@ -49,7 +55,10 @@ romimage "fallback" # payload ../../../payloads/filo_mem.elf # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3.zelf +# payload ../../../payloads/tg3--filo_hda2_vga.zelf payload ../../../payloads/forcedeth--filo_hda2_vga.zelf +# payload ../../../payloads/forcedeth_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_vga_5_4.zelf # payload ../../../payloads/tg3_vga.zelf # payload ../../../payloads/tg3--filo_hda2_vgax.zelf # payload ../../../payloads/tg3--filo_hda2_com2.zelf diff --git a/targets/tyan/s4880/Config.lb b/targets/tyan/s4880/Config.lb index 84a7f2105a..c61bb9f836 100644 --- a/targets/tyan/s4880/Config.lb +++ b/targets/tyan/s4880/Config.lb @@ -8,9 +8,9 @@ mainboard tyan/s4880 # Tyan s4880 romimage "normal" # 48K for SCSI FW or ATI ROM - option ROM_SIZE = 475136 +# option ROM_SIZE = 475136 # 48K for SCSI FW and 48K for ATI ROM -# option ROM_SIZE = 425984 + option ROM_SIZE = 425984 # 64K for Etherboot # option ROM_SIZE = 458752 option USE_FALLBACK_IMAGE=0 diff --git a/targets/tyan/s4882/Config.lb b/targets/tyan/s4882/Config.lb index 0e4f336596..e8a1553ada 100644 --- a/targets/tyan/s4882/Config.lb +++ b/targets/tyan/s4882/Config.lb @@ -15,9 +15,9 @@ romimage "normal" # option ROM_SIZE = 458752 option USE_FALLBACK_IMAGE=0 # option ROM_IMAGE_SIZE=0x19000 -# option ROM_IMAGE_SIZE=0x19c00 + option ROM_IMAGE_SIZE=0x19c00 # option ROM_IMAGE_SIZE=0x18800 - option ROM_IMAGE_SIZE=0x16200 +# option ROM_IMAGE_SIZE=0x16200 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" # payload ../../../payloads/tg3--ide_disk.zelf @@ -25,9 +25,9 @@ romimage "normal" # payload ../../../payloads/filo_mem.elf # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3.zelf -# payload ../../../payloads/tg3_vga.zelf + payload ../../../payloads/tg3_vga.zelf # payload ../../../payloads/filo_vga_memtest.zelf - payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_vga.zelf # payload ../../../payloads/tg3--filo_hda2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf @@ -37,9 +37,9 @@ end romimage "fallback" option USE_FALLBACK_IMAGE=1 # option ROM_IMAGE_SIZE=0x19000 -# option ROM_IMAGE_SIZE=0x19c00 + option ROM_IMAGE_SIZE=0x19c00 # option ROM_IMAGE_SIZE=0x18800 - option ROM_IMAGE_SIZE=0x16200 +# option ROM_IMAGE_SIZE=0x16200 option XIP_ROM_SIZE=0x20000 option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" # payload ../../../payloads/tg3--ide_disk.zelf @@ -47,9 +47,9 @@ romimage "fallback" # payload ../../../payloads/filo_mem.elf # payload ../../../payloads/filo.zelf # payload ../../../payloads/tg3.zelf -# payload ../../../payloads/tg3_vga.zelf + payload ../../../payloads/tg3_vga.zelf # payload ../../../payloads/filo_vga_kernel.zelf - payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_vga.zelf # payload ../../../payloads/tg3--filo_hda2.zelf # payload ../../../payloads/e1000--filo.zelf # payload ../../../payloads/tg3--e1000--filo.zelf diff --git a/util/romcc/Makefile b/util/romcc/Makefile index c06777d7df..1734fe5c89 100644 --- a/util/romcc/Makefile +++ b/util/romcc/Makefile @@ -1,5 +1,3 @@ - - # Move the configuration defines to makefile.conf CC=gcc CPPFLAGS= @@ -110,6 +108,10 @@ TESTS=\ simple_test84.c \ simple_test85.c \ simple_test86.c \ + simple_test87.c \ + simple_test88.c \ + simple_test89.c \ + simple_test90.c \ raminit_test1.c \ raminit_test2.c \ raminit_test3.c \ diff --git a/util/romcc/tests.sh b/util/romcc/tests.sh index 0dba165a75..4dddbb1920 100644 --- a/util/romcc/tests.sh +++ b/util/romcc/tests.sh @@ -21,13 +21,15 @@ stem="$root$N" base=tests/$stem op="-Itests/include" op="$op -feliminate-inefectual-code -fsimplify -fscc-transform " -#op="$op -O2" +#op="$op -O2 " +#op="$op -mmmx -msse" op="$op -finline-policy=defaulton" #op="$op -finline-policy=nopenalty" #op="$op -finline-policy=never" op="$op -fdebug -fdebug-triples -fdebug-interference -fdebug-verification" -#op="$op -fdebug-inline" -#op="$op -fdebug-calls" +op="$op -fdebug-fdominators" +op="$op -fdebug-inline" +op="$op -fdebug-calls" #op="$op -mnoop-copy" #op="$op -fsimplify -fno-simplify-op -fno-simplify-phi -fno-simplify-label -fno-simplify-branch -fno-simplify-copy -fno-simplify-arith -fno-simplify-shift -fno-simplify-bitwise -fno-simplify-logical" #op="$op -fdebug-rebuild-ssa-form" |