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