Author: rminnich
Date: 2008-08-28 19:14:04 +0200 (Thu, 28 Aug 2008)
New Revision: 841
Added:
coreboot-v3/arch/x86/amd/model_fxx/fidvid.c
Modified:
coreboot-v3/arch/x86/amd/model_fxx/dualcore.c
coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c
coreboot-v3/mainboard/amd/serengeti/Makefile
coreboot-v3/mainboard/amd/serengeti/initram.c
coreboot-v3/mainboard/amd/serengeti/mainboard.h
coreboot-v3/northbridge/amd/k8/libstage1.c
Log:
Closer to compiling. Add the fidvid functions. Continue to remove romcc
legacy. Use constants as much as possible instead of magic numbers. Set
up common prototypes in an include file.
The fidvid needs major cleanup but this code is so tricky I don't want
to start cleanup until I feel it is more or less working.
Signed-off-by: Ronald G. minnich <rminnich(a)gmail.com>
Acked-by: Ronald G. minnich <rminnich(a)gmail.com>
Modified: coreboot-v3/arch/x86/amd/model_fxx/dualcore.c
===================================================================
--- coreboot-v3/arch/x86/amd/model_fxx/dualcore.c 2008-08-28 07:15:43 UTC (rev 840)
+++ coreboot-v3/arch/x86/amd/model_fxx/dualcore.c 2008-08-28 17:14:04 UTC (rev 841)
@@ -24,27 +24,32 @@
* @param nodeid The nodeid
* @returns The number of cores in that node.
*/
-unsigned int get_core_count(unsigned nodeid)
+unsigned int get_core_count(unsigned int nodeid)
{
u32 dword;
- dword = pci_read_config32(PCI_BDF(0, 0x18+nodeid, 3), NORTHBRIDGE_CAP);
+ dword = pci_conf1_read_config32(PCI_BDF(0, 0x18+nodeid, 3), NORTHBRIDGE_CAP);
dword >>= NBCAP_CmpCap_SHIFT;
dword &= NBCAP_CmpCap_MASK;
return dword;
}
+/**
+ * Set the "cpuid and node id" bits are swapped, from page 374:
+ * "When this bit is set, CpuId and NodeId[2:0] bit field positions
+ * are swapped in the APICID"
+ * 0: APICID = {CpuId, NodeId[2:0]}
+ * 1: APICID = {NodeId[2:0], CpuId}
+ */
+void set_apicid_cpuid_lo(void)
+{
#if SET_NB_CFG_54 == 1
-u8 set_apicid_cpuid_lo(void)
-{
- // set the NB_CFG[54]=1; Why the OS thinks this is a good thing is not yet known.
+ //Why the OS thinks this is a good thing is not yet known.
struct msr msr;
msr = rdmsr(NB_CFG_MSR);
msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
wrmsr(NB_CFG_MSR, msr);
-
- return 1;
+#endif
}
-#endif
/**
* Start the cores on a given node (cores > 0). It is important that MC4 and other accesses
@@ -57,19 +62,19 @@
/* 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), MCA_NB_CONFIG);
+ dword = pci_conf1_read_config32(PCI_BDF(0, 0x18+nodeid, 3), MCA_NB_CONFIG);
dword |= MNC_NBMCATOMSTCPUEN; // NbMcaToMstCpuEn bit
- pci_write_config32(PCI_DEV(0, 0x18+nodeid, 3), MCA_NB_CONFIG, dword);
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+nodeid, 3), MCA_NB_CONFIG, dword);
// set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
- dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 0), HT_TRANSACTION_CONTROL);
+ dword = pci_conf1_read_config32(PCI_BDF(0, 0x18+nodeid, 0), HT_TRANSACTION_CONTROL);
dword |= HTTC_CPU1_EN;
- pci_write_config32(PCI_DEV(0, 0x18+nodeid, 0), HT_TRANSACTION_CONTROL, dword);
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+nodeid, 0), HT_TRANSACTION_CONTROL, dword);
}
/**
* start cores on all nodes including BSP. This is assumed to be running on core 0 of node 0
*/
-static inline void start_other_cores(void)
+static inline void start_all_cores(void)
{
unsigned nodes;
unsigned nodeid;
Added: coreboot-v3/arch/x86/amd/model_fxx/fidvid.c
===================================================================
--- coreboot-v3/arch/x86/amd/model_fxx/fidvid.c (rev 0)
+++ coreboot-v3/arch/x86/amd/model_fxx/fidvid.c 2008-08-28 17:14:04 UTC (rev 841)
@@ -0,0 +1,536 @@
+#include <mainboard.h>
+#include <types.h>
+#include <lib.h>
+#include <console.h>
+#include <globalvars.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <string.h>
+#include <msr.h>
+#include <io.h>
+#include <cpu.h>
+#include <amd/k8/k8.h>
+#include <mc146818rtc.h>
+#include <spd.h>
+
+#define K8_SET_FIDVID_DEBUG 1
+
+#define K8_SET_FIDVID_ONE_BY_ONE 1
+
+#define K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST 1
+
+#ifndef SB_VFSMAF
+#define SB_VFSMAF 1
+#endif
+
+#define FX_SUPPORT 1
+
+static void enable_fid_change(void)
+{
+ u32 dword;
+ unsigned nodes;
+ int i;
+
+ nodes = ((pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), NODEID) >> 4) & 7) + 1;
+
+#warning document these settings!
+ for (i = 0; i < nodes; i++) {
+ dword = pci_conf1_read_config32(PCI_DEV(0, 0x18+i, 3), 0xd8);
+ dword &= 0x8ff00000;
+ dword |= (2 << 28) | (0x02710);
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+i, 3), 0xd8, dword);
+
+ dword = 0x04e2a707;
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+i, 3), 0xd4, dword);
+
+ /* disable the DRAM interface at first, it will be enabled
+ * by raminit again */
+ dword = pci_conf1_read_config32(PCI_DEV(0, 0x18+i, 2), 0x94);
+ dword |= (1 << 14);
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+i, 2), 0x94, dword);
+
+ dword = 0x23070700; /* enable FID/VID change */
+// dword = 0x00070000; /* enable FID/VID change */
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+i, 3), 0x80, dword);
+
+ dword = 0x00132113;
+ pci_conf1_write_config32(PCI_DEV(0, 0x18+i, 3), 0x84, dword);
+
+ }
+}
+
+#if K8_SET_FIDVID_ONE_BY_ONE == 0
+static unsigned set_fidvid_without_init(unsigned fidvid)
+{
+ struct msr msr;
+ u32 vid;
+ u32 fid;
+
+ fid = (fidvid >> 8) & 0x3f;
+ vid = (fidvid >> 16) & 0x3f;
+
+ /* set new FID/VID */
+ msr.hi = 1;
+ msr.lo = (vid<<8) | fid;
+ wrmsr(FIDVID_CTL, msr);
+ return fidvid;
+}
+#endif
+
+static unsigned set_fidvid(unsigned apicid, unsigned fidvid, int showmessage)
+{
+ /* for (cur, new) there is one <1600MHz x8 to find out next_fid */
+ static const u8 next_fid_a[] = {
+ /* x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 */
+/* x4 */ 0, 9, 9, 8, 9, 9, 9, 9, 9, 9, 9, 9,
+/* x5 */ 9, 0, 11, 11, 9, 9, 10, 11, 11, 11, 11, 11,
+/* x6 */ 11, 11, 0, 13, 11, 11, 11, 11, 12, 13, 13, 13,
+/* x7 */ 13, 13, 13, 0, 13, 13, 13, 13, 13, 13, 14, 15,
+/* x8 */ 4, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9,
+/* x9 */ 4, 5, 10, 10, 8, 0, 0, 0, 0, 0, 0, 0,
+/*x10 */ 9, 5, 11, 11, 9, 0, 0, 0, 0, 0, 0, 0,
+/*x11 */ 10, 5, 6, 12, 10, 0, 0, 0, 0, 0, 0, 0,
+/*x12 */ 11, 11, 6, 13, 11, 0, 0, 0, 0, 0, 0, 0,
+/*x13 */ 12, 12, 6, 7, 12, 0, 0, 0, 0, 0, 0, 0,
+/*x14 */ 13, 13, 13, 7, 13, 0, 0, 0, 0, 0, 0, 0,
+/*x15 */ 14, 14, 14, 7, 14, 0, 0, 0, 0, 0, 0, 0,
+/* 0:x4, 2:x5....BASE=4, MIN=4, MAX=25, INC=2 result = (xX-BASE)*INC */
+ };
+
+ struct msr msr;
+ u32 vid;
+ u32 fid;
+ u32 vid_max;
+ u32 fid_max;
+ u32 vid_cur;
+ u32 fid_cur;
+ unsigned int apicidx;
+
+ int steps;
+ int loop;
+
+ apicidx = lapicid();
+
+ if (apicid != apicidx) {
+ printk(BIOS_ERR,
+ "wrong apicid, we want change %x, but it is %x\n", apicid, apicidx);
+ return fidvid;
+ }
+
+ fid = (fidvid >> 8) & 0x3f;
+ vid = (fidvid >> 16) & 0x3f;
+
+ msr = rdmsr(FIDVID_STATUS);
+
+ vid_cur = msr.hi & 0x3f;
+ fid_cur = msr.lo & 0x3f;
+
+ if ((vid_cur==vid) && (fid_cur==fid))
+ return fidvid;
+
+ vid_max = (msr.hi>>(48-32)) & 0x3f;
+ fid_max = ((msr.lo>>16) & 0x3f); /* max fid */
+#if FX_SUPPORT
+ if (fid_max>=((25-4)*2)) { /* FX max fid is 5G */
+ fid_max = ((msr.lo >> 8) & 0x3f) + 5 * 2; /* max FID is min fid + 1G */
+ if (fid_max >= ((25-4) * 2)) {
+ fid_max = (10-4) * 2; /* hard set to 2G */
+ }
+ }
+#endif
+
+ /* set vid to max */
+ msr.hi = 1;
+ msr.lo = (vid_max << 8) | (fid_cur);
+#if SB_VFSMAF == 1
+ msr.lo |= (1<<16); /* init changes */
+#endif
+ wrmsr(FIDVID_CTL, msr);
+#if SB_VFSMAF == 0
+ ldtstop_sb();
+#endif
+
+
+ for (loop=0;loop<100000;loop++){
+ msr = rdmsr(FIDVID_STATUS);
+ if (!(msr.lo & (1<<31)))
+ break;
+ }
+ vid_cur = msr.hi & 0x3f;
+
+ steps = 8; //??
+ while ((fid_cur != fid) && (steps-- > 0)) {
+ u32 fid_temp;
+ if ((fid_cur > (8-4)*2) && (fid> (8-4)*2)) {
+ if (fid_cur<fid) {
+ fid_temp = fid_cur + 2;
+ } else {
+ fid_temp = fid_cur - 2;
+ }
+ } else {
+ /* there is one < 8, So we need to lookup the table to
+ * find the fid_cur */
+ int temp;
+ temp = next_fid_a[(fid_cur/2)*12+(fid/2)];
+ if (temp <= 0) break;
+ fid_temp = (temp-4) * 2;
+ }
+ if (fid_temp > fid_max)
+ break;
+
+ fid_cur = fid_temp;
+
+ /* set target fid */
+ msr.hi = (100000/5);
+ msr.lo = (vid_cur << 8) | fid_cur;
+#if SB_VFSMAF == 1
+ msr.lo |= (1 << 16); /* init changes */
+#endif
+ wrmsr(FIDVID_CTL, msr);
+#if SB_VFSMAF == 0
+ ldtstop_sb();
+#endif
+
+#if K8_SET_FIDVID_DEBUG == 1
+ if (showmessage) {
+ printk(BIOS_DEBUG, "\tapicid in set_fidvid = %02x\n", apicid);
+ printk(BIOS_DEBUG, "ctrl msr fid, vid %08x:%08x\n", msr.hi, msr.lo);
+ }
+#endif
+ for (loop = 0; loop < 100000; loop++){
+ msr = rdmsr(FIDVID_STATUS);
+ if (!(msr.lo & (1 << 31)))
+ break;
+ }
+ fid_cur = msr.lo & 0x3f;
+
+#if K8_SET_FIDVID_DEBUG == 1
+ if (showmessage) {
+ printk(BIOS_DEBUG, "status msr fid, vid %08x:%08x\n",
+ msr.hi, msr.lo);
+ }
+#endif
+ }
+
+ /* set vid to final */
+ msr.hi = 1;
+ msr.lo = (vid << 8) | (fid_cur);
+#if SB_VFSMAF == 1
+ msr.lo |= (1 << 16); // init changes
+#endif
+ wrmsr(FIDVID_CTL, msr);
+#if SB_VFSMAF == 0
+ ldtstop_sb();
+#endif
+
+ for (loop = 0; loop < 100000; loop++){
+ msr = rdmsr(FIDVID_STATUS);
+ if (!(msr.lo & (1 << 31)))
+ break;
+ }
+ vid_cur = msr.hi & 0x3f;
+
+ fidvid = (vid_cur << 16) | (fid_cur << 8);
+
+ if (showmessage) {
+ if (vid!=vid_cur) {
+ printk(BIOS_ERR, "set vid failed for apicid =%08x\n", apicidx);
+ }
+ if (fid!=fid_cur) {
+ printk(BIOS_ERR, "set fid failed for apicid =%08x\n",apicidx);
+ }
+ }
+
+ return fidvid;
+
+}
+
+void init_fidvid_ap(unsigned bsp_apicid, unsigned apicid)
+{
+ u32 send;
+ u32 readback = 0;
+ unsigned int timeout = 1;
+ struct msr;
+ u32 vid_cur;
+ u32 fid_cur;
+ u32 fid_max;
+ int loop;
+
+ msr = rdmsr(FIDVID_STATUS);
+ fid_max = ((msr.lo >> 16) & 0x3f); /* max fid */
+#if FX_SUPPORT
+ if (fid_max >= ((25-4) * 2)) { /* FX max fid is 5G */
+ fid_max = ((msr.lo>>8) & 0x3f) + 5*2; /* maxFID = minFID + 1G */
+ if (fid_max >= ((25-4) * 2)) {
+ fid_max = (10-4) * 2; // hard set to 2G
+ }
+ }
+#endif
+ send = fid_max<<8;
+
+ send |= ((msr.hi >> (48-32)) & 0x3f) << 16; /* max vid */
+ send |= (apicid << 24); /* ap apicid */
+
+#if K8_SET_FIDVID_ONE_BY_ONE == 1
+ vid_cur = msr.hi & 0x3f;
+ fid_cur = msr.lo & 0x3f;
+
+ /* set to current */
+ msr.hi = 1;
+ msr.lo = (vid_cur << 8) | (fid_cur);
+ wrmsr(FIDVID_CTL, msr);
+#endif
+
+ timeout = wait_cpu_state(bsp_apicid, 1);
+ if (timeout) {
+ printk(BIOS_ERR,
+ "fidvid_ap_stage1: time out while reading from BSP on %08x\n",
+ apicid);
+ }
+ /* send signal to BSP about this AP max fid and vid */
+ /* AP at state 1 that sent our fid and vid */
+ lapic_write(LAPIC_MSG_REG, send | 1);
+
+// wait_cpu_state(bsp_apicid, 2); /* don't need we can use apicid directly */
+ loop = 1000000;
+ while (--loop > 0) {
+ /* remote read BSP signal that include vid/fid that need to set */
+ if (lapic_remote_read(bsp_apicid, LAPIC_MSG_REG, &readback)!=0)
+ continue;
+ if (((readback >> 24) & 0xff) == apicid)
+ break; /* it is this cpu turn */
+ }
+
+ if (loop > 0) {
+ #if K8_SET_FIDVID_ONE_BY_ONE == 1
+ readback = set_fidvid(apicid, readback & 0xffff00, 1); // this AP
+ #else
+ readback = set_fidvid_without_init(readback & 0xffff00); // this AP
+ #endif
+ /* send signal to BSP that this AP fid/vid is set */
+ /* allow to change state2 is together with apicid */
+ /* AP at state that We set the requested fid/vid */
+ send = (apicid<<24) | (readback & 0x00ffff00);
+ } else {
+ printk(BIOS_ERR,
+ "fidvid_ap_stage2: time out while reading from BSP on %08x\n",
+ apicid);
+ }
+
+ lapic_write(LAPIC_MSG_REG, send | 2);
+
+ timeout = wait_cpu_state(bsp_apicid, 3);
+ if (timeout) {
+ printk(BIOS_ERR,
+ "fidvid_ap_stage3: time out while reading from BSP on %08x\n",
+ apicid);
+ }
+}
+
+static unsigned int calc_common_fidvid(unsigned int fidvid, unsigned int fidvidx)
+{
+ /* FIXME: need to check the change path to verify if it is reachable
+ * when common fid is small than 1.6G */
+ if ((fidvid & 0xff00) <= (fidvidx & 0xff00)) {
+ return fidvid;
+ }
+ else {
+ return fidvidx;
+ }
+}
+
+struct fidvid_st {
+ unsigned common_fidvid;
+};
+
+static void init_fidvid_bsp_stage1(unsigned int ap_apicid, void *gp )
+{
+ unsigned int readback = 0;
+ unsigned int timeout = 1;
+
+ struct fidvid_st *fvp = gp;
+ int loop;
+
+ printk(BIOS_DEBUG, "state 1: ap_apicid=%08x\n", ap_apicid);
+
+ loop = 1000000;
+ while (--loop > 0) {
+ if (lapic_remote_read(ap_apicid, LAPIC_MSG_REG, &readback)!=0)
+ continue;
+ if ((readback & 0xff) == 1) {
+ timeout = 0;
+ break; /* target ap is in stage 1 */
+ }
+ }
+ if (timeout) {
+ printk(BIOS_ERR,
+ "fidvid_bsp_stage1: time out while reading from ap %08x\n",
+ ap_apicid);
+ return;
+ }
+
+ printk(BIOS_DEBUG, "\treadback=%x\n", readback);
+
+ fvp->common_fidvid = calc_common_fidvid(fvp->common_fidvid, readback & 0xffff00);
+
+ printk(BIOS_DEBUG, "\tcommon_fidvid=%08x\n", fvp->common_fidvid);
+}
+
+static void init_fidvid_bsp_stage2(unsigned ap_apicid, void *gp)
+{
+ unsigned int readback = 0;
+ unsigned int timeout = 1;
+
+ struct fidvid_st *fvp = gp;
+ int loop;
+
+ printk(BIOS_DEBUG, "state 2: ap_apicid=%08x\n", ap_apicid);
+
+ /* all set to state2 */
+ lapic_write(LAPIC_MSG_REG, fvp->common_fidvid | (ap_apicid<<24) | 2);
+
+ loop = 1000000;
+ while (--loop > 0) {
+ if (lapic_remote_read(ap_apicid, LAPIC_MSG_REG, &readback)!=0)
+ continue;
+ if ((readback & 0xff) == 2) {
+ timeout = 0;
+ break; /* target ap is stage 2, it's FID has beed set */
+ }
+ }
+
+ if (timeout) {
+ printk(BIOS_ERR,
+ "fidvid_bsp_stage2: time out while reading from ap %08x\n",
+ ap_apicid);
+ return;
+ }
+
+ printk(BIOS_DEBUG, "\treadback=%08x", readback);
+}
+
+#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
+struct ap_apicid_st {
+ unsigned num;
+ unsigned apicid[16]; /* 8 way dual core need 16 */
+ /* FIXME: 32 node quad core, may need 128 */
+};
+
+static void store_ap_apicid(unsigned ap_apicid, void *gp)
+{
+ struct ap_apicid_st *p = gp;
+
+ p->apicid[p->num++] = ap_apicid;
+
+}
+#endif
+
+static void init_fidvid_bsp(unsigned bsp_apicid)
+{
+ u32 vid_max;
+ u32 fid_max;
+
+ struct fidvid_st fv;
+
+#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
+ struct ap_apicid_st ap_apicidx;
+ unsigned int i;
+#endif
+
+ struct msr msr;
+ msr = rdmsr(FIDVID_STATUS);
+ fid_max = ((msr.lo >> 16) & 0x3f); /* max fid */
+#if FX_SUPPORT == 1
+ if (fid_max >= ((25-4) * 2)) { /* FX max fid is 5G */
+ fid_max = ((msr.lo >> 8) & 0x3f) + 5*2; /* maxFID = minFID + 1G */
+ if (fid_max >= ((25-4) * 2)) {
+ fid_max = (10-4) * 2; /* hard set to 2G */
+ }
+ }
+#endif
+ vid_max = ((msr.hi>>(48-32)) & 0x3f); //max vid
+ fv.common_fidvid = (fid_max << 8)|(vid_max << 16);
+
+
+ /* for all APs (We know the APIC ID of all APs even the APIC ID is lifted)
+ * remote read from AP about max fid/vid */
+
+ /* let all ap trains to state 1 */
+ lapic_write(LAPIC_MSG_REG, (bsp_apicid << 24) | 1);
+
+ /* calculate the common max fid/vid that could be used for
+ * all APs and BSP */
+#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
+ ap_apicidx.num = 0;
+
+ for_each_ap(bsp_apicid, K8_SET_FIDVID_CORE0_ONLY, store_ap_apicid, &ap_apicidx);
+
+ for (i = 0; i < ap_apicidx.num; i++) {
+ init_fidvid_bsp_stage1(ap_apicidx.apicid[i], &fv);
+ }
+#else
+ for_each_ap(bsp_apicid, K8_SET_FIDVID_CORE0_ONLY, init_fidvid_bsp_stage1, &fv);
+#endif
+
+
+#if 0
+ unsigned fid, vid;
+ /* Can we use max only? So we can only set fid in one around,
+ * otherwise we need to set that to max after raminit */
+ /* set fid vid to DQS training required */
+ fid = (fv.common_fidvid >> 8) & 0x3f;
+ vid = (fv.common_fidvid >> 16) & 0x3f;
+
+ if (fid > (10-4) * 2) {
+ fid = (10-4) * 2; // x10
+ }
+
+ if (vid >= 0x1f) {
+ vid += 4; /* unit is 12.5mV */
+ } else {
+ vid += 2; /* unit is 25mV */
+ }
+
+ fv.common_fidvid = (fid<<8) | (vid<<16);
+
+ printk(BIOS_DEBUG, "common_fidvid=%08x\n", fv.common_fidvid);
+
+#endif
+
+#if K8_SET_FIDVID_ONE_BY_ONE == 1
+ /* set BSP fid and vid */
+ printk(BIOS_DEBUG,"bsp apicid=%08x\n", bsp_apicid);
+ fv.common_fidvid = set_fidvid(bsp_apicid, fv.common_fidvid, 1);
+ printk(BIOS_DEBUG,"common_fidvid=%08x\n", fv.common_fidvid);
+#endif
+
+ /* For all APs ( We know the APIC ID of all AP even the APIC ID is lifted)
+ * send signal to the AP it could change it's fid/vid */
+ /* remote read signal from AP that AP is done */
+
+ fv.common_fidvid &= 0xffff00;
+
+ /* set state 2 allow is in init_fidvid_bsp_stage2 */
+#if K8_SET_FIDVID_STORE_AP_APICID_AT_FIRST == 1
+ for (i = 0; i < ap_apicidx.num; i++) {
+ init_fidvid_bsp_stage2(ap_apicidx.apicid[i], &fv);
+ }
+#else
+ for_each_ap(bsp_apicid, K8_SET_FIDVID_CORE0_ONLY, init_fidvid_bsp_stage2, &fv);
+#endif
+
+#if K8_SET_FIDVID_ONE_BY_ONE == 0
+ /* set BSP fid and vid */
+ printk(BIOS_DEBUG, "bsp apicid=%08x\n", bsp_apicid);
+ fv.common_fidvid = set_fidvid(bsp_apicid, fv.common_fidvid, 1);
+ printk(BIOS_DEBUG, "common_fidvid=%08x\n", fv.common_fidvid);
+
+#endif
+
+ /* clear the state */
+ lapic_write(LAPIC_MSG_REG, fv.common_fidvid | (bsp_apicid << 24) | 3);
+
+ /* here wait a while, so last ap could read pack, and stop it, don't
+ * call init_timer too early or just don't use init_timer */
+
+}
Modified: coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c
===================================================================
--- coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c 2008-08-28 07:15:43 UTC (rev 840)
+++ coreboot-v3/arch/x86/amd/model_fxx/init_cpus.c 2008-08-28 17:14:04 UTC (rev 841)
@@ -33,37 +33,8 @@
#include <amd/k8/k8.h>
#include <mc146818rtc.h>
#include <spd.h>
+#include <lapic.h>
-// for rev F, need to set FID to max
-#define K8_SET_FIDVID 1
-
-#ifndef K8_SET_FIDVID_CORE0_ONLY
- /* MSR FIDVID_CTL and FIDVID_STATUS are shared by cores, so may don't need to do twice */
-#define K8_SET_FIDVID_CORE0_ONLY 1
-#endif
-
-static void print_initcpu8(const char *strval, unsigned int val)
-{
- printk(BIOS_DEBUG, "%s%02x\n", strval, val);
-}
-
-static void print_initcpu8_nocr(const char *strval, unsigned val)
-{
- printk(BIOS_DEBUG, "%s%02x", strval, val);
-}
-
-
-static void print_initcpu16(const char *strval, unsigned val)
-{
- printk(BIOS_DEBUG, "%s%04x\n", strval, val);
-}
-
-static inline void print_initcpu(const char *strval, unsigned val)
-{
- printk(BIOS_DEBUG, "%s%08x\n", strval, val);
-
-}
-
typedef void (*process_ap_t) (unsigned apicid, void *gp);
/* See page 330 of Publication # 26094 Revision: 3.30 Issue Date: February 2006
* for APIC id discussion
@@ -173,7 +144,7 @@
* @param pvalue pointer to int for return value
* @returns 0 on success, -1 on error
*/
-static int lapic_remote_read(int apicid, int reg, unsigned int *pvalue)
+int lapic_remote_read(int apicid, int reg, unsigned int *pvalue)
{
int timeout;
unsigned status;
@@ -216,27 +187,13 @@
#define LAPIC_MSG_REG 0x380
+void init_fidvid_ap(unsigned bsp_apicid, unsigned apicid);
-#if K8_SET_FIDVID == 1
-static void init_fidvid_ap(unsigned bsp_apicid, unsigned apicid);
-#endif
-
-static inline __attribute__ ((always_inline))
void print_apicid_nodeid_coreid(unsigned apicid, struct node_core_id id,
const char *str)
{
-#if CONFIG_USE_PRINTK_IN_CAR
- printk_debug
- ("%s --- { APICID = %02x NODEID = %02x COREID = %02x} ---\r\n",
+ printk(BIOS_DEBUG, ""%s --- { APICID = %02x NODEID = %02x COREID = %02x} ---\r\n",
str, apicid, id.nodeid, id.coreid);
-#else
- printk(BIOS_DEBUG, str);
- printk(BIOS_DEBUG, " ---- {APICID = ");
- print_debug_hex8(apicid);
- printk(BIOS_DEBUG, " NODEID = "), print_debug_hex8(id.nodeid);
- printk(BIOS_DEBUG, " COREID = "), print_debug_hex8(id.coreid);
- printk(BIOS_DEBUG, "} --- \r\n");
-#endif
}
@@ -247,7 +204,7 @@
* @param state The state we are waiting for
* @return 0 on success, readback value on error
*/
-static unsigned int wait_cpu_state(unsigned apicid, unsigned state)
+unsigned int wait_cpu_state(unsigned apicid, unsigned state)
{
unsigned readback = 0;
unsigned timeout = 1;
@@ -275,15 +232,15 @@
* @param ap_apicid the apic id of the CPu
* @param gp arbitrary parameter
*/
-static void wait_ap_started(unsigned ap_apicid, void *gp)
+void wait_ap_started(unsigned ap_apicid, void *gp)
{
unsigned timeout;
timeout = wait_cpu_state(ap_apicid, 0x33); // started
if (timeout) {
- print_initcpu8_nocr("*", ap_apicid);
- print_initcpu("*", timeout);
+ printk(BIOS_DEBUG, "%s%02x", "*", ap_apicid);
+ printk(BIOS_DEBUG, "%s%08x\n", "*", timeout);
} else {
- print_initcpu8_nocr(" ", ap_apicid);
+ printk(BIOS_DEBUG, "%s%02x", " ", ap_apicid);
}
}
@@ -300,7 +257,7 @@
* Wait on all other cores to start. This includes cores on bsp, we think.
* @param bsp_apicid The BSP APIC ID
*/
-static void wait_all_other_cores_started(unsigned bsp_apicid) // all aps other than core0
+void wait_all_other_cores_started(unsigned bsp_apicid) // all aps other than core0
{
printk(BIOS_DEBUG, "started ap apicid: ");
for_each_ap(bsp_apicid, 2, wait_ap_started, (void *) 0);
@@ -311,12 +268,12 @@
* Stop all APs
* @param bsp_apicid The BSP apic id, to make sure we don't send ourselves the stop
*/
-static void allow_all_aps_stop(unsigned bsp_apicid)
+void allow_all_aps_stop(unsigned bsp_apicid)
{
lapic_write(LAPIC_MSG_REG, (bsp_apicid << 24) | 0x44); // allow aps to stop
}
-static void STOP_CAR_AND_CPU(void)
+void STOP_CAR_AND_CPU(void)
{
disable_cache_as_ram(); // inline
stop_this_cpu(); // inline, it will stop all cores except node0/core0 the bsp ....
@@ -529,7 +486,7 @@
/**
* Wait for all core 0s on all CPUs to start up.
*/
-static void wait_all_core0_started(void)
+void wait_all_core0_started(void)
{
//When core0 is started, it will distingush_cpu_resets. So wait for that
// whatever that comment means?
@@ -543,7 +500,7 @@
for (i = 1; i < nodes; i++) {
while (!is_core0_started(i)) {
}
- print_initcpu8_nocr(" ", i);
+ printk(BIOS_DEBUG, "%s%02x", " ", i);
}
printk(BIOS_DEBUG, "\r\n");
Modified: coreboot-v3/mainboard/amd/serengeti/Makefile
===================================================================
--- coreboot-v3/mainboard/amd/serengeti/Makefile 2008-08-28 07:15:43 UTC (rev 840)
+++ coreboot-v3/mainboard/amd/serengeti/Makefile 2008-08-28 17:14:04 UTC (rev 841)
@@ -38,6 +38,7 @@
$(src)/arch/x86/amd/model_fxx/init_cpus.c \
$(src)/arch/x86/amd/model_fxx/dualcore.c \
$(src)/arch/x86/amd/model_fxx/dualcore_id.c \
+ $(src)/arch/x86/amd/model_fxx/fidvid.c \
$(src)/lib/clog2.c
Modified: coreboot-v3/mainboard/amd/serengeti/initram.c
===================================================================
--- coreboot-v3/mainboard/amd/serengeti/initram.c 2008-08-28 07:15:43 UTC (rev 840)
+++ coreboot-v3/mainboard/amd/serengeti/initram.c 2008-08-28 17:14:04 UTC (rev 841)
@@ -106,6 +106,10 @@
*/
int main(void)
{
+ /* sure, we could put this in a .h. It's called precisely once, from this one
+ * place. And it only relates to the initram stage. I think I'll leave it here.
+ * That way we can see the definition without grepping the source tree.
+ */
void enable_smbus(void);
u32 init_detected;
static const u16 spd_addr[] = {
@@ -161,7 +165,7 @@
* So here need to make sure last core0 is started, esp for two way system,
* (there may be apic id conflicts in that case)
*/
- start_other_cores();
+ start_all_cores();
wait_all_other_cores_started(bsp_apicid);
#endif
@@ -177,9 +181,9 @@
#if K8_SET_FIDVID == 1
{
- msr_t msr;
- msr=rdmsr(0xc0010042);
- print_debug("begin msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\r\n");
+ struct msr msr;
+ msr=rdmsr(FIDVID_STATUS);
+ printk(BIOS_DEBUG, "begin msr fid, vid %08x:%08x\n", msr.hi ,msr.lo);
}
@@ -191,9 +195,9 @@
// show final fid and vid
{
- msr_t msr;
- msr=rdmsr(0xc0010042);
- print_debug("end msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\r\n");
+ struct msr;
+ msr=rdmsr(msr_t);
+ printk(BIOS_DEBUG, "begin msr fid, vid %08x:%08x\n", msr.hi ,msr.lo);
}
#endif
@@ -204,8 +208,9 @@
// fidvid change will issue one LDTSTOP and the HT change will be effective too
if (needs_reset) {
- print_info("ht reset -\r\n");
- soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn);
+ printk(BIOS_INFO, "ht reset -\r\n");
+#warning define soft_reset_x
+//FIXME soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn);
}
#endif
allow_all_aps_stop(bsp_apicid);
@@ -247,10 +252,9 @@
dump_pci_device_index_wait(PCI_DEV(0, 0x19, 2), 0x98);
#endif
- post_cache_as_ram(); // bsp swtich stack to ram and copy sysinfo ram now
+#warning re-implement post_cache_as_ram
+ // post_cache_as_ram(); // bsp swtich stack to ram and copy sysinfo ram now
-1
-
printk(BIOS_DEBUG, "stage1 returns\n");
return 0;
}
Modified: coreboot-v3/mainboard/amd/serengeti/mainboard.h
===================================================================
--- coreboot-v3/mainboard/amd/serengeti/mainboard.h 2008-08-28 07:15:43 UTC (rev 840)
+++ coreboot-v3/mainboard/amd/serengeti/mainboard.h 2008-08-28 17:14:04 UTC (rev 841)
@@ -33,3 +33,14 @@
#define SB_HT_CHAIN_UNITID_OFFSET_ONLY 1
#define ENABLE_APIC_EXT_ID 0
#define LIFT_BSP_APIC_ID 1
+
+#warning clean up confusion on FIDVID. v2 was inconsistent.
+/* In v2 there is confusion on the settings of these.
+ * The serengeti config sets it to zero.
+ * In the model_fxx support it is hardwired to 1.
+ * We'll assume that setting it to 1 is ok.
+ */
+#define K8_SET_FIDVID 1
+/* MSR FIDVID_CTL and FIDVID_STATUS are shared by cores,
+ * so may don't need to do twice */
+#define K8_SET_FIDVID_CORE0_ONLY 1
Modified: coreboot-v3/northbridge/amd/k8/libstage1.c
===================================================================
--- coreboot-v3/northbridge/amd/k8/libstage1.c 2008-08-28 07:15:43 UTC (rev 840)
+++ coreboot-v3/northbridge/amd/k8/libstage1.c 2008-08-28 17:14:04 UTC (rev 841)
@@ -38,13 +38,6 @@
#include <mc146818rtc.h>
#include <lib.h>
-#define NODE_ID 0x60
-#define HT_INIT_CONTROL 0x6c
-
-#define HTIC_ColdR_Detect (1<<4)
-#define HTIC_BIOSR_Detect (1<<5)
-#define HTIC_INIT_Detect (1<<6)
-
int cpu_init_detected(unsigned int nodeid)
{
unsigned long htic;