summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorarch import user (historical) <svn@openbios.org>2005-07-06 17:15:30 +0000
committerarch import user (historical) <svn@openbios.org>2005-07-06 17:15:30 +0000
commitef03afa405b049a172146aab93cfb81fb21f3945 (patch)
tree3b59033be66edd60c2cc6c66d6875153dc052a72 /src
parent014c3e185fe8e1455e56efeb496715a67ce292bb (diff)
downloadcoreboot-ef03afa405b049a172146aab93cfb81fb21f3945.tar.xz
Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-34
Creator: Yinghai Lu <yhlu@tyan.com> 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
Diffstat (limited to 'src')
-rw-r--r--src/config/Options.lb16
-rw-r--r--src/cpu/amd/dualcore/Config.lb5
-rw-r--r--src/cpu/amd/dualcore/amd_sibling.c244
-rw-r--r--src/cpu/amd/dualcore/dualcore.c99
-rw-r--r--src/cpu/amd/dualcore/dualcore_id.c45
-rw-r--r--src/cpu/amd/model_fxx/Config.lb1
-rw-r--r--src/cpu/amd/model_fxx/model_fxx_init.c143
-rw-r--r--src/cpu/amd/model_fxx/model_fxx_msr.h10
-rw-r--r--src/cpu/amd/model_fxx/node_id.c12
-rw-r--r--src/cpu/x86/16bit/reset16.lds2
-rw-r--r--src/cpu/x86/lapic/lapic_cpu_init.c13
-rw-r--r--src/cpu/x86/mtrr/mtrr.c4
-rw-r--r--src/devices/hypertransport.c5
-rw-r--r--src/drivers/i2c/adm1027/adm1027.c4
-rw-r--r--src/include/cpu/amd/dualcore.h19
-rw-r--r--src/lib/malloc.c2
-rw-r--r--src/mainboard/Iwill/DK8S2/Options.lb2
-rw-r--r--src/mainboard/Iwill/DK8X/Options.lb2
-rw-r--r--src/mainboard/amd/quartet/Options.lb2
-rw-r--r--src/mainboard/amd/serenade/Options.lb2
-rw-r--r--src/mainboard/amd/solo/Options.lb2
-rw-r--r--src/mainboard/arima/hdama/Options.lb2
-rw-r--r--src/mainboard/ibm/e325/Options.lb2
-rw-r--r--src/mainboard/island/aruma/Options.lb2
-rw-r--r--src/mainboard/newisys/khepri/Options.lb2
-rw-r--r--src/mainboard/tyan/s2850/Options.lb12
-rw-r--r--src/mainboard/tyan/s2850/auto.c123
-rw-r--r--src/mainboard/tyan/s2850/cmos.layout1
-rw-r--r--src/mainboard/tyan/s2850/failover.c31
-rw-r--r--src/mainboard/tyan/s2850/mptable.c102
-rw-r--r--src/mainboard/tyan/s2875/Options.lb14
-rw-r--r--src/mainboard/tyan/s2875/auto.c145
-rw-r--r--src/mainboard/tyan/s2875/cmos.layout1
-rw-r--r--src/mainboard/tyan/s2875/failover.c32
-rw-r--r--src/mainboard/tyan/s2875/mptable.c102
-rw-r--r--src/mainboard/tyan/s2880/Config.lb10
-rw-r--r--src/mainboard/tyan/s2880/Options.lb14
-rw-r--r--src/mainboard/tyan/s2880/auto.c136
-rw-r--r--src/mainboard/tyan/s2880/cmos.layout1
-rw-r--r--src/mainboard/tyan/s2880/failover.c34
-rw-r--r--src/mainboard/tyan/s2880/irq_tables.c2
-rw-r--r--src/mainboard/tyan/s2880/mptable.c102
-rw-r--r--src/mainboard/tyan/s2881/Config.lb72
-rw-r--r--src/mainboard/tyan/s2881/Options.lb14
-rw-r--r--src/mainboard/tyan/s2881/auto.c138
-rw-r--r--src/mainboard/tyan/s2881/cmos.layout1
-rw-r--r--src/mainboard/tyan/s2881/failover.c32
-rw-r--r--src/mainboard/tyan/s2881/mptable.c78
-rw-r--r--src/mainboard/tyan/s2881/resourcemap.c4
-rw-r--r--src/mainboard/tyan/s2882/Options.lb18
-rw-r--r--src/mainboard/tyan/s2882/auto.c136
-rw-r--r--src/mainboard/tyan/s2882/cmos.layout1
-rw-r--r--src/mainboard/tyan/s2882/failover.c27
-rw-r--r--src/mainboard/tyan/s2882/mptable.c108
-rw-r--r--src/mainboard/tyan/s2885/Options.lb23
-rw-r--r--src/mainboard/tyan/s2885/auto.c194
-rw-r--r--src/mainboard/tyan/s2885/chip.h2
-rw-r--r--src/mainboard/tyan/s2885/cmos.layout1
-rw-r--r--src/mainboard/tyan/s2885/failover.c30
-rw-r--r--src/mainboard/tyan/s2885/mptable.c101
-rw-r--r--src/mainboard/tyan/s2885/resourcemap.c12
-rw-r--r--src/mainboard/tyan/s2891/Config.lb8
-rw-r--r--src/mainboard/tyan/s2891/Options.lb10
-rw-r--r--src/mainboard/tyan/s2891/auto.c30
-rw-r--r--src/mainboard/tyan/s2891/failover.c13
-rw-r--r--src/mainboard/tyan/s2891/mptable.c21
-rw-r--r--src/mainboard/tyan/s2892/Config.lb298
-rw-r--r--src/mainboard/tyan/s2892/Options.lb245
-rw-r--r--src/mainboard/tyan/s2892/auto.c200
-rw-r--r--src/mainboard/tyan/s2892/chip.h6
-rw-r--r--src/mainboard/tyan/s2892/cmos.layout98
-rw-r--r--src/mainboard/tyan/s2892/failover.c111
-rw-r--r--src/mainboard/tyan/s2892/irq_tables.c35
-rw-r--r--src/mainboard/tyan/s2892/mainboard.c12
-rw-r--r--src/mainboard/tyan/s2892/mptable.c270
-rw-r--r--src/mainboard/tyan/s2892/resourcemap.c273
-rw-r--r--src/mainboard/tyan/s2895/Config.lb10
-rw-r--r--src/mainboard/tyan/s2895/Options.lb10
-rw-r--r--src/mainboard/tyan/s2895/auto.c52
-rw-r--r--src/mainboard/tyan/s2895/failover.c18
-rw-r--r--src/mainboard/tyan/s2895/mptable.c22
-rw-r--r--src/mainboard/tyan/s4880/Config.lb10
-rw-r--r--src/mainboard/tyan/s4880/Options.lb18
-rw-r--r--src/mainboard/tyan/s4880/auto.c177
-rw-r--r--src/mainboard/tyan/s4880/cmos.layout1
-rw-r--r--src/mainboard/tyan/s4880/failover.c42
-rw-r--r--src/mainboard/tyan/s4880/mptable.c116
-rw-r--r--src/mainboard/tyan/s4880/resourcemap.c2
-rw-r--r--src/mainboard/tyan/s4882/Options.lb23
-rw-r--r--src/mainboard/tyan/s4882/auto.c225
-rw-r--r--src/mainboard/tyan/s4882/cmos.layout1
-rw-r--r--src/mainboard/tyan/s4882/failover.c38
-rw-r--r--src/mainboard/tyan/s4882/irq_tables.c2
-rw-r--r--src/mainboard/tyan/s4882/mptable.c117
-rw-r--r--src/mainboard/tyan/s4882/resourcemap.c2
-rw-r--r--src/northbridge/amd/amdk8/coherent_ht.c358
-rw-r--r--src/northbridge/amd/amdk8/cpu_rev.c31
-rw-r--r--src/northbridge/amd/amdk8/debug.c24
-rw-r--r--src/northbridge/amd/amdk8/incoherent_ht.c3
-rw-r--r--src/northbridge/amd/amdk8/misc_control.c4
-rw-r--r--src/northbridge/amd/amdk8/northbridge.c217
-rw-r--r--src/northbridge/amd/amdk8/raminit.c288
102 files changed, 4336 insertions, 1601 deletions
diff --git a/src/config/Options.lb b/src/config/Options.lb
index 35a3151b52..370eba21c8 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 0000000000..dd8dd09963
--- /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 0000000000..da5928ab14
--- /dev/null
+++ b/src/cpu/amd/dualcore/amd_sibling.c
@@ -0,0 +1,244 @@
+/* 2004.12 yhlu add dual core support */
+
+#include <console/console.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/amd/dualcore.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <pc80/mc146818rtc.h>
+#include <smp/spinlock.h>
+#include <cpu/x86/mtrr.h>
+#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<nodes; nodeid++){
+ int j;
+ dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid, 3));
+ j = (pci_read_config32(dev, 0xe8) >> 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<nodes; nodeid++){
+ uint32_t val;
+ dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid, 0));
+ val = pci_read_config32(dev, 0x68);
+ val |= (1<<17)|(1<<18);
+ pci_write_config32(dev, 0x68, val);
+ }
+}
+
+
+unsigned get_apicid_base(unsigned ioapic_num)
+{
+ device_t dev;
+ int nodes;
+ unsigned apicid_base;
+ int siblings;
+ unsigned nb_cfg_54;
+ int bsp_apic_id = lapicid(); // bsp apicid
+
+ int disable_siblings = !CONFIG_LOGICAL_CPUS;
+
+
+ get_option(&disable_siblings, "dual_core");
+
+ //get the nodes number
+ dev = dev_find_slot(0, PCI_DEVFN(0x18,0));
+ nodes = ((pci_read_config32(dev, 0x60)>>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; i<nodes; i++) {
+ if(is_e0_later_in_bsp(i)) {
+ siblings = 1;
+ break;
+ }
+ }
+ }
+#endif
+
+ //contruct apicid_base
+
+ if((!disable_siblings) && (siblings>0) ) {
+ /* 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 0000000000..1c3b2751a5
--- /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<nodes; nodeid++) {
+ if( get_core_num_in_bsp(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 0000000000..feab682851
--- /dev/null
+++ b/src/cpu/amd/dualcore/dualcore_id.c
@@ -0,0 +1,45 @@
+/* 2004.12 yhlu add dual core support */
+
+#include <arch/cpu.h>
+#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 bf7b9987cc..924dc8f155 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 22b8f015c3..fdaf05cb66 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 <console/console.h>
#include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h>
@@ -16,6 +21,11 @@
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/mem.h>
+
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 930054a9ba..c8d57bee1a 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 0000000000..1904719270
--- /dev/null
+++ b/src/cpu/amd/model_fxx/node_id.c
@@ -0,0 +1,12 @@
+/* 2004.12 yhlu add dual core support */
+
+#include <arch/cpu.h>
+#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 4c42c76b37..f32597c00c 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 20615e61c8..7c40f6a3c0 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 1c028a9ea1..59f9ca1e91 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 7bc1c215b8..80c621ed79 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 fc8ba732af..6248f95e42 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 0000000000..a8c49475ec
--- /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 bd403e47e9..c853452284 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 91fb272e86..373d1a98a9 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 2904cccf43..f9987d4392 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 2de7258e12..052306ae05 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 37fd3ea508..11bc28b232 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 6051cb0a2d..eec85778df 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 f669ba9ec2..091f792e3b 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 9e46555e63..74f74a787e 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 87441d07e4..4e2cef1ff1 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 a7f8f61e67..c975e08c8f 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 b9f488f194..c829098721 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 93578dac62..9220738d87 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 ea027282c4..c1f3d75316 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 e6ecb65c4d..fee04156a4 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 f4795be6d8..6a28ecbe79 100644
--- a/src/mainboard/tyan/s2850/mptable.c
+++ b/src/mainboard/tyan/s2850/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 eb9cfd6ec8..d1e22c0063 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 6bbdaa9a43..1b055bf2ec 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 ea027282c4..c1f3d75316 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 e6ecb65c4d..a993aedb86 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 82569c931a..9b93decd80 100644
--- a/src/mainboard/tyan/s2875/mptable.c
+++ b/src/mainboard/tyan/s2875/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 6c4ac7b7c1..f82bd23b44 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 2fd9dfbf51..af9aea7b36 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 6384f4d152..1ed43bc19e 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 ea027282c4..c1f3d75316 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 e68164db7c..9164e7b091 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 2b1b5ce34d..92a5198e2d 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 46cad33d45..9c4764a77b 100644
--- a/src/mainboard/tyan/s2880/mptable.c
+++ b/src/mainboard/tyan/s2880/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 ba28422aac..47ab2df45a 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 c0d4ede89b..a1c7b4e32f 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 e1161ac9a3..391be78879 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 ea027282c4..c1f3d75316 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 780b3052eb..a993aedb86 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 67c19c8e35..06f1301ee5 100644
--- a/src/mainboard/tyan/s2881/mptable.c
+++ b/src/mainboard/tyan/s2881/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 7119c4a557..22723eafad 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 5d7ac25eda..4f084c86ba 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 db50fde657..fb7a63abb5 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 ea027282c4..c1f3d75316 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 45315521ac..9164e7b091 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 4bf298923d..a331247fa9 100644
--- a/src/mainboard/tyan/s2882/mptable.c
+++ b/src/mainboard/tyan/s2882/mptable.c
@@ -4,6 +4,9 @@
#include <device/pci_ids.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 b4d0bd25d7..74aaedbe69 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 aacb4b007b..cff103b9cc 100644
--- a/src/mainboard/tyan/s2885/auto.c
+++ b/src/mainboard/tyan/s2885/auto.c
@@ -6,13 +6,11 @@
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <cpu/x86/lapic.h>
-#include <arch/cpu.h>
#include "option_table.h"
#include "pc80/mc146818rtc_early.c"
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/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 bcedaec668..dadfb0f4ee 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 ea027282c4..c1f3d75316 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 45315521ac..345d3f4d1a 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 ba7bc390ad..2396ade53e 100644
--- a/src/mainboard/tyan/s2885/mptable.c
+++ b/src/mainboard/tyan/s2885/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 2c51f1d114..bc2a8ba673 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 71d4f9341c..0f428d10c1 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 75deaf69a7..b4a374db74 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 d0ee70ba2b..4a8ef3f952 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 fb092e7203..98b01b8f79 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 9aa2f336b8..e8d5f4ccc9 100644
--- a/src/mainboard/tyan/s2891/mptable.c
+++ b/src/mainboard/tyan/s2891/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 0000000000..215c4a80db
--- /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 0000000000..6423773a27
--- /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 0000000000..d2512e9f61
--- /dev/null
+++ b/src/mainboard/tyan/s2892/auto.c
@@ -0,0 +1,200 @@
+#define ASSEMBLY 1
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "option_table.h"
+#include "pc80/mc146818rtc_early.c"
+#include "pc80/serial.c"
+#include "arch/i386/lib/console.c"
+#include "ram/ramtest.c"
+
+#include "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 0000000000..28fb8a02e1
--- /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 0000000000..c1f3d75316
--- /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 0000000000..b8d21f1d93
--- /dev/null
+++ b/src/mainboard/tyan/s2892/failover.c
@@ -0,0 +1,111 @@
+#define ASSEMBLY 1
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <cpu/x86/lapic.h>
+#include "pc80/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 0000000000..8a00214c18
--- /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 <arch/pirq_routing.h>
+
+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 0000000000..32a2e609c9
--- /dev/null
+++ b/src/mainboard/tyan/s2892/mainboard.c
@@ -0,0 +1,12 @@
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "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 0000000000..b4f26aaeba
--- /dev/null
+++ b/src/mainboard/tyan/s2892/mptable.c
@@ -0,0 +1,270 @@
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 0000000000..5801264a16
--- /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 5a7cb14e9a..09448facc8 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 545dbe9f42..22812e9a20 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 209f284d58..b6f121e6e8 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 a70264ec2f..7cd004f82b 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 61ab3f26a8..f6b534d866 100644
--- a/src/mainboard/tyan/s2895/mptable.c
+++ b/src/mainboard/tyan/s2895/mptable.c
@@ -4,6 +4,10 @@
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 1caca96986..d053c663f6 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 235b070843..4cadb725c4 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 21855aa51c..12c0c9541c 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 ea027282c4..c1f3d75316 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 45315521ac..39758aefa7 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 2577a8b1bc..2b6ba531f7 100644
--- a/src/mainboard/tyan/s4880/mptable.c
+++ b/src/mainboard/tyan/s4880/mptable.c
@@ -3,6 +3,9 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 c18c257f89..d9315a026a 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 5d592596ba..e1a431bde3 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 e7d46d2187..21d459b6e4 100644
--- a/src/mainboard/tyan/s4882/auto.c
+++ b/src/mainboard/tyan/s4882/auto.c
@@ -6,13 +6,11 @@
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <cpu/x86/lapic.h>
-#include <arch/cpu.h>
#include "option_table.h"
#include "pc80/mc146818rtc_early.c"
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
-#include "northbridge/amd/amdk8/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 ea027282c4..c1f3d75316 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 2c8fb0041b..9d793f447f 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 dd293ca966..6bd4a2123a 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 98dd0cbf64..c16603a926 100644
--- a/src/mainboard/tyan/s4882/mptable.c
+++ b/src/mainboard/tyan/s4882/mptable.c
@@ -3,12 +3,15 @@
#include <device/pci.h>
#include <string.h>
#include <stdint.h>
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#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 423ac3cf00..8d9307c68f 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 8ca1bfbf89..ca7791cf63 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<num; i+=3) {
+ opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
+ }
}
+static void opt_broadcast_rt_plus(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 opt_broadcast_rt_plus_group(const u8 *conn, int num) {
+ int i;
+
+ for(i=0; i<num; i+=3) {
+ opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
+ }
+}
+#endif
-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 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<dest) {
val_s-=link_connection(temp, source-2); /* -down*/
} else {
- val_s-=link_connection(temp, source+2); /* -up*/
+#if CROSS_BAR_47_56
+ #if 0
+ if(source==7) {
+ val_s-=link_connection(temp, 6); // for 7,2 via 5
+ } else if (source==6){
+ val_s-=link_connection(temp, 7); // for 6,3 via 4
+ } else
+ #endif
+ if (source < gateway) { // for 5, 4 via 7
+ val_s-=link_connection(temp, source-2);
+ } else
+#endif
+ val_s-=link_connection(temp, source+2); /* -up*/
}
}
#endif
@@ -581,12 +664,16 @@ static void setup_remote_row_indirect_group(const u8 *conn, int num)
}
}
-#endif /*CONFIG_MAX_CPUS > 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<nodes; node++) {
+ tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 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 15b4cf6318..1eb47f85f5 100644
--- a/src/northbridge/amd/amdk8/cpu_rev.c
+++ b/src/northbridge/amd/amdk8/cpu_rev.c
@@ -1,25 +1,46 @@
#include <arch/cpu.h>
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 7686662d04..eeba1e1e2c 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 d76a3e8731..ec767456e8 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 379d8b1dc4..4ac6ef473d 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 3d30430d3c..89602f37a6 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 <console/console.h>
#include <arch/io.h>
#include <stdint.h>
@@ -9,11 +15,22 @@
#include <string.h>
#include <bitops.h>
#include <cpu/cpu.h>
+
+#include <cpu/x86/lapic.h>
+
+#if CONFIG_LOGICAL_CPUS==1
+#include <cpu/amd/dualcore.h>
+#include <pc80/mc146818rtc.h>
+#endif
+
#include "chip.h"
#include "root_complex/chip.h"
#include "northbridge.h"
#include "amdk8.h"
-#include <cpu/x86/lapic.h>
+
+#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_id<apic_id_offset) {
- //all add offset except bsp cores
- if( (cpu->path.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_id<apic_id_offset) { //all add offset except bsp core0
+ if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) )
+ cpu->path.u.apic.apic_id += apic_id_offset;
+ }
+ }
+ printk_debug("CPU: %s %s\n",
+ dev_path(cpu), cpu->enabled?"enabled":"disabled");
+ }
+ } //j
}
+
return max;
}
diff --git a/src/northbridge/amd/amdk8/raminit.c b/src/northbridge/amd/amdk8/raminit.c
index e4043493ab..3bdf8c3b11 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 <cpu/x86/mem.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
@@ -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<<DIMM_SOCKETS)) ) {
+ int ranks = 4;
+ for(i = 0; (i < 4) && (ctrl->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 */