YhLu fix on multi ht and s2885

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1485 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Li-Ta Lo 2004-03-26 21:34:04 +00:00
parent 2f92e14dd4
commit 4cd79f3f86
4 changed files with 127 additions and 117 deletions

View File

@ -120,10 +120,6 @@ mainboardinit cpu/i386/bist32_fail.inc
###
### Romcc output
###
#makerule ./failover.E dep "$(MAINBOARD)/failover.c" act "$(CPP) -I$(TOP)/src $(CPPFLAGS) $(MAINBOARD)/failover.c > ./failever.E"
#makerule ./failover.inc dep "./romcc ./failover.E" act "./romcc -O ./failover.E > failover.inc"
#mainboardinit .failover.inc
makerule ./failover.E
depends "$(MAINBOARD)/failover.c"
action "$(CPP) -I$(TOP)/src $(ROMCCPPFLAGS) $(CPPFLAGS) $(MAINBOARD)/failover.c > ./failover.E"
@ -141,8 +137,7 @@ end
makerule ./auto.inc
depends "./romcc ./auto.E"
action "./romcc -O -mcpu=k8 -o auto.inc --label-prefix=auto ./auto.E"
# action "./romcc -mcpu=k8 -O ./auto.E > auto.inc"
action "./romcc -O2 -mcpu=k8 -o auto.inc --label-prefix=auto ./auto.E"
end
mainboardinit cpu/k8/enable_mmx_sse.inc

View File

@ -151,16 +151,13 @@ static void main(void)
{
.udev = PCI_DEV(0, 0x18, 0),
.upos = 0xc0,
.devreg = 0xe2,
.mindev = 1,
},
.devreg = 0xe0,
},
{
.udev = PCI_DEV(0, 0x18, 0),
.upos = 0x80,
.devreg = 0xe6,
.mindev = 5,
},
.devreg = 0xe4,
},
};
int needs_reset;

View File

@ -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, 0x04010207,
PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x06050007,
PCI_ADDR(0, 0x18, 1, 0xE0), 0x0000FC88, 0x06010207,
PCI_ADDR(0, 0x18, 1, 0xE4), 0x0000FC88, 0x00000007,
PCI_ADDR(0, 0x18, 1, 0xE8), 0x0000FC88, 0x00000000,
PCI_ADDR(0, 0x18, 1, 0xEC), 0x0000FC88, 0x00000000,
};

View File

@ -12,7 +12,7 @@ static unsigned ht_lookup_slave_capability(device_t dev)
hdr_type &= 0x7f;
if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
(hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
(hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
pos = PCI_CAPABILITY_LIST;
}
if (pos > PCI_CAP_LIST_NEXT) {
@ -48,7 +48,7 @@ static void ht_collapse_previous_enumeration(unsigned bus)
id = pci_read_config32(dev, PCI_VENDOR_ID);
if ((id == 0xffffffff) || (id == 0x00000000) ||
(id == 0x0000ffff) || (id == 0xffff0000)) {
(id == 0x0000ffff) || (id == 0xffff0000)) {
continue;
}
pos = ht_lookup_slave_capability(dev);
@ -63,7 +63,6 @@ static void ht_collapse_previous_enumeration(unsigned bus)
}
}
static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
{
/* Handle bugs in valid hypertransport frequency reporting */
@ -90,27 +89,27 @@ static unsigned ht_read_freq_cap(device_t dev, unsigned pos)
return freq_cap;
}
#define LINK_OFFS(WIDTH,FREQ,FREQ_CAP) \
#define LINK_OFFS(WIDTH,FREQ,FREQ_CAP) \
(((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
#define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF)
#define LINK_FREQ(OFFS) ((OFFS >> 8) & 0xFF)
#define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
#define PCI_HT_HOST_OFFS LINK_OFFS( \
PCI_HT_CAP_HOST_WIDTH, \
PCI_HT_CAP_HOST_FREQ, \
PCI_HT_CAP_HOST_FREQ_CAP)
#define PCI_HT_HOST_OFFS LINK_OFFS( \
PCI_HT_CAP_HOST_WIDTH, \
PCI_HT_CAP_HOST_FREQ, \
PCI_HT_CAP_HOST_FREQ_CAP)
#define PCI_HT_SLAVE0_OFFS LINK_OFFS( \
PCI_HT_CAP_SLAVE_WIDTH0, \
PCI_HT_CAP_SLAVE_FREQ0, \
PCI_HT_CAP_SLAVE_FREQ_CAP0)
#define PCI_HT_SLAVE0_OFFS LINK_OFFS( \
PCI_HT_CAP_SLAVE_WIDTH0, \
PCI_HT_CAP_SLAVE_FREQ0, \
PCI_HT_CAP_SLAVE_FREQ_CAP0)
#define PCI_HT_SLAVE1_OFFS LINK_OFFS( \
PCI_HT_CAP_SLAVE_WIDTH1, \
PCI_HT_CAP_SLAVE_FREQ1, \
PCI_HT_CAP_SLAVE_FREQ_CAP1)
#define PCI_HT_SLAVE1_OFFS LINK_OFFS( \
PCI_HT_CAP_SLAVE_WIDTH1, \
PCI_HT_CAP_SLAVE_FREQ1, \
PCI_HT_CAP_SLAVE_FREQ_CAP1)
static int ht_optimize_link(
device_t dev1, uint8_t pos1, unsigned offs1,
@ -212,8 +211,8 @@ static int ht_setup_chain(device_t udev, unsigned upos)
id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
break;
}
pos = ht_lookup_slave_capability(dev);
@ -242,111 +241,130 @@ static int ht_setup_chain(device_t udev, unsigned upos)
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
return reset_needed;
}
struct ht_chain {
device_t udev;
unsigned upos;
unsigned devreg;
unsigned mindev;
};
device_t udev;
unsigned upos;
unsigned devreg;
};
static int ht_setup_chainx(device_t udev, unsigned upos, unsigned next_unitid)
{
unsigned last_unitid;
unsigned uoffs;
int reset_needed=0;
uoffs = PCI_HT_HOST_OFFS;
do {
uint32_t id;
uint8_t pos;
unsigned flags, count;
device_t dev = PCI_DEV(0, 0, 0);
last_unitid = next_unitid;
id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
break;
}
pos = ht_lookup_slave_capability(dev);
if (!pos) {
print_err("HT link capability not found\r\n");
break;
}
/* Setup the Hypertransport link */
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, PCI_HT_SLAVE0_OFFS);
/* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
flags &= ~0x1f; /* mask out the bse Unit ID */
flags |= next_unitid & 0x1f;
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
/* Remeber the location of the last device */
udev = PCI_DEV(0, next_unitid, 0);
upos = pos;
uoffs = PCI_HT_SLAVE1_OFFS;
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f;
next_unitid += count;
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
if(reset_needed!=0) next_unitid |= 0xffff0000;
return next_unitid;
}
static int ht_setup_chains(const struct ht_chain *ht_c, int ht_c_num)
{
/* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
* On most boards this just happens. If a cpu has multiple
* non Coherent links the appropriate bus registers for the
* links needs to be programed to point at bus 0.
*/
unsigned next_unitid, last_unitid;
int reset_needed;
unsigned uoffs;
unsigned upos;
device_t udev;
int i;
{
/* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
* On most boards this just happens. If a cpu has multiple
* non Coherent links the appropriate bus registers for the
* links needs to be programed to point at bus 0.
*/
unsigned next_unitid;
int reset_needed;
unsigned upos;
device_t udev;
int i;
/* Make certain the HT bus is not enumerated */
ht_collapse_previous_enumeration(0);
/* Make certain the HT bus is not enumerated */
ht_collapse_previous_enumeration(0);
reset_needed = 0;
next_unitid = 1;
reset_needed = 0;
next_unitid = 1;
for(i=0;i<ht_c_num;i++) {
#if 0
unsigned tmp;
tmp = pci_read_config8(PCI_DEV(0,0x18,1),ht_c[i].devreg);
#endif
for(i=0;i<ht_c_num;i++) {
uint32_t reg;
uint8_t reg8;
reg = pci_read_config32(PCI_DEV(0,0x18,1), ht_c[i].devreg);
reg |= (0xff<<24) | 7;
reg &= ~(0xff<<16);
pci_write_config32(PCI_DEV(0,0x18,1), ht_c[i].devreg, reg);
pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg, 0);
#if CONFIG_MAX_CPUS > 1
pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg, 0);
pci_write_config32(PCI_DEV(0,0x19,1), ht_c[i].devreg, reg);
#endif
#if CONFIG_MAX_CPUS > 2
pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg, 0);
pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg, 0);
pci_write_config32(PCI_DEV(0,0x1a,1), ht_c[i].devreg, reg);
pci_write_config32(PCI_DEV(0,0x1b,1), ht_c[i].devreg, reg);
#endif
uoffs = PCI_HT_HOST_OFFS;
upos = ht_c[i].upos;
udev = ht_c[i].udev;
do {
uint32_t id;
uint8_t pos;
unsigned flags, count;
device_t dev = PCI_DEV(0, 0, 0);
last_unitid = next_unitid;
id = pci_read_config32(dev, PCI_VENDOR_ID);
/* If the chain is enumerated quit */
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
break;
}
pos = ht_lookup_slave_capability(dev);
if (!pos) {
print_err("HT link capability not found\r\n");
break;
}
/* Setup the Hypertransport link */
reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, PCI_HT_SLAVE0_OFFS);
//Store dev min
reg8 = next_unitid & 0xff ;
upos = ht_c[i].upos;
udev = ht_c[i].udev;
/* Update the Unitid of the current device */
flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
flags &= ~0x1f; /* mask out the bse Unit ID */
flags |= next_unitid & 0x1f;
pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
next_unitid = ht_setup_chainx(udev,upos,next_unitid);
if((next_unitid & 0xffff0000) == 0xffff0000) {
reset_needed |= 1;
next_unitid &=0x0000ffff;
}
/* Remeber the location of the last device */
udev = PCI_DEV(0, next_unitid, 0);
upos = pos;
uoffs = PCI_HT_SLAVE1_OFFS;
/* Compute the number of unitids consumed */
count = (flags >> 5) & 0x1f;
next_unitid += count;
} while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
#if 0
pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg, tmp);
//set dev min
pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg+2, reg8);
#if CONFIG_MAX_CPUS > 1
pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg, tmp);
pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg+2, reg8);
#endif
#if CONFIG_MAX_CPUS > 2
pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg, tmp);
pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg, tmp);
pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg+2, reg8);
pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg+2, reg8);
#endif
#else
pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg, ht_c[i].mindev);
#if CONFIG_MAX_CPUS > 1
pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg, ht_c[i].mindev);
//Set dev max
reg8 = (next_unitid-1) & 0xff ;
pci_write_config8(PCI_DEV(0,0x18,1), ht_c[i].devreg+3, reg8);
#if CONFIG_MAX_CPUS > 1
pci_write_config8(PCI_DEV(0,0x19,1), ht_c[i].devreg+3, reg8);
#endif
#if CONFIG_MAX_CPUS > 2
pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg, ht_c[i].mindev);
pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg, ht_c[i].mindev);
#endif
pci_write_config8(PCI_DEV(0,0x1a,1), ht_c[i].devreg+3, reg8);
pci_write_config8(PCI_DEV(0,0x1b,1), ht_c[i].devreg+3, reg8);
#endif
}
}
return reset_needed;
return reset_needed;
}