Arne Georg Gleditsch <[email protected]> writes:
> Regarding hangs, I suspect this might be a PCI config race condition
> between the cores. I tried to adjust my configuration to use MMCONFIG
> to address this. It didn't seem to be supported out of the box, and I
> didn't have the time to look into it further at the moment. I still
> intend to do so, but it would be nice to know if anyone is using
> MMCONFIG with fam10 configurations. Is it supposed to work?
Having looked at it some more, it is hard to see how mmconf support can
possibly be functional at the moment. I've made some progress on
getting it to work on my s2912 test rig; I'm appending the patch I'm
currently running. (This is against r5200.)
My only remaining real issue is that parts of the nvidia mcp55 init code
will not run properly using mmconf. The offending line is
RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xC0FFFFFF, 0x19000000,
which causes the operations
pci_read_config32: 00010000:0078: 20040000
pci_write_config32: 00010000:0078: 19040000
the second of which never returns when executed using mmconf. I'm
speculating that this might be related to missing HT responses or
something due to bus reconfiguration. As far as I can tell the device
being targeted here is 10de:0364 (ISA bridge: nVidia Corporation MCP55
LPC Bridge).
Anoyone familiar with the mcp55 who can shed some light on what this
write is supposed to accomplish and perhaps also on why it succeeds
using the IO config mechanism when mmconf fails?
--
Arne.
diff --git a/src/arch/i386/include/arch/mmio_conf.h b/src/arch/i386/include/arch/mmio_conf.h
index df91cb5..79f8373 100644
--- a/src/arch/i386/include/arch/mmio_conf.h
+++ b/src/arch/i386/include/arch/mmio_conf.h
@@ -8,7 +8,7 @@ static inline __attribute__((always_inline)) uint8_t read8x(uint32_t addr)
{
uint8_t value;
__asm__ volatile (
- "movb %%gs:(%1), %0\n\t"
+ "movb %%gs:(%1), %%al\n\t"
:"=a"(value): "b" (addr)
);
return value;
@@ -18,7 +18,7 @@ static inline __attribute__((always_inline)) uint16_t read16x(uint32_t addr)
{
uint16_t value;
__asm__ volatile (
- "movw %%gs:(%1), %0\n\t"
+ "movw %%gs:(%1), %%ax\n\t"
:"=a"(value): "b" (addr)
);
@@ -30,7 +30,7 @@ static inline __attribute__((always_inline)) uint32_t read32x(uint32_t addr)
{
uint32_t value;
__asm__ volatile (
- "movl %%gs:(%1), %0\n\t"
+ "movl %%gs:(%1), %%eax\n\t"
:"=a"(value): "b" (addr)
);
@@ -41,7 +41,7 @@ static inline __attribute__((always_inline)) uint32_t read32x(uint32_t addr)
static inline __attribute__((always_inline)) void write8x(uint32_t addr, uint8_t value)
{
__asm__ volatile (
- "movb %1, %%gs:(%0)\n\t"
+ "movb %%al, %%gs:(%0)\n\t"
:: "b" (addr), "a" (value)
);
@@ -50,7 +50,7 @@ static inline __attribute__((always_inline)) void write8x(uint32_t addr, uint8_t
static inline __attribute__((always_inline)) void write16x(uint32_t addr, uint16_t value)
{
__asm__ volatile (
- "movw %1, %%gs:(%0)\n\t"
+ "movw %%ax, %%gs:(%0)\n\t"
:: "b" (addr), "a" (value)
);
@@ -59,7 +59,7 @@ static inline __attribute__((always_inline)) void write16x(uint32_t addr, uint16
static inline __attribute__((always_inline)) void write32x(uint32_t addr, uint32_t value)
{
__asm__ volatile (
- "movl %1, %%gs:(%0)\n\t"
+ "movl %%eax, %%gs:(%0)\n\t"
:: "b" (addr), "a" (value)
);
}
diff --git a/src/arch/i386/include/arch/romcc_io.h b/src/arch/i386/include/arch/romcc_io.h
index 738af66..f20fdf7 100644
--- a/src/arch/i386/include/arch/romcc_io.h
+++ b/src/arch/i386/include/arch/romcc_io.h
@@ -106,7 +106,7 @@ static inline __attribute__((always_inline)) uint8_t pci_io_read_config8(device_
static inline __attribute__((always_inline)) uint8_t pci_mmio_read_config8(device_t dev, unsigned where)
{
unsigned addr;
- addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where;
+ addr = dev | where;
return read8x(addr);
}
#endif
@@ -135,7 +135,7 @@ static inline __attribute__((always_inline)) uint16_t pci_io_read_config16(devic
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 = dev | where;
return read16x(addr);
}
#endif
@@ -166,7 +166,7 @@ static inline __attribute__((always_inline)) uint32_t pci_io_read_config32(devic
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 = dev | where;
return read32x(addr);
}
#endif
@@ -196,7 +196,7 @@ static inline __attribute__((always_inline)) void pci_io_write_config8(device_t
static inline __attribute__((always_inline)) void pci_mmio_write_config8(device_t dev, unsigned where, uint8_t value)
{
unsigned addr;
- addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where;
+ addr = dev | where;
write8x(addr, value);
}
#endif
@@ -227,7 +227,7 @@ static inline __attribute__((always_inline)) void pci_io_write_config16(device_t
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 = dev | where;
write16x(addr, value);
}
#endif
@@ -258,7 +258,7 @@ static inline __attribute__((always_inline)) void pci_io_write_config32(device_t
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 = dev | where;
write32x(addr, value);
}
#endif
diff --git a/src/arch/i386/lib/pci_ops_mmconf.c b/src/arch/i386/lib/pci_ops_mmconf.c
index a605708..c69e604 100644
--- a/src/arch/i386/lib/pci_ops_mmconf.c
+++ b/src/arch/i386/lib/pci_ops_mmconf.c
@@ -12,42 +12,64 @@
* Functions for accessing PCI configuration space with mmconf accesses
*/
+#define _ULLx(x) x ## ULL
+#define _ULL(x) _ULLx(x)
+#define PCI_MMIO_BASE _ULL(CONFIG_MMCONF_BASE_ADDRESS)
+
#define PCI_MMIO_ADDR(SEGBUS, DEVFN, WHERE) ( \
- CONFIG_MMCONF_BASE_ADDRESS | \
(((SEGBUS) & 0xFFF) << 20) | \
(((DEVFN) & 0xFF) << 12) | \
((WHERE) & 0xFFF))
+#define MSR_GS_BASE 0xc0000101
+
#include <arch/mmio_conf.h>
+
+static inline __attribute__((always_inline)) void set_gs_base(uint64_t base)
+{
+ /* Make sure %gs is a valid descriptor */
+ __asm__ volatile (
+ "mov %%ds, %%ax\n\tmov %%ax, %%gs" ::: "eax");
+ /* Set base */
+ __asm__ volatile (
+ "wrmsr" :: "A"(base), "c"(MSR_GS_BASE));
+}
+
static uint8_t pci_mmconf_read_config8(struct bus *pbus, int bus, int devfn, int where)
{
+ set_gs_base(PCI_MMIO_BASE);
return (read8x(PCI_MMIO_ADDR(bus, devfn, where)));
}
static uint16_t pci_mmconf_read_config16(struct bus *pbus, int bus, int devfn, int where)
{
+ set_gs_base(PCI_MMIO_BASE);
return (read16x(PCI_MMIO_ADDR(bus, devfn, where)));
}
static uint32_t pci_mmconf_read_config32(struct bus *pbus, int bus, int devfn, int where)
{
+ set_gs_base(PCI_MMIO_BASE);
return (read32x(PCI_MMIO_ADDR(bus, devfn, where)));
}
static void pci_mmconf_write_config8(struct bus *pbus, int bus, int devfn, int where, uint8_t value)
{
+ set_gs_base(PCI_MMIO_BASE);
write8x(PCI_MMIO_ADDR(bus, devfn, where), value);
}
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);
+ set_gs_base(PCI_MMIO_BASE);
+ write16x(PCI_MMIO_ADDR(bus, devfn, where), 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);
+ set_gs_base(PCI_MMIO_BASE);
+ write32x(PCI_MMIO_ADDR(bus, devfn, where), value);
}
diff --git a/src/cpu/amd/model_10xxx/init_cpus.c b/src/cpu/amd/model_10xxx/init_cpus.c
index 822e362..aa98464 100644
--- a/src/cpu/amd/model_10xxx/init_cpus.c
+++ b/src/cpu/amd/model_10xxx/init_cpus.c
@@ -72,9 +72,21 @@ static void set_EnableCf8ExtCfg(void)
static void set_EnableCf8ExtCfg(void) { }
#endif
+static void set_wrap32dis(void) {
+ msr_t msr;
-/*[39:8] */
-#define PCI_MMIO_BASE 0xfe000000
+ msr = rdmsr(0xc0010015);
+ msr.lo |= (1<<17);
+
+ wrmsr(0xc0010015, msr);
+
+}
+
+#define _ULLx(x) x ## ULL
+#define _ULL(x) _ULLx(x)
+
+/*[63:0] */
+#define PCI_MMIO_BASE _ULL(CONFIG_MMCONF_BASE_ADDRESS)
/* 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*/
@@ -87,7 +99,7 @@ static void set_pci_mmio_conf_reg(void)
// 256 bus per segment, MMIO reg will be 4G , enable MMIO Config space
msr.lo |= ((8+CONFIG_PCI_BUS_SEGN_BITS) << 2) | (1 << 0);
msr.hi &= ~(0x0000ffff);
- msr.hi |= (PCI_MMIO_BASE >> (32-8));
+ msr.hi |= (PCI_MMIO_BASE >> (32));
wrmsr(0xc0010058, msr); // MMIO Config Base Address Reg
//mtrr for that range?
@@ -95,12 +107,9 @@ static void set_pci_mmio_conf_reg(void)
set_wrap32dis();
- msr.hi = (PCI_MMIO_BASE >> (32-8));
+ msr.hi = (PCI_MMIO_BASE >> (32));
msr.lo = 0;
wrmsr(0xc0000101, msr); //GS_Base Reg
-
-
-
#endif
}
diff --git a/src/mainboard/tyan/s2912_fam10/Kconfig b/src/mainboard/tyan/s2912_fam10/Kconfig
index 740932f..62ced8a 100644
--- a/src/mainboard/tyan/s2912_fam10/Kconfig
+++ b/src/mainboard/tyan/s2912_fam10/Kconfig
@@ -182,3 +182,8 @@ config HEAP_SIZE
hex
default 0xc0000
depends on BOARD_TYAN_S2912_FAM10
+
+config MMCONF_SUPPORT_DEFAULT
+ bool
+ default y
+ depends on BOARD_TYAN_S2912_FAM10
diff --git a/src/northbridge/amd/amdfam10/Kconfig b/src/northbridge/amd/amdfam10/Kconfig
index e6459d4..f64fdc2 100644
--- a/src/northbridge/amd/amdfam10/Kconfig
+++ b/src/northbridge/amd/amdfam10/Kconfig
@@ -52,6 +52,16 @@ config HW_MEM_HOLE_SIZE_AUTO_INC
default n
depends on NORTHBRIDGE_AMD_AMDFAM10
+config MMCONF_SUPPORT
+ bool
+ default y
+ depends on NORTHBRIDGE_AMD_AMDFAM10
+
+config MMCONF_BASE_ADDRESS
+ hex
+ default 0xffffff0000000000
+ depends on NORTHBRIDGE_AMD_AMDFAM10
+
config BOOTBLOCK_NORTHBRIDGE_INIT
string
default "northbridge/amd/amdfam10/bootblock.c"
diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c
index 22e9902..1779938 100644
--- a/src/northbridge/amd/amdmct/mct/mct_d.c
+++ b/src/northbridge/amd/amdmct/mct/mct_d.c
@@ -1970,7 +1970,7 @@ static void StitchMemory_D(struct MCTStatStruc *pMCTstat,
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++;
diff --git a/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c b/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c
index cee5f25..b9b9858 100644
--- a/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c
+++ b/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c
@@ -272,8 +272,13 @@ static void mcp55_early_setup(unsigned mcp55_num, unsigned *busn, unsigned *devn
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,
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot