diff --git a/arch/x86/amd/model_fxx/dualcore.c b/arch/x86/amd/model_fxx/dualcore.c index a90dbfefb3..06b8d3eafb 100644 --- a/arch/x86/amd/model_fxx/dualcore.c +++ b/arch/x86/amd/model_fxx/dualcore.c @@ -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; } -#if SET_NB_CFG_54 == 1 -u8 set_apicid_cpuid_lo(void) +/** + * 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) { - // set the NB_CFG[54]=1; Why the OS thinks this is a good thing is not yet known. +#if SET_NB_CFG_54 == 1 + //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 +} /** * Start the cores on a given node (cores > 0). It is important that MC4 and other accesses @@ -57,19 +62,19 @@ void start_cores(unsigned nodeid) /* 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; diff --git a/arch/x86/amd/model_fxx/fidvid.c b/arch/x86/amd/model_fxx/fidvid.c new file mode 100644 index 0000000000..353c4cd1ef --- /dev/null +++ b/arch/x86/amd/model_fxx/fidvid.c @@ -0,0 +1,536 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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_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 */ + +} diff --git a/arch/x86/amd/model_fxx/init_cpus.c b/arch/x86/amd/model_fxx/init_cpus.c index 9f28b100e8..7d133ca6ad 100644 --- a/arch/x86/amd/model_fxx/init_cpus.c +++ b/arch/x86/amd/model_fxx/init_cpus.c @@ -33,36 +33,7 @@ #include #include #include - -// 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); - -} +#include typedef void (*process_ap_t) (unsigned apicid, void *gp); /* See page 330 of Publication # 26094 Revision: 3.30 Issue Date: February 2006 @@ -173,7 +144,7 @@ static void for_each_ap(unsigned bsp_apicid, unsigned core_range, * @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 @@ static int lapic_remote_read(int apicid, int reg, unsigned int *pvalue) #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 @@ void print_apicid_nodeid_coreid(unsigned apicid, struct node_core_id id, * @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 @@ static unsigned int wait_cpu_state(unsigned apicid, unsigned state) * @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 @@ static void wait_all_aps_started(unsigned bsp_apicid) * 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 @@ static void wait_all_other_cores_started(unsigned bsp_apicid) // all aps other t * 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 @@ static unsigned int is_core0_started(unsigned nodeid) /** * 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 @@ static void wait_all_core0_started(void) 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"); diff --git a/mainboard/amd/serengeti/Makefile b/mainboard/amd/serengeti/Makefile index 99ad5eae55..3891144ac8 100644 --- a/mainboard/amd/serengeti/Makefile +++ b/mainboard/amd/serengeti/Makefile @@ -38,6 +38,7 @@ INITRAM_SRC= $(src)/mainboard/$(MAINBOARDDIR)/initram.c \ $(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 diff --git a/mainboard/amd/serengeti/initram.c b/mainboard/amd/serengeti/initram.c index 1f292cf6d6..2744de9eb4 100644 --- a/mainboard/amd/serengeti/initram.c +++ b/mainboard/amd/serengeti/initram.c @@ -106,6 +106,10 @@ u8 spd_read_byte(u16 device, u8 address) */ 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 @@ int main(void) * 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 @@ int main(void) #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 @@ int main(void) // 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 @@ int main(void) // 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,9 +252,8 @@ int main(void) 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 - -1 +#warning re-implement post_cache_as_ram + // post_cache_as_ram(); // bsp swtich stack to ram and copy sysinfo ram now printk(BIOS_DEBUG, "stage1 returns\n"); return 0; diff --git a/mainboard/amd/serengeti/mainboard.h b/mainboard/amd/serengeti/mainboard.h index 0e071aceff..7b215f3321 100644 --- a/mainboard/amd/serengeti/mainboard.h +++ b/mainboard/amd/serengeti/mainboard.h @@ -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 diff --git a/northbridge/amd/k8/libstage1.c b/northbridge/amd/k8/libstage1.c index 213aa53c89..1207b10714 100644 --- a/northbridge/amd/k8/libstage1.c +++ b/northbridge/amd/k8/libstage1.c @@ -38,13 +38,6 @@ #include #include -#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;