From ef03afa405b049a172146aab93cfb81fb21f3945 Mon Sep 17 00:00:00 2001 From: "arch import user (historical)" Date: Wed, 6 Jul 2005 17:15:30 +0000 Subject: [PATCH] Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-34 Creator: Yinghai Lu AMD D0/E0 Opteron new mem mapping support, AMD E Opteron mem hole support,AMD K8 Four Ranks DIMM support git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1950 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/config/Options.lb | 16 + src/cpu/amd/dualcore/Config.lb | 5 + src/cpu/amd/dualcore/amd_sibling.c | 244 +++++++++++++++ src/cpu/amd/dualcore/dualcore.c | 99 ++++++ src/cpu/amd/dualcore/dualcore_id.c | 45 +++ src/cpu/amd/model_fxx/Config.lb | 1 + src/cpu/amd/model_fxx/model_fxx_init.c | 143 ++++++++- src/cpu/amd/model_fxx/model_fxx_msr.h | 10 + src/cpu/amd/model_fxx/node_id.c | 12 + src/cpu/x86/16bit/reset16.lds | 2 +- src/cpu/x86/lapic/lapic_cpu_init.c | 13 +- src/cpu/x86/mtrr/mtrr.c | 4 +- src/devices/hypertransport.c | 5 + src/drivers/i2c/adm1027/adm1027.c | 4 +- src/include/cpu/amd/dualcore.h | 19 ++ src/lib/malloc.c | 2 +- src/mainboard/Iwill/DK8S2/Options.lb | 2 + src/mainboard/Iwill/DK8X/Options.lb | 2 + src/mainboard/amd/quartet/Options.lb | 2 + src/mainboard/amd/serenade/Options.lb | 2 + src/mainboard/amd/solo/Options.lb | 2 + src/mainboard/arima/hdama/Options.lb | 2 + src/mainboard/ibm/e325/Options.lb | 2 + src/mainboard/island/aruma/Options.lb | 2 + src/mainboard/newisys/khepri/Options.lb | 2 + src/mainboard/tyan/s2850/Options.lb | 12 +- src/mainboard/tyan/s2850/auto.c | 123 +++----- src/mainboard/tyan/s2850/cmos.layout | 1 + src/mainboard/tyan/s2850/failover.c | 31 +- src/mainboard/tyan/s2850/mptable.c | 102 +++--- src/mainboard/tyan/s2875/Options.lb | 14 + src/mainboard/tyan/s2875/auto.c | 145 +++------ src/mainboard/tyan/s2875/cmos.layout | 1 + src/mainboard/tyan/s2875/failover.c | 32 +- src/mainboard/tyan/s2875/mptable.c | 102 +++--- src/mainboard/tyan/s2880/Config.lb | 10 +- src/mainboard/tyan/s2880/Options.lb | 14 + src/mainboard/tyan/s2880/auto.c | 136 +++----- src/mainboard/tyan/s2880/cmos.layout | 1 + src/mainboard/tyan/s2880/failover.c | 34 +- src/mainboard/tyan/s2880/irq_tables.c | 2 +- src/mainboard/tyan/s2880/mptable.c | 102 +++--- src/mainboard/tyan/s2881/Config.lb | 72 ++--- src/mainboard/tyan/s2881/Options.lb | 14 + src/mainboard/tyan/s2881/auto.c | 138 +++------ src/mainboard/tyan/s2881/cmos.layout | 1 + src/mainboard/tyan/s2881/failover.c | 32 +- src/mainboard/tyan/s2881/mptable.c | 78 +++-- src/mainboard/tyan/s2881/resourcemap.c | 4 +- src/mainboard/tyan/s2882/Options.lb | 18 +- src/mainboard/tyan/s2882/auto.c | 136 +++----- src/mainboard/tyan/s2882/cmos.layout | 1 + src/mainboard/tyan/s2882/failover.c | 27 +- src/mainboard/tyan/s2882/mptable.c | 108 ++++--- src/mainboard/tyan/s2885/Options.lb | 23 +- src/mainboard/tyan/s2885/auto.c | 194 +++++------- src/mainboard/tyan/s2885/chip.h | 2 +- src/mainboard/tyan/s2885/cmos.layout | 1 + src/mainboard/tyan/s2885/failover.c | 30 +- src/mainboard/tyan/s2885/mptable.c | 101 +++--- src/mainboard/tyan/s2885/resourcemap.c | 12 +- src/mainboard/tyan/s2891/Config.lb | 8 + src/mainboard/tyan/s2891/Options.lb | 10 +- src/mainboard/tyan/s2891/auto.c | 30 ++ src/mainboard/tyan/s2891/failover.c | 13 + src/mainboard/tyan/s2891/mptable.c | 21 +- src/mainboard/tyan/s2892/Config.lb | 298 ++++++++++++++++++ src/mainboard/tyan/s2892/Options.lb | 245 +++++++++++++++ src/mainboard/tyan/s2892/auto.c | 200 ++++++++++++ src/mainboard/tyan/s2892/chip.h | 6 + src/mainboard/tyan/s2892/cmos.layout | 98 ++++++ src/mainboard/tyan/s2892/failover.c | 111 +++++++ src/mainboard/tyan/s2892/irq_tables.c | 35 +++ src/mainboard/tyan/s2892/mainboard.c | 12 + src/mainboard/tyan/s2892/mptable.c | 270 ++++++++++++++++ src/mainboard/tyan/s2892/resourcemap.c | 273 +++++++++++++++++ src/mainboard/tyan/s2895/Config.lb | 10 + src/mainboard/tyan/s2895/Options.lb | 10 +- src/mainboard/tyan/s2895/auto.c | 52 +++- src/mainboard/tyan/s2895/failover.c | 18 +- src/mainboard/tyan/s2895/mptable.c | 22 +- src/mainboard/tyan/s4880/Config.lb | 10 +- src/mainboard/tyan/s4880/Options.lb | 18 +- src/mainboard/tyan/s4880/auto.c | 177 +++-------- src/mainboard/tyan/s4880/cmos.layout | 1 + src/mainboard/tyan/s4880/failover.c | 42 ++- src/mainboard/tyan/s4880/mptable.c | 116 ++++--- src/mainboard/tyan/s4880/resourcemap.c | 2 +- src/mainboard/tyan/s4882/Options.lb | 23 +- src/mainboard/tyan/s4882/auto.c | 225 +++++--------- src/mainboard/tyan/s4882/cmos.layout | 1 + src/mainboard/tyan/s4882/failover.c | 38 ++- src/mainboard/tyan/s4882/irq_tables.c | 2 +- src/mainboard/tyan/s4882/mptable.c | 117 ++++--- src/mainboard/tyan/s4882/resourcemap.c | 2 +- src/northbridge/amd/amdk8/coherent_ht.c | 358 ++++++++++++++++------ src/northbridge/amd/amdk8/cpu_rev.c | 31 +- src/northbridge/amd/amdk8/debug.c | 24 +- src/northbridge/amd/amdk8/incoherent_ht.c | 3 + src/northbridge/amd/amdk8/misc_control.c | 4 +- src/northbridge/amd/amdk8/northbridge.c | 217 +++++++++---- src/northbridge/amd/amdk8/raminit.c | 288 +++++++++++++++-- targets/tyan/s2892/Config.lb | 57 ++++ targets/tyan/s2892/VERSION | 1 + targets/tyan/s2895/Config.lb | 4 +- 105 files changed, 4396 insertions(+), 1603 deletions(-) create mode 100644 src/cpu/amd/dualcore/Config.lb create mode 100644 src/cpu/amd/dualcore/amd_sibling.c create mode 100644 src/cpu/amd/dualcore/dualcore.c create mode 100644 src/cpu/amd/dualcore/dualcore_id.c create mode 100644 src/cpu/amd/model_fxx/node_id.c create mode 100644 src/include/cpu/amd/dualcore.h create mode 100644 src/mainboard/tyan/s2892/Config.lb create mode 100644 src/mainboard/tyan/s2892/Options.lb create mode 100644 src/mainboard/tyan/s2892/auto.c create mode 100644 src/mainboard/tyan/s2892/chip.h create mode 100644 src/mainboard/tyan/s2892/cmos.layout create mode 100644 src/mainboard/tyan/s2892/failover.c create mode 100644 src/mainboard/tyan/s2892/irq_tables.c create mode 100644 src/mainboard/tyan/s2892/mainboard.c create mode 100644 src/mainboard/tyan/s2892/mptable.c create mode 100644 src/mainboard/tyan/s2892/resourcemap.c create mode 100644 targets/tyan/s2892/Config.lb create mode 100644 targets/tyan/s2892/VERSION diff --git a/src/config/Options.lb b/src/config/Options.lb index 35a3151b5..370eba21c 100644 --- a/src/config/Options.lb +++ b/src/config/Options.lb @@ -503,6 +503,11 @@ define CONFIG_MAX_CPUS export always comment "Maximum CPU count for this machine" end +define CONFIG_MAX_PHYSICAL_CPUS + default 1 + export always + comment "Maximum physical CPU count for this machine" +end define CONFIG_LOGICAL_CPUS default 0 export always @@ -513,6 +518,11 @@ define HAVE_MP_TABLE export used comment "Define to build an MP table" end +define SERIAL_CPU_INIT + default 1 + export always + comment "Serialize CPU init" +end ############################################### # Boot options @@ -769,6 +779,12 @@ define CK804_DEVN_BASE comment "CK804 device count from 0 or 1" end +define K8_E0_MEM_HOLE_SIZEK + default 0 + export always + comment "Opteron E0 later memory hole size in K" +end + define CONFIG_PCI_ROM_RUN default 0 export always diff --git a/src/cpu/amd/dualcore/Config.lb b/src/cpu/amd/dualcore/Config.lb new file mode 100644 index 000000000..dd8dd0996 --- /dev/null +++ b/src/cpu/amd/dualcore/Config.lb @@ -0,0 +1,5 @@ +uses CONFIG_LOGICAL_CPUS + +if CONFIG_LOGICAL_CPUS + object amd_sibling.o +end diff --git a/src/cpu/amd/dualcore/amd_sibling.c b/src/cpu/amd/dualcore/amd_sibling.c new file mode 100644 index 000000000..da5928ab1 --- /dev/null +++ b/src/cpu/amd/dualcore/amd_sibling.c @@ -0,0 +1,244 @@ +/* 2004.12 yhlu add dual core support */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../model_fxx/model_fxx_msr.h" +#include "../../../northbridge/amd/amdk8/cpu_rev.c" + +static int first_time = 1; +static int disable_siblings = !CONFIG_LOGICAL_CPUS; + + +int is_e0_later_in_bsp(int nodeid) +{ + uint32_t val; + uint32_t val_old; + int e0_later; + if(nodeid==0) { // we don't need to do that for node 0 in core0/node0 + return !is_cpu_pre_e0(); + } + // d0 will be treated as e0 with this methods, but the d0 nb_cfg_54 always 0 + device_t dev; + dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid,2)); + if(!dev) return 0; + val_old = pci_read_config32(dev, 0x80); + val = val_old; + val |= (1<<3); + pci_write_config32(dev, 0x80, val); + val = pci_read_config32(dev, 0x80); + e0_later = !!(val & (1<<3)); + if(e0_later) { // pre_e0 bit 3 always be 0 and can not be changed + pci_write_config32(dev, 0x80, val_old); // restore it + } + + return e0_later; +} + +unsigned int read_nb_cfg_54(void) +{ + msr_t msr; + msr = rdmsr(NB_CFG_MSR); + return ( ( msr.hi >> (54-32)) & 1); +} + +struct node_core_id get_node_core_id(unsigned int nb_cfg_54) { + struct node_core_id id; + // get the apicid via cpuid(1) ebx[27:24] + if(nb_cfg_54) { + // when NB_CFG[54] is set, nodid = ebx[27:25], coreid = ebx[24] + id.coreid = (cpuid_ebx(1) >> 24) & 0xf; + id.nodeid = (id.coreid>>1); + id.coreid &= 1; + } else { // single core should be here too + // when NB_CFG[54] is clear, nodeid = ebx[26:24], coreid = ebx[27] + id.nodeid = (cpuid_ebx(1) >> 24) & 0xf; + id.coreid = (id.nodeid>>3); + id.nodeid &= 7; + } + return id; + + +} + +static int get_max_siblings(int nodes) +{ + device_t dev; + int nodeid; + int siblings=0; + + //get max siblings from all the nodes + for(nodeid=0; nodeid> 12) & 3; + if(siblings < j) { + siblings = j; + } + } + + return siblings; +} + +static void enable_apic_ext_id(int nodes) +{ + device_t dev; + int nodeid; + + //enable APIC_EXIT_ID all the nodes + for(nodeid=0; nodeid>4) & 7) + 1; + + siblings = get_max_siblings(nodes); + + if(bsp_apic_id > 0) { // io apic could start from 0 + return 0; + } else if(pci_read_config32(dev, 0x68) & ( (1<<17) | (1<<18)) ) { // enabled ext id but bsp = 0 + if(!disable_siblings) { return siblings + 1; } + else { return 1; } + } + + nb_cfg_54 = read_nb_cfg_54(); + +#if 0 + //it is for all e0 single core and nc_cfg_54 low is set, but in the auto.c stage we do not set that bit for it. + if(nb_cfg_54 && (!disable_siblings) && (siblings == 0)) { + //we need to check if e0 single core is there + int i; + for(i=0; i0) ) { + /* for 8 way dual core, we will used up apicid 16:16, actualy 16 is not allowed by current kernel + and the kernel will try to get one that is small than 16 to make io apic work. + I don't know when the kernel can support 256 apic id. (APIC_EXT_ID is enabled) */ + + //4:10 for two way 8:12 for four way 16:16 for eight way + //Use CONFIG_MAX_PHYSICAL_CPUS instead of nodes for better consistency? + apicid_base = nb_cfg_54 ? (siblings+1) * nodes : 8 * siblings + nodes; + + } + else { + apicid_base = nodes; + } + + if((apicid_base+ioapic_num-1)>0xf) { + // We need to enable APIC EXT ID + printk_info("if the IO APIC device doesn't support 256 apic id, \r\n you need to set ENABLE_APIC_EXT_ID in auto.c so you can spare 16 id for ioapic\r\n"); + enable_apic_ext_id(nodes); + } + + return apicid_base; +} +#if 0 +void amd_sibling_init(device_t cpu) +{ + unsigned i, siblings; + struct cpuid_result result; + unsigned nb_cfg_54; + struct node_core_id id; + + /* On the bootstrap processor see if I want sibling cpus enabled */ + if (first_time) { + first_time = 0; + get_option(&disable_siblings, "dual_core"); + } + result = cpuid(0x80000008); + /* See how many sibling cpus we have */ + /* Is dualcore supported */ + siblings = (result.ecx & 0xff); + if ( siblings < 1) { + return; + } + +#if 1 + printk_debug("CPU: %u %d siblings\n", + cpu->path.u.apic.apic_id, + siblings); +#endif + + nb_cfg_54 = read_nb_cfg_54(); +#if 1 + id = get_node_core_id(nb_cfg_54); // pre e0 nb_cfg_54 can not be set + + /* See if I am a sibling cpu */ + //if ((cpu->path.u.apic.apic_id>>(nb_cfg_54?0:3)) & siblings ) { // siblings = 1, 3, 7, 15,.... + //if ( ( (cpu->path.u.apic.apic_id>>(nb_cfg_54?0:3)) % (siblings+1) ) != 0 ) { + if(id.coreid != 0) { + if (disable_siblings) { + cpu->enabled = 0; + } + return; + } +#endif + + /* I am the primary cpu start up my siblings */ + + for(i = 1; i <= siblings; i++) { + struct device_path cpu_path; + device_t new; + /* Build the cpu device path */ + cpu_path.type = DEVICE_PATH_APIC; + cpu_path.u.apic.apic_id = cpu->path.u.apic.apic_id + i * (nb_cfg_54?1:8); + + /* See if I can find the cpu */ + new = find_dev_path(cpu->bus, &cpu_path); + /* Allocate the new cpu device structure */ + if(!new) { + new = alloc_dev(cpu->bus, &cpu_path); + new->enabled = 1; + new->initialized = 0; + } + +#if 1 + printk_debug("CPU: %u has sibling %u\n", + cpu->path.u.apic.apic_id, + new->path.u.apic.apic_id); +#endif + /* Start the new cpu */ + if(new->enabled && !new->initialized) + start_cpu(new); + } + +} +#endif + diff --git a/src/cpu/amd/dualcore/dualcore.c b/src/cpu/amd/dualcore/dualcore.c new file mode 100644 index 000000000..1c3b2751a --- /dev/null +++ b/src/cpu/amd/dualcore/dualcore.c @@ -0,0 +1,99 @@ +/* 2004.12 yhlu add dual core support */ + + +#ifndef SET_NB_CFG_54 +#define SET_NB_CFG_54 1 +#endif + +#include "cpu/amd/dualcore/dualcore_id.c" + +static inline unsigned get_core_num_in_bsp(unsigned nodeid) +{ + return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12) & 3); +} + +static inline +#if SET_NB_CFG_54 == 1 + uint8_t +#else + void +#endif + set_apicid_cpuid_lo(void) { +#if SET_NB_CFG_54 + //for pre_e0, even we set nb_cfg_54, but it will still be 0 + //for e0 later you should use get_node_id(read_nb_cfg_54()) even for single core cpu + //get siblings via cpuid(0x80000008) ecx[7:0] + #if CONFIG_MAX_PHYSICAL_CPUS != 8 + if( get_core_num_in_bsp(0) == 0) { + /*first node only has one core, pre_e0 + all e0 single core installed don't need enable lo too, + So if mixing e0 single core and dual core, + don't put single core in first socket */ + return 0; + } + #endif + + if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core + return 0; + } + + // set the NB_CFG[54]=1; why the OS will be happy with that ??? + msr_t msr; + msr = rdmsr(NB_CFG_MSR); + msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo + wrmsr(NB_CFG_MSR, msr); + + return 1; + +#endif + +} + +static inline void real_start_other_core(unsigned nodeid) +{ + uint32_t dword; + // set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4 accesses and error logging to core0 + dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44); + dword |= 1<<27; // NbMcaToMstCpuEn bit + pci_write_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44, dword); + // set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1 + dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68); + dword |= 1<<5; + pci_write_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68, dword); +} + +//it is running on core0 of every node +static inline void start_other_core(unsigned nodeid) { + + if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core + return; + } + + if( get_core_num() >0) { // defined in dualcore_id.c + real_start_other_core(nodeid); + } +} + +static inline unsigned get_nodes(void) +{ + return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1; +} + +//it is running on core0 of node0 +static inline void start_other_cores(void) { + unsigned nodes; + unsigned nodeid; + + if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core + return; + } + + nodes = get_nodes(); + + for(nodeid=0; nodeid 0) { + real_start_other_core(nodeid); + } + } + +} diff --git a/src/cpu/amd/dualcore/dualcore_id.c b/src/cpu/amd/dualcore/dualcore_id.c new file mode 100644 index 000000000..feab68285 --- /dev/null +++ b/src/cpu/amd/dualcore/dualcore_id.c @@ -0,0 +1,45 @@ +/* 2004.12 yhlu add dual core support */ + +#include +#include "cpu/amd/model_fxx/model_fxx_msr.h" + +static inline unsigned int read_nb_cfg_54(void) +{ + msr_t msr; + msr = rdmsr(NB_CFG_MSR); + return ( ( msr.hi >> (54-32)) & 1); +} + +struct node_core_id { + unsigned nodeid; + unsigned coreid; +}; + +static inline struct node_core_id get_node_core_id(unsigned nb_cfg_54) { + struct node_core_id id; + // get the apicid via cpuid(1) ebx[27:24] + if( nb_cfg_54) { + // when NB_CFG[54] is set, nodid = ebx[27:25], coreid = ebx[24] + id.coreid = (cpuid_ebx(1) >> 24) & 0xf; + id.nodeid = (id.coreid>>1); + id.coreid &= 1; + } + else + { + // when NB_CFG[54] is clear, nodeid = ebx[26:24], coreid = ebx[27] + id.nodeid = (cpuid_ebx(1) >> 24) & 0xf; + id.coreid = (id.nodeid>>3); + id.nodeid &= 7; + } + return id; +} + +static inline unsigned get_core_num(void) +{ + return (cpuid_ecx(0x80000008) & 0xff); +} + +static inline struct node_core_id get_node_core_id_x(void) { + return get_node_core_id( read_nb_cfg_54() ); +} + diff --git a/src/cpu/amd/model_fxx/Config.lb b/src/cpu/amd/model_fxx/Config.lb index bf7b9987c..924dc8f15 100644 --- a/src/cpu/amd/model_fxx/Config.lb +++ b/src/cpu/amd/model_fxx/Config.lb @@ -10,5 +10,6 @@ dir /cpu/x86/lapic dir /cpu/x86/cache dir /cpu/x86/pae dir /cpu/amd/mtrr +dir /cpu/amd/dualcore driver model_fxx_init.o object apic_timer.o diff --git a/src/cpu/amd/model_fxx/model_fxx_init.c b/src/cpu/amd/model_fxx/model_fxx_init.c index 22b8f015c..fdaf05cb6 100644 --- a/src/cpu/amd/model_fxx/model_fxx_init.c +++ b/src/cpu/amd/model_fxx/model_fxx_init.c @@ -1,4 +1,9 @@ /* Needed so the AMD K8 runs correctly. */ +/* this should be done by Eric + * 2004.11 yhlu add d0 e0 support + * 2004.12 yhlu add dual core support + * 2005.02 yhlu add e0 memory hole support +*/ #include #include #include @@ -16,6 +21,11 @@ #include #include #include + +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif + #include "model_fxx_msr.h" #define MCI_STATUS 0x401 @@ -139,16 +149,18 @@ static void set_init_ecc_mtrrs(void) enable_cache(); } - static void init_ecc_memory(unsigned node_id) { unsigned long startk, begink, endk; +#if K8_E0_MEM_HOLE_SIZEK != 0 + unsigned long hole_startk = 0, hole_endk = 0; +#endif unsigned long basek; struct mtrr_state mtrr_state; device_t f1_dev, f2_dev, f3_dev; int enable_scrubbing; uint32_t dcl; - + f1_dev = dev_find_slot(0, PCI_DEVFN(0x18 + node_id, 1)); if (!f1_dev) { die("Cannot find cpu function 1\n"); @@ -186,6 +198,19 @@ static void init_ecc_memory(unsigned node_id) startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >> 2; endk = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000) >> 2) + 0x4000; +#if K8_E0_MEM_HOLE_SIZEK != 0 + if (!is_cpu_pre_e0()) { + uint32_t val; + val = pci_read_config32(f1_dev, 0xf0); + if((val & 1)==1) { + hole_startk = ((val & (0xff<<24)) >> 10); + hole_endk = ((val & (0xff<<8))<<(16-10)) - startk; + hole_endk += hole_startk; + } + } +#endif + + /* Don't start too early */ begink = startk; if (begink < CONFIG_LB_MEM_TOPK) { @@ -206,6 +231,9 @@ static void init_ecc_memory(unsigned node_id) unsigned long size; void *addr; +#if K8_E0_MEM_HOLE_SIZEK != 0 + if ((basek >= hole_startk) && (basek < hole_endk)) continue; +#endif /* Report every 64M */ if ((basek % (64*1024)) == 0) { /* Restore the normal state */ @@ -220,6 +248,7 @@ static void init_ecc_memory(unsigned node_id) set_init_ecc_mtrrs(); disable_lapic(); } + limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1); if (limitk > endk) { limitk = endk; @@ -280,7 +309,8 @@ static inline void k8_errata(void) msr = rdmsr(NB_CFG_MSR); msr.lo |= 1 << 3; - if (!is_cpu_pre_c0()) { + if (!is_cpu_pre_c0() && is_cpu_pre_d0()) { + /* D0 later don't need it */ /* Erratum 86 Disable data masking on C0 and * later processor revs. * FIXME this is only needed if ECC is enabled. @@ -289,31 +319,57 @@ static inline void k8_errata(void) } wrmsr(NB_CFG_MSR, msr); } - - /* Erratum 97 ... */ - if (!is_cpu_pre_c0()) { +// AMD_D0_SUPPORT + 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); - } - - /* Erratum 94 ... */ - msr = rdmsr_amd(IC_CFG_MSR); - msr.lo |= 1 << 11; - wrmsr_amd(IC_CFG_MSR, msr); + } + +//AMD_D0_SUPPORT + if(is_cpu_pre_d0()) { + /*D0 later don't need it */ + /* Erratum 94 ... */ + msr = rdmsr_amd(IC_CFG_MSR); + msr.lo |= 1 << 11; + wrmsr_amd(IC_CFG_MSR, msr); + } /* Erratum 91 prefetch miss is handled in the kernel */ + +//AMD_D0_SUPPORT + 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 ...*/ + msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR); + msr.hi |=1; + wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr); + } } void model_fxx_init(device_t dev) { - unsigned long mmio_basek, tomk; unsigned long i; msr_t msr; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; + 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(); @@ -330,14 +386,45 @@ void model_fxx_init(device_t dev) enable_cache(); +#if CONFIG_LOGICAL_CPUS==1 +//AMD_DUAL_CORE_SUPPORT + 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) { + msr = rdmsr_amd(CPU_ID_FEATURES_MSR); + msr.lo |= 1 << 28; + wrmsr_amd(CPU_ID_FEATURES_MSR, msr); + + msr = rdmsr_amd(LOGICAL_CPUS_NUM_MSR); + msr.lo = (siblings+1)<<16; + wrmsr_amd(LOGICAL_CPUS_NUM_MSR, msr); + + msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR); + msr.hi |= 1<<(33-32); + 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? */ - nodeid = lapicid() & 0xf; + if(id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core0 +#else + /* For now there is a 1-1 mapping between node_id and cpu_id */ + nodeid = lapicid() & 0x7; 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 = { @@ -357,7 +444,31 @@ static struct cpu_device_id cpu_table[] = { { X86_VENDOR_AMD, 0xff0 }, { X86_VENDOR_AMD, 0xf82 }, /* CH7-CG */ { X86_VENDOR_AMD, 0xfb2 }, +//AMD_D0_SUPPORT + { X86_VENDOR_AMD, 0x10f50 }, /* SH7-D0 */ + { X86_VENDOR_AMD, 0x10f40 }, + { X86_VENDOR_AMD, 0x10f70 }, + { X86_VENDOR_AMD, 0x10fc0 }, /* DH7-D0 */ + { X86_VENDOR_AMD, 0x10ff0 }, + { X86_VENDOR_AMD, 0x10f80 }, /* CH7-D0 */ + { X86_VENDOR_AMD, 0x10fb0 }, +//AMD_E0_SUPPORT + { X86_VENDOR_AMD, 0x20f50 }, /* SH7-E0*/ + { X86_VENDOR_AMD, 0x20f40 }, + { X86_VENDOR_AMD, 0x20f70 }, + { X86_VENDOR_AMD, 0x20fc0 }, /* DH7-E0 */ /* DH-E3 */ + { X86_VENDOR_AMD, 0x20ff0 }, + { X86_VENDOR_AMD, 0x20f10 }, /* JH7-E0 */ + { X86_VENDOR_AMD, 0x20f30 }, + { X86_VENDOR_AMD, 0x20f51 }, /* SH-E4 */ + { X86_VENDOR_AMD, 0x20f71 }, + { X86_VENDOR_AMD, 0x20f42 }, /* SH-E5 */ + { X86_VENDOR_AMD, 0x20ff2 }, /* DH-E6 */ + { X86_VENDOR_AMD, 0x20fc2 }, + { X86_VENDOR_AMD, 0x20f12 }, /* JH-E6 */ + { X86_VENDOR_AMD, 0x20f32 }, #endif + { 0, 0 }, }; static struct cpu_driver model_fxx __cpu_driver = { diff --git a/src/cpu/amd/model_fxx/model_fxx_msr.h b/src/cpu/amd/model_fxx/model_fxx_msr.h index 930054a9b..c8d57bee1 100644 --- a/src/cpu/amd/model_fxx/model_fxx_msr.h +++ b/src/cpu/amd/model_fxx/model_fxx_msr.h @@ -7,4 +7,14 @@ #define DC_CFG_MSR 0xC0011022 #define BU_CFG_MSR 0xC0011023 + +#define CPU_ID_FEATURES_MSR 0xc0011004 + +/* D0 only */ +#define CPU_ID_HYPER_EXT_FEATURES 0xc001100d +/* E0 only */ +#define LOGICAL_CPUS_NUM_MSR 0xc001100d + +#define CPU_ID_EXT_FEATURES_MSR 0xc0011005 + #endif /* CPU_AMD_MODEL_FXX_MSR_H */ diff --git a/src/cpu/amd/model_fxx/node_id.c b/src/cpu/amd/model_fxx/node_id.c new file mode 100644 index 000000000..190471927 --- /dev/null +++ b/src/cpu/amd/model_fxx/node_id.c @@ -0,0 +1,12 @@ +/* 2004.12 yhlu add dual core support */ + +#include +#include "cpu/amd/model_fxx/model_fxx_msr.h" + +static inline unsigned get_node_id(void) { + unsigned nodeid; + // get the apicid via cpuid(1) ebx[27:24] + nodeid = (cpuid_ebx(1) >> 24) & 0x7; + return nodeid; +} + diff --git a/src/cpu/x86/16bit/reset16.lds b/src/cpu/x86/16bit/reset16.lds index 4c42c76b3..f32597c00 100644 --- a/src/cpu/x86/16bit/reset16.lds +++ b/src/cpu/x86/16bit/reset16.lds @@ -5,7 +5,7 @@ SECTIONS { /* Trigger an error if I have an unuseable start address */ - _ROMTOP = (_start >= 0xffff0000) ? 0xfffffff0 : 0xffffffff8; + _ROMTOP = (_start >= 0xffff0000) ? 0xfffffff0 : 0xfffffff8; . = _ROMTOP; .reset . : { *(.reset) diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index 20615e61c..7c40f6a3c 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -11,6 +11,7 @@ #if CONFIG_SMP == 1 + /* This is a lot more paranoid now, since Linux can NOT handle * being told there is a CPU when none exists. So any errors * will return 0, meaning no CPU. @@ -229,12 +230,16 @@ int start_cpu(device_t cpu) void secondary_cpu_init(void) { atomic_inc(&active_cpus); -#if CONFIG_MAX_CPUS>2 +#if SERIAL_CPU_INIT == 1 + #if CONFIG_MAX_CPUS>2 spin_lock(&start_cpu_lock); + #endif #endif cpu_initialize(); -#if CONFIG_MAX_CPUS>2 +#if SERIAL_CPU_INIT == 1 + #if CONFIG_MAX_CPUS>2 spin_unlock(&start_cpu_lock); + #endif #endif atomic_dec(&active_cpus); stop_this_cpu(); @@ -260,8 +265,10 @@ static void initialize_other_cpus(struct bus *cpu_bus) printk_err("CPU %u would not start!\n", cpu->path.u.apic.apic_id); } -#if CONFIG_MAX_CPUS>2 +#if SERIAL_CPU_INIT == 1 + #if CONFIG_MAX_CPUS>2 udelay(10); + #endif #endif } diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index 1c028a9ea..59f9ca1e9 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -236,8 +236,8 @@ 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") + (type==MTRR_TYPE_UNCACHEABLE) ? "NC" : + ((type==MTRR_TYPE_WRBACK) ? "WB" : "Other") ); set_var_mtrr(reg++, range_startk, sizek, type); range_startk += sizek; diff --git a/src/devices/hypertransport.c b/src/devices/hypertransport.c index 7bc1c215b..80c621ed7 100644 --- a/src/devices/hypertransport.c +++ b/src/devices/hypertransport.c @@ -10,6 +10,10 @@ #define OPT_HT_LINK 0 +#if OPT_HT_LINK == 1 +#include "../northbridge/amd/amdk8/cpu_rev.c" +#endif + static device_t ht_scan_get_devs(device_t *old_devices) { device_t first, last; @@ -47,6 +51,7 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos) } else /* AMD K8 Unsupported 1Ghz? */ if ((dev->vendor == PCI_VENDOR_ID_AMD) && (dev->device == 0x1100)) { + if (is_cpu_pre_e0()) freq_cap &= ~(1 << HT_FREQ_1000Mhz); } return freq_cap; diff --git a/src/drivers/i2c/adm1027/adm1027.c b/src/drivers/i2c/adm1027/adm1027.c index fc8ba732a..6248f95e4 100644 --- a/src/drivers/i2c/adm1027/adm1027.c +++ b/src/drivers/i2c/adm1027/adm1027.c @@ -26,7 +26,7 @@ static void adm1027_enable_monitoring(device_t dev) result = smbus_read_byte(dev, ADM1027_REG_CONFIG1); if(!(result & CFG1_RDY) ) { - printk_debug("ADM1027: monitoring not ready"); + printk_debug("ADM1027: monitoring not ready\r\n"); return; } result = (result | CFG1_STRT); @@ -34,7 +34,7 @@ static void adm1027_enable_monitoring(device_t dev) result = smbus_read_byte(dev, ADM1027_REG_CONFIG1); if (!(result & CFG1_STRT)) { - printk_debug("ADM1027: monitoring would not enable"); + printk_debug("ADM1027: monitoring would not enable\r\n"); } } diff --git a/src/include/cpu/amd/dualcore.h b/src/include/cpu/amd/dualcore.h new file mode 100644 index 000000000..a8c49475e --- /dev/null +++ b/src/include/cpu/amd/dualcore.h @@ -0,0 +1,19 @@ +#ifndef CPU_AMD_DUALCORE_H +#define CPU_AMD_DUALCORE_H + +struct device; +void amd_sibling_init(struct device *cpu); + +int is_e0_later_in_bsp(int nodeid); +unsigned int read_nb_cfg_54(void); + +struct node_core_id { + unsigned nodeid; + unsigned coreid; +}; + +// it can be used to get unitid and coreid it running only +struct node_core_id get_node_core_id(unsigned int nb_cfg_54); +unsigned get_apicid_base(unsigned ioapic_num); + +#endif /* CPU_AMD_DUALCORE_H */ diff --git a/src/lib/malloc.c b/src/lib/malloc.c index bd403e47e..c85345228 100644 --- a/src/lib/malloc.c +++ b/src/lib/malloc.c @@ -39,7 +39,7 @@ void *malloc(size_t size) free_mem_ptr += size; if (free_mem_ptr >= free_mem_end_ptr) - die("Error! malloc: Free_mem_ptr >= free_mem_end_ptr"); + die("Error! malloc: free_mem_ptr >= free_mem_end_ptr"); MALLOCDBG(("malloc 0x%08lx\n", (unsigned long)p)); diff --git a/src/mainboard/Iwill/DK8S2/Options.lb b/src/mainboard/Iwill/DK8S2/Options.lb index 91fb272e8..373d1a98a 100644 --- a/src/mainboard/Iwill/DK8S2/Options.lb +++ b/src/mainboard/Iwill/DK8S2/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -109,6 +110,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/Iwill/DK8X/Options.lb b/src/mainboard/Iwill/DK8X/Options.lb index 2904cccf4..f9987d439 100644 --- a/src/mainboard/Iwill/DK8X/Options.lb +++ b/src/mainboard/Iwill/DK8X/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -109,6 +110,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/amd/quartet/Options.lb b/src/mainboard/amd/quartet/Options.lb index 2de7258e1..052306ae0 100644 --- a/src/mainboard/amd/quartet/Options.lb +++ b/src/mainboard/amd/quartet/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -108,6 +109,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=4 +default CONFIG_MAX_PHYSICAL_CPUS=4 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/amd/serenade/Options.lb b/src/mainboard/amd/serenade/Options.lb index 37fd3ea50..11bc28b23 100644 --- a/src/mainboard/amd/serenade/Options.lb +++ b/src/mainboard/amd/serenade/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -107,6 +108,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/amd/solo/Options.lb b/src/mainboard/amd/solo/Options.lb index 6051cb0a2..eec85778d 100644 --- a/src/mainboard/amd/solo/Options.lb +++ b/src/mainboard/amd/solo/Options.lb @@ -10,6 +10,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -109,6 +110,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=1 +default CONFIG_MAX_PHYSICAL_CPUS=1 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/arima/hdama/Options.lb b/src/mainboard/arima/hdama/Options.lb index f669ba9ec..091f792e3 100644 --- a/src/mainboard/arima/hdama/Options.lb +++ b/src/mainboard/arima/hdama/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -111,6 +112,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/ibm/e325/Options.lb b/src/mainboard/ibm/e325/Options.lb index 9e46555e6..74f74a787 100644 --- a/src/mainboard/ibm/e325/Options.lb +++ b/src/mainboard/ibm/e325/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -108,6 +109,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=1 +default CONFIG_MAX_PHYSICAL_CPUS=1 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/island/aruma/Options.lb b/src/mainboard/island/aruma/Options.lb index 87441d07e..4e2cef1ff 100644 --- a/src/mainboard/island/aruma/Options.lb +++ b/src/mainboard/island/aruma/Options.lb @@ -10,6 +10,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -116,6 +117,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=4 +default CONFIG_MAX_PHYSICAL_CPUS=4 #default ALLOW_HT_OVERCLOCKING=1 ## diff --git a/src/mainboard/newisys/khepri/Options.lb b/src/mainboard/newisys/khepri/Options.lb index a7f8f61e6..c975e08c8 100644 --- a/src/mainboard/newisys/khepri/Options.lb +++ b/src/mainboard/newisys/khepri/Options.lb @@ -9,6 +9,7 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -107,6 +108,7 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/tyan/s2850/Options.lb b/src/mainboard/tyan/s2850/Options.lb index b9f488f19..c82909872 100644 --- a/src/mainboard/tyan/s2850/Options.lb +++ b/src/mainboard/tyan/s2850/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -53,6 +55,7 @@ uses OBJCOPY uses CONFIG_CHIP_NAME uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -115,6 +118,11 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=1 +default CONFIG_MAX_PHYSICAL_CPUS=1 +default CONFIG_LOGICAL_CPUS=0 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 #BTEXT CONSOLE #default CONFIG_CONSOLE_BTEXT=1 @@ -221,9 +229,9 @@ default TTYS0_LCS=0x3 ## SPEW 9 Way too many details ## Request this level of debugging output -default DEFAULT_CONSOLE_LOGLEVEL=8 +default DEFAULT_CONSOLE_LOGLEVEL=7 ## At a maximum only compile in this level of debugging -default MAXIMUM_CONSOLE_LOGLEVEL=8 +default MAXIMUM_CONSOLE_LOGLEVEL=7 ## ## Select power on after power fail setting diff --git a/src/mainboard/tyan/s2850/auto.c b/src/mainboard/tyan/s2850/auto.c index 93578dac6..9220738d8 100644 --- a/src/mainboard/tyan/s2850/auto.c +++ b/src/mainboard/tyan/s2850/auto.c @@ -42,12 +42,6 @@ static void soft_reset(void) pci_write_config8(PCI_DEV(0, 0x02, 0), 0x47, 1); } -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(PCI_DEV(1, 0x02, 0), 0x47, 1); -} - #define REV_B_RESET 0 static void memreset_setup(void) { @@ -69,38 +63,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } - -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 */ - - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -111,12 +73,16 @@ static inline int spd_read_byte(unsigned device, unsigned address) return smbus_read_byte(device, address); } -//#include "northbridge/amd/amdk8/setup_resource_map.c" +#include "northbridge/amd/amdk8/setup_resource_map.c" #include "northbridge/amd/amdk8/raminit.c" #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" #include "northbridge/amd/amdk8/resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif static void main(unsigned long bist) { @@ -137,22 +103,48 @@ static void main(unsigned long bist) }; int needs_reset; - unsigned nodeid; + +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); - - nodeid = lapicid() & 0xf; + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); - } - } +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); @@ -163,50 +155,17 @@ static void main(unsigned long bist) setup_default_resource_map(); needs_reset = setup_coherent_ht_domain(); +#if CONFIG_LOGICAL_CPUS==1 + start_other_cores(); +#endif needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0x80); if (needs_reset) { print_info("ht reset -\r\n"); soft_reset(); } -#if 0 - print_pci_devices(); -#endif enable_smbus(); -#if 0 -// dump_spd_registers(&cpu[0]); - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu) / sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x01000000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x81000000); -#endif -#endif -*/ } diff --git a/src/mainboard/tyan/s2850/cmos.layout b/src/mainboard/tyan/s2850/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s2850/cmos.layout +++ b/src/mainboard/tyan/s2850/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s2850/failover.c b/src/mainboard/tyan/s2850/failover.c index e6ecb65c4..fee04156a 100644 --- a/src/mainboard/tyan/s2850/failover.c +++ b/src/mainboard/tyan/s2850/failover.c @@ -11,16 +11,31 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ - unsigned nodeid; - /* Make cerain my local apic is useable */ - enable_lapic(); - - nodeid = lapicid() & 0xf; +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ + enable_lapic(); + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { if (last_boot_normal()) { goto normal_image; } else { diff --git a/src/mainboard/tyan/s2850/mptable.c b/src/mainboard/tyan/s2850/mptable.c index f4795be6d..6a28ecbe7 100644 --- a/src/mainboard/tyan/s2850/mptable.c +++ b/src/mainboard/tyan/s2850/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -14,6 +17,8 @@ void *smp_write_config_table(void *v) unsigned char bus_num; unsigned char bus_isa; unsigned char bus_8111_1; + unsigned apicid_base; + unsigned apicid_8111; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); @@ -59,77 +64,84 @@ void *smp_write_config_table(void *v) /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 1, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(1); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ - smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x1, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x1, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x1, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x1, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x1, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x1, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x1, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x1, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x1, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x1, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x1, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x1, 0xf); - - - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (2<<2)|3, 0x1, 0x13); + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + 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); //On Board AMD USB - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, 0x1, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); //On Board ATI Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, 0x1, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, apicid_8111, 0x12); //Onboard Broadcom 5705 NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0d<<2)|0, 0x1, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0e<<2)|0, 0x1, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0d<<2)|0, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0e<<2)|0, apicid_8111, 0x10); //Onboard SI Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0c<<2)|0, 0x1, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0c<<2)|0, apicid_8111, 0x11); //PCI Slot 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|0, 0x1, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|1, 0x1, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|2, 0x1, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|3, 0x1, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|2, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|3, apicid_8111, 0x13); //PCI Slot 2 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|0, 0x1, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|1, 0x1, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|2, 0x1, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|3, 0x1, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|0, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|1, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|2, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|3, apicid_8111, 0x10); //PCI Slot 3 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|0, 0x1, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|1, 0x1, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|2, 0x1, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|3, 0x1, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|0, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|1, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|2, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|3, apicid_8111, 0x11); //PCI Slot 4 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|0, 0x1, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|1, 0x1, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|2, 0x1, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|3, 0x1, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|0, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|1, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|2, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|3, apicid_8111, 0x12); //PCI Slot 5 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|0, 0x1, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|1, 0x1, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|2, 0x1, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|3, 0x1, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|2, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|3, apicid_8111, 0x13); //PCI Slot 6 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, 0x1, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|1, 0x1, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|2, 0x1, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|3, 0x1, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|1, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|2, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|3, apicid_8111, 0x10); /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); diff --git a/src/mainboard/tyan/s2875/Options.lb b/src/mainboard/tyan/s2875/Options.lb index eb9cfd6ec..d1e22c006 100644 --- a/src/mainboard/tyan/s2875/Options.lb +++ b/src/mainboard/tyan/s2875/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -50,6 +52,9 @@ uses CC uses HOSTCC uses OBJCOPY uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -112,6 +117,15 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 +default CONFIG_LOGICAL_CPUS=0 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=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 6bbdaa9a4..1b055bf2e 100644 --- a/src/mainboard/tyan/s2875/auto.c +++ b/src/mainboard/tyan/s2875/auto.c @@ -43,12 +43,6 @@ static void soft_reset(void) pci_write_config8(PCI_DEV(0, 0x05, 0), 0x47, 1); } -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(PCI_DEV(1, 0x05, 0), 0x47, 1); -} - static void memreset_setup(void) { if (is_cpu_pre_c0()) { @@ -69,54 +63,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -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) (L1) (L0) - CPU1-------------CPU0--------8151---------8111 -*/ - /* Link1 of CPU0 to Link1 of CPU1 */ - static const unsigned int rows_2p[2][2] = { - { 0x00050101, 0x00010404 }, - { 0x00010404, 0x00050101 } - }; - - if(maxnodes>2) { - print_debug("this mainboard is only designed for 2 cpus\r\n"); - maxnodes=2; - } - - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_2p[node][row]; - } - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -128,12 +74,17 @@ static inline int spd_read_byte(unsigned device, unsigned address) } -//#include "northbridge/amd/amdk8/setup_resource_map.c" +#include "northbridge/amd/amdk8/setup_resource_map.c" #include "northbridge/amd/amdk8/raminit.c" #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" #include "northbridge/amd/amdk8/resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif + #define FIRST_CPU 1 #define SECOND_CPU 1 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) @@ -165,80 +116,70 @@ static void main(unsigned long bist) }; int needs_reset; - unsigned nodeid; + +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); - - nodeid = lapicid() & 0xf; +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); - } - } - +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } + w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); /* Halt if there was a built in self test failure */ -// report_bist_failure(bist); + report_bist_failure(bist); setup_default_resource_map(); needs_reset = setup_coherent_ht_domain(); + +#if CONFIG_LOGICAL_CPUS==1 + start_other_cores(); +#endif needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0x80); if (needs_reset) { print_info("ht reset -\r\n"); soft_reset(); } -#if 0 - dump_pci_devices(); -#endif -#if 0 - print_pci_devices(); -#endif enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x00100000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x80100000); -#endif -#endif -*/ } diff --git a/src/mainboard/tyan/s2875/cmos.layout b/src/mainboard/tyan/s2875/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s2875/cmos.layout +++ b/src/mainboard/tyan/s2875/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s2875/failover.c b/src/mainboard/tyan/s2875/failover.c index e6ecb65c4..a993aedb8 100644 --- a/src/mainboard/tyan/s2875/failover.c +++ b/src/mainboard/tyan/s2875/failover.c @@ -11,16 +11,30 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ - unsigned nodeid; - /* Make cerain my local apic is useable */ - enable_lapic(); - - nodeid = lapicid() & 0xf; - - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ + enable_lapic(); + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { diff --git a/src/mainboard/tyan/s2875/mptable.c b/src/mainboard/tyan/s2875/mptable.c index 82569c931..9b93decd8 100644 --- a/src/mainboard/tyan/s2875/mptable.c +++ b/src/mainboard/tyan/s2875/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -15,7 +18,8 @@ void *smp_write_config_table(void *v) unsigned char bus_isa; unsigned char bus_8111_1; unsigned char bus_8151_1; - + unsigned apicid_base; + unsigned apicid_8111; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); @@ -36,7 +40,7 @@ void *smp_write_config_table(void *v) smp_write_processors(mc); - { + { device_t dev; /* 8111 */ @@ -69,8 +73,6 @@ void *smp_write_config_table(void *v) } - - /*Bus: Bus ID Type*/ /* define bus and isa numbers */ for(bus_num = 0; bus_num < bus_isa; bus_num++) { @@ -79,75 +81,81 @@ void *smp_write_config_table(void *v) smp_write_bus(mc, bus_isa, "ISA "); /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 2, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(1); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# -*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x2, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x2, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x2, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x2, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x2, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x2, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x2, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x2, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x2, 0xf); +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); //??? What - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (5<<2)|3, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (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, 0x2, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (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, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); // AGP Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8151_1, 0x0, 0x2, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8151_1, 0x0, apicid_8111, 0x10); // Onboard Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x05<<2)|0, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x05<<2)|0, apicid_8111, 0x13); //Onboard Firewire - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, 0x2, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, apicid_8111, 0x11); //Onboard Broadcom NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|0, 0x2, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x03<<2)|0, apicid_8111, 0x12); //Onboard VIA USB 1.1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|1, 0x2, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|2, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|1, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|2, apicid_8111, 0x13); //Slot 1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|0, 0x2, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|1, 0x2, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|2, 0x2, 0x10); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|3, 0x2, 0x11); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|0, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|1, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|2, apicid_8111, 0x10); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x06<<2)|3, apicid_8111, 0x11); // //Slot 2 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|0, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|1, 0x2, 0x12); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|2, 0x2, 0x13); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|3, 0x2, 0x10); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|0, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|1, apicid_8111, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|2, apicid_8111, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x08<<2)|3, apicid_8111, 0x10); // //Slot 3 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|0, 0x2, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|1, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|2, 0x2, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|3, 0x2, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x09<<2)|3, apicid_8111, 0x13); // //Slot 4 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|0, 0x2, 0x13); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|1, 0x2, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|2, 0x2, 0x11); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|3, 0x2, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|0, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|1, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|2, apicid_8111, 0x11); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x07<<2)|3, apicid_8111, 0x12); // //Slot 5 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|0, 0x2, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|1, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|2, 0x2, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|3, 0x2, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x04<<2)|3, apicid_8111, 0x13); // diff --git a/src/mainboard/tyan/s2880/Config.lb b/src/mainboard/tyan/s2880/Config.lb index 6c4ac7b7c..f82bd23b4 100644 --- a/src/mainboard/tyan/s2880/Config.lb +++ b/src/mainboard/tyan/s2880/Config.lb @@ -143,11 +143,11 @@ chip northbridge/amd/amdk8/root_complex device pci 9.0 on end #broadcom device pci 9.1 on end end -# chip drivers/lsi/53c1030 -# device pci a.0 on end -# device pci a.1 on end -# register "fw_address" = "0xfff8c000" -# end + chip drivers/lsi/53c1030 + device pci a.0 on end + device pci a.1 on end + register "fw_address" = "0xfff8c000" + end end device pci 0.1 on end device pci 1.0 on end diff --git a/src/mainboard/tyan/s2880/Options.lb b/src/mainboard/tyan/s2880/Options.lb index 2fd9dfbf5..af9aea7b3 100644 --- a/src/mainboard/tyan/s2880/Options.lb +++ b/src/mainboard/tyan/s2880/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -50,6 +52,9 @@ uses CC uses HOSTCC uses OBJCOPY uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -112,6 +117,15 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 +default CONFIG_LOGICAL_CPUS=0 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/tyan/s2880/auto.c b/src/mainboard/tyan/s2880/auto.c index 6384f4d15..1ed43bc19 100644 --- a/src/mainboard/tyan/s2880/auto.c +++ b/src/mainboard/tyan/s2880/auto.c @@ -42,11 +42,6 @@ static void soft_reset(void) set_bios_reset(); pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); } -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(PCI_DEV(3, 0x04, 0), 0x47, 1); -} static void memreset_setup(void) { @@ -68,50 +63,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -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 */ - /* Link1 of CPU0 to Link1 of CPU1 */ - static const unsigned int rows_2p[2][2] = { - { 0x00050101, 0x00010404 }, - { 0x00010404, 0x00050101 } - }; - - if(maxnodes>2) { - print_debug("this mainboard is only designed for 2 cpus\r\n"); - maxnodes=2; - } - - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_2p[node][row]; - } - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -123,13 +74,18 @@ static inline int spd_read_byte(unsigned device, unsigned address) } -//#include "northbridge/amd/amdk8/setup_resource_map.c" +#include "northbridge/amd/amdk8/setup_resource_map.c" #include "northbridge/amd/amdk8/raminit.c" #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" #include "northbridge/amd/amdk8/resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif + #define FIRST_CPU 1 #define SECOND_CPU 1 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) @@ -160,77 +116,71 @@ static void main(unsigned long bist) #endif }; int needs_reset; - unsigned nodeid; + +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); - - nodeid = lapicid() & 0xf; +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); - } - } +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); /* Halt if there was a built in self test failure */ -// report_bist_failure(bist); + report_bist_failure(bist); setup_default_resource_map(); needs_reset = setup_coherent_ht_domain(); + +#if CONFIG_LOGICAL_CPUS==1 + start_other_cores(); +#endif + needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0x80); if (needs_reset) { print_info("ht reset -\r\n"); soft_reset(); } -#if 0 - print_pci_devices(); -#endif enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x01000000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x81000000); -#endif -#endif -*/ } diff --git a/src/mainboard/tyan/s2880/cmos.layout b/src/mainboard/tyan/s2880/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s2880/cmos.layout +++ b/src/mainboard/tyan/s2880/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s2880/failover.c b/src/mainboard/tyan/s2880/failover.c index e68164db7..9164e7b09 100644 --- a/src/mainboard/tyan/s2880/failover.c +++ b/src/mainboard/tyan/s2880/failover.c @@ -11,17 +11,30 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ - unsigned nodeid; - - /* Make cerain my local apic is useable */ - enable_lapic(); - - nodeid = lapicid() & 0xf; - - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ + enable_lapic(); + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { @@ -36,7 +49,6 @@ static unsigned long main(unsigned long bist) goto fallback_image; } } - /* Nothing special needs to be done to find bus 0 */ /* Allow the HT devices to be found */ diff --git a/src/mainboard/tyan/s2880/irq_tables.c b/src/mainboard/tyan/s2880/irq_tables.c index 2b1b5ce34..92a5198e2 100644 --- a/src/mainboard/tyan/s2880/irq_tables.c +++ b/src/mainboard/tyan/s2880/irq_tables.c @@ -18,7 +18,7 @@ const struct irq_routing_table intel_irq_routing_table = { 0x746b, /* Device */ 0, /* Crap (miniport) */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ - 0x37, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */ + 0x59, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (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}, diff --git a/src/mainboard/tyan/s2880/mptable.c b/src/mainboard/tyan/s2880/mptable.c index 46cad33d4..9c4764a77 100644 --- a/src/mainboard/tyan/s2880/mptable.c +++ b/src/mainboard/tyan/s2880/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -16,6 +19,10 @@ void *smp_write_config_table(void *v) unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; + unsigned apicid_base; + unsigned apicid_8111; + unsigned apicid_8131_1; + unsigned apicid_8131_2; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); @@ -36,7 +43,6 @@ void *smp_write_config_table(void *v) smp_write_processors(mc); - { device_t dev; @@ -86,7 +92,15 @@ void *smp_write_config_table(void *v) /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 2, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); { device_t dev; @@ -95,81 +109,81 @@ void *smp_write_config_table(void *v) if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x03, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x04, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# -*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x2, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x2, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x2, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x2, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x2, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x2, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x2, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x2, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x2, 0xf); +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + 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, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (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, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); //On Board ATI Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, 0x2, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, apicid_8111, 0x12); //Slot 5 PCI 32 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, 0x2, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, 0x2, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, 0x2, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, apicid_8111, 0x13); // //On Board Promise Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, 0x2, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, apicid_8111, 0x11); //Slot 3 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, 0x3, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, 0x3, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, 0x3, 0x2);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x2);// //Slot 4 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|0, 0x3, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|1, 0x3, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|2, 0x3, 0x0);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|3, 0x3, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|0, apicid_8131_1, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|1, apicid_8131_1, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|2, apicid_8131_1, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|3, apicid_8131_1, 0x1);// //On Board NIC and LSI scsi - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, 0x3, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, 0x3, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, apicid_8131_1, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, apicid_8131_1, 0x1); //Slot 1 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, 0x4, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, 0x4, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, 0x4, 0x3); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<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)|2, apicid_8131_2, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); // //Slot 2 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, 0x4, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|2, 0x4, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|3, 0x4, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|2, apicid_8131_2, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|3, apicid_8131_2, 0x0);// /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); diff --git a/src/mainboard/tyan/s2881/Config.lb b/src/mainboard/tyan/s2881/Config.lb index ba28422aa..47ab2df45 100644 --- a/src/mainboard/tyan/s2881/Config.lb +++ b/src/mainboard/tyan/s2881/Config.lb @@ -215,42 +215,42 @@ chip northbridge/amd/amdk8/root_complex 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 -# chip drivers/i2c/adm1027 # ADT7463A CPU0/1 temp, CPU1 vid, SYS FAN 1/2/3 -# device i2c 2d on end -# end -# chip drivers/generic/generic # Winbond HWM 0x54 CPU0/1 VRM temp, SYSFAN 4,CPU0 vid, CPU0/1 FAN -# device i2c 2a on end -# end -# chip drivers/generic/generic # Winbond HWM 0x92 -# device i2c 49 on end -# end -# chip drivers/generic/generic # Winbond HWM 0x94 -# device i2c 4a on end -# end + 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 + chip drivers/i2c/adm1027 # ADT7463A CPU0/1 temp, CPU1 vid, SYS FAN 1/2/3 + device i2c 2d on end + end + chip drivers/generic/generic # Winbond HWM 0x54 CPU0/1 VRM temp, SYSFAN 4,CPU0 vid, CPU0/1 FAN + device i2c 2a on end + end + chip drivers/generic/generic # Winbond HWM 0x92 + device i2c 49 on end + end + chip drivers/generic/generic # Winbond HWM 0x94 + device i2c 4a on end + end end # acpi device pci 1.5 off end device pci 1.6 off end diff --git a/src/mainboard/tyan/s2881/Options.lb b/src/mainboard/tyan/s2881/Options.lb index c0d4ede89..a1c7b4e32 100644 --- a/src/mainboard/tyan/s2881/Options.lb +++ b/src/mainboard/tyan/s2881/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -50,6 +52,9 @@ uses CC uses HOSTCC uses OBJCOPY uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -112,6 +117,15 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=2 +default CONFIG_MAX_PHYSICAL_CPUS=2 +default CONFIG_LOGICAL_CPUS=0 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/tyan/s2881/auto.c b/src/mainboard/tyan/s2881/auto.c index e1161ac9a..391be7887 100644 --- a/src/mainboard/tyan/s2881/auto.c +++ b/src/mainboard/tyan/s2881/auto.c @@ -43,12 +43,6 @@ static void soft_reset(void) pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); } -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(PCI_DEV(3, 0x04, 0), 0x47, 1); -} - static void memreset_setup(void) { if (is_cpu_pre_c0()) { @@ -69,50 +63,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -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 */ - /* Link0 of CPU0 to Link0 of CPU1 */ - static const unsigned int rows_2p[2][2] = { - { 0x00030101, 0x00010202 }, - { 0x00010202, 0x00030101 } - }; - - if(maxnodes>2) { - print_debug("this mainboard is only designed for 2 cpus\r\n"); - maxnodes=2; - } - - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_2p[node][row]; - } - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -124,6 +74,7 @@ static inline int spd_read_byte(unsigned device, unsigned address) } //#include "northbridge/amd/amdk8/setup_resource_map.c" +#define K8_4RANK_DIMM_SUPPORT 1 #include "northbridge/amd/amdk8/raminit.c" #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" @@ -131,6 +82,11 @@ static inline int spd_read_byte(unsigned device, unsigned address) /* tyan does not want the default */ #include "resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif + #define FIRST_CPU 1 #define SECOND_CPU 1 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) @@ -161,77 +117,69 @@ static void main(unsigned long bist) #endif }; int needs_reset; - unsigned nodeid; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); - nodeid = lapicid() & 0xf; - +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); - } - } - +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } + w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); /* Halt if there was a built in self test failure */ -// report_bist_failure(bist); +// report_bist_failure(bist); setup_s2881_resource_map(); needs_reset = setup_coherent_ht_domain(); - needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0); +#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"); soft_reset(); } -#if 0 - print_pci_devices(); -#endif enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x01000000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x81000000); -#endif -#endif -*/ } diff --git a/src/mainboard/tyan/s2881/cmos.layout b/src/mainboard/tyan/s2881/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s2881/cmos.layout +++ b/src/mainboard/tyan/s2881/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s2881/failover.c b/src/mainboard/tyan/s2881/failover.c index 780b3052e..a993aedb8 100644 --- a/src/mainboard/tyan/s2881/failover.c +++ b/src/mainboard/tyan/s2881/failover.c @@ -11,16 +11,30 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ - unsigned nodeid; - /* Make cerain my local apic is useable */ - enable_lapic(); - - nodeid = lapicid() & 0xf; - - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ + enable_lapic(); + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { diff --git a/src/mainboard/tyan/s2881/mptable.c b/src/mainboard/tyan/s2881/mptable.c index 67c19c8e3..06f1301ee 100644 --- a/src/mainboard/tyan/s2881/mptable.c +++ b/src/mainboard/tyan/s2881/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -16,6 +19,10 @@ void *smp_write_config_table(void *v) unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; + unsigned apicid_base; + unsigned apicid_8111; + unsigned apicid_8131_1; + unsigned apicid_8131_2; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); @@ -86,7 +93,16 @@ void *smp_write_config_table(void *v) /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 2, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; + + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); { device_t dev; struct resource *res; @@ -94,63 +110,63 @@ void *smp_write_config_table(void *v) if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x03, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x04, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# -*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x2, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x2, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x2, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x2, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x2, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x2, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x2, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x2, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x2, 0xf); +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + 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, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (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, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); //On Board ATI Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, 0x2, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, apicid_8111, 0x12); //On Board SI Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, 0x2, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, apicid_8111, 0x11); //Slot 3 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, 0x3, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, 0x3, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, 0x3, 0x2);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x2);// //On Board NIC and adaptec scsi - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, 0x3, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, 0x3, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, apicid_8131_1, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, apicid_8131_1, 0x1); //Slot 1 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, 0x4, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, 0x4, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, 0x4, 0x3); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<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)|2, apicid_8131_2, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); // /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ diff --git a/src/mainboard/tyan/s2881/resourcemap.c b/src/mainboard/tyan/s2881/resourcemap.c index 7119c4a55..22723eafa 100644 --- a/src/mainboard/tyan/s2881/resourcemap.c +++ b/src/mainboard/tyan/s2881/resourcemap.c @@ -252,8 +252,8 @@ static void setup_s2881_resource_map(void) * [31:24] Bus Number Limit i * This field defines the highest bus number in configuration regin i */ - PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000203, - PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000, +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000203, +// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000, }; diff --git a/src/mainboard/tyan/s2882/Options.lb b/src/mainboard/tyan/s2882/Options.lb index 5d7ac25ed..4f084c86b 100644 --- a/src/mainboard/tyan/s2882/Options.lb +++ b/src/mainboard/tyan/s2882/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -50,6 +52,9 @@ uses CC uses HOSTCC uses OBJCOPY uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -111,7 +116,16 @@ 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=1 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 ## ## Build code to setup a generic IOAPIC @@ -211,7 +225,7 @@ 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=8 diff --git a/src/mainboard/tyan/s2882/auto.c b/src/mainboard/tyan/s2882/auto.c index db50fde65..fb7a63abb 100644 --- a/src/mainboard/tyan/s2882/auto.c +++ b/src/mainboard/tyan/s2882/auto.c @@ -43,13 +43,6 @@ static void soft_reset(void) pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); } -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(PCI_DEV(1, 0x04, 0), 0x47, 1); -} - - #define REV_B_RESET 0 static void memreset_setup(void) { @@ -72,50 +65,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } -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 */ - /* Link1 of CPU0 to Link1 of CPU1 */ - static const unsigned int rows_2p[2][2] = { - { 0x00050101, 0x00010404 }, - { 0x00010404, 0x00050101 } - }; -#if 0 - if(maxnodes>2) { - printo_debug("this mainboard is only designed for 2 cpus\r\n"); - maxnodes=2; - } -#endif - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_2p[node][row]; - } - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -126,11 +75,17 @@ static inline int spd_read_byte(unsigned device, unsigned address) return smbus_read_byte(device, address); } +#include "northbridge/amd/amdk8/setup_resource_map.c" +#define K8_4RANK_DIMM_SUPPORT 1 #include "northbridge/amd/amdk8/raminit.c" +#include "northbridge/amd/amdk8/resourcemap.c" #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" -#include "northbridge/amd/amdk8/resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif #define FIRST_CPU 1 #define SECOND_CPU 1 @@ -167,22 +122,45 @@ static void main(unsigned long bist) }; int needs_reset; - unsigned nodeid; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); - nodeid = lapicid() & 0xf; - +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); } } @@ -191,54 +169,22 @@ 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_default_resource_map(); needs_reset = setup_coherent_ht_domain(); - needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0x80); +#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"); soft_reset(); } -#if 0 - print_pci_devices(); -#endif enable_smbus(); -#if 0 -// dump_spd_registers(&cpu[0]); - dump_smbus_registers(); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x01000000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x81000000); -#endif -#endif -*/ } diff --git a/src/mainboard/tyan/s2882/cmos.layout b/src/mainboard/tyan/s2882/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s2882/cmos.layout +++ b/src/mainboard/tyan/s2882/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s2882/failover.c b/src/mainboard/tyan/s2882/failover.c index 45315521a..9164e7b09 100644 --- a/src/mainboard/tyan/s2882/failover.c +++ b/src/mainboard/tyan/s2882/failover.c @@ -11,16 +11,30 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif /* Make cerain my local apic is useable */ enable_lapic(); - - nodeid = lapicid() & 0xf; - - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { @@ -35,7 +49,6 @@ static unsigned long main(unsigned long bist) goto fallback_image; } } - /* Nothing special needs to be done to find bus 0 */ /* Allow the HT devices to be found */ diff --git a/src/mainboard/tyan/s2882/mptable.c b/src/mainboard/tyan/s2882/mptable.c index 4bf298923..a331247fa 100644 --- a/src/mainboard/tyan/s2882/mptable.c +++ b/src/mainboard/tyan/s2882/mptable.c @@ -4,6 +4,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif #define ASSIGN_IRQ 0 @@ -19,8 +22,12 @@ void *smp_write_config_table(void *v) unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; - - mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + unsigned apicid_base; + unsigned apicid_8111; + unsigned apicid_8131_1; + unsigned apicid_8131_2; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); memcpy(mc->mpc_signature, sig, sizeof(sig)); @@ -86,7 +93,16 @@ void *smp_write_config_table(void *v) /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 2, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; + + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); { device_t dev; struct resource *res; @@ -94,35 +110,35 @@ void *smp_write_config_table(void *v) if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x03, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x04, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ - smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x2, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x2, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x2, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x2, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x2, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x2, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x2, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x2, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x2, 0xf); + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); #if ASSIGN_IRQ - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (4<<2)|3, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, (4<<2)|3, apicid_8111, 0x13); { device_t dev; @@ -148,7 +164,7 @@ void *smp_write_config_table(void *v) #endif //On Board AMD USB - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); #if ASSIGN_IRQ printk_info("setting Onboard AMD USB \n"); @@ -157,7 +173,7 @@ void *smp_write_config_table(void *v) #endif //On Board ATI Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, 0x2, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, apicid_8111, 0x12); #if ASSIGN_IRQ printk_info("setting Onboard ATI Display Adapter\n"); @@ -167,10 +183,10 @@ void *smp_write_config_table(void *v) #if 1 //Slot 5 PCI 32 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, 0x2, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, 0x2, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, 0x2, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, apicid_8111, 0x13); // #if ASSIGN_IRQ printk_info("setting Slot 5 \n"); @@ -180,7 +196,7 @@ void *smp_write_config_table(void *v) #endif //Onboard SI Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, apicid_8111, 0x13); #if ASSIGN_IRQ printk_info("setting Onboard SI Serail ATA\n"); @@ -189,7 +205,7 @@ void *smp_write_config_table(void *v) #endif //Onboard Intel 82551 10/100M NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (8<<2)|0, 0x2, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (8<<2)|0, apicid_8111, 0x12); #if ASSIGN_IRQ printk_info("setting Onboard Intel NIC\n"); @@ -199,10 +215,10 @@ void *smp_write_config_table(void *v) #if 1 //Slot 3 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, 0x3, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|2, 0x3, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|3, 0x3, 0x2);// + 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); + 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);// #if ASSIGN_IRQ printk_info("setting Slot 3\n"); @@ -211,10 +227,10 @@ void *smp_write_config_table(void *v) #endif //Slot 4 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, 0x3, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|1, 0x3, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, 0x3, 0x0);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|3, 0x3, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); + 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)|3, apicid_8131_1, 0x1);// #if ASSIGN_IRQ printk_info("setting Slot 4\n"); @@ -224,8 +240,8 @@ void *smp_write_config_table(void *v) #endif //Onboard adaptec scsi - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (6<<2)|0, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (6<<2)|1, 0x3, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (6<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (6<<2)|1, apicid_8131_1, 0x1); #if ASSIGN_IRQ printk_info("setting Onboard Adaptec SCSI\n"); @@ -234,8 +250,8 @@ void *smp_write_config_table(void *v) #endif //On Board NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, 0x3, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, apicid_8131_1, 0x1); #if ASSIGN_IRQ @@ -246,10 +262,10 @@ void *smp_write_config_table(void *v) #if 1 //Slot 1 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, 0x4, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, 0x4, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, 0x4, 0x3); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<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)|2, apicid_8131_2, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); // #if ASSIGN_IRQ printk_info("setting Slot 1\n"); @@ -258,10 +274,10 @@ void *smp_write_config_table(void *v) #endif //Slot 2 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, 0x4, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, 0x4, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, 0x4, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, apicid_8131_2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, apicid_8131_2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, apicid_8131_2, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, apicid_8131_2, 0x0);// #if ASSIGN_IRQ printk_info("setting Slot 2\n"); diff --git a/src/mainboard/tyan/s2885/Options.lb b/src/mainboard/tyan/s2885/Options.lb index b4d0bd25d..74aaedbe6 100644 --- a/src/mainboard/tyan/s2885/Options.lb +++ b/src/mainboard/tyan/s2885/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -53,6 +55,7 @@ uses OBJCOPY uses CONFIG_CHIP_NAME uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -66,7 +69,7 @@ default ROM_SIZE=524288 ## ## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use ## -default FALLBACK_SIZE=262144 +default FALLBACK_SIZE=131072 ## ## Build code for the fallback boot @@ -114,17 +117,25 @@ 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=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 ## ## Build code to setup a generic IOAPIC ## default CONFIG_IOAPIC=1 -#VGA -default CONFIG_CONSOLE_VGA=1 -default CONFIG_PCI_ROM_RUN=1 - ## ## Clean up the motherboard id strings ## diff --git a/src/mainboard/tyan/s2885/auto.c b/src/mainboard/tyan/s2885/auto.c index aacb4b007..cff103b9c 100644 --- a/src/mainboard/tyan/s2885/auto.c +++ b/src/mainboard/tyan/s2885/auto.c @@ -6,13 +6,11 @@ #include #include #include -#include #include "option_table.h" #include "pc80/mc146818rtc_early.c" #include "pc80/serial.c" #include "arch/i386/lib/console.c" #include "ram/ramtest.c" -#include "northbridge/amd/amdk8/incoherent_ht.c" #include "southbridge/amd/amd8111/amd8111_early_smbus.c" #include "northbridge/amd/amdk8/raminit.h" #include "cpu/amd/model_fxx/apic_timer.c" @@ -20,6 +18,7 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" #include "northbridge/amd/amdk8/debug.c" +#include "northbridge/amd/amdk8/incoherent_ht.c" #include "northbridge/amd/amdk8/cpu_rev.c" #include "superio/winbond/w83627hf/w83627hf_early_serial.c" #include "cpu/amd/mtrr/amd_earlymtrr.c" @@ -43,17 +42,6 @@ static void soft_reset(void) pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); } -#define AMD8111_RESET PCI_DEV( \ - HARD_RESET_BUS, \ - HARD_RESET_DEVICE, \ - HARD_RESET_FUNCTION) - -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(AMD8111_RESET, 0x47, 1); -} - static void memreset_setup(void) { if (is_cpu_pre_c0()) { @@ -74,61 +62,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -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) (L1) (L2) - CPU1-------------CPU0--------8131------8111 - |(L0) - | - | - | - | - | - 8151 -*/ - /* Link1 of CPU0 to Link1 of CPU1 */ - static const unsigned int rows_2p[2][2] = { - { 0x00050101, 0x00010404 }, - { 0x00010404, 0x00050101 } - }; - - if(maxnodes>2) { - print_debug("this mainboard is only designed for 2 cpus\r\n"); - maxnodes=2; - } - - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_2p[node][row]; - } - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { /* nothing to do */ @@ -140,16 +73,33 @@ static inline int spd_read_byte(unsigned device, unsigned address) } //#include "northbridge/amd/amdk8/setup_resource_map.c" +#define K8_4RANK_DIMM_SUPPORT 1 #include "northbridge/amd/amdk8/raminit.c" + +#if 0 + #define ENABLE_APIC_EXT_ID 1 + #define APIC_ID_OFFSET 0x10 + #define LIFT_BSP_APIC_ID 0 +#else + #define ENABLE_APIC_EXT_ID 0 +#endif #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" /* tyan does not want the default */ #include "resourcemap.c" +#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 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) + static void main(unsigned long bist) { static const struct mem_controller cpu[] = { @@ -178,22 +128,71 @@ static void main(unsigned long bist) }; int needs_reset; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); + + 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); + } + #endif +#else + nodeid = get_node_id(); + #if ENABLE_APIC_EXT_ID == 1 + enable_apic_ext_id(nodeid); + #endif +#endif + enable_lapic(); init_timer(); - nodeid = lapicid() & 0xf; - - if (cpu_init_detected(nodeid)) { - asm volatile ("jmp __cpu_reset"); - } - distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); +#if CONFIG_LOGICAL_CPUS==1 + #if ENABLE_APIC_EXT_ID == 1 + #if LIFT_BSP_APIC_ID == 0 + if( id.nodeid != 0 ) //all except cores in node0 + #endif + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); + #endif + + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } + +#else + #if ENABLE_APIC_EXT_ID == 1 + #if LIFT_BSP_APIC_ID == 0 + if(nodeid != 0) + #endif + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10 + + #endif + + if (cpu_init_detected(nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(nodeid); +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); } } @@ -202,51 +201,26 @@ 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_s2885_resource_map(); needs_reset = setup_coherent_ht_domain(); -#if 0 - needs_reset |= ht_setup_chains(2); -#else - needs_reset |= ht_setup_chains_x(); + +#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"); soft_reset(); } enable_smbus(); -#if 0 - dump_spd_registers(&cpu[0]); -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif - -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#endif - -#if 0 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x00100000); - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x80100000); -#endif - } diff --git a/src/mainboard/tyan/s2885/chip.h b/src/mainboard/tyan/s2885/chip.h index bcedaec66..dadfb0f4e 100644 --- a/src/mainboard/tyan/s2885/chip.h +++ b/src/mainboard/tyan/s2885/chip.h @@ -1,6 +1,6 @@ extern struct chip_operations mainboard_tyan_s2885_ops; struct mainboard_tyan_s2885_config { - int fixup_scsi; +// int fixup_scsi; // int fixup_vga; }; diff --git a/src/mainboard/tyan/s2885/cmos.layout b/src/mainboard/tyan/s2885/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s2885/cmos.layout +++ b/src/mainboard/tyan/s2885/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s2885/failover.c b/src/mainboard/tyan/s2885/failover.c index 45315521a..345d3f4d1 100644 --- a/src/mainboard/tyan/s2885/failover.c +++ b/src/mainboard/tyan/s2885/failover.c @@ -11,16 +11,33 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#else +#include "cpu/amd/model_fxx/node_id.c" +#endif + static unsigned long main(unsigned long bist) { - unsigned nodeid; - /* Make cerain my local apic is useable */ - enable_lapic(); - - nodeid = lapicid() & 0xf; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ +// enable_lapic(); +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else +// nodeid = lapicid() & 0xf; + nodeid = get_node_id(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { if (last_boot_normal()) { goto normal_image; } else { @@ -36,7 +53,6 @@ static unsigned long main(unsigned long bist) } } - /* Nothing special needs to be done to find bus 0 */ /* Allow the HT devices to be found */ enumerate_ht_chain(); diff --git a/src/mainboard/tyan/s2885/mptable.c b/src/mainboard/tyan/s2885/mptable.c index ba7bc390a..2396ade53 100644 --- a/src/mainboard/tyan/s2885/mptable.c +++ b/src/mainboard/tyan/s2885/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -20,6 +23,10 @@ void *smp_write_config_table(void *v) unsigned char bus_8111_1; unsigned char bus_8151_0; unsigned char bus_8151_1; + unsigned apicid_base; + unsigned apicid_8111; + unsigned apicid_8131_1; + unsigned apicid_8131_2; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); @@ -110,7 +117,15 @@ void *smp_write_config_table(void *v) smp_write_bus(mc, bus_isa, "ISA "); /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 2, 0x11, 0xfec00000); //8111 +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); //8111 { device_t dev; struct resource *res; @@ -118,78 +133,78 @@ void *smp_write_config_table(void *v) if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 3, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x04, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# -*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x2, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x2, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x2, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x2, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, 0x2, 0x5); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x2, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x2, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x2, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x2, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x2, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x2, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x2, 0xf); +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, apicid_8111, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); //??? What - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_0, (4<<2)|3, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_0, (4<<2)|3, apicid_8111, 0x13); //Onboard AMD AC97 Audio - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_0, (4<<2)|1, 0x2, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_0, (4<<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, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); // AGP Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8151_1, 0x0, 0x2, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8151_1, 0x0, apicid_8111, 0x10); //Onboard Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, 0x2, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, apicid_8111, 0x11); //Onboard Firewire - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0c<<2)|0, 0x2, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0c<<2)|0, apicid_8111, 0x13); //Onboard Broadcom NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, 0x3, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, apicid_8131_1, 0x0); //Slot 5 PCI 32 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, 0x2, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|1, 0x2, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|2, 0x2, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|3, 0x2, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|3, apicid_8111, 0x13); // //Slot 3 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, 0x3, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, 0x3, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, 0x3, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, 0x3, 0x2);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x2);// //Slot 4 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|0, 0x3, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|1, 0x3, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|2, 0x3, 0x0);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|3, 0x3, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|0, apicid_8131_1, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|1, apicid_8131_1, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|2, apicid_8131_1, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|3, apicid_8131_1, 0x1);// //Slot 1 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, 0x4, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, 0x4, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, 0x4, 0x3); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<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)|2, apicid_8131_2, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); // //Slot 2 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, 0x4, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|2, 0x4, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|3, 0x4, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|2, apicid_8131_2, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|3, apicid_8131_2, 0x0);// /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); diff --git a/src/mainboard/tyan/s2885/resourcemap.c b/src/mainboard/tyan/s2885/resourcemap.c index 2c51f1d11..bc2a8ba67 100644 --- a/src/mainboard/tyan/s2885/resourcemap.c +++ b/src/mainboard/tyan/s2885/resourcemap.c @@ -119,7 +119,7 @@ static void setup_s2885_resource_map(void) PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000, - PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff20, +// PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff20, /* Memory-Mapped I/O Base i Registers * F1:0x80 i = 0 @@ -154,7 +154,7 @@ static void setup_s2885_resource_map(void) PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000, - PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003, +// PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003, /* PCI I/O Limit i Registers * F1:0xC4 i = 0 @@ -181,7 +181,7 @@ static void setup_s2885_resource_map(void) * This field defines the end of PCI I/O region n * [31:25] Reserved */ - PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff020, +// PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff020, PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000, @@ -211,7 +211,7 @@ static void setup_s2885_resource_map(void) * This field defines the start of PCI I/O region n * [31:25] Reserved */ - PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000003, +// PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000003, PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000, @@ -252,8 +252,8 @@ static void setup_s2885_resource_map(void) * [31:24] Bus Number Limit i * This field defines the highest bus number in configuration regin i */ - PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x06000203, // AMD 8111 on link2 of CPU 0 - PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x08070003, // AMD 8151 on link0 of CPU 0 +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x06000203, // AMD 8111 on link2 of CPU 0 +// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x08070003, // AMD 8151 on link0 of CPU 0 PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000, }; diff --git a/src/mainboard/tyan/s2891/Config.lb b/src/mainboard/tyan/s2891/Config.lb index 71d4f9341..0f428d10c 100644 --- a/src/mainboard/tyan/s2891/Config.lb +++ b/src/mainboard/tyan/s2891/Config.lb @@ -284,4 +284,12 @@ chip northbridge/amd/amdk8/root_complex end # pci_domain +# chip drivers/generic/debug +# device pnp 0.0 off end +# device pnp 0.1 off end +# device pnp 0.2 off end +# device pnp 0.3 off end +# device pnp 0.4 off end +# device pnp 0.5 on end +# end end # root_complex diff --git a/src/mainboard/tyan/s2891/Options.lb b/src/mainboard/tyan/s2891/Options.lb index 75deaf69a..b4a374db7 100644 --- a/src/mainboard/tyan/s2891/Options.lb +++ b/src/mainboard/tyan/s2891/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -54,6 +56,7 @@ uses CONFIG_GDB_STUB uses CONFIG_CHIP_NAME uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK uses CK804_DEVN_BASE @@ -113,7 +116,12 @@ 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=1 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 #CK804 setting diff --git a/src/mainboard/tyan/s2891/auto.c b/src/mainboard/tyan/s2891/auto.c index d0ee70ba2..4a8ef3f95 100644 --- a/src/mainboard/tyan/s2891/auto.c +++ b/src/mainboard/tyan/s2891/auto.c @@ -77,11 +77,17 @@ static inline int spd_read_byte(unsigned device, unsigned address) /* tyan does not want the default */ #include "resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif + #define FIRST_CPU 1 #define SECOND_CPU 1 #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" @@ -113,23 +119,44 @@ static void main(unsigned long bist) }; int needs_reset; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); +#endif if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif ) { stop_this_cpu(); } @@ -146,6 +173,9 @@ static void main(unsigned long bist) needs_reset = setup_coherent_ht_domain(); +#if CONFIG_LOGICAL_CPUS==1 + start_other_cores(); +#endif needs_reset |= ht_setup_chains_x(); needs_reset |= ck804_early_setup_x(); diff --git a/src/mainboard/tyan/s2891/failover.c b/src/mainboard/tyan/s2891/failover.c index fb092e720..98b01b8f7 100644 --- a/src/mainboard/tyan/s2891/failover.c +++ b/src/mainboard/tyan/s2891/failover.c @@ -36,16 +36,29 @@ static void sio_setup(void) } +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif static unsigned long main(unsigned long bist) { +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif /* Make cerain my local apic is useable */ enable_lapic(); +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else nodeid = lapicid(); /* Is this a cpu only reset? */ if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { diff --git a/src/mainboard/tyan/s2891/mptable.c b/src/mainboard/tyan/s2891/mptable.c index 9aa2f336b..e8d5f4ccc 100644 --- a/src/mainboard/tyan/s2891/mptable.c +++ b/src/mainboard/tyan/s2891/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -128,7 +131,11 @@ void *smp_write_config_table(void *v) smp_write_bus(mc, bus_isa, "ISA "); /*I/O APICs: APIC ID Version State Address*/ - apicid_base = CONFIG_MAX_CPUS; +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif apicid_ck804 = apicid_base; apicid_8131_1 = apicid_base+1; apicid_8131_2 = apicid_base+2; @@ -149,12 +156,12 @@ void *smp_write_config_table(void *v) dword = 0x0000d218; pci_write_config32(dev, 0x7c, dword); - dword = 0x8d001a00; + dword = 0x12008a00; pci_write_config32(dev, 0x80, dword); - dword = 0x00000072; + dword = 0x0000007d; pci_write_config32(dev, 0x84, dword); @@ -193,13 +200,13 @@ void *smp_write_config_table(void *v) 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); - 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, 0x16); + 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)|1, apicid_ck804, 0x17); + 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 +7)<<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 +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 +8)<<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 +8)<<2)|0, apicid_ck804, 0x16); #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); // diff --git a/src/mainboard/tyan/s2892/Config.lb b/src/mainboard/tyan/s2892/Config.lb new file mode 100644 index 000000000..215c4a80d --- /dev/null +++ b/src/mainboard/tyan/s2892/Config.lb @@ -0,0 +1,298 @@ +## +## 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) +default CONFIG_ROM_STREAM = 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=65536 +default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE ) + +arch i386 end + + +## +## Build the objects we have code for in this directory. +## + +driver mainboard.o + +#dir /drivers/ati/ragexl + +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=k8 -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=k8 -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 southbridge/nvidia/ck804/id.inc +ldscript /southbridge/nvidia/ck804/id.lds + +## +## ROMSTRAP table for CK804 +## +if USE_FALLBACK_IMAGE + mainboardinit southbridge/nvidia/ck804/romstrap.inc + ldscript /southbridge/nvidia/ck804/romstrap.lds +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 +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 +## +if CONFIG_CHIP_NAME + config chip.h +end + + +# sample config for tyan/s2892 +chip northbridge/amd/amdk8/root_complex + device apic_cluster 0 on + chip cpu/amd/socket_940 + device apic 0 on end + end + end + + device pci_domain 0 on + chip northbridge/amd/amdk8 #mc0 + device pci 18.0 on # northbridge + # devices on link 0, link 0 == LDT 0 + chip southbridge/nvidia/ck804 + device pci 0.0 on end # HT + device pci 1.0 on # LPC + chip superio/winbond/w83627hf + device pnp 2e.0 on # Floppy + io 0x60 = 0x3f0 + irq 0x70 = 6 + drq 0x74 = 2 + end + device pnp 2e.1 off # Parallel Port + io 0x60 = 0x378 + irq 0x70 = 7 + end + device pnp 2e.2 on # Com1 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 off # Com2 + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.5 on # Keyboard + io 0x60 = 0x60 + io 0x62 = 0x64 + irq 0x70 = 1 + irq 0x72 = 12 + end + device pnp 2e.6 off # CIR + io 0x60 = 0x100 + end + device pnp 2e.7 off # GAME_MIDI_GIPO1 + io 0x60 = 0x220 + io 0x62 = 0x300 + irq 0x70 = 9 + end + device pnp 2e.8 off end # GPIO2 + device pnp 2e.9 off end # GPIO3 + device pnp 2e.a off end # ACPI + device pnp 2e.b on # HW Monitor + io 0x60 = 0x290 + irq 0x70 = 5 + end + end + end + device pci 1.1 on # SM 0 + 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 # SM + device pci 1.1 on # SM 1 + chip drivers/i2c/adm1027 # ADT7463A CPU0 temp, SYS FAN 2/3/4 + device i2c 2d on end + end + chip drivers/i2c/adm1027 # ADT7463A CPU1 temp, CPU0/1 FAN , SYS FAN 1/5 + device i2c 2e on end + end + chip drivers/generic/generic # Winbond HWM 0x54 CPU0/1 VRM temp, SYSFAN 6/7, SB FAN + device i2c 2a on end + end + chip drivers/generic/generic # Winbond HWM 0x92 + device i2c 49 on end + end + chip drivers/generic/generic # Winbond HWM 0x94 + device i2c 4a on end + end + end #SM + device pci 2.0 on end # USB 1.1 + device pci 2.1 on end # USB 2 + device pci 4.0 off end # ACI + device pci 4.1 off end # MCI + device pci 6.0 on end # IDE + device pci 7.0 on end # SATA 1 + device pci 8.0 on end # SATA 0 + device pci 9.0 on # PCI + # chip drivers/ati/ragexl + chip drivers/pci/onboard + device pci 6.0 on end + register "rom_address" = "0xfff80000" + end + chip drivers/pci/onboard + device pci 8.0 on end + end + end + device pci a.0 off end # NIC + device pci b.0 off end # PCI E 3 + device pci c.0 off end # PCI E 2 + device pci d.0 on end # PCI E 1 + device pci e.0 on end # PCI E 0 + register "ide0_enable" = "1" + register "ide1_enable" = "1" + register "sata0_enable" = "1" + register "sata1_enable" = "1" + end + end # device pci 18.0 + device pci 18.0 on end # Link 1 + device pci 18.0 on + # devices on link 2, link 2 == LDT 2 + chip southbridge/amd/amd8131 + # the on/off keyword is mandatory + device pci 0.0 on end + device pci 0.1 on end + device pci 1.0 on + chip drivers/pci/onboard + device pci 9.0 on end # broadcom 5704 + device pci 9.1 on end + end + end + device pci 1.1 on end + end + end # device pci 18.0 + device pci 18.1 on end + device pci 18.2 on end + device pci 18.3 on end + end #mc0 + + end # pci_domain + +# chip drivers/generic/debug +# device pnp 0.0 off end +# device pnp 0.1 off end +# device pnp 0.2 off end +# device pnp 0.3 off end +# device pnp 0.4 off end +# device pnp 0.5 on end +# end +end # root_complex diff --git a/src/mainboard/tyan/s2892/Options.lb b/src/mainboard/tyan/s2892/Options.lb new file mode 100644 index 000000000..6423773a2 --- /dev/null +++ b/src/mainboard/tyan/s2892/Options.lb @@ -0,0 +1,245 @@ +uses HAVE_MP_TABLE +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 +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_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_PART_NUMBER +uses MAINBOARD_VENDOR +uses MAINBOARD +uses MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID +uses MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID +uses LINUXBIOS_EXTRA_VERSION +uses _RAMBASE +uses CONFIG_GDB_STUB +uses CROSS_COMPILE +uses CC +uses HOSTCC +uses OBJCOPY +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_SERIAL8250 +uses CONFIG_CONSOLE_BTEXT +uses HAVE_INIT_TIMER +uses CONFIG_GDB_STUB +uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK + +uses CK804_DEVN_BASE + +## ROM_SIZE is the size of boot ROM that this board will use. +#512K bytes +default ROM_SIZE=524288 + +## +## FALLBACK_SIZE is the amount of the ROM the complete fallback image will use +## +default FALLBACK_SIZE=131072 + +### +### Build options +### + +## +## Build code for the fallback boot +## +default HAVE_FALLBACK_BOOT=1 + +## +## Build code to reset the motherboard from linuxBIOS +## +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 +## +default HAVE_PIRQ_TABLE=1 +default IRQ_SLOT_COUNT=11 + +## +## 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_MAX_PHYSICAL_CPUS=2 +default CONFIG_LOGICAL_CPUS=1 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#CK804 setting + +default CK804_DEVN_BASE=0 + +#BTEXT Console +#default CONFIG_CONSOLE_BTEXT=1 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 + + +## +## Build code to setup a generic IOAPIC +## +default CONFIG_IOAPIC=1 + +## +## Clean up the motherboard id strings +## +default MAINBOARD_PART_NUMBER="Tyan" +default MAINBOARD_VENDOR="s2892" +default MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID=0x10f1 +default MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID=0x2892 + +### +### 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 16K heap +## +default HEAP_SIZE=0x4000 + +## +## Only use the option table in a normal image +## +default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE + +## +## 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" + +### End Options.lb +end diff --git a/src/mainboard/tyan/s2892/auto.c b/src/mainboard/tyan/s2892/auto.c new file mode 100644 index 000000000..d2512e9f6 --- /dev/null +++ b/src/mainboard/tyan/s2892/auto.c @@ -0,0 +1,200 @@ +#define ASSEMBLY 1 + +#include +#include +#include +#include +#include +#include +#include "option_table.h" +#include "pc80/mc146818rtc_early.c" +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "ram/ramtest.c" + +#include "northbridge/amd/amdk8/cpu_rev.c" +#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" +#include "cpu/amd/model_fxx/apic_timer.c" +#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 "superio/winbond/w83627hf/w83627hf_early_serial.c" + +#include "cpu/amd/mtrr/amd_earlymtrr.c" +#include "cpu/x86/bist.h" + +#include "northbridge/amd/amdk8/setup_resource_map.c" + +#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1) + +static void hard_reset(void) +{ + set_bios_reset(); + + /* full reset */ + outb(0x0a, 0x0cf9); + outb(0x0e, 0x0cf9); +} + +static void soft_reset(void) +{ + set_bios_reset(); +#if 1 + /* link reset */ + outb(0x02, 0x0cf9); + outb(0x06, 0x0cf9); +#endif +} + +static void memreset_setup(void) +{ +} + +static void memreset(int controllers, const struct mem_controller *ctrl) +{ +} + +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); +} + +#define K8_4RANK_DIMM_SUPPORT 1 +#include "northbridge/amd/amdk8/raminit.c" +#include "northbridge/amd/amdk8/coherent_ht.c" +#include "sdram/generic_sdram.c" + + /* tyan does not want the default */ +#include "resourcemap.c" + +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif + +#define FIRST_CPU 1 +#define SECOND_CPU 1 +#define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) + +#define CK804_NUM 1 +#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h" +//set GPIO to input mode +#define CK804_MB_SETUP \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+15, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),/* M8,GPIO16, PCIXA_PRSNT2_L*/ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+44, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),/* P5,GPIO45, PCIXA_PRSNT1_L*/ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/ \ + RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/ \ + +#include "southbridge/nvidia/ck804/ck804_early_setup.c" + + +static void main(unsigned long bist) +{ + 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 = { (0xa<<3)|0, (0xa<<3)|2, 0, 0 }, + .channel1 = { (0xa<<3)|1, (0xa<<3)|3, 0, 0 }, + }, +#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 = { (0xa<<3)|4, (0xa<<3)|6, 0, 0 }, + .channel1 = { (0xa<<3)|5, (0xa<<3)|7, 0, 0 }, + }, +#endif + }; + + int needs_reset; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + + if (bist == 0) { + /* Skip this if there was a built in self test failure */ + amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + + enable_lapic(); + init_timer(); + + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); + if (cpu_init_detected(nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(nodeid); +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } + + + w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); + uart_init(); + console_init(); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); + + setup_s2892_resource_map(); + + needs_reset = setup_coherent_ht_domain(); + +#if CONFIG_LOGICAL_CPUS==1 + start_other_cores(); +#endif + needs_reset |= ht_setup_chains_x(); + + needs_reset |= ck804_early_setup_x(); + + if (needs_reset) { + print_info("ht reset -\r\n"); + soft_reset(); + } + + enable_smbus(); + + memreset_setup(); + sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); + +} diff --git a/src/mainboard/tyan/s2892/chip.h b/src/mainboard/tyan/s2892/chip.h new file mode 100644 index 000000000..28fb8a02e --- /dev/null +++ b/src/mainboard/tyan/s2892/chip.h @@ -0,0 +1,6 @@ +extern struct chip_operations mainboard_tyan_s2892_ops; + +struct mainboard_tyan_s2892_config { + int fixup_scsi; + int fixup_vga; +}; diff --git a/src/mainboard/tyan/s2892/cmos.layout b/src/mainboard/tyan/s2892/cmos.layout new file mode 100644 index 000000000..c1f3d7531 --- /dev/null +++ b/src/mainboard/tyan/s2892/cmos.layout @@ -0,0 +1,98 @@ +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 1 hw_scrubber +396 1 e 1 interleave_chip_selects +397 2 e 8 max_mem_clock +399 1 e 2 dual_core +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 +440 4 e 9 slow_cpu +444 1 e 1 nmi +445 1 e 1 iommu +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 +8 0 200Mhz +8 1 166Mhz +8 2 133Mhz +8 3 100Mhz +9 0 off +9 1 87.5% +9 2 75.0% +9 3 62.5% +9 4 50.0% +9 5 37.5% +9 6 25.0% +9 7 12.5% + +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/tyan/s2892/failover.c b/src/mainboard/tyan/s2892/failover.c new file mode 100644 index 000000000..b8d21f1d9 --- /dev/null +++ b/src/mainboard/tyan/s2892/failover.c @@ -0,0 +1,111 @@ +#define ASSEMBLY 1 +#include +#include +#include +#include +#include +#include +#include "pc80/mc146818rtc_early.c" + +#include "southbridge/nvidia/ck804/ck804_enable_rom.c" +#include "northbridge/amd/amdk8/early_ht.c" +#include "cpu/x86/lapic/boot_cpu.c" +#include "northbridge/amd/amdk8/reset_test.c" + +static void sio_setup(void) +{ + + unsigned value; + uint32_t dword; + uint8_t byte; + + 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); + + dword = pci_read_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0); + dword |= (1<<0); + pci_write_config32(PCI_DEV(0, CK804_DEVN_BASE+1 , 0), 0xa0, dword); + + +} + +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + +static unsigned long main(unsigned long bist) +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ + enable_lapic(); + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + + /* Is this a secondary cpu? */ + if (!boot_cpu()) { + if (last_boot_normal()) { + goto normal_image; + } else { + goto fallback_image; + } + } + + /* Nothing special needs to be done to find bus 0 */ + /* Allow the HT devices to be found */ + + enumerate_ht_chain(); + + sio_setup(); + + /* Setup the ck804 */ + ck804_enable_rom(); + + /* Is this a deliberate reset by the bios */ + if (bios_reset_detected() && last_boot_normal()) { + goto normal_image; + } + /* 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: +#if 0 + //CPU reset will reset memtroller ??? + asm volatile ("jmp __cpu_reset" + : /* outputs */ + : "a"(bist) /* inputs */ + : /* clobbers */ + ); +#endif + + fallback_image: + return bist; +} diff --git a/src/mainboard/tyan/s2892/irq_tables.c b/src/mainboard/tyan/s2892/irq_tables.c new file mode 100644 index 000000000..8a00214c1 --- /dev/null +++ b/src/mainboard/tyan/s2892/irq_tables.c @@ -0,0 +1,35 @@ +/* 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 + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32+16*11, /* there can be total 11 devices on the bus */ + 1, /* Where the interrupt router lies (bus) */ + ((CK804_DEVN_BASE+9)<<3)|0, /* Where the interrupt router lies (dev) */ + 0, /* IRQs devoted exclusively to PCI usage */ + 0x10de, /* Vendor */ + 0x005c, /* Device */ + 0, /* Crap (miniport) */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 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) */ + { + {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}, + {0x5,(4<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x0, 0}, + {0x5,(3<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x1, 0}, + {0x5,(6<<3)|0, {{0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}}, 0x2, 0}, + {0x4,(8<<3)|0, {{0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}}, 0x3, 0}, + {0x4,(7<<3)|0, {{0x3, 0xdef8}, {0x4, 0xdef8}, {0x1, 0xdef8}, {0x2, 0xdef8}}, 0x4, 0}, + {0x6,(0x0a<<3)|0, {{0x1, 0xdef8}, {0x2, 0xdef8}, {0x3, 0xdef8}, {0x4, 0xdef8}}, 0x5, 0}, + {0x4,(9<<3)|0, {{0x1, 0xdef8}, {2, 0xdef8}, {0, 0}, {0, 0}}, 0, 0}, + {0x6,(0x0b<<3)|0, {{0x2, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0}, + {0x6,(0x0c<<3)|0, {{0x4, 0xdef8}, {0, 0}, {0, 0}, {0, 0}}, 0, 0}, + } +}; diff --git a/src/mainboard/tyan/s2892/mainboard.c b/src/mainboard/tyan/s2892/mainboard.c new file mode 100644 index 000000000..32a2e609c --- /dev/null +++ b/src/mainboard/tyan/s2892/mainboard.c @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include +#include "chip.h" + +#if CONFIG_CHIP_NAME == 1 +struct chip_operations mainboard_tyan_s2892_ops = { + CHIP_NAME("Tyan s2892 mainboard") +}; +#endif diff --git a/src/mainboard/tyan/s2892/mptable.c b/src/mainboard/tyan/s2892/mptable.c new file mode 100644 index 000000000..b4f26aaeb --- /dev/null +++ b/src/mainboard/tyan/s2892/mptable.c @@ -0,0 +1,270 @@ +#include +#include +#include +#include +#include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif + +void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "TYAN "; + static const char productid[12] = "S2892 "; + struct mp_config_table *mc; + + unsigned char bus_num; + unsigned char bus_isa; + unsigned char bus_ck804_0; //1 + unsigned char bus_ck804_1; //2 + unsigned char bus_ck804_2; //3 + unsigned char bus_ck804_3; //4 + unsigned char bus_ck804_4; //5 + unsigned char bus_ck804_5; //6 + unsigned char bus_8131_0; //7 + unsigned char bus_8131_1; //8 + unsigned char bus_8131_2; //9 + unsigned apicid_base; + unsigned apicid_ck804; + unsigned apicid_8131_1; + unsigned apicid_8131_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; + + + /* 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); + 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 + 0x09); + + bus_ck804_1 = 2; + bus_ck804_4 = 3; + + } + 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; + } + + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0)); + if (dev) { + bus_ck804_5 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_8131_0 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_8131_0++; + } + else { + printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0e); + + bus_8131_0 = bus_ck804_5+1; + } + + /* 8131-1 */ + dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x01,0)); + if (dev) { + bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); + bus_8131_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS); + bus_8131_2++; + } + else { + printk_debug("ERROR - could not find PCI %02x:01.0, using defaults\n", bus_8131_0); + + bus_8131_1 = bus_8131_0+1; + bus_8131_2 = bus_8131_0+2; + } + /* 8131-2 */ + dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x02,0)); + if (dev) { + bus_8131_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 %02x:02.0, using defaults\n", bus_8131_0); + + bus_8131_2 = bus_8131_1+1; + bus_isa = bus_8131_1+2; + } + + } + + + +/*Bus: Bus ID Type*/ + /* 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 "); + +/*I/O APICs: APIC ID Version State Address*/ +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_ck804 = apicid_base; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; +// smp_write_ioapic(mc, 2, 0x11, 0xfec00000); + { + device_t dev; + struct resource *res; + uint32_t dword; + + dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE+ 0x1,0)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_1); + if (res) { + smp_write_ioapic(mc, apicid_ck804, 0x11, res->base); + } + + dword = 0x0000d218; + pci_write_config32(dev, 0x7c, dword); + + dword = 0x12008a00; + pci_write_config32(dev, 0x80, dword); + + dword = 0x0000007d; + pci_write_config32(dev, 0x84, dword); + + } + + dev = dev_find_slot(bus_8131_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(bus_8131_0, PCI_DEVFN(0x2,1)); + if (dev) { + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); + } + } + + } + +/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# +*/ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_ck804, 0x1); + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_ck804, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_ck804, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_ck804, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_ck804, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_ck804, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_ck804, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_ck804, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_ck804, 0xe); + 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); + + 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)|1, apicid_ck804, 0x14); + + 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 +8)<<2)|0, apicid_ck804, 0x16); + +#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); // +#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); // + 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); // +#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_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)|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);// + 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); // + 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)|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);// + 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); // + 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)|3, apicid_8131_1, 0x1);// + + +/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ + smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); + smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1); + /* 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/tyan/s2892/resourcemap.c b/src/mainboard/tyan/s2892/resourcemap.c new file mode 100644 index 000000000..5801264a1 --- /dev/null +++ b/src/mainboard/tyan/s2892/resourcemap.c @@ -0,0 +1,273 @@ +/* + * Tyan S2892 needs a different resource map + * + */ + +static void setup_s2892_resource_map(void) +{ + static const unsigned int register_values[] = { +#if 1 + /* Careful set limit registers before base registers which contain the enables */ + /* DRAM Limit i Registers + * F1:0x44 i = 0 + * F1:0x4C i = 1 + * F1:0x54 i = 2 + * F1:0x5C i = 3 + * F1:0x64 i = 4 + * F1:0x6C i = 5 + * F1:0x74 i = 6 + * F1:0x7C i = 7 + * [ 2: 0] Destination Node ID + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 7: 3] Reserved + * [10: 8] Interleave select + * specifies the values of A[14:12] to use with interleave enable. + * [15:11] Reserved + * [31:16] DRAM Limit Address i Bits 39-24 + * This field defines the upper address bits of a 40 bit address + * that define the end of the DRAM region. + */ + PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001, + PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002, + PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003, + PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004, + PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005, + PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006, + PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007, + /* DRAM Base i Registers + * F1:0x40 i = 0 + * F1:0x48 i = 1 + * F1:0x50 i = 2 + * F1:0x58 i = 3 + * F1:0x60 i = 4 + * F1:0x68 i = 5 + * F1:0x70 i = 6 + * F1:0x78 i = 7 + * [ 0: 0] Read Enable + * 0 = Reads Disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes Disabled + * 1 = Writes Enabled + * [ 7: 2] Reserved + * [10: 8] Interleave Enable + * 000 = No interleave + * 001 = Interleave on A[12] (2 nodes) + * 010 = reserved + * 011 = Interleave on A[12] and A[14] (4 nodes) + * 100 = reserved + * 101 = reserved + * 110 = reserved + * 111 = Interleve on A[12] and A[13] and A[14] (8 nodes) + * [15:11] Reserved + * [13:16] DRAM Base Address i Bits 39-24 + * This field defines the upper address bits of a 40-bit address + * that define the start of the DRAM region. + */ + PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000, +#endif +#if 1 + + /* Memory-Mapped I/O Limit i Registers + * F1:0x84 i = 0 + * F1:0x8C i = 1 + * F1:0x94 i = 2 + * F1:0x9C i = 3 + * F1:0xA4 i = 4 + * F1:0xAC i = 5 + * F1:0xB4 i = 6 + * F1:0xBC i = 7 + * [ 2: 0] Destination Node ID + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 3: 3] Reserved + * [ 5: 4] Destination Link ID + * 00 = Link 0 + * 01 = Link 1 + * 10 = Link 2 + * 11 = Reserved + * [ 6: 6] Reserved + * [ 7: 7] Non-Posted + * 0 = CPU writes may be posted + * 1 = CPU writes must be non-posted + * [31: 8] Memory-Mapped I/O Limit Address i (39-16) + * This field defines the upp adddress bits of a 40-bit address that + * defines the end of a memory-mapped I/O region n + */ + PCI_ADDR(0, 0x18, 1, 0x84), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x8C), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x94), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x9C), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xA4), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xAC), 0x00000048, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xB4), 0x00000048, 0x00000000, +// PCI_ADDR(0, 0x18, 1, 0xBC), 0x00000048, 0x00ffff00, + + /* Memory-Mapped I/O Base i Registers + * F1:0x80 i = 0 + * F1:0x88 i = 1 + * F1:0x90 i = 2 + * F1:0x98 i = 3 + * F1:0xA0 i = 4 + * F1:0xA8 i = 5 + * F1:0xB0 i = 6 + * F1:0xB8 i = 7 + * [ 0: 0] Read Enable + * 0 = Reads disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes disabled + * 1 = Writes Enabled + * [ 2: 2] Cpu Disable + * 0 = Cpu can use this I/O range + * 1 = Cpu requests do not use this I/O range + * [ 3: 3] Lock + * 0 = base/limit registers i are read/write + * 1 = base/limit registers i are read-only + * [ 7: 4] Reserved + * [31: 8] Memory-Mapped I/O Base Address i (39-16) + * This field defines the upper address bits of a 40bit address + * that defines the start of memory-mapped I/O region i + */ + PCI_ADDR(0, 0x18, 1, 0x80), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x88), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x90), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0x98), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xA0), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xA8), 0x000000f0, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xB0), 0x000000f0, 0x00000000, +// PCI_ADDR(0, 0x18, 1, 0xB8), 0x000000f0, 0x00fc0003, +#endif +#if 1 + + /* PCI I/O Limit i Registers + * F1:0xC4 i = 0 + * F1:0xCC i = 1 + * F1:0xD4 i = 2 + * F1:0xDC i = 3 + * [ 2: 0] Destination Node ID + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 3: 3] Reserved + * [ 5: 4] Destination Link ID + * 00 = Link 0 + * 01 = Link 1 + * 10 = Link 2 + * 11 = reserved + * [11: 6] Reserved + * [24:12] PCI I/O Limit Address i + * This field defines the end of PCI I/O region n + * [31:25] Reserved + */ + PCI_ADDR(0, 0x18, 1, 0xC4), 0xFE000FC8, 0x01fff000, + PCI_ADDR(0, 0x18, 1, 0xCC), 0xFE000FC8, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xD4), 0xFE000FC8, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xDC), 0xFE000FC8, 0x00000000, + + /* PCI I/O Base i Registers + * F1:0xC0 i = 0 + * F1:0xC8 i = 1 + * F1:0xD0 i = 2 + * F1:0xD8 i = 3 + * [ 0: 0] Read Enable + * 0 = Reads Disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes Disabled + * 1 = Writes Enabled + * [ 3: 2] Reserved + * [ 4: 4] VGA Enable + * 0 = VGA matches Disabled + * 1 = matches all address < 64K and where A[9:0] is in the + * range 3B0-3BB or 3C0-3DF independen of the base & limit registers + * [ 5: 5] ISA Enable + * 0 = ISA matches Disabled + * 1 = Blocks address < 64K and in the last 768 bytes of eack 1K block + * from matching agains this base/limit pair + * [11: 6] Reserved + * [24:12] PCI I/O Base i + * This field defines the start of PCI I/O region n + * [31:25] Reserved + */ + PCI_ADDR(0, 0x18, 1, 0xC0), 0xFE000FCC, 0x00000033, + PCI_ADDR(0, 0x18, 1, 0xC8), 0xFE000FCC, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xD0), 0xFE000FCC, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xD8), 0xFE000FCC, 0x00000000, +#endif + /* Config Base and Limit i Registers + * F1:0xE0 i = 0 + * F1:0xE4 i = 1 + * F1:0xE8 i = 2 + * F1:0xEC i = 3 + * [ 0: 0] Read Enable + * 0 = Reads Disabled + * 1 = Reads Enabled + * [ 1: 1] Write Enable + * 0 = Writes Disabled + * 1 = Writes Enabled + * [ 2: 2] Device Number Compare Enable + * 0 = The ranges are based on bus number + * 1 = The ranges are ranges of devices on bus 0 + * [ 3: 3] Reserved + * [ 6: 4] Destination Node + * 000 = Node 0 + * 001 = Node 1 + * 010 = Node 2 + * 011 = Node 3 + * 100 = Node 4 + * 101 = Node 5 + * 110 = Node 6 + * 111 = Node 7 + * [ 7: 7] Reserved + * [ 9: 8] Destination Link + * 00 = Link 0 + * 01 = Link 1 + * 10 = Link 2 + * 11 - Reserved + * [15:10] Reserved + * [23:16] Bus Number Base i + * This field defines the lowest bus number in configuration region i + * [31:24] Bus Number Limit i + * This field defines the highest bus number in configuration region i + */ +#if 1 +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x07000003, +// PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x7f080203, + PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, + PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000, +#endif + + }; + + int max; + max = sizeof(register_values)/sizeof(register_values[0]); + setup_resource_map(register_values, max); +} + diff --git a/src/mainboard/tyan/s2895/Config.lb b/src/mainboard/tyan/s2895/Config.lb index 5a7cb14e9..09448facc 100644 --- a/src/mainboard/tyan/s2895/Config.lb +++ b/src/mainboard/tyan/s2895/Config.lb @@ -315,4 +315,14 @@ chip northbridge/amd/amdk8/root_complex end end # PCI domain +# chip drivers/generic/debug +# device pnp 0.0 off end # chip name +# 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.5 off end # dual core msr +# device pnp 0.6 off end # cache size +# device pnp 0.7 off end # tsc +# end end #root_complex diff --git a/src/mainboard/tyan/s2895/Options.lb b/src/mainboard/tyan/s2895/Options.lb index 545dbe9f4..22812e9a2 100644 --- a/src/mainboard/tyan/s2895/Options.lb +++ b/src/mainboard/tyan/s2895/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -53,6 +55,7 @@ uses CONFIG_GDB_STUB uses CONFIG_CHIP_NAME uses CONFIG_CONSOLE_VGA uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK uses CK804_DEVN_BASE @@ -115,11 +118,16 @@ 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=1 #CHIP_NAME ? #default CONFIG_CHIP_NAME=1 +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + #CK804 setting default CK804_DEVN_BASE=0 diff --git a/src/mainboard/tyan/s2895/auto.c b/src/mainboard/tyan/s2895/auto.c index 209f284d5..b6f121e6e 100644 --- a/src/mainboard/tyan/s2895/auto.c +++ b/src/mainboard/tyan/s2895/auto.c @@ -105,6 +105,13 @@ static inline int spd_read_byte(unsigned device, unsigned address) /* tyan does not want the default */ #include "resourcemap.c" +#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 #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU) @@ -113,6 +120,7 @@ static inline int spd_read_byte(unsigned device, unsigned address) #define CK804B_BUSN 0xc #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 @@ -155,26 +163,57 @@ static void main(unsigned long bist) }; int needs_reset; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); - nodeid = lapicid();; +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); + + 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); + } + #endif +#else + nodeid = get_node_id(); #if ENABLE_APIC_EXT_ID == 1 enable_apic_ext_id(nodeid); #endif +#endif enable_lapic(); init_timer(); +#if CONFIG_LOGICAL_CPUS==1 + #if ENABLE_APIC_EXT_ID == 1 + #if LIFT_BSP_APIC_ID == 0 + if( id.nodeid != 0 ) + #endif + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); + #endif + + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } + +#else #if ENABLE_APIC_EXT_ID == 1 #if LIFT_BSP_APIC_ID == 0 if(nodeid != 0) #endif - lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10 + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); #endif @@ -182,11 +221,15 @@ static void main(unsigned long bist) asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); +#endif if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif ) { - stop_this_cpu(); // it will stop all cores except core0 of cpu0 + stop_this_cpu(); } } @@ -203,6 +246,9 @@ static void main(unsigned long bist) setup_s2895_resource_map(); needs_reset = setup_coherent_ht_domain(); +#if CONFIG_LOGICAL_CPUS==1 + start_other_cores(); +#endif needs_reset |= ht_setup_chains_x(); diff --git a/src/mainboard/tyan/s2895/failover.c b/src/mainboard/tyan/s2895/failover.c index a70264ec2..7cd004f82 100644 --- a/src/mainboard/tyan/s2895/failover.c +++ b/src/mainboard/tyan/s2895/failover.c @@ -50,16 +50,32 @@ static void sio_setup(void) } +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#else +#include "cpu/amd/model_fxx/node_id.c" +#endif + static unsigned long main(unsigned long bist) { +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif /* Make cerain my local apic is useable */ // enable_lapic(); - nodeid = lapicid();; +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = get_node_id(); /* Is this a cpu only reset? */ if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { diff --git a/src/mainboard/tyan/s2895/mptable.c b/src/mainboard/tyan/s2895/mptable.c index 61ab3f26a..f6b534d86 100644 --- a/src/mainboard/tyan/s2895/mptable.c +++ b/src/mainboard/tyan/s2895/mptable.c @@ -4,6 +4,10 @@ #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -142,7 +146,11 @@ void *smp_write_config_table(void *v) smp_write_bus(mc, bus_isa, "ISA "); /*I/O APICs: APIC ID Version State Address*/ - apicid_base = CONFIG_MAX_CPUS; +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(4); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif apicid_ck804 = apicid_base; apicid_8131_1 = apicid_base+1; apicid_8131_2 = apicid_base+2; @@ -163,10 +171,10 @@ void *smp_write_config_table(void *v) dword = 0x0120d218; pci_write_config32(dev, 0x7c, dword); - dword = 0x00001a00; + dword = 0x12008a00; pci_write_config32(dev, 0x80, dword); - dword = 0x00080d72; + dword = 0x00080d7d; pci_write_config32(dev, 0x84, dword); } @@ -222,15 +230,15 @@ void *smp_write_config_table(void *v) 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); - 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, 0x16); + 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)|1, apicid_ck804, 0x17); + 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+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 +7)<<2)|0, apicid_ck804, 0x11); + 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 +8)<<2)|0, apicid_ck804, 0x12); + 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 +0x0a)<<2)|0, apicid_ck804, 0x15); diff --git a/src/mainboard/tyan/s4880/Config.lb b/src/mainboard/tyan/s4880/Config.lb index 1caca9698..d053c663f 100644 --- a/src/mainboard/tyan/s4880/Config.lb +++ b/src/mainboard/tyan/s4880/Config.lb @@ -144,11 +144,11 @@ chip northbridge/amd/amdk8/root_complex chip southbridge/amd/amd8131 # the on/off keyword is mandatory device pci 0.0 on -# chip drivers/lsi/53c1030 -# device pci 4.0 on end -# device pci 4.1 on end -# register "fw_address" = "0xfff8c000" -# end + chip drivers/lsi/53c1030 + device pci 4.0 on end + device pci 4.1 on end + register "fw_address" = "0xfff8c000" + end chip drivers/pci/onboard device pci 9.0 on end device pci 9.1 on end diff --git a/src/mainboard/tyan/s4880/Options.lb b/src/mainboard/tyan/s4880/Options.lb index 235b07084..4cadb725c 100644 --- a/src/mainboard/tyan/s4880/Options.lb +++ b/src/mainboard/tyan/s4880/Options.lb @@ -9,6 +9,8 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -50,6 +52,9 @@ uses CC uses HOSTCC uses OBJCOPY uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -112,6 +117,15 @@ default LB_CKS_LOC=123 ## default CONFIG_SMP=1 default CONFIG_MAX_CPUS=4 +default CONFIG_MAX_PHYSICAL_CPUS=4 +default CONFIG_LOGICAL_CPUS=0 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 ## ## Build code to setup a generic IOAPIC @@ -211,9 +225,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/s4880/auto.c b/src/mainboard/tyan/s4880/auto.c index 21855aa51..12c0c9541 100644 --- a/src/mainboard/tyan/s4880/auto.c +++ b/src/mainboard/tyan/s4880/auto.c @@ -43,12 +43,6 @@ static void soft_reset(void) pci_write_config8(PCI_DEV(0, 0x04, 0), 0x47, 1); } -static void soft2_reset(void) -{ - set_bios_reset(); - pci_write_config8(PCI_DEV(3, 0x04, 0), 0x47, 1); -} - static void memreset_setup(void) { if (is_cpu_pre_c0()) { @@ -69,63 +63,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -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; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { #define SMBUS_HUB 0x18 @@ -133,21 +70,13 @@ 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) { return smbus_read_byte(device, address); } -//#include "northbridge/amd/amdk8/setup_resource_map.c" +#include "northbridge/amd/amdk8/setup_resource_map.c" #include "northbridge/amd/amdk8/raminit.c" #include "northbridge/amd/amdk8/coherent_ht.c" @@ -156,6 +85,11 @@ static inline int spd_read_byte(unsigned device, unsigned address) /* tyan does not want the default */ #include "resourcemap.c" +#if CONFIG_LOGICAL_CPUS==1 +#define SET_NB_CFG_54 1 +#include "cpu/amd/dualcore/dualcore.c" +#endif + #define FIRST_CPU 1 #define SECOND_CPU 1 @@ -228,89 +162,74 @@ static void main(unsigned long bist) }; int i; int needs_reset; - unsigned nodeid; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); +#endif + enable_lapic(); init_timer(); - nodeid = lapicid() & 0xf; - +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + nodeid = lapicid(); if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - if (!boot_cpu()) { - stop_this_cpu(); - } - } - +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } + w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init(); /* Halt if there was a built in self test failure */ - report_bist_failure(bist); + report_bist_failure(bist); setup_s4880_resource_map(); + needs_reset = setup_coherent_ht_domain(); - needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xc0); + +#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"); soft_reset(); } -#if 0 - dump_pci_devices(); -#endif enable_smbus(); -#if 0 - -// activate_spd_rom(&cpu[0]); -// dump_spd_registers(&cpu[0]); - -// for(i=0;i<4;i++) { -// activate_spd_rom(&cpu[i]); -// dump_smbus_registers(); -// } - for(i=1;i<256;i=i*2) { - change_i2c_mux(i); - dump_smbus_registers(); - } - -#endif + memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x01000000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x81000000); -#endif -#endif -*/ } diff --git a/src/mainboard/tyan/s4880/cmos.layout b/src/mainboard/tyan/s4880/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s4880/cmos.layout +++ b/src/mainboard/tyan/s4880/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s4880/failover.c b/src/mainboard/tyan/s4880/failover.c index 45315521a..39758aefa 100644 --- a/src/mainboard/tyan/s4880/failover.c +++ b/src/mainboard/tyan/s4880/failover.c @@ -11,24 +11,38 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else unsigned nodeid; +#endif /* Make cerain my local apic is useable */ enable_lapic(); - - nodeid = lapicid() & 0xf; - - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { - if (last_boot_normal()) { - goto normal_image; - } else { - goto cpu_reset; - } - } - /* Is this a secondary cpu? */ - if (!boot_cpu()) { + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else + nodeid = lapicid(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif + if (last_boot_normal()) { + goto normal_image; + } else { + goto cpu_reset; + } + } + /* Is this a secondary cpu? */ + if (!boot_cpu()) { if (last_boot_normal()) { goto normal_image; } else { diff --git a/src/mainboard/tyan/s4880/mptable.c b/src/mainboard/tyan/s4880/mptable.c index 2577a8b1b..2b6ba531f 100644 --- a/src/mainboard/tyan/s4880/mptable.c +++ b/src/mainboard/tyan/s4880/mptable.c @@ -3,6 +3,9 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { @@ -16,6 +19,10 @@ void *smp_write_config_table(void *v) unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; + unsigned apicid_base; + unsigned apicid_8111; + unsigned apicid_8131_1; + unsigned apicid_8131_2; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); @@ -86,7 +93,16 @@ void *smp_write_config_table(void *v) /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 4, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; + + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); { device_t dev; struct resource *res; @@ -94,91 +110,91 @@ void *smp_write_config_table(void *v) if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x05, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x06, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# -*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x4, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x4, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x4, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x4, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, 0x4, 0x5); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x4, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x4, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x4, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, 0x4, 0x9); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xa, 0x4, 0xa); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xb, 0x4, 0xb); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x4, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x4, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x4, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x4, 0xf); +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, apicid_8111, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, apicid_8111, 0x9); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xa, apicid_8111, 0xa); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xb, apicid_8111, 0xb); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + 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, 0x4, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (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, 0x4, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); //On Board Via USB 1.1 and 2 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|0, 0x4, 0x11); //1.1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|1, 0x4, 0x10); //1.1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|2, 0x4, 0x12); //2 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|0, apicid_8111, 0x11); //1.1 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|1, apicid_8111, 0x10); //1.1 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|2, apicid_8111, 0x12); //2 //Slot 5 PCI 32 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, 0x4, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, 0x4, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, 0x4, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, 0x4, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, apicid_8111, 0x13); // //On Board SI Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, 0x4, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, apicid_8111, 0x13); //On Board ATI Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, 0x4, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, apicid_8111, 0x12); //Slot 4 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, 0x5, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, 0x5, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|2, 0x5, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|3, 0x5, 0x2);// + 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); + 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);// //Slot 3 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, 0x5, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|1, 0x5, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, 0x5, 0x0);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|3, 0x5, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); + 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)|3, apicid_8131_1, 0x1);// //On Board LSI scsi and NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, 0x5, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|1, 0x5, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, 0x5, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, 0x5, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); + 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, (9<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, apicid_8131_1, 0x1); //Slot 2 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, 0x6, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, 0x6, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, 0x6, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, 0x6, 0x3); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<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)|2, apicid_8131_2, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); // //Slot 1 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, 0x6, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, 0x6, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, 0x6, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, 0x6, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, apicid_8131_2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, apicid_8131_2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, apicid_8131_2, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, apicid_8131_2, 0x0);// /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); diff --git a/src/mainboard/tyan/s4880/resourcemap.c b/src/mainboard/tyan/s4880/resourcemap.c index c18c257f8..d9315a026 100644 --- a/src/mainboard/tyan/s4880/resourcemap.c +++ b/src/mainboard/tyan/s4880/resourcemap.c @@ -252,7 +252,7 @@ static void setup_s4880_resource_map(void) * [31:24] Bus Number Limit i * This field defines the highest bus number in configuration regin i */ - PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000203, +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000203, PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000, diff --git a/src/mainboard/tyan/s4882/Options.lb b/src/mainboard/tyan/s4882/Options.lb index 5d592596b..e1a431bde 100644 --- a/src/mainboard/tyan/s4882/Options.lb +++ b/src/mainboard/tyan/s4882/Options.lb @@ -9,6 +9,9 @@ uses HARD_RESET_FUNCTION uses IRQ_SLOT_COUNT uses HAVE_OPTION_TABLE uses CONFIG_MAX_CPUS +uses CONFIG_MAX_PHYSICAL_CPUS +uses CONFIG_LOGICAL_CPUS +uses SERIAL_CPU_INIT uses CONFIG_IOAPIC uses CONFIG_SMP uses FALLBACK_SIZE @@ -50,6 +53,10 @@ uses CC uses HOSTCC uses OBJCOPY uses CONFIG_CHIP_NAME +uses CONFIG_CONSOLE_BTEXT +uses CONFIG_CONSOLE_VGA +uses CONFIG_PCI_ROM_RUN +uses K8_E0_MEM_HOLE_SIZEK ### ### Build options @@ -111,7 +118,21 @@ default LB_CKS_LOC=123 ## Only worry about 2 micro processors ## default CONFIG_SMP=1 -default CONFIG_MAX_CPUS=4 +default CONFIG_MAX_CPUS=8 +default CONFIG_MAX_PHYSICAL_CPUS=4 +default CONFIG_LOGICAL_CPUS=1 + +#default SERIAL_CPU_INIT=0 + +#1G memory hole +default K8_E0_MEM_HOLE_SIZEK=0x100000 + +#BTEXT Console +#default CONFIG_CONSOLE_BTEXT=1 + +#VGA Console +default CONFIG_CONSOLE_VGA=1 +default CONFIG_PCI_ROM_RUN=1 ## ## Build code to setup a generic IOAPIC diff --git a/src/mainboard/tyan/s4882/auto.c b/src/mainboard/tyan/s4882/auto.c index e7d46d218..21d459b6e 100644 --- a/src/mainboard/tyan/s4882/auto.c +++ b/src/mainboard/tyan/s4882/auto.c @@ -6,13 +6,11 @@ #include #include #include -#include #include "option_table.h" #include "pc80/mc146818rtc_early.c" #include "pc80/serial.c" #include "arch/i386/lib/console.c" #include "ram/ramtest.c" -#include "northbridge/amd/amdk8/incoherent_ht.c" #include "southbridge/amd/amd8111/amd8111_early_smbus.c" #include "northbridge/amd/amdk8/raminit.h" #include "cpu/amd/model_fxx/apic_timer.c" @@ -20,6 +18,7 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" #include "northbridge/amd/amdk8/debug.c" +#include "northbridge/amd/amdk8/incoherent_ht.c" #include "northbridge/amd/amdk8/cpu_rev.c" #include "superio/winbond/w83627hf/w83627hf_early_serial.c" #include "cpu/amd/mtrr/amd_earlymtrr.c" @@ -69,100 +68,47 @@ static void memreset(int controllers, const struct mem_controller *ctrl) } } -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 */ - -/* - (L2) (L1) - CPU3-------------CPU1 - (L0)| |(L0) - | | - | | - | | - | | - (L0)| |(L0) - CPU2-------------CPU0---------8131----------8111 - (L1) (L2) (L1) -*/ - - /* Link0 of CPU0 to Link0 of CPU1 */ - /* Link2 of CPU0 to Link1 of CPU2 */ - /* Link1 of CPU1 to Link2 of CPU3 */ - /* Link0 of CPU2 to Link0 of CPU3 */ - - static const unsigned int rows_4p[4][4] = { - { 0x000b0101, 0x00010202, 0x00030808, 0x00010208 }, - { 0x00010202, 0x00070101, 0x00010204, 0x00030404 }, - { 0x00030404, 0x00010204, 0x00070101, 0x00010202 }, - { 0x00010208, 0x00030808, 0x00010202, 0x000b0101 } - }; - - if (!(node>=maxnodes || row>=maxnodes)) { - ret=rows_4p[node][row]; - } - - return ret; -} - static inline void activate_spd_rom(const struct mem_controller *ctrl) { #define SMBUS_HUB 0x18 + int ret,i; unsigned device=(ctrl->channel0[0])>>8; - 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); + i=2; + do { + ret = smbus_write_byte(SMBUS_HUB, 0x01, device); + } while ((ret!=0) && (i-->0)); + + smbus_write_byte(SMBUS_HUB, 0x03, 0); } -#endif static inline int spd_read_byte(unsigned device, unsigned address) { return smbus_read_byte(device, address); } -//#include "northbridge/amd/amdk8/setup_resource_map.c" +#include "northbridge/amd/amdk8/setup_resource_map.c" +#define K8_4RANK_DIMM_SUPPORT 1 #include "northbridge/amd/amdk8/raminit.c" - -#if 1 +#if 0 #define ENABLE_APIC_EXT_ID 1 #define APIC_ID_OFFSET 0x10 -#else + #define LIFT_BSP_APIC_ID 0 +#else #define ENABLE_APIC_EXT_ID 0 #endif - #include "northbridge/amd/amdk8/coherent_ht.c" #include "sdram/generic_sdram.c" /* tyan does not want the default */ #include "resourcemap.c" +#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 @@ -171,10 +117,10 @@ static inline int spd_read_byte(unsigned device, unsigned address) #define TOTAL_CPUS (FIRST_CPU + SECOND_CPU + THIRD_CPU + FOURTH_CPU) -#define RC0 ((1<<1)<<8) -#define RC1 ((1<<2)<<8) -#define RC2 ((1<<3)<<8) -#define RC3 ((1<<4)<<8) +#define RC0 ((1<<2)<<8) +#define RC1 ((1<<1)<<8) +#define RC2 ((1<<4)<<8) +#define RC3 ((1<<3)<<8) #define DIMM0 0x50 #define DIMM1 0x51 @@ -235,28 +181,69 @@ static void main(unsigned long bist) }; int i; int needs_reset; - unsigned nodeid; +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + if (bist == 0) { /* Skip this if there was a built in self test failure */ amd_early_mtrr_init(); + +#if CONFIG_LOGICAL_CPUS==1 + set_apicid_cpuid_lo(); + + id = get_node_core_id_x(); + #if ENABLE_APIC_EXT_ID == 1 + if(id.coreid == 0) { + enable_apic_ext_id(id.nodeid); + } + #endif +#else + nodeid = get_node_id(); + #if ENABLE_APIC_EXT_ID == 1 + enable_apic_ext_id(nodeid); + #endif +#endif + enable_lapic(); init_timer(); - nodeid = lapicid() & 0xf; + +#if CONFIG_LOGICAL_CPUS==1 #if ENABLE_APIC_EXT_ID == 1 - enable_apic_ext_id(nodeid); - if(nodeid != 0) { - lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10 - } + #if LIFT_BSP_APIC_ID == 0 + if( id.nodeid != 0 ) + #endif + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); + #endif + if(id.coreid == 0) { + if (cpu_init_detected(id.nodeid)) { + asm volatile ("jmp __cpu_reset"); + } + distinguish_cpu_resets(id.nodeid); + } +#else + #if ENABLE_APIC_EXT_ID == 1 + #if LIFT_BSP_APIC_ID == 0 + if(nodeid != 0) + #endif + lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10 #endif if (cpu_init_detected(nodeid)) { asm volatile ("jmp __cpu_reset"); } distinguish_cpu_resets(nodeid); - - if (!boot_cpu()) { - stop_this_cpu(); - } - } +#endif + + if (!boot_cpu() +#if CONFIG_LOGICAL_CPUS==1 + || (id.coreid != 0) +#endif + ) { + stop_this_cpu(); + } + } w83627hf_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); @@ -264,69 +251,25 @@ static void main(unsigned long bist) /* Halt if there was a built in self test failure */ report_bist_failure(bist); - + setup_s4882_resource_map(); + needs_reset = setup_coherent_ht_domain(); -#if 0 - needs_reset |= ht_setup_chain(PCI_DEV(0, 0x18, 0), 0xa0); -#else + +#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(); -#endif if (needs_reset) { print_info("ht reset -\r\n"); soft_reset(); } -#if 0 - dump_pci_devices(); -#endif enable_smbus(); -#if 0 -// activate_spd_rom(&cpu[0]); -// dump_spd_registers(&cpu[0]); - -// for(i=0;i<4;i++) { -// activate_spd_rom(&cpu[i]); -// dump_smbus_registers(); -// } - for(i=1;i<256;i=i*2) { - change_i2c_mux(i); - dump_smbus_registers(); - } - -#endif memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu); - -#if 0 - dump_pci_devices(); -#endif -#if 0 - dump_pci_device(PCI_DEV(0, 0x18, 1)); -#endif - - /* Check all of memory */ -#if 0 - msr_t msr; - msr = rdmsr(TOP_MEM2); - print_debug("TOP_MEM2: "); - print_debug_hex32(msr.hi); - print_debug_hex32(msr.lo); - print_debug("\r\n"); -#endif -/* -#if 0 - ram_check(0x00000000, msr.lo+(msr.hi<<32)); -#else -#if TOTAL_CPUS < 2 - // Check 16MB of memory @ 0 - ram_check(0x00000000, 0x01000000); -#else - // Check 16MB of memory @ 2GB - ram_check(0x80000000, 0x81000000); -#endif -#endif -*/ + } diff --git a/src/mainboard/tyan/s4882/cmos.layout b/src/mainboard/tyan/s4882/cmos.layout index ea027282c..c1f3d7531 100644 --- a/src/mainboard/tyan/s4882/cmos.layout +++ b/src/mainboard/tyan/s4882/cmos.layout @@ -32,6 +32,7 @@ entries 395 1 e 1 hw_scrubber 396 1 e 1 interleave_chip_selects 397 2 e 8 max_mem_clock +399 1 e 2 dual_core 400 1 e 1 power_on_after_fail 412 4 e 6 debug_level 416 4 e 7 boot_first diff --git a/src/mainboard/tyan/s4882/failover.c b/src/mainboard/tyan/s4882/failover.c index 2c8fb0041..9d793f447 100644 --- a/src/mainboard/tyan/s4882/failover.c +++ b/src/mainboard/tyan/s4882/failover.c @@ -11,18 +11,33 @@ #include "cpu/x86/lapic/boot_cpu.c" #include "northbridge/amd/amdk8/reset_test.c" +#if CONFIG_LOGICAL_CPUS==1 +#include "cpu/amd/dualcore/dualcore_id.c" +#else +#include "cpu/amd/model_fxx/node_id.c" +#endif + + static unsigned long main(unsigned long bist) -{ - - unsigned nodeid; - - /* Make cerain my local apic is useable */ - enable_lapic(); - - nodeid = lapicid() & 0xf; - - /* Is this a cpu only reset? */ - if (cpu_init_detected(nodeid)) { +{ +#if CONFIG_LOGICAL_CPUS==1 + struct node_core_id id; +#else + unsigned nodeid; +#endif + /* Make cerain my local apic is useable */ +// enable_lapic(); + +#if CONFIG_LOGICAL_CPUS==1 + id = get_node_core_id_x(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(id.nodeid)) { +#else +// nodeid = lapicid() & 0xf; + nodeid = get_node_id(); + /* Is this a cpu only reset? */ + if (cpu_init_detected(nodeid)) { +#endif if (last_boot_normal()) { goto normal_image; } else { @@ -37,7 +52,6 @@ static unsigned long main(unsigned long bist) goto fallback_image; } } - /* Nothing special needs to be done to find bus 0 */ /* Allow the HT devices to be found */ diff --git a/src/mainboard/tyan/s4882/irq_tables.c b/src/mainboard/tyan/s4882/irq_tables.c index dd293ca96..6bd4a2123 100644 --- a/src/mainboard/tyan/s4882/irq_tables.c +++ b/src/mainboard/tyan/s4882/irq_tables.c @@ -18,7 +18,7 @@ const struct irq_routing_table intel_irq_routing_table = { 0x7400, /* Device */ 0, /* Crap (miniport) */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ - 0x9a, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */ + 0x5b, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */ { {0,0xc0, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, {1,(3<<3)|0, {{0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}, {0, 0xdef8}}, 0, 0}, diff --git a/src/mainboard/tyan/s4882/mptable.c b/src/mainboard/tyan/s4882/mptable.c index 98dd0cbf6..c16603a92 100644 --- a/src/mainboard/tyan/s4882/mptable.c +++ b/src/mainboard/tyan/s4882/mptable.c @@ -3,12 +3,15 @@ #include #include #include +#if CONFIG_LOGICAL_CPUS==1 +#include +#endif void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; static const char oem[8] = "TYAN "; - static const char productid[12] = "S48822 "; + static const char productid[12] = "S4882 "; struct mp_config_table *mc; unsigned char bus_num; @@ -16,6 +19,10 @@ void *smp_write_config_table(void *v) unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; + unsigned apicid_base; + unsigned apicid_8111; + unsigned apicid_8131_1; + unsigned apicid_8131_2; mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); memset(mc, 0, sizeof(*mc)); @@ -86,7 +93,15 @@ void *smp_write_config_table(void *v) /*I/O APICs: APIC ID Version State Address*/ - smp_write_ioapic(mc, 4, 0x11, 0xfec00000); +#if CONFIG_LOGICAL_CPUS==1 + apicid_base = get_apicid_base(3); +#else + apicid_base = CONFIG_MAX_PHYSICAL_CPUS; +#endif + apicid_8111 = apicid_base+0; + apicid_8131_1 = apicid_base+1; + apicid_8131_2 = apicid_base+2; + smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); { device_t dev; struct resource *res; @@ -94,91 +109,91 @@ void *smp_write_config_table(void *v) if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x05, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { - smp_write_ioapic(mc, 0x06, 0x11, res->base); + smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base); } } } /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# -*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x4, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, 0x4, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, 0x4, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, 0x4, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, 0x4, 0x4); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, 0x4, 0x5); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, 0x4, 0x6); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, 0x4, 0x7); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, 0x4, 0x8); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, 0x4, 0x9); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xa, 0x4, 0xa); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xb, 0x4, 0xb); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, 0x4, 0xc); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, 0x4, 0xd); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, 0x4, 0xe); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, 0x4, 0xf); +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_8111, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_8111, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_8111, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x5, apicid_8111, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_8111, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_8111, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_8111, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x9, apicid_8111, 0x9); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xa, apicid_8111, 0xa); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xb, apicid_8111, 0xb); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_8111, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_8111, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_8111, 0xe); + 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, 0x4, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (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, 0x4, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); //On Board Via USB 1.1 and 2 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|0, 0x4, 0x11); //1.1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|1, 0x4, 0x10); //1.1 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|2, 0x4, 0x12); //2 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|0, apicid_8111, 0x11); //1.1 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|1, apicid_8111, 0x10); //1.1 + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|2, apicid_8111, 0x12); //2 //Slot 5 PCI 32 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, 0x4, 0x10); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, 0x4, 0x11); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, 0x4, 0x12); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, 0x4, 0x13); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, apicid_8111, 0x10); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, apicid_8111, 0x11); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, apicid_8111, 0x12); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, apicid_8111, 0x13); // //On Board SI Serial ATA - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, 0x4, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, apicid_8111, 0x13); //On Board ATI Display Adapter - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, 0x4, 0x12); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, apicid_8111, 0x12); //Slot 4 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, 0x5, 0x3); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, 0x5, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|2, 0x5, 0x1);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|3, 0x5, 0x2);// + 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); + 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);// //Slot 3 PCIX 100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, 0x5, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|1, 0x5, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, 0x5, 0x0);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|3, 0x5, 0x1);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2); + 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)|3, apicid_8131_1, 0x1);// //On Board LSI scsi and NIC - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, 0x5, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|1, 0x5, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, 0x5, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, 0x5, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0); + 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, (9<<2)|0, apicid_8131_1, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, apicid_8131_1, 0x1); //Slot 2 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, 0x6, 0x0); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, 0x6, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, 0x6, 0x2); // - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, 0x6, 0x3); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<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)|2, apicid_8131_2, 0x2); // + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); // //Slot 1 PCI-X 133/100/66 - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, 0x6, 0x1); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, 0x6, 0x2); - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, 0x6, 0x3);// - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, 0x6, 0x0);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, apicid_8131_2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, apicid_8131_2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, apicid_8131_2, 0x3);// + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, apicid_8131_2, 0x0);// /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0); diff --git a/src/mainboard/tyan/s4882/resourcemap.c b/src/mainboard/tyan/s4882/resourcemap.c index 423ac3cf0..8d9307c68 100644 --- a/src/mainboard/tyan/s4882/resourcemap.c +++ b/src/mainboard/tyan/s4882/resourcemap.c @@ -252,7 +252,7 @@ static void setup_s4882_resource_map(void) * [31:24] Bus Number Limit i * This field defines the highest bus number in configuration regin i */ - PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000103, +// PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0xff000103, PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000, PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000, diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c index 8ca1bfbf8..ca7791cf6 100644 --- a/src/northbridge/amd/amdk8/coherent_ht.c +++ b/src/northbridge/amd/amdk8/coherent_ht.c @@ -92,14 +92,22 @@ typedef uint32_t u32; #define K8_HT_FREQ_1G_SUPPORT 0 #endif -#ifndef CONFIG_MAX_CPUS_4_BUT_MORE_INSTALLED -#define CONFIG_MAX_CPUS_4_BUT_MORE_INSTALLED 0 +#ifndef K8_HT_CHECK_PENDING_LINK + #if CONFIG_MAX_PHYSICAL_CPUS >= 4 + #define K8_HT_CHECK_PENDING_LINK 1 + #else + #define K8_HT_CHECK_PENDING_LINK 0 + #endif +#endif + +#ifndef CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED +#define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0 #endif static inline void print_linkn (const char *strval, uint8_t byteval) { -#if 1 +#if 0 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n"); #endif } @@ -203,7 +211,7 @@ static void fill_row(u8 node, u8 row, u32 value) pci_write_config32(NODE_HT(node), 0x40+(row<<2), value); } -#if CONFIG_MAX_CPUS > 1 +#if CONFIG_MAX_PHYSICAL_CPUS > 1 static u8 link_to_register(int ldt) { /* @@ -247,6 +255,23 @@ static void rename_temp_node(u8 node) print_spew(" done.\r\n"); } +#if K8_HT_CHECK_PENDING_LINK == 1 +static void wait_ht_stable(uint8_t node) +{ + uint8_t linkn; + for(linkn = 0; linkn<3; linkn++) { + uint8_t regpos; + uint16_t i; + uint32_t reg; + regpos = 0x98 + 0x20 * linkn; + for(i = 0; i < 0xff; i++) { //wait to make sure it is done + reg = pci_read_config32(NODE_HT(node), regpos); + if ((reg & 0x10) == 0) break; // init complete + udelay(10); + } + } +} +#endif static int check_connection(u8 dest) { @@ -260,21 +285,32 @@ 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; } -static unsigned read_freq_cap(device_t dev, unsigned pos) +static uint16_t read_freq_cap(device_t dev, uint8_t pos) { /* Handle bugs in valid hypertransport frequency reporting */ - unsigned freq_cap; + uint16_t freq_cap; uint32_t id; freq_cap = pci_read_config16(dev, pos); freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */ - /* AMD K8 Unsupported 1Ghz? */ + + #if K8_HT_FREQ_1G_SUPPORT == 1 + if (!is_cpu_pre_e0()) + return freq_cap; + #endif + id = pci_read_config32(dev, 0); + + /* AMD K8 Unsupported 1Ghz? */ if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) { freq_cap &= ~(1 << HT_FREQ_1000Mhz); } @@ -338,7 +374,7 @@ static int optimize_connection(device_t node1, uint8_t link1, device_t node2, ui /* Set node1's widths */ pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width); - /* Calculate node2's width */ + // * Calculate node2's width */ width = ((width & 0x70) >> 4) | ((width & 0x7) << 4); /* See if I am changing node2's width */ @@ -351,13 +387,38 @@ static int optimize_connection(device_t node1, uint8_t link1, device_t node2, ui return needs_reset; } +static uint8_t get_linkn_first(uint8_t byte) +{ + if(byte & 0x02) { byte = 0; } + else if(byte & 0x04) { byte = 1; } + else if(byte & 0x08) { byte = 2; } + return byte; +} + +static uint8_t get_linkn_last(uint8_t byte) +{ + if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; } + if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; } + if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; } + return byte>>4; +} + +static uint8_t get_linkn_last_count(uint8_t byte) +{ + byte &= 0x0f; + if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; } + if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; } + if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; } + return byte>>4; +} + static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/ { - unsigned linkn; + uint8_t linkn; uint32_t val; val = 1; for(linkn = 0; linkn<3; linkn++) { - unsigned regpos; + uint8_t regpos; uint32_t reg; regpos = 0x98 + 0x20 * linkn; reg = pci_read_config32(NODE_HT(source), regpos); @@ -378,12 +439,16 @@ static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn) if(((source &1)!=(dest &1)) #if CROSS_BAR_47_56 - && (source<4) && (dest<4) + && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here + //(6,5) (7,4) should be here #endif ){ val |= (1<<16); } else { - /*for CROSS_BAR_47_56 47, 74, 56, 65 should be here too*/ + /*for CROSS_BAR_47_56 47, 56, should be here too + and for 47, 56, 57, 75, 46, 64 we need to substract another link to + 6, 7, 6, 6, 7, 7 + */ val_s = get_row(temp, source); val |= ((val_s>>16) - (1<<(linkn+1)))<<16; } @@ -391,37 +456,43 @@ static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn) fill_row(temp,dest, val ); } -static void setup_row_direct(u8 source, u8 dest, u8 linkn){ - setup_row_direct_x(source, source, dest, linkn); +#if CROSS_BAR_47_56 +static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) { + uint32_t val; + val = get_row(source, dest); + val -= link_connection(source, kickout)<<16; + fill_row(source, dest, val); } -static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){ - setup_row_direct_x(7, source, dest, linkn); -} +static void opt_broadcast_rt_group(const u8 *conn, int num) { + int i; -static uint8_t get_linkn_first(uint8_t byte) -{ - if(byte & 0x02) { byte = 0; } - else if(byte & 0x04) { byte = 1; } - else if(byte & 0x08) { byte = 2; } - return byte; + for(i=0; i>4; +static void setup_row_direct(u8 source, u8 dest, u8 linkn){ + setup_row_direct_x(source, source, dest, linkn); } -static uint8_t get_linkn_last_count(uint8_t byte) -{ - byte &= 0x0f; - if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; } - if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; } - if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; } - return byte>>4; +static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){ + setup_row_direct_x(7, source, dest, linkn); } static void setup_temp_row(u8 source, u8 dest) @@ -462,10 +533,10 @@ static void setup_remote_node(u8 node) print_spew("done\r\n"); } -#endif /* CONFIG_MAX_CPUS > 1*/ +#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/ -#if CONFIG_MAX_CPUS > 2 +#if CONFIG_MAX_PHYSICAL_CPUS > 2 #if !CROSS_BAR_47_56 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest) #else @@ -497,7 +568,7 @@ static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 dif if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/ val_s -= val & 0xff; -#if (CONFIG_MAX_CPUS > 4) || (CONFIG_MAX_CPUS_4_BUT_MORE_INSTALLED == 1) +#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1) uint8_t byte; /* Some node have two links left * don't worry we only have (2, (3 as source need to handle @@ -508,7 +579,19 @@ static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 dif if(source 2*/ +#endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/ static void setup_uniprocessor(void) { print_spew("Enabling UP settings\r\n"); +#if CONFIG_LOGICAL_CPUS==1 + unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3; + if (tmp>0) return; +#endif disable_probes(); } @@ -595,7 +682,7 @@ struct setup_smp_result { int needs_reset; }; -#if CONFIG_MAX_CPUS > 2 +#if CONFIG_MAX_PHYSICAL_CPUS > 2 static int optimize_connection_group(const u8 *opt_conn, int num) { int needs_reset = 0; int i; @@ -608,7 +695,7 @@ static int optimize_connection_group(const u8 *opt_conn, int num) { } #endif -#if CONFIG_MAX_CPUS > 1 +#if CONFIG_MAX_PHYSICAL_CPUS > 1 static struct setup_smp_result setup_smp2(void) { struct setup_smp_result result; @@ -635,7 +722,7 @@ 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); /* We found 2 nodes so far */ @@ -645,7 +732,7 @@ static struct setup_smp_result setup_smp2(void) setup_row_local(7,1); setup_remote_row_direct(1, 0, byte); -#if (CONFIG_MAX_CPUS > 4) || (CONFIG_MAX_CPUS_4_BUT_MORE_INSTALLED == 1) +#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1) val = get_row(7,1); byte = (val>>16) & 0xfe; byte = get_linkn_last_count(byte); @@ -660,7 +747,7 @@ 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); /* We found 2 nodes so far */ @@ -679,16 +766,16 @@ static struct setup_smp_result setup_smp2(void) /*don't need and it is done by clear_dead_links */ clear_temp_row(0); #endif - - result.needs_reset = optimize_connection( + + result.needs_reset |= optimize_connection( NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)), NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) ); return result; } -#endif /*CONFIG_MAX_CPUS > 1 */ +#endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */ -#if CONFIG_MAX_CPUS > 2 +#if CONFIG_MAX_PHYSICAL_CPUS > 2 static struct setup_smp_result setup_smp4(int needs_reset) { @@ -776,7 +863,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) setup_temp_row(2,3); check_connection(7); /* to 3*/ -#if (CONFIG_MAX_CPUS > 4) || (CONFIG_MAX_CPUS_4_BUT_MORE_INSTALLED == 1) +#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 */ if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/ val = get_row(7,3); @@ -797,7 +884,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) print_linkn("(3,2) link=", byte); setup_remote_row_direct(3,2, byte); -#if (CONFIG_MAX_CPUS > 4) || (CONFIG_MAX_CPUS_4_BUT_MORE_INSTALLED == 1) +#if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1) /* set link from 3 to 5 before enable it*/ val = get_row(7,3); byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1); @@ -861,15 +948,15 @@ static struct setup_smp_result setup_smp4(int needs_reset) 2,3, }; - result.needs_reset = optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0])); + result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0])); return result; } -#endif /* CONFIG_MAX_CPUS > 2 */ +#endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */ -#if CONFIG_MAX_CPUS > 4 +#if CONFIG_MAX_PHYSICAL_CPUS > 4 static struct setup_smp_result setup_smp6(int needs_reset) { @@ -975,7 +1062,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) setup_temp_row(4,5); check_connection(7); /* to 5*/ -#if CONFIG_MAX_CPUS > 6 +#if CONFIG_MAX_PHYSICAL_CPUS > 6 /* We need to find out which link is to node5 */ if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/ @@ -1075,15 +1162,15 @@ static struct setup_smp_result setup_smp6(int needs_reset) 4, 5, #endif }; - result.needs_reset = optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0])); + result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0])); return result; } -#endif /* CONFIG_MAX_CPUS > 4 */ +#endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */ -#if CONFIG_MAX_CPUS > 6 +#if CONFIG_MAX_PHYSICAL_CPUS > 6 static struct setup_smp_result setup_smp8(int needs_reset) { @@ -1114,10 +1201,10 @@ static struct setup_smp_result setup_smp8(int needs_reset) return result; } #if TRY_HIGH_FIRST == 1 - byte &= 3; /* bit [3,2] is count-1 or 2*/ -#else byte = ((val>>16) & 0xfe) - link_connection(4,2); byte = get_linkn_first(byte); /*Min link to 6*/ +#else + byte &= 3; /* bit [3,2] is count-1 or 2*/ #endif print_linkn("(4,6) link=", byte); setup_row_direct(4, 6, byte); @@ -1153,7 +1240,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) /*1, 7, 3, 0,*/ 2, 6, 4, 0, /*2, 7, 4, 0,*/ - 3, 6, 5, 0, + 3, 6, 5, 1, /*3, 7, 5, 0,*/ #endif }; @@ -1190,9 +1277,9 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(5,5); byte = ((val>>16) & 0xfe) - link_connection(5,3); #if TRY_HIGH_FIRST == 1 - byte = get_linkn_last(byte); + byte = get_linkn_first(byte); #else - byte = get_linkn_first(byte); + byte = get_linkn_last(byte); #endif print_linkn("(5,6) link=", byte); setup_row_direct(5, 6, byte); @@ -1339,30 +1426,93 @@ static struct setup_smp_result setup_smp8(int needs_reset) 7, 3, 7, 4, #else + + + 4, 5, 6, 1, + 5, 4, 7, 1, + + 6, 1, 5, 0, // or 4, 1 + 6, 2, 4, 0, + 6, 3, 5, 0, // or 4, 1 + + 7, 0, 4, 0, // or 5, 1 + 7, 1, 5, 0, + 7, 2, 4, 0, // or 5, 1 + 7, 3, 5, 0, + 0, 7, 2, 0, /* restore it*/ 1, 7, 3, 0, - 2, 7, 4, 0, + 2, 7, 4, 1, 3, 7, 5, 0, - 6, 1, 5, 0, - 6, 2, 4, 0, - 6, 3, 5, 0, - - 7, 0, 4, 0, - 7, 1, 5, 0, - 7, 2, 4, 0, - 7, 3, 5, 0, + 2, 5, 4, 1, /* reset it */ + 3, 4, 5, 1, + + 4, 1, 2, 1, /* reset it */ + 4, 3, 2, 1, + + 5, 2, 3, 1, /* reset it */ + 5, 0, 3, 1, - 4, 5, 6, 1, - 5, 4, 7, 1, #endif }; setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0])); + +#if CROSS_BAR_47_56 + /* for 47, 56, 57, 75, 46, 64 we need to substract another link to + 6, 7, 6, 6, 7, 7 */ + static const u8 conn8_4[] = { +//direct + 4, 7, 6, + 5, 6, 7, + 5, 7, 6, + 7, 5, 6, + 4, 6, 7, + 6, 4, 7, + +//in direct + 0, 6, 1, + 0, 7, 1, + + 1, 6, 0, + 1, 7, 0, + + 2, 6, 3, +// 2, 7, 3, + + +// 3, 6, 1, + + 3, 7, 2, + + 6, 0, 7, + 6, 1, 7, // needed for via 5 + 6, 1, 4, // ??? + 6, 2, 7, + 6, 3, 7, // needed for via 5 + 6, 3, 4, //??? + 7, 0, 6, // needed for via 4 + 7, 0, 5, //??? + 7, 1, 6, + 7, 2, 6, // needed for via 4 + 7, 2, 5, //??? + 7, 3, 6, + }; + + opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0])); + + static const u8 conn8_5[] = { + 2, 7, 0, + + 3, 6, 1, + }; + + opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0])); +#endif + + /* ready to enable RT for Node 7 */ enable_routing(7); /* enable routing on node 7 (temp.) */ - static const uint8_t opt_conn8[] ={ 4, 6, @@ -1374,15 +1524,15 @@ static struct setup_smp_result setup_smp8(int needs_reset) 6, 7, }; /* optimize physical connections - by LYH */ - result.needs_reset = optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0])); + result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0])); return result; } -#endif /* CONFIG_MAX_CPUS > 6 */ +#endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */ -#if CONFIG_MAX_CPUS > 1 +#if CONFIG_MAX_PHYSICAL_CPUS > 1 static struct setup_smp_result setup_smp(void) { @@ -1391,17 +1541,17 @@ static struct setup_smp_result setup_smp(void) print_spew("Enabling SMP settings\r\n"); result = setup_smp2(); -#if CONFIG_MAX_CPUS > 2 +#if CONFIG_MAX_PHYSICAL_CPUS > 2 if(result.nodes == 2) result = setup_smp4(result.needs_reset); #endif -#if CONFIG_MAX_CPUS > 4 +#if CONFIG_MAX_PHYSICAL_CPUS > 4 if(result.nodes == 4) result = setup_smp6(result.needs_reset); #endif -#if CONFIG_MAX_CPUS > 6 +#if CONFIG_MAX_PHYSICAL_CPUS > 6 if(result.nodes == 6) result = setup_smp8(result.needs_reset); #endif @@ -1424,7 +1574,7 @@ static unsigned verify_mp_capabilities(unsigned nodes) } switch(mask) { -#if CONFIG_MAX_CPUS > 2 +#if CONFIG_MAX_PHYSICAL_CPUS > 2 case 0x02: /* MPCap */ if(nodes > 2) { print_err("Going back to DP\r\n"); @@ -1449,7 +1599,7 @@ static void clear_dead_routes(unsigned nodes) { int last_row; int node, row; -#if CONFIG_MAX_CPUS > 6 +#if CONFIG_MAX_PHYSICAL_CPUS > 6 if(nodes==8) return;/* don't touch (7,7)*/ #endif last_row = nodes; @@ -1471,12 +1621,38 @@ static void clear_dead_routes(unsigned nodes) fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101); } } -#endif /* CONFIG_MAX_CPUS > 1 */ +#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */ + +#if CONFIG_LOGICAL_CPUS==1 +static unsigned verify_dualcore(unsigned nodes) +{ + unsigned node, totalcpus, tmp; + + totalcpus = 0; + for (node=0; node> 12) & 3 ; + totalcpus += (tmp + 1); + } + + return totalcpus; + +} +#endif static void coherent_ht_finalize(unsigned nodes) { unsigned node; int rev_a0; +#if CONFIG_LOGICAL_CPUS==1 + unsigned total_cpus; + + if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /* dual_core */ + total_cpus = verify_dualcore(nodes); + } + else { + total_cpus = nodes; + } +#endif /* set up cpu count and node count and enable Limit * Config Space Range for all available CPUs. @@ -1494,7 +1670,11 @@ static void coherent_ht_finalize(unsigned nodes) /* Set the Total CPU and Node count in the system */ val = pci_read_config32(dev, 0x60); val &= (~0x000F0070); +#if CONFIG_LOGICAL_CPUS==1 + val |= ((total_cpus-1)<<16)|((nodes-1)<<4); +#else val |= ((nodes-1)<<16)|((nodes-1)<<4); +#endif pci_write_config32(dev, 0x60, val); /* Only respond to real cpu pci configuration cycles @@ -1557,7 +1737,7 @@ static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset) } } - else { + else if(is_cpu_pre_d0()) { // d0 later don't need it uint32_t cmd_ref; /* Errata 98 * Set Clk Ramp Hystersis to 7 @@ -1607,9 +1787,13 @@ static int setup_coherent_ht_domain(void) { struct setup_smp_result result; +#if K8_HT_CHECK_PENDING_LINK == 1 + //needed? + wait_ht_stable(0); +#endif enable_bsp_routing(); -#if CONFIG_MAX_CPUS > 1 +#if CONFIG_MAX_PHYSICAL_CPUS > 1 result = setup_smp(); result.nodes = verify_mp_capabilities(result.nodes); clear_dead_routes(result.nodes); diff --git a/src/northbridge/amd/amdk8/cpu_rev.c b/src/northbridge/amd/amdk8/cpu_rev.c index 15b4cf631..1eb47f85f 100644 --- a/src/northbridge/amd/amdk8/cpu_rev.c +++ b/src/northbridge/amd/amdk8/cpu_rev.c @@ -1,25 +1,46 @@ #include static int is_cpu_rev_a0(void) { - return (cpuid_eax(1) & 0xffef) == 0x0f00; + return (cpuid_eax(1) & 0xfffef) == 0x0f00; +} +//AMD_D0_SUPPORT +static int is_cpu_pre_d0(void) +{ + return (cpuid_eax(1) & 0xfff0f) < 0x10f00; +} + +static int is_cpu_d0(void) +{ + return (cpuid_eax(1) & 0xfff0f) == 0x10f00; +} + +//AMD_E0_SUPPORT +static int is_cpu_pre_e0(void) +{ + return (cpuid_eax(1) & 0xfff0f) < 0x20f00; +} + +static int is_cpu_e0(void) +{ + return (cpuid_eax(1) & 0xfff00) == 0x20f00; } static int is_cpu_pre_c0(void) { - return (cpuid_eax(1) & 0xffef) < 0x0f48; + return (cpuid_eax(1) & 0xfffef) < 0x0f48; } static int is_cpu_c0(void) { - return (cpuid_eax(1) & 0xffef) == 0x0f48; + return (cpuid_eax(1) & 0xfffef) == 0x0f48; } static int is_cpu_pre_b3(void) { - return (cpuid_eax(1) & 0xffef) < 0x0f41; + return (cpuid_eax(1) & 0xfffef) < 0x0f41; } static int is_cpu_b3(void) { - return (cpuid_eax(1) & 0xffef) == 0x0f41; + return (cpuid_eax(1) & 0xfffef) == 0x0f41; } diff --git a/src/northbridge/amd/amdk8/debug.c b/src/northbridge/amd/amdk8/debug.c index 7686662d0..eeba1e1e2 100644 --- a/src/northbridge/amd/amdk8/debug.c +++ b/src/northbridge/amd/amdk8/debug.c @@ -27,10 +27,6 @@ static void print_pci_devices(void) continue; } print_debug_pci_dev(dev); - print_debug(" "); - print_debug_hex16(id & 0xffff); - print_debug(" "); - print_debug_hex16((id>>16) & 0xffff); print_debug("\r\n"); } } @@ -113,7 +109,6 @@ static void dump_spd_registers(const struct mem_controller *ctrl) } status = smbus_read_byte(device, j); if (status < 0) { - print_debug("bad device\r\n"); break; } byte = status & 0xff; @@ -139,7 +134,6 @@ static void dump_spd_registers(const struct mem_controller *ctrl) } status = smbus_read_byte(device, j); if (status < 0) { - print_debug("bad device\r\n"); break; } byte = status & 0xff; @@ -152,29 +146,25 @@ static void dump_spd_registers(const struct mem_controller *ctrl) } static void dump_smbus_registers(void) { - int i; + unsigned device; print_debug("\r\n"); - for(i = 1; i < 0x80; i++) { - unsigned device; - device = i; + for(device = 1; device < 0x80; device++) { int j; + if( smbus_read_byte(device, 0) < 0 ) continue; print_debug("smbus: "); print_debug_hex8(device); for(j = 0; j < 256; j++) { int status; unsigned char byte; + status = smbus_read_byte(device, j); + if (status < 0) { + break; + } 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 status="); - print_debug_hex32(status); - print_debug("\r\n"); - break; - } byte = status & 0xff; print_debug_hex8(byte); print_debug_char(' '); diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c index d76a3e873..ec767456e 100644 --- a/src/northbridge/amd/amdk8/incoherent_ht.c +++ b/src/northbridge/amd/amdk8/incoherent_ht.c @@ -123,6 +123,9 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos) /* AMD K8 Unsupported 1Ghz? */ if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) { + #if K8_HT_FREQ_1G_SUPPORT == 1 + if (is_cpu_pre_e0()) // CK804 support 1G? + #endif freq_cap &= ~(1 << HT_FREQ_1000Mhz); } diff --git a/src/northbridge/amd/amdk8/misc_control.c b/src/northbridge/amd/amdk8/misc_control.c index 379d8b1dc..4ac6ef473 100644 --- a/src/northbridge/amd/amdk8/misc_control.c +++ b/src/northbridge/amd/amdk8/misc_control.c @@ -158,7 +158,7 @@ static void misc_control_init(struct device *dev) needs_reset = 1; /* Needed? */ } } - else { + else if(is_cpu_pre_d0()) { uint32_t dcl; f2_dev = dev_find_slot(0, dev->path.u.pci.devfn - 3 + 2); /* Errata 98 @@ -187,7 +187,7 @@ 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 please */ + if ((link_type & 7) == 3) { /* Only handle coherent link here */ 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 3d30430d3..89602f37a 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -1,3 +1,9 @@ +/* This should be done by Eric + 2004.12 yhlu add dual core support + 2005.01 yhlu add support move apic before pci_domain in MB Config.lb + 2005.02 yhlu add e0 memory hole support +*/ + #include #include #include @@ -9,11 +15,22 @@ #include #include #include + +#include + +#if CONFIG_LOGICAL_CPUS==1 +#include +#include +#endif + #include "chip.h" #include "root_complex/chip.h" #include "northbridge.h" #include "amdk8.h" -#include + +#if K8_E0_MEM_HOLE_SIZEK != 0 +#include "./cpu_rev.c" +#endif #define FX_DEVS 8 static device_t __f0_dev[FX_DEVS]; @@ -387,8 +404,8 @@ static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned limit |= (nodeid & 7); if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) { - printk_spew("%s, enabling legacy VGA IO forwarding for %s link %s\n", - __func__, dev_path(dev), link); + printk_spew("%s, enabling legacy VGA IO forwarding for %s link %s\n", + __func__, dev_path(dev), link); base |= PCI_IO_BASE_VGA_EN; } if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) { @@ -440,7 +457,7 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid) break; } } - + printk_spew("%s: link %d has VGA device\n", __func__, link); /* no VGA card installed */ @@ -468,6 +485,7 @@ static void amdk8_create_vga_resource(device_t dev, unsigned nodeid) /* release the temp resource */ resource->flags = 0; + } static void amdk8_set_resources(device_t dev) @@ -652,6 +670,26 @@ static void pci_domain_set_resources(device_t dev) mmio_basek &= ~((64*1024) - 1); #endif +#if K8_E0_MEM_HOLE_SIZEK != 0 + if (!is_cpu_pre_e0()) + for (i = 0; i < 8; i++) { + uint32_t base; + base = f1_read_config32(0x40 + (i << 3)); + if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) { + continue; + } + + base = pci_read_config32(__f1_dev[i], 0xf0); + if((base & 1)==0) continue; + base &= 0xff<<24; + base >>= 10; + if (mmio_basek > base) { + mmio_basek = base; + } + break; // only one hole + } +#endif + idx = 10; for (i = 0; i < 8; i++) { uint32_t base, limit; @@ -672,6 +710,7 @@ static void pci_domain_set_resources(device_t dev) sizek = limitk - ((8*64)+(16*16)); } + /* See if I need to split the region to accomodate pci memory space */ if ((basek < mmio_basek) && (limitk > mmio_basek)) { @@ -716,24 +755,36 @@ 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 i, j; - int enable_apic_ext_id = 0; - int bsp_apic_id = lapicid(); // bsp apicid - int apic_id_offset = bsp_apic_id; - - 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)) { - enable_apic_ext_id = 1; - if (apic_id_offset==0) { - //bsp apic id is not changed - apic_id_offset = 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; + +#if CONFIG_LOGICAL_CPUS==1 + int e0_later_single_core; + int 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) + // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp??? and differ d0 and e0 single core + + 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)) { + enable_apic_ext_id = 1; + 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]; @@ -741,60 +792,102 @@ static unsigned int cpu_bus_scan(device_t dev, unsigned int max) device_t dev, cpu; struct device_path cpu_path; - /* Find the cpu's memory controller */ - dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3)); - if(!dev) { - // in case in mb Config.lb we move apic cluster before pci_domain and not set that for second CPU + /* Find the cpu's memory controller */ + 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; + 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); + 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); } - } - } - - /* Build the cpu device path */ - cpu_path.type = DEVICE_PATH_APIC; - cpu_path.u.apic.apic_id = i; + } + } - /* See if I can find the cpu */ - cpu = find_dev_path(cpu_bus, &cpu_path); +#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 + + printk_debug(" %s siblings=%d\r\n", dev_path(dev), j); + + if(nb_cfg_54) { + // For e0 single core if nb_cfg_54 is set, apicid will be 0, 2, 4.... + // ----> you can mixed single core e0 and dual core e0 at any sequence + // That is the typical case + + if(j == 0 ){ + e0_later_single_core = is_e0_later_in_bsp(i); // single core + } else { + e0_later_single_core = 0; + } + if(e0_later_single_core) { + printk_debug("\tFound e0 single core\r\n"); + j=1; + } + + if(siblings > j ) { + //actually we can't be here, because d0 nb_cfg_54 can not be set + //even worse is_e0_later_in_bsp() can not find out if it is d0 or e0 - /* 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; + die("When NB_CFG_54 is set, if you want to mix e0 (single core and dual core) and single core(pre e0) CPUs, you need to put all the single core (pre e0) CPUs before all the (e0 single or dual core) CPUs\r\n"); + } + else { + siblings = j; + } + } else { + siblings = j; } } - - /* 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_idpath.u.apic.apic_id > 0) || (bsp_apic_id!=0) ) - cpu->path.u.apic.apic_id += apic_id_offset; +#endif + +#if CONFIG_LOGICAL_CPUS==1 + for (j = 0; j <= (e0_later_single_core?0:siblings); j++ ) { +#else + 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); } - } - printk_debug("CPU: %s %s\n", dev_path(cpu), - cpu->enabled?"enabled":"disabled"); - } + 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_idpath.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/raminit.c b/src/northbridge/amd/amdk8/raminit.c index e4043493a..3bdf8c3b1 100644 --- a/src/northbridge/amd/amdk8/raminit.c +++ b/src/northbridge/amd/amdk8/raminit.c @@ -1,3 +1,9 @@ +/* This should be done by Eric + 2004.11 yhlu add 4 rank DIMM support + 2004.12 yhlu add D0 support + 2005.02 yhlu add E0 memory hole support +*/ + #include #include #include @@ -7,10 +13,16 @@ #if (CONFIG_LB_MEM_TOPK & (CONFIG_LB_MEM_TOPK -1)) != 0 # error "CONFIG_LB_MEM_TOPK must be a power of 2" #endif + +#ifndef K8_4RANK_DIMM_SUPPORT +#define K8_4RANK_DIMM_SUPPORT 0 +#endif + +#if 1 static void setup_resource_map(const unsigned int *register_values, int max) { int i; - print_debug("setting up resource map...."); +// print_debug("setting up resource map...."); #if 0 print_debug("\r\n"); #endif @@ -37,7 +49,13 @@ static void setup_resource_map(const unsigned int *register_values, int max) pci_write_config32(register_values[i], reg); #endif } - print_debug("done.\r\n"); +// print_debug("done.\r\n"); +} +#endif + +static int controller_present(const struct mem_controller *ctrl) +{ + return pci_read_config32(ctrl->f0, 0) == 0x11001022; } static void sdram_set_registers(const struct mem_controller *ctrl) @@ -504,6 +522,13 @@ static void sdram_set_registers(const struct mem_controller *ctrl) }; int i; int max; + +#if 1 + if (!controller_present(ctrl)) { +// print_debug("No memory controller present\r\n"); + return; + } +#endif print_spew("setting up CPU"); print_spew_hex8(ctrl->node_id); print_spew(" northbridge registers\r\n"); @@ -585,6 +610,11 @@ static int is_registered(const struct mem_controller *ctrl) struct dimm_size { unsigned long side1; unsigned long side2; + unsigned long rows; + unsigned long col; +#if K8_4RANK_DIMM_SUPPORT == 1 + unsigned long rank; +#endif }; static struct dimm_size spd_get_dimm_size(unsigned device) @@ -594,6 +624,11 @@ static struct dimm_size spd_get_dimm_size(unsigned device) int value, low; sz.side1 = 0; sz.side2 = 0; + sz.rows = 0; + sz.col = 0; +#if K8_4RANK_DIMM_SUPPORT == 1 + sz.rank = 0; +#endif /* 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 @@ -603,11 +638,13 @@ static struct dimm_size spd_get_dimm_size(unsigned device) if (value < 0) goto hw_err; if ((value & 0xf) == 0) goto val_err; sz.side1 += value & 0xf; + sz.rows = 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; + sz.col = value & 0xf; value = spd_read_byte(device, 17); /* banks */ if (value < 0) goto hw_err; @@ -630,7 +667,12 @@ static struct dimm_size spd_get_dimm_size(unsigned device) value = spd_read_byte(device, 5); /* number of physical banks */ if (value < 0) goto hw_err; if (value == 1) goto out; - if (value != 2) goto val_err; + if ((value != 2) && (value != 4 )) { + goto val_err; + } +#if K8_4RANK_DIMM_SUPPORT == 1 + sz.rank = value; +#endif /* Start with the symmetrical case */ sz.side2 = sz.side1; @@ -646,6 +688,7 @@ static struct dimm_size spd_get_dimm_size(unsigned device) 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: @@ -654,10 +697,22 @@ static struct dimm_size spd_get_dimm_size(unsigned device) hw_err: sz.side1 = 0; sz.side2 = 0; + sz.rows = 0; + sz.col = 0; +#if K8_4RANK_DIMM_SUPPORT == 1 + sz.rank = 0; +#endif out: return sz; } +static const unsigned cs_map_aa[15] = { + /* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */ + 0, 1, 3, 6, 0, + 0, 2, 4, 7, 9, + 0, 0, 5, 8,10, +}; + static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index) { uint32_t base0, base1, map; @@ -668,6 +723,11 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz } map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP); map &= ~(0xf << (index * 4)); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + map &= ~(0xf << ( (index + 2) * 4)); + } +#endif /* For each base register. * Place the dimm size in 32 MB quantities in the bits 31 - 21. @@ -679,9 +739,25 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz /* Make certain side1 of the dimm is at least 32MB */ if (sz.side1 >= (25 +3)) { - map |= (sz.side1 - (25 + 3)) << (index *4); + if(is_cpu_pre_d0()) { + map |= (sz.side1 - (25 + 3)) << (index *4); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + map |= (sz.side1 - (25 + 3)) << ( (index + 2) * 4); + } +#endif + } + else { + map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << (index*4); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << ( (index + 2) * 4); + } +#endif + } base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1; } + /* Make certain side2 of the dimm is at least 32MB */ if (sz.side2 >= (25 + 3)) { base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1; @@ -700,12 +776,24 @@ static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz /* Set the appropriate DIMM base address register */ pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), base0); pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), base1); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+4)<<2), base0); + pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+5)<<2), base1); + } +#endif + pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map); /* Enable the memory clocks for this DIMM */ if (base0) { dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH); dch |= DCH_MEMCLK_EN0 << index; +#if K8_4RANK_DIMM_SUPPORT == 1 + if(sz.rank == 4) { + dch |= DCH_MEMCLK_EN0 << (index + 2); + } +#endif pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch); } } @@ -798,10 +886,28 @@ static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) /* 1GB */ (1 << (16 - 4)), /* 2GB */ (1 << (16 - 4)), }; + + static const uint32_t csbase_low_d0[] = { + /* 32MB */ (1 << (13 - 4)), + /* 64MB */ (1 << (14 - 4)), + /* 128MB */ (1 << (14 - 4)), + /* 128MB */ (1 << (15 - 4)), + /* 256MB */ (1 << (15 - 4)), + /* 512MB */ (1 << (15 - 4)), + /* 256MB */ (1 << (16 - 4)), + /* 512MB */ (1 << (16 - 4)), + /* 1GB */ (1 << (16 - 4)), + /* 1GB */ (1 << (17 - 4)), + /* 2GB */ (1 << (17 - 4)), + }; + + /* cs_base_high is not changed */ + uint32_t csbase_inc; int chip_selects, index; int bits; unsigned common_size; + unsigned common_cs_mode; uint32_t csbase, csmask; /* See if all of the memory chip selects are the same size @@ -809,8 +915,10 @@ static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) */ chip_selects = 0; common_size = 0; + common_cs_mode = 0; for(index = 0; index < 8; index++) { unsigned size; + unsigned cs_mode; uint32_t value; value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2)); @@ -828,26 +936,50 @@ static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) if (common_size != size) { return 0; } + + value = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP); + cs_mode =( value >> ((index>>1)*4)) & 0xf; + if(cs_mode == 0 ) continue; + if(common_cs_mode == 0) { + common_cs_mode = cs_mode; + } + /* The size differed fail */ + if(common_cs_mode != cs_mode) { + return 0; + } } + /* Chip selects can only be interleaved when there is * more than one and their is a power of two of them. */ bits = log2(chip_selects); if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) { return 0; - - } - /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */ - if ((bits == 3) && (common_size == (1 << (32 - 3)))) { - print_debug("8 4GB chip selects cannot be interleaved\r\n"); - return 0; } + /* Find the bits of csbase that we need to interleave on */ - if (is_dual_channel(ctrl)) { - csbase_inc = csbase_low[log2(common_size) - 1] << 1; - } else { - csbase_inc = csbase_low[log2(common_size)]; + if(is_cpu_pre_d0()){ + csbase_inc = csbase_low[common_cs_mode]; + if(is_dual_channel(ctrl)) { + /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */ + if ((bits == 3) && (common_size == (1 << (32 - 3)))) { +// print_debug("8 4GB chip selects cannot be interleaved\r\n"); + return 0; + } + csbase_inc <<=1; + } + } + else { + csbase_inc = csbase_low_d0[common_cs_mode]; + if(is_dual_channel(ctrl)) { + if( (bits==3) && (common_cs_mode > 8)) { +// print_debug("8 cs_mode>8 chip selects cannot be interleaved\r\n"); + return 0; + } + csbase_inc <<=1; + } } + /* Compute the initial values for csbase and csbask. * In csbase just set the enable bit and the base to zero. * In csmask set the mask bits for the size and page level interleave. @@ -877,7 +1009,7 @@ static unsigned long interleave_chip_selects(const struct mem_controller *ctrl) static unsigned long order_chip_selects(const struct mem_controller *ctrl) { unsigned long tom; - + /* Remember which registers we have used in the high 8 bits of tom */ tom = 0; for(;;) { @@ -960,6 +1092,25 @@ unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id) return end_k; } +#if K8_E0_MEM_HOLE_SIZEK != 0 +#define K8_E0_MEM_HOLE_LIMITK 4*1024*1024 +#define K8_E0_MEM_HOLE_BASEK (K8_E0_MEM_HOLE_LIMITK - K8_E0_MEM_HOLE_SIZEK ) + +static void set_e0_mem_hole(const struct mem_controller *ctrl, unsigned base_k) +{ + /* Route the addresses to the controller node */ + unsigned val; + + val = pci_read_config32(ctrl->f1,0xf0); + + val &= 0x00ff00fe; + val = (K8_E0_MEM_HOLE_BASEK << 10) | ((K8_E0_MEM_HOLE_SIZEK+base_k)>>(16-10)) | 1; + + pci_write_config32(ctrl->f1, 0xf0, val); +} + +#endif + static void order_dimms(const struct mem_controller *ctrl) { unsigned long tom_k, base_k; @@ -976,6 +1127,14 @@ static void order_dimms(const struct mem_controller *ctrl) /* Compute the memory base address */ base_k = memory_end_k(ctrl, ctrl->node_id); tom_k += base_k; +#if K8_E0_MEM_HOLE_SIZEK != 0 + if(!is_cpu_pre_e0()) { + /* See if I need to check the range cover hole */ + if ((base_k <= K8_E0_MEM_HOLE_BASEK) && (tom_k > K8_E0_MEM_HOLE_BASEK)) { + tom_k += K8_E0_MEM_HOLE_SIZEK; + } + } +#endif route_dram_accesses(ctrl, base_k, tom_k); set_top_mem(tom_k); } @@ -1020,9 +1179,12 @@ static long spd_handle_unbuffered_dimms(const struct mem_controller *ctrl, long if (unbuffered && registered) { die("Mixed buffered and registered dimms not supported"); } +#if 1 + //By yhlu for debug Athlon64 939 can do dual channel, but it use unbuffer DIMM if (unbuffered && is_opteron(ctrl)) { die("Unbuffered Dimms not supported on Opteron"); } +#endif dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW); dcl &= ~DCL_UnBufDimm; @@ -1360,12 +1522,46 @@ static struct spd_set_memclk_result spd_set_memclk(const struct mem_controller * dimm_err: dimm_mask = disable_dimm(ctrl, i, dimm_mask); } +#if 0 +//down speed for full load 4 rank support +#if K8_4RANK_DIMM_SUPPORT + if(dimm_mask == (3|(3<channel0[i]); i++) { + int val; + if (!(dimm_mask & (1 << i))) { + continue; + } + val = spd_read_byte(ctrl->channel0[i], 5); + if(val!=ranks) { + ranks = val; + break; + } + } + if(ranks==4) { + if(min_cycle_time <= 0x50 ) { + min_cycle_time = 0x60; + } + } + + } +#endif +#endif /* Now that I know the minimum cycle time lookup the memory parameters */ result.param = get_mem_param(min_cycle_time); /* Update DRAM Config High with our selected memory speed */ value = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH); value &= ~(DCH_MEMCLK_MASK << DCH_MEMCLK_SHIFT); +#if 1 + /* Improves DQS centering by correcting for case when core speed multiplier and MEMCLK speed result in odd clock divisor, by selecting the next lowest memory speed, required only at DDR400 and higher speeds with certain DIMM loadings ---- cheating???*/ + if(!is_cpu_pre_e0()) { + if(min_cycle_time==0x50) { + value |= 1<<31; + } + } +#endif + value |= result.param->dch_memclk; pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value); @@ -1594,17 +1790,32 @@ static int update_dimm_x4(const struct mem_controller *ctrl, const struct mem_pa { uint32_t dcl; int value; +#if K8_4RANK_DIMM_SUPPORT == 1 + int rank; +#endif int dimm; value = spd_read_byte(ctrl->channel0[i], 13); if (value < 0) { return -1; } - dimm = i; - dimm += DCL_x4DIMM_SHIFT; + +#if K8_4RANK_DIMM_SUPPORT == 1 + rank = spd_read_byte(ctrl->channel0[i], 5); /* number of physical banks */ + if (rank < 0) { + return -1; + } +#endif + + dimm = 1<<(DCL_x4DIMM_SHIFT+i); +#if K8_4RANK_DIMM_SUPPORT == 1 + if(rank==4) { + dimm |= 1<<(DCL_x4DIMM_SHIFT+i+2); + } +#endif dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW); - dcl &= ~(1 << dimm); + dcl &= ~dimm; if (value == 4) { - dcl |= (1 << dimm); + dcl |= dimm; } pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl); return 1; @@ -1921,10 +2132,6 @@ static long spd_set_dram_timing(const struct mem_controller *ctrl, const struct return dimm_mask; } -static int controller_present(const struct mem_controller *ctrl) -{ - return pci_read_config32(ctrl->f0, 0) == 0x11001022; -} static void sdram_set_spd_registers(const struct mem_controller *ctrl) { struct spd_set_memclk_result result; @@ -1932,7 +2139,7 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl) long dimm_mask; #if 1 if (!controller_present(ctrl)) { - print_debug("No memory controller present\r\n"); +// print_debug("No memory controller present\r\n"); return; } #endif @@ -2064,16 +2271,37 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl) dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW); } while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) ); } + + // init e0 mem hole here +#if K8_E0_MEM_HOLE_SIZEK != 0 + if (!is_cpu_pre_e0()) { + uint32_t base, limit; + unsigned base_k, limit_k; + base = pci_read_config32(ctrl->f1, 0x40 + (i << 3)); + limit = pci_read_config32(ctrl->f1, 0x44 + (i << 3)); + base_k = (base & 0xffff0000) >> 2; + limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2; + if ((base_k <= K8_E0_MEM_HOLE_BASEK) && (limit_k > K8_E0_MEM_HOLE_BASEK)) { + set_e0_mem_hole(ctrl+i, base_k); + } + } + +#endif + print_debug(" done\r\n"); } + //FIXME add enable node interleaving here --yhlu + /*needed? + 1. check how many nodes we have , if not all has ram installed get out + 2. check cs_base lo is 0, node 0 f2 0x40,,,,, if any one is not using lo is CS_BASE, get out + 3. check if other node is the same as node 0 about f2 0x40,,,,, otherwise get out + 4. if all ready enable node_interleaving in f1 0x40..... of every node + 5. for node interleaving we need to set mem hole to every node ( need recalcute hole offset in f0 for every node) + */ + + /* Make certain the first 1M of memory is intialized */ - msr_t msr, msr_201; - uint32_t cnt; - - /* Save the value of msr_201 */ - msr_201 = rdmsr(0x201); - print_debug("Clearing initial memory region: "); /* Use write combine caching while we setup the first 1M */ diff --git a/targets/tyan/s2892/Config.lb b/targets/tyan/s2892/Config.lb new file mode 100644 index 000000000..dd5a70b51 --- /dev/null +++ b/targets/tyan/s2892/Config.lb @@ -0,0 +1,57 @@ +# Sample config file for +# the Tyan s2892 +# This will make a target directory of ./s2892 + +target s2892 +mainboard tyan/s2892 + +# Tyan s2892 +romimage "normal" +# 48K for SCSI FW or ATI ROM + option ROM_SIZE = 475136 +# 48K for SCSI FW and 48K for ATI ROM +# option ROM_SIZE = 425984 +# 64K for Etherboot +# option ROM_SIZE = 458752 + option USE_FALLBACK_IMAGE=0 +# option ROM_IMAGE_SIZE=0x11800 +# option ROM_IMAGE_SIZE=0x13800 + option ROM_IMAGE_SIZE=0x16000 +# option ROM_IMAGE_SIZE=0x17800 + option XIP_ROM_SIZE=0x20000 + option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Normal" +# payload ../../../payloads/tg3--ide_disk.zelf +# payload ../../../payloads/filo.elf +# payload ../../../payloads/filo_mem.elf +# payload ../../../payloads/filo.zelf +# payload ../../../payloads/tg3.zelf +# payload ../../../payloads/tg3_vga.zelf + payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_com2.zelf +# payload ../../../payloads/e1000--filo.zelf +# payload ../../../payloads/tg3--e1000--filo.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2.zelf +end + +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=0x17800 + option XIP_ROM_SIZE=0x20000 + option LINUXBIOS_EXTRA_VERSION="$(shell cat ../../VERSION)_Fallback" +# payload ../../../payloads/tg3--ide_disk.zelf +# payload ../../../payloads/filo.elf +# payload ../../../payloads/filo_mem.elf +# payload ../../../payloads/filo.zelf +# payload ../../../payloads/tg3.zelf +# payload ../../../payloads/tg3_vga.zelf + payload ../../../payloads/tg3--filo_hda2_vga.zelf +# payload ../../../payloads/tg3--filo_hda2_com2.zelf +# payload ../../../payloads/e1000--filo.zelf +# payload ../../../payloads/tg3--e1000--filo.zelf +# payload ../../../payloads/tg3--eepro100--e1000--filo_hda2.zelf +end + +buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback" diff --git a/targets/tyan/s2892/VERSION b/targets/tyan/s2892/VERSION new file mode 100644 index 000000000..91e6ccd3b --- /dev/null +++ b/targets/tyan/s2892/VERSION @@ -0,0 +1 @@ +_s2892 diff --git a/targets/tyan/s2895/Config.lb b/targets/tyan/s2895/Config.lb index 02d1db60d..58a0d150e 100644 --- a/targets/tyan/s2895/Config.lb +++ b/targets/tyan/s2895/Config.lb @@ -27,7 +27,7 @@ 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/tg3_vga.zelf # payload ../../../payloads/tg3--filo_hda2_vgax.zelf # payload ../../../payloads/tg3--filo_hda2_com2.zelf @@ -49,7 +49,7 @@ 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/tg3_vga.zelf # payload ../../../payloads/tg3--filo_hda2_vgax.zelf # payload ../../../payloads/tg3--filo_hda2_com2.zelf -- 2.25.1