Author: myles Date: Thu Sep 9 16:54:07 2010 New Revision: 5796 URL: https://tracker.coreboot.org/trac/coreboot/changeset/5796
Log: Please find appended. This patch gets rid of the %gs magic altogether, fixes a few alignment wrinkles and sets up and registers the MMCONF area for AMD Fam10h CPUs (where selected by mainboard configuration). It removes a bit of code that proved troublesome in MMCONF setups from mcp55_early_setup_car.c, as per earlier discussion.
Signed-off-by: Arne Georg Gleditsch arne.gleditsch@numascale.com Acked-by: Myles Watson mylesgw@gmail.com
Modified: trunk/src/arch/i386/include/arch/mmio_conf.h trunk/src/arch/i386/include/arch/romcc_io.h trunk/src/arch/i386/lib/pci_ops_mmconf.c trunk/src/cpu/amd/model_10xxx/init_cpus.c trunk/src/mainboard/tyan/s2912_fam10/Kconfig trunk/src/northbridge/amd/amdfam10/Kconfig trunk/src/northbridge/amd/amdfam10/early_ht.c trunk/src/northbridge/amd/amdfam10/northbridge.c trunk/src/northbridge/amd/amdmct/mct/mct_d.c trunk/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c
Modified: trunk/src/arch/i386/include/arch/mmio_conf.h ============================================================================== --- trunk/src/arch/i386/include/arch/mmio_conf.h Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/arch/i386/include/arch/mmio_conf.h Thu Sep 9 16:54:07 2010 (r5796) @@ -2,13 +2,13 @@ #define ARCH_MMIO_H 1
-//extended read, GS is already set +// Extended read, constrain to use registers as mandated by AMD MMCONFIG mechanism.
static inline __attribute__((always_inline)) uint8_t read8x(uint32_t addr) { uint8_t value; __asm__ volatile ( - "movb %%gs:(%1), %0\n\t" + "movb (%1), %%al\n\t" :"=a"(value): "b" (addr) ); return value; @@ -18,7 +18,7 @@ { uint16_t value; __asm__ volatile ( - "movw %%gs:(%1), %0\n\t" + "movw (%1), %%ax\n\t" :"=a"(value): "b" (addr) );
@@ -30,7 +30,7 @@ { uint32_t value; __asm__ volatile ( - "movl %%gs:(%1), %0\n\t" + "movl (%1), %%eax\n\t" :"=a"(value): "b" (addr) );
@@ -41,7 +41,7 @@ static inline __attribute__((always_inline)) void write8x(uint32_t addr, uint8_t value) { __asm__ volatile ( - "movb %1, %%gs:(%0)\n\t" + "movb %%al, (%0)\n\t" :: "b" (addr), "a" (value) );
@@ -50,7 +50,7 @@ static inline __attribute__((always_inline)) void write16x(uint32_t addr, uint16_t value) { __asm__ volatile ( - "movw %1, %%gs:(%0)\n\t" + "movw %%ax, (%0)\n\t" :: "b" (addr), "a" (value) );
@@ -59,7 +59,7 @@ static inline __attribute__((always_inline)) void write32x(uint32_t addr, uint32_t value) { __asm__ volatile ( - "movl %1, %%gs:(%0)\n\t" + "movl %%eax, (%0)\n\t" :: "b" (addr), "a" (value) ); }
Modified: trunk/src/arch/i386/include/arch/romcc_io.h ============================================================================== --- trunk/src/arch/i386/include/arch/romcc_io.h Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/arch/i386/include/arch/romcc_io.h Thu Sep 9 16:54:07 2010 (r5796) @@ -107,7 +107,7 @@ static inline __attribute__((always_inline)) uint16_t pci_mmio_read_config16(device_t dev, unsigned where) { unsigned addr; - addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where; + addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~1); return read16x(addr); } #endif @@ -138,7 +138,7 @@ static inline __attribute__((always_inline)) uint32_t pci_mmio_read_config32(device_t dev, unsigned where) { unsigned addr; - addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where; + addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3); return read32x(addr); } #endif @@ -199,7 +199,7 @@ static inline __attribute__((always_inline)) void pci_mmio_write_config16(device_t dev, unsigned where, uint16_t value) { unsigned addr; - addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where; + addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~1); write16x(addr, value); } #endif @@ -230,7 +230,7 @@ static inline __attribute__((always_inline)) void pci_mmio_write_config32(device_t dev, unsigned where, uint32_t value) { unsigned addr; - addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where; + addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3); write32x(addr, value); } #endif
Modified: trunk/src/arch/i386/lib/pci_ops_mmconf.c ============================================================================== --- trunk/src/arch/i386/lib/pci_ops_mmconf.c Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/arch/i386/lib/pci_ops_mmconf.c Thu Sep 9 16:54:07 2010 (r5796) @@ -27,12 +27,12 @@
static uint16_t pci_mmconf_read_config16(struct bus *pbus, int bus, int devfn, int where) { - return (read16x(PCI_MMIO_ADDR(bus, devfn, where))); + return (read16x(PCI_MMIO_ADDR(bus, devfn, where) & ~1)); }
static uint32_t pci_mmconf_read_config32(struct bus *pbus, int bus, int devfn, int where) { - return (read32x(PCI_MMIO_ADDR(bus, devfn, where))); + return (read32x(PCI_MMIO_ADDR(bus, devfn, where) & ~3)); }
static void pci_mmconf_write_config8(struct bus *pbus, int bus, int devfn, int where, uint8_t value) @@ -42,12 +42,12 @@
static void pci_mmconf_write_config16(struct bus *pbus, int bus, int devfn, int where, uint16_t value) { - write8x(PCI_MMIO_ADDR(bus, devfn, where), value); + write16x(PCI_MMIO_ADDR(bus, devfn, where) & ~1, value); }
static void pci_mmconf_write_config32(struct bus *pbus, int bus, int devfn, int where, uint32_t value) { - write8x(PCI_MMIO_ADDR(bus, devfn, where), value); + write32x(PCI_MMIO_ADDR(bus, devfn, where) & ~3, value); }
Modified: trunk/src/cpu/amd/model_10xxx/init_cpus.c ============================================================================== --- trunk/src/cpu/amd/model_10xxx/init_cpus.c Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/cpu/amd/model_10xxx/init_cpus.c Thu Sep 9 16:54:07 2010 (r5796) @@ -57,32 +57,28 @@ static void set_EnableCf8ExtCfg(void) { } #endif
-/*[39:8] */ -#define PCI_MMIO_BASE 0xfe000000 -/* because we will use gs to store hi, so need to make sure lo can start - from 0, So PCI_MMIO_BASE & 0x00ffffff should be equal to 0*/ + +#define _ULLx(x) x ## ULL +#define _ULL(x) _ULLx(x) + +/*[63:0] */ +#define PCI_MMIO_BASE _ULL(CONFIG_MMCONF_BASE_ADDRESS)
static void set_pci_mmio_conf_reg(void) { #if CONFIG_MMCONF_SUPPORT +# if PCI_MMIO_BASE > 0xffffffff +# error CONFIG_MMCONF_BASE_ADDRESS must currently fit in 32 bits! +# endif msr_t msr; msr = rdmsr(0xc0010058); msr.lo &= ~(0xfff00000 | (0xf << 2)); - // 256 bus per segment, MMIO reg will be 4G , enable MMIO Config space - msr.lo |= ((8 + CONFIG_PCI_BUS_SEGN_BITS) << 2) | (1 << 0); + // 256 buses, one segment. Total 256M address space. + msr.lo |= (PCI_MMIO_BASE & 0xfff00000) | (8 << 2) | (1 << 0); msr.hi &= ~(0x0000ffff); - msr.hi |= (PCI_MMIO_BASE >> (32 - 8)); - wrmsr(0xc0010058, msr); // MMIO Config Base Address Reg - - //mtrr for that range? - // set_var_mtrr_x(7, PCI_MMIO_BASE<<8, PCI_MMIO_BASE>>(32-8), 0x00000000, 0x01, MTRR_TYPE_UNCACHEABLE); - - set_wrap32dis(); - - msr.hi = (PCI_MMIO_BASE >> (32 - 8)); - msr.lo = 0; - wrmsr(0xc0000101, msr); //GS_Base Reg + msr.hi |= (PCI_MMIO_BASE >> (32));
+ wrmsr(0xc0010058, msr); // MMIO Config Base Address Reg #endif }
Modified: trunk/src/mainboard/tyan/s2912_fam10/Kconfig ============================================================================== --- trunk/src/mainboard/tyan/s2912_fam10/Kconfig Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/mainboard/tyan/s2912_fam10/Kconfig Thu Sep 9 16:54:07 2010 (r5796) @@ -18,6 +18,7 @@ select ENABLE_APIC_EXT_ID select AMDMCT select TINY_BOOTBLOCK + select MMCONF_SUPPORT_DEFAULT
config MAINBOARD_DIR string
Modified: trunk/src/northbridge/amd/amdfam10/Kconfig ============================================================================== --- trunk/src/northbridge/amd/amdfam10/Kconfig Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/northbridge/amd/amdfam10/Kconfig Thu Sep 9 16:54:07 2010 (r5796) @@ -23,6 +23,7 @@ select HAVE_DEBUG_SMBUS select HYPERTRANSPORT_PLUGIN_SUPPORT select NORTHBRIDGE_AMD_AMDFAM10_ROOT_COMPLEX + select MMCONF_SUPPORT
config AGP_APERTURE_SIZE hex @@ -54,6 +55,16 @@ default n depends on NORTHBRIDGE_AMD_AMDFAM10
+config MMCONF_BASE_ADDRESS + hex + default 0xe0000000 + depends on NORTHBRIDGE_AMD_AMDFAM10 + +config MMCONF_BUS_NUMBER + int + default 256 + depends on NORTHBRIDGE_AMD_AMDFAM10 + config BOOTBLOCK_NORTHBRIDGE_INIT string default "northbridge/amd/amdfam10/bootblock.c"
Modified: trunk/src/northbridge/amd/amdfam10/early_ht.c ============================================================================== --- trunk/src/northbridge/amd/amdfam10/early_ht.c Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/northbridge/amd/amdfam10/early_ht.c Thu Sep 9 16:54:07 2010 (r5796) @@ -129,7 +129,7 @@ PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1;
do { - ctrl = pci_read_config16(devx, pos + ctrl_off); + ctrl = pci_io_read_config16(devx, pos + ctrl_off); /* Is this the end of the hypertransport chain? */ if (ctrl & (1 << 6)) { goto out; @@ -144,8 +144,8 @@ * 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); + pci_io_write_config16(devx, pos + ctrl_off, ctrl); + ctrl = pci_io_read_config16(devx, pos + ctrl_off); if (ctrl & ((1 << 4) | (1 << 8))) { // can not clear the error break;
Modified: trunk/src/northbridge/amd/amdfam10/northbridge.c ============================================================================== --- trunk/src/northbridge/amd/amdfam10/northbridge.c Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/northbridge/amd/amdfam10/northbridge.c Thu Sep 9 16:54:07 2010 (r5796) @@ -1440,9 +1440,29 @@ { }
+static void cpu_bus_read_resources(device_t dev) +{ +#if CONFIG_MMCONF_SUPPORT + struct resource *resource = new_resource(dev, 0xc0010058); + resource->base = CONFIG_MMCONF_BASE_ADDRESS; + resource->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256; + resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +#endif +} + +static void cpu_bus_set_resources(device_t dev) +{ + struct resource *resource = find_resource(dev, 0xc0010058); + if (resource) { + report_resource_stored(dev, resource, " <mmconfig>"); + } + pci_dev_set_resources(dev); +} + static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_noop, - .set_resources = cpu_bus_noop, + .read_resources = cpu_bus_read_resources, + .set_resources = cpu_bus_set_resources, .enable_resources = cpu_bus_noop, .init = cpu_bus_init, .scan_bus = cpu_bus_scan,
Modified: trunk/src/northbridge/amd/amdmct/mct/mct_d.c ============================================================================== --- trunk/src/northbridge/amd/amdmct/mct/mct_d.c Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/northbridge/amd/amdmct/mct/mct_d.c Thu Sep 9 16:54:07 2010 (r5796) @@ -1970,7 +1970,7 @@ reg = 0x40 + (q << 2) + reg_off; /* Base[q] reg.*/ val = Get_NB32(dev, reg); if (!(val & 3)) { /* (CSEnable|Spare==1)bank is enabled already? */ - reg = 0x60 + (q << 1) + reg_off; /*Mask[q] reg.*/ + reg = 0x60 + ((q << 1) & 0xc) + reg_off; /*Mask[q] reg.*/ val = Get_NB32(dev, reg); val >>= 19; val++;
Modified: trunk/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c ============================================================================== --- trunk/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c Thu Sep 9 16:51:17 2010 (r5795) +++ trunk/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c Thu Sep 9 16:54:07 2010 (r5796) @@ -267,8 +267,13 @@ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x74), 0xFFFFFFC0, 0x00000000, RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC0), 0x00000000, 0xCB8410DE, RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC4), 0xFFFFFFF8, 0x00000007, - - RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xC0FFFFFF, 0x19000000, + /* The following operation hangs when performed via MMCFG: + pci_read_config32(romcc): 00010000:0078: 20040000 + setup_resource_map_x_offset: 10000, 78: 20040000 + pci_write_config32(romcc): 00010000:0078: 19040000 + (hang) + Response missing? */ + /* RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xC0FFFFFF, 0x19000000, */
#if MCP55_USE_AZA == 1 RES_PCI_IO, PCI_ADDR(0, 6, 1, 0x40), 0x00000000, 0xCB8410DE,