[coreboot] r824 - in coreboot-v3: mainboard/amd/serengeti northbridge/amd/k8
svn at coreboot.org
svn at coreboot.org
Wed Aug 27 00:12:02 CEST 2008
Author: rminnich
Date: 2008-08-27 00:12:02 +0200 (Wed, 27 Aug 2008)
New Revision: 824
Modified:
coreboot-v3/mainboard/amd/serengeti/stage1.c
coreboot-v3/northbridge/amd/k8/libstage1.c
Log:
1. Add call to stage 1 ht setup for mainboard
2. add support for same, brought over from v2.
Still no luck on 8111 ISA however. What are we missing?
The symptom is simple: Device 0:b.0 does not appear in the PCI list, so
device with vid/did 1022/7468 is not there, so we can not enable 5 MiB
flash addressing.
Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>
Modified: coreboot-v3/mainboard/amd/serengeti/stage1.c
===================================================================
--- coreboot-v3/mainboard/amd/serengeti/stage1.c 2008-08-26 18:01:19 UTC (rev 823)
+++ coreboot-v3/mainboard/amd/serengeti/stage1.c 2008-08-26 22:12:02 UTC (rev 824)
@@ -290,10 +290,12 @@
void hardware_stage1(void)
{
+ void enumerate_ht_chain(void);
int max;
printk(BIOS_ERR, "Stage1: enable rom ...\n");
max = ARRAY_SIZE(register_values);
setup_resource_map(register_values, max);
+ enumerate_ht_chain();
amd8111_enable_rom();
printk(BIOS_ERR, "Done.\n");
post_code(POST_START_OF_MAIN);
Modified: coreboot-v3/northbridge/amd/k8/libstage1.c
===================================================================
--- coreboot-v3/northbridge/amd/k8/libstage1.c 2008-08-26 18:01:19 UTC (rev 823)
+++ coreboot-v3/northbridge/amd/k8/libstage1.c 2008-08-26 22:12:02 UTC (rev 824)
@@ -58,7 +58,8 @@
int bios_reset_detected(void)
{
unsigned long htic;
- htic = pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL);
+ htic =
+ pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL);
return (htic & HTIC_ColdR_Detect) && !(htic & HTIC_BIOSR_Detect);
}
@@ -66,12 +67,13 @@
int cold_reset_detected(void)
{
unsigned long htic;
- htic = pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL);
+ htic =
+ pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL);
return !(htic & HTIC_ColdR_Detect);
}
-void distinguish_cpu_resets(unsigned int nodeid)
+void distinguish_cpu_resets(unsigned int nodeid)
{
u32 htic;
u32 device;
@@ -84,36 +86,38 @@
void set_bios_reset(void)
{
unsigned long htic;
- htic = pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL);
+ htic =
+ pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL);
htic &= ~HTIC_BIOSR_Detect;
- pci_conf1_write_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL, htic);
+ pci_conf1_write_config32(PCI_BDF(0, 0x18, 0), HT_INIT_CONTROL,
+ htic);
}
-u8 node_link_to_bus(unsigned int node, unsigned int link)
+u8 node_link_to_bus(unsigned int node, unsigned int link)
{
- u16 reg;
+ u16 reg;
- for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
- u32 config_map;
- config_map = pci_conf1_read_config32(PCI_BDF(0, 0x18, 1), reg);
- if ((config_map & 3) != 3) {
- continue;
- }
- if ((((config_map >> 4) & 7) == node) &&
- (((config_map >> 8) & 3) == link))
- {
- return (config_map >> 16) & 0xff;
- }
- }
- return 0;
+ for (reg = 0xE0; reg < 0xF0; reg += 0x04) {
+ u32 config_map;
+ config_map =
+ pci_conf1_read_config32(PCI_BDF(0, 0x18, 1), reg);
+ if ((config_map & 3) != 3) {
+ continue;
+ }
+ if ((((config_map >> 4) & 7) == node) &&
+ (((config_map >> 8) & 3) == link)) {
+ return (config_map >> 16) & 0xff;
+ }
+ }
+ return 0;
}
u32 get_sblk(void)
{
- u32 reg;
- /* read PCI_BDF(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
- reg = pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), 0x64);
- return ((reg>>8) & 3) ;
+ u32 reg;
+ /* read PCI_BDF(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
+ reg = pci_conf1_read_config32(PCI_BDF(0, 0x18, 0), 0x64);
+ return ((reg >> 8) & 3);
}
u8 get_sbbusn(unsigned int sblk)
@@ -122,3 +126,187 @@
}
+/* this supports early enumeration of the ht chain */
+/*
+ 2005.11 yhlu add let the real sb to use small unitid
+*/
+// only for sb ht chain
+void enumerate_ht_chain(void)
+{
+#if HT_CHAIN_UNITID_BASE != 0
+/* HT_CHAIN_UNITID_BASE could be 0 (only one ht device in the ht chain), if so, don't need to go through the chain */
+
+ /* 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;
+ u32 dev;
+#if HT_CHAIN_END_UNITID_BASE != 0x20
+ //let's record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
+ unsigned real_last_unitid;
+ u8 real_last_pos;
+ int ht_dev_num = 0; // except host_bridge
+ u8 end_used = 0;
+#endif
+
+ dev = PCI_BDF(0, 0, 0);
+ next_unitid = HT_CHAIN_UNITID_BASE;
+ do {
+ u32 id;
+ u8 hdr_type, pos;
+ last_unitid = next_unitid;
+
+ id = pci_conf1_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;
+ }
+
+ hdr_type = pci_con1_read_config8(dev, PCI_HEADER_TYPE);
+ pos = 0;
+ hdr_type &= 0x7f;
+
+ if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
+ (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
+ pos =
+ pci_conf1_read_config8(dev,
+ PCI_CAPABILITY_LIST);
+ }
+ while (pos != 0) {
+ u8 cap;
+ cap =
+ pci_conf1_read_config8(dev,
+ pos + PCI_CAP_LIST_ID);
+ if (cap == PCI_CAP_ID_HT) {
+ u16 flags;
+ /* Read and write and reread flags so the link
+ * direction bit is valid.
+ */
+ flags =
+ pci_conf1_read_config16(dev,
+ pos +
+ PCI_CAP_FLAGS);
+ pci_write_conf1_config16(dev,
+ pos +
+ PCI_CAP_FLAGS,
+ flags);
+ flags =
+ pci_conf1_read_config16(dev,
+ pos +
+ PCI_CAP_FLAGS);
+ if ((flags >> 13) == 0) {
+ unsigned count;
+ unsigned ctrl, ctrl_off;
+ u32 devx;
+
+#if HT_CHAIN_END_UNITID_BASE != 0x20
+ if (next_unitid >= 0x18) { // don't get mask out by k8, at this time BSP, RT is not enabled, it will response from 0x18,0--0x1f.
+ if (!end_used) {
+ next_unitid =
+ HT_CHAIN_END_UNITID_BASE;
+ end_used = 1;
+ } else {
+ goto out;
+ }
+ }
+ real_last_unitid = next_unitid;
+ real_last_pos = pos;
+ ht_dev_num++;
+#endif
+
+ flags &= ~0x1f;
+ flags |= next_unitid & 0x1f;
+ count = (flags >> 5) & 0x1f;
+
+ devx = PCI_BDF(0, next_unitid, 0);
+ pci_conf1_write_config16(dev,
+ pos +
+ PCI_CAP_FLAGS,
+ flags);
+
+ next_unitid += count;
+
+ flags =
+ pci_conf1_read_config16(devx,
+ pos +
+ PCI_CAP_FLAGS);
+ /* Test for end of chain */
+ ctrl_off = ((flags >> 10) & 1) ? PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1; // another end
+
+ do {
+ ctrl =
+ pci_read_config16(devx,
+ pos +
+ ctrl_off);
+ /* Is this the end of the hypertransport chain? */
+ if (ctrl & (1 << 6)) {
+ goto out;
+ }
+
+ if (ctrl &
+ ((1 << 4) | (1 << 8)))
+ {
+ /*
+ * Either the link has failed, or we have
+ * a CRC error.
+ * Sometimes this can happen due to link
+ * retrain, so lets knock it down and see
+ * if its transient
+ */
+ ctrl |= ((1 << 4) | (1 << 8)); // Link fail + Crc
+ pci_write_config16
+ (devx,
+ pos +
+ ctrl_off,
+ ctrl);
+ ctrl =
+ pci_read_config16
+ (devx,
+ pos +
+ ctrl_off);
+ if (ctrl &
+ ((1 << 4) |
+ (1 << 8))) {
+ // can not clear the error
+ break;
+ }
+ }
+ } while ((ctrl & (1 << 5)) == 0);
+
+ break;
+ }
+ }
+ pos =
+ pci_conf1_read_config8(dev,
+ pos +
+ PCI_CAP_LIST_NEXT);
+ }
+ } while (last_unitid != next_unitid);
+
+ out:
+ ;
+
+#if HT_CHAIN_END_UNITID_BASE != 0x20
+ if ((ht_dev_num > 1)
+ && (real_last_unitid != HT_CHAIN_END_UNITID_BASE)
+ && !end_used) {
+ u16 flags;
+ dev = PCI_BDF(0, real_last_unitid, 0);
+ flags =
+ pci_conf1_read_config16(dev,
+ real_last_pos + PCI_CAP_FLAGS);
+ flags &= ~0x1f;
+ flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
+ pci_conf1_write_config16(dev,
+ real_last_pos + PCI_CAP_FLAGS,
+ flags);
+ }
+#endif
+
+#endif
+
+}
More information about the coreboot
mailing list