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@gmail.com>
Acked-by: Ronald G. minnich <rminnich@gmail.com>


git-svn-id: svn://coreboot.org/repository/coreboot-v3@841 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Ronald G. Minnich 2008-08-28 17:14:04 +00:00
parent acf7535747
commit fd31dee2a6
7 changed files with 596 additions and 89 deletions

View file

@ -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;

View file

@ -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 */
}

View file

@ -33,36 +33,7 @@
#include <amd/k8/k8.h>
#include <mc146818rtc.h>
#include <spd.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);
}
#include <lapic.h>
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");

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;