(Re-submitting with correction to GFX debug bar setup procedure needed for use with AMD family 0Fh processor).
This patch solves crashes and BSODs that occur when booting Win7 with AMD RS780 uma graphics. Tested with frame buffer sizes 64m through 1GB by running dxdiag and Windows media player at 1600x1200 true color. Additional changes needed to boot Win7 on Mahogany_fam10 will follow.
-- Enable and program the debug bar as required by the ATI graphics driver. First, make the debug bar writable and allow resource allocation code to program it. Once programmed, enable its operation. -- Disable the family 10h processor mmconf while the RS780 mmconf is in use. -- Make strap programming more closely follow the reference BIOS. -- Disable PCIe bar 3 after using it. -- UMA size is no longer hardcoded. -- Disable write combining for all steppings to eliminate stability problem. -- Correct task file data. -- Improve the accuracy of the Atom table that passes information to the driver.
Signed-off-by: Scott Duplichan scott@notabs.org
Index: src/southbridge/amd/rs780/rs780.c =================================================================== --- src/southbridge/amd/rs780/rs780.c (revision 6011) +++ src/southbridge/amd/rs780/rs780.c (working copy) @@ -133,11 +133,6 @@ temp32 = pci_read_config32(nb_dev, 0x4c); printk(BIOS_DEBUG, "NB_PCI_REG4C = %x.\n", temp32);
- /* disable GFX debug. */ - temp8 = pci_read_config8(nb_dev, 0x8d); - temp8 &= ~(1<<1); - pci_write_config8(nb_dev, 0x8d, temp8); - /* set temporary NB TOM to 0x40000000. */ rs780_set_tom(nb_dev);
@@ -194,14 +189,24 @@ static void rs780_nb_gfx_dev_table(device_t nb_dev, device_t dev) { /* NB_InitGFXStraps */ - u32 MMIOBase, apc04, apc18, apc24; + u32 MMIOBase, apc04, apc18, apc24, romstrap2; + msr_t pcie_mmio_save; volatile u32 * strap;
+ // disable processor pcie mmio, if enabled + if (is_family10h()) { + msr_t temp; + pcie_mmio_save = temp = rdmsr (0xc0010058); + temp.lo &= ~1; + wrmsr (0xc0010058, temp); + } + /* Get PCIe configuration space. */ MMIOBase = pci_read_config32(nb_dev, 0x1c) & 0xfffffff0; /* Temporarily disable PCIe configuration space. */ set_htiu_enable_bits(nb_dev, 0x32, 1<<28, 0);
+ // 1E: NB_BIF_SPARE set_nbmisc_enable_bits(nb_dev, 0x1e, 0xffffffff, 1<<1 | 1<<4 | 1<<6 | 1<<7); /* Set a temporary Bus number. */ apc18 = pci_read_config32(dev, 0x18); @@ -214,18 +219,27 @@ pci_write_config8(dev, 0x04, 0x02);
/* Program Straps. */ - strap = (volatile u32 *)(MMIOBase + 0x15020); + romstrap2 = 1 << 26; // enables audio function #if (CONFIG_GFXUMA == 1) - *strap = 1<<7; /* the format of BIF_MEM_AP_SIZE. 001->256MB? */ -#else - *strap = 0; /* 128M SP memory, 000 -> 128MB */ + extern uint64_t uma_memory_size; + // bits 7-9: aperture size + // 0-7: 128mb, 256mb, 64mb, 32mb, 512mb, 1g, 2g, 4g + if (uma_memory_size == 0x02000000) romstrap2 |= 3 << 7; + if (uma_memory_size == 0x04000000) romstrap2 |= 2 << 7; + if (uma_memory_size == 0x08000000) romstrap2 |= 0 << 7; + if (uma_memory_size == 0x10000000) romstrap2 |= 1 << 7; + if (uma_memory_size == 0x20000000) romstrap2 |= 4 << 7; + if (uma_memory_size == 0x40000000) romstrap2 |= 5 << 7; + if (uma_memory_size == 0x80000000) romstrap2 |= 6 << 7; #endif + strap = (volatile u32 *)(MMIOBase + 0x15020); + *strap = romstrap2; strap = (volatile u32 *)(MMIOBase + 0x15000); *strap = 0x2c006300; strap = (volatile u32 *)(MMIOBase + 0x15010); *strap = 0x03015330; - //strap = (volatile u32 *)(MMIOBase + 0x15020); - //*strap |= 0x00000040; /* Disable HDA device. */ + strap = (volatile u32 *)(MMIOBase + 0x15020); + *strap = romstrap2 | 0x00000040; strap = (volatile u32 *)(MMIOBase + 0x15030); *strap = 0x00001002; strap = (volatile u32 *)(MMIOBase + 0x15040); @@ -240,8 +254,9 @@ /* BIF switches into normal functional mode. */ set_nbmisc_enable_bits(nb_dev, 0x1e, 1<<4 | 1<<5, 1<<5);
- /* NB Revision is A12. */ - set_nbmisc_enable_bits(nb_dev, 0x1e, 1<<9, 1<<9); + /* NB Revision is A12 or newer */ + if (get_nb_rev(nb_dev) >= REV_RS780_A12) + set_nbmisc_enable_bits(nb_dev, 0x1e, 1<<9, 1<<9);
/* Restore APC04, APC18, APC24. */ pci_write_config32(dev, 0x04, apc04); @@ -250,6 +265,11 @@
/* Enable PCIe configuration space. */ set_htiu_enable_bits(nb_dev, 0x32, 0, 1<<28); + + // restore processor pcie mmio + if (is_family10h()) + wrmsr (0xc0010058, pcie_mmio_save); + printk(BIOS_INFO, "GC is accessible from now on.\n"); }
@@ -332,18 +352,17 @@ (dev->enabled ? 1 : 0) << 6); if (dev->enabled) rs780_gpp_sb_init(nb_dev, dev, dev_ind); - disable_pcie_bar3(nb_dev); break; case 9: /* bus 0, dev 9,10, GPP */ case 10: printk(BIOS_INFO, "Bus-0, Dev-9, 10, Fun-0. enable=%d\n", dev->enabled); - enable_pcie_bar3(nb_dev); /* PCIEMiscInit */ set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << (7 + dev_ind), (dev->enabled ? 0 : 1) << (7 + dev_ind)); if (dev->enabled) rs780_gpp_sb_init(nb_dev, dev, dev_ind); - /* Dont call disable_pcie_bar3(nb_dev) here, otherwise the screen will crash. */ + + if (dev_ind == 10) disable_pcie_bar3(nb_dev); break; default: printk(BIOS_DEBUG, "unknown dev: %s\n", dev_path(dev)); Index: src/southbridge/amd/rs780/rs780.h =================================================================== --- src/southbridge/amd/rs780/rs780.h (revision 6011) +++ src/southbridge/amd/rs780/rs780.h (working copy) @@ -208,4 +208,9 @@ void config_gpp_core(device_t nb_dev, device_t sb_dev); void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port); u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port); +u32 extractbit(u32 data, int bit_number); +u32 extractbits(u32 source, int lsb, int msb); +int cpuidFamily(void); +int is_family0Fh(void); +int is_family10h(void); #endif /* RS780_H */ Index: src/southbridge/amd/rs780/rs780_cmn.c =================================================================== --- src/southbridge/amd/rs780/rs780_cmn.c (revision 6011) +++ src/southbridge/amd/rs780/rs780_cmn.c (working copy) @@ -29,6 +29,7 @@ #include <cpu/amd/mtrr.h> #include <boot/coreboot_tables.h> #include <delay.h> +#include <cpu/cpu.h> #include "rs780.h"
static u32 nb_read_index(device_t dev, u32 index_reg, u32 index) @@ -223,7 +224,7 @@ pci_write_config32(k8_f1, 0xbc, 0); pci_write_config32(k8_f1, 0xb0, 0); pci_write_config32(k8_f1, 0xb4, 0); - } + } }
void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port) @@ -361,3 +362,42 @@ pci_write_config32(nb_dev, 0x90, uma_memory_base); //nbmc_write_index(nb_dev, 0x1e, uma_memory_base); } + +// extract single bit +u32 extractbit(u32 data, int bit_number) +{ + return (data >> bit_number) & 1; +} + +// extract bit field +u32 extractbits(u32 source, int lsb, int msb) +{ + int field_width = msb - lsb + 1; + u32 mask = 0xFFFFFFFF >> (32 - field_width); + return (source >> lsb) & mask; +} + +// return AMD cpuid family +int cpuidFamily(void) +{ + u32 baseFamily, extendedFamily, fms; + + fms = cpuid_eax (1); + baseFamily = extractbits (fms, 8, 11); + extendedFamily = extractbits (fms, 20, 27); + return baseFamily + extendedFamily; +} + + +// return non-zero for AMD family 0Fh processor found +int is_family0Fh(void) +{ + return cpuidFamily() == 0x0F; +} + + +// return non-zero for AMD family 10h processor found +int is_family10h(void) +{ + return cpuidFamily() == 0x10; +} Index: src/southbridge/amd/rs780/rs780_early_setup.c =================================================================== --- src/southbridge/amd/rs780/rs780_early_setup.c (revision 6011) +++ src/southbridge/amd/rs780/rs780_early_setup.c (working copy) @@ -483,9 +483,11 @@ /* Reg94h[31:29] = 0x7 Enables HT transmitter de-emphasis */ set_nbcfg_enable_bits_8(nb_dev, 0x97, (u8)(~0x1F), 0xE0);
- /*Reg8Ch[10:9] = 0x3 Enables Gfx Debug BAR, - * force this BAR as mem type in rs780_gfx.c */ - set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x03); + /* Reg8Ch[9] enables Gfx Debug BAR programming + * Reg8Ch[10] enables Gfx Debug BAR operation + * Enable programming of the debug bar now, but enable + * operation only after it has been programmed */ + set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x02); }
static void rs780_por_mc_index_init(device_t nb_dev) Index: src/southbridge/amd/rs780/rs780_gfx.c =================================================================== --- src/southbridge/amd/rs780/rs780_gfx.c (revision 6011) +++ src/southbridge/amd/rs780/rs780_gfx.c (working copy) @@ -39,6 +39,8 @@ void set_pcie_reset(void); void set_pcie_dereset(void);
+extern uint64_t uma_memory_base, uma_memory_size; + /* Trust the original resource allocation. Don't do it again. */ #undef DONT_TRUST_RESOURCE_ALLOCATION //#define DONT_TRUST_RESOURCE_ALLOCATION @@ -304,11 +306,15 @@ volatile u32 * pointer; int i; u16 command; - u32 value, sblk; + u32 value; u16 deviceid, vendorid; device_t nb_dev = dev_find_slot(0, 0); device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2)); device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0)); + static u8 ht_freq_lookup [] = {2, 0, 4, 0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 0, 0, 28, 30, 32}; + static u8 ht_width_lookup [] = {8, 16, 0, 0, 2, 4, 0, 0}; + static u16 memclk_lookup_fam0F [] = {100, 0, 133, 0, 0, 166, 0, 200}; + static u16 memclk_lookup_fam10 [] = {200, 266, 333, 400, 533, 667, 800, 800};
/* We definetely will use this in future. Just leave it here. */ /*struct southbridge_amd_rs780_config *cfg = @@ -339,6 +345,8 @@ *(GpuF0MMReg + 0x2180/4) = ((value&0xff00)>>8)|((value&0xff000000)>>8); *(GpuF0MMReg + 0x2c04/4) = ((value&0xff00)<<8); *(GpuF0MMReg + 0x5428/4) = ((value&0xffff0000)+0x10000)-((value&0xffff)<<16); + *(GpuF0MMReg + 0xF774/4) = 0xffffffff; + *(GpuF0MMReg + 0xF770/4) = 0x00000001; *(GpuF0MMReg + 0x2000/4) = 0x00000011; *(GpuF0MMReg + 0x200c/4) = 0x00000020; *(GpuF0MMReg + 0x2010/4) = 0x10204810; @@ -352,21 +360,26 @@ *(GpuF0MMReg + 0x7de4/4) |= (1<<3) | (1<<4); /* Force allow LDT_STOP Cool'n'Quiet workaround. */ *(GpuF0MMReg + 0x655c/4) |= 1<<4; + + // disable write combining, needed for stability + *(GpuF0MMReg + 0x2000/4) = 0x00000010; + *(GpuF0MMReg + 0x2408/4) = 1 << 9; + *(GpuF0MMReg + 0x2000/4) = 0x00000011; + /* GFX_InitFBAccess finished. */
+#if (CONFIG_GFXUMA == 1) /* for UMA mode. */ /* GFX_StartMC. */ -#if (CONFIG_GFXUMA == 1) /* for UMA mode. */ - /* MC_INIT_COMPLETE. */ - set_nbmc_enable_bits(nb_dev, 0x2, 0, 1<<31); - /* MC_STARTUP, MC_POWERED_UP and MC_VMODE.*/ - set_nbmc_enable_bits(nb_dev, 0x1, 1<<18, 1|1<<2); - - set_nbmc_enable_bits(nb_dev, 0xb1, 0, 1<<6); - set_nbmc_enable_bits(nb_dev, 0xc3, 0, 1); - nbmc_write_index(nb_dev, 0x07, 0x18); - nbmc_write_index(nb_dev, 0x06, 0x00000102); - nbmc_write_index(nb_dev, 0x09, 0x40000008); - set_nbmc_enable_bits(nb_dev, 0x6, 0, 1<<31); + set_nbmc_enable_bits(nb_dev, 0x02, 0x00000000, 0x80000000); + set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000001); + set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000004); + set_nbmc_enable_bits(nb_dev, 0x01, 0x00040000, 0x00000000); + set_nbmc_enable_bits(nb_dev, 0xB1, 0xFFFF0000, 0x00000040); + set_nbmc_enable_bits(nb_dev, 0xC3, 0x00000000, 0x00000001); + set_nbmc_enable_bits(nb_dev, 0x07, 0xFFFFFFFF, 0x00000018); + set_nbmc_enable_bits(nb_dev, 0x06, 0xFFFFFFFF, 0x00000102); + set_nbmc_enable_bits(nb_dev, 0x09, 0xFFFFFFFF, 0x40000008); + set_nbmc_enable_bits(nb_dev, 0x06, 0x00000000, 0x80000000); /* GFX_StartMC finished. */ #else /* for SP mode. */ @@ -418,77 +431,110 @@ vgainfo.sHeader.ucTableContentRevision = 2;
#if (CONFIG_GFXUMA == 0) /* SP mode. */ + // Side port support is incomplete, do not use it + // These parameters must match the motherboard vgainfo.ulBootUpSidePortClock = 667*100; - vgainfo.ucMemoryType = 3; + vgainfo.ucMemoryType = 3; // 3=ddr3 sp mem, 2=ddr2 sp mem vgainfo.ulMinSidePortClock = 333*100; #endif
- vgainfo.ulBootUpEngineClock = 500 * 100; /* set boot up GFX engine clock. */ - vgainfo.ulReserved1[0] = 0; vgainfo.ulReserved1[1] = 0; - value = pci_read_config32(k8_f2, 0x94); - printk(BIOS_DEBUG, "MEMCLK = %x\n", value&0x7); - vgainfo.ulBootUpUMAClock = 333 * 100; /* set boot up UMA memory clock. */ - vgainfo.ulBootUpSidePortClock = 0; /* disable SP. */ - vgainfo.ulMinSidePortClock = 0; /* disable SP. */ - for(i=0; i<6; i++) - vgainfo.ulReserved2[i] = 0; - vgainfo.ulSystemConfig = 0; - //vgainfo.ulSystemConfig |= 1<<1 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7 | 1; - vgainfo.ulBootUpReqDisplayVector = 0; //? - vgainfo.ulOtherDisplayMisc = 0; //? - vgainfo.ulDDISlot1Config = 0x000c0011; //0; //VGA - //vgainfo.ulDDISlot1Config = 0x000c00FF; //0; //HDMI - vgainfo.ulDDISlot2Config = 0x00130022; //0; //? - vgainfo.ucMemoryType = 2; - /* UMA Channel Number: 1 or 2. */ - vgainfo.ucUMAChannelNumber = 2; - vgainfo.ucDockingPinBit = 0; //? - vgainfo.ucDockingPinPolarity = 0; //? - vgainfo.ulDockingPinCFGInfo = 0; //? - vgainfo.ulCPUCapInfo = 3; /* K8. */ + vgainfo.ulBootUpEngineClock = 500 * 100; // setup option on reference BIOS, 500 is default
- /* page 5-19 on BDG. */ - vgainfo.usNumberOfCyclesInPeriod = 0x8019; - vgainfo.usMaxNBVoltage = 0x1a; - vgainfo.usMinNBVoltage = 0; - vgainfo.usBootUpNBVoltage = 0x1a; + // find the DDR memory frequency + if (is_family10h()) { + value = pci_read_config32(k8_f2, 0x94); // read channel 0 DRAM Configuration High Register + if (extractbit(value, 14)) // if channel 0 disabled, channel 1 must have memory + value = pci_read_config32(k8_f2, 0x194);// read channel 1 DRAM Configuration High Register + vgainfo.ulBootUpUMAClock = memclk_lookup_fam10 [extractbits (value, 0, 2)] * 100; + } + if (is_family0Fh()) { + value = pci_read_config32(k8_f2, 0x94); + vgainfo.ulBootUpUMAClock = memclk_lookup_fam0F [extractbits (value, 20, 22)] * 100; + }
- /* Get SBLink value (HyperTransport I/O Hub Link ID). */ - value = pci_read_config32(k8_f0, 0x64); - sblk = (value >> 8) & 0x3; - printk(BIOS_DEBUG, "SBLINK = %d.\n", sblk); + /* UMA Channel Number: 1 or 2. */ + vgainfo.ucUMAChannelNumber = 1; + if (is_family0Fh()) { + value = pci_read_config32(k8_f2, 0x90); + if (extractbit(value, 11)) // 128-bit mode + vgainfo.ucUMAChannelNumber = 2; + } + if (is_family10h()) { + u32 dch0 = pci_read_config32(k8_f2, 0x94); + u32 dch1 = pci_read_config32(k8_f2, 0x194); + if (extractbit(dch0, 14) == 0 && extractbit(dch1, 14) == 0) { // both channels enabled + value = pci_read_config32(k8_f2, 0x110); + if (extractbit(value, 4)) // ganged mode + vgainfo.ucUMAChannelNumber = 2; + } + } + + // processor type + if (is_family0Fh()) + vgainfo.ulCPUCapInfo = 3; + if (is_family10h()) + vgainfo.ulCPUCapInfo = 2;
/* HT speed */ - value = pci_read_config32(nb_dev, 0xd0); - printk(BIOS_DEBUG, "NB HT speed = %x.\n", value); - value = pci_read_config32(k8_f0, 0x88 + (sblk * 0x20)); - printk(BIOS_DEBUG, "CPU HT speed = %x.\n", value); - vgainfo.ulHTLinkFreq = 100 * 100; /* set HT speed. */ + value = pci_read_config8(nb_dev, 0xd1); + value = ht_freq_lookup [value] * 100; // HT link frequency in MHz + vgainfo.ulHTLinkFreq = value * 100; // HT frequency in units of 100 MHz + vgainfo.ulHighVoltageHTLinkFreq = vgainfo.ulHTLinkFreq; + vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
+ if (value <= 1800) + vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq; + else { + int sblink, cpuLnkFreqCap, nbLnkFreqCap; + value = pci_read_config32(k8_f0, 0x64); + sblink = extractbits(value, 8, 10); + cpuLnkFreqCap = pci_read_config16(k8_f0, 0x8a + sblink * 0x20); + nbLnkFreqCap = pci_read_config16(nb_dev, 0xd2); + if (cpuLnkFreqCap & nbLnkFreqCap & (1 << 10)) // if both 1800 MHz capable + vgainfo.ulLowVoltageHTLinkFreq = 1800*100; + } + /* HT width. */ - value = pci_read_config32(nb_dev, 0xc8); - printk(BIOS_DEBUG, "HT width = %x.\n", value); - vgainfo.usMinHTLinkWidth = 16; - vgainfo.usMaxHTLinkWidth = 16; - vgainfo.usUMASyncStartDelay = 322; - vgainfo.usUMADataReturnTime = 86; - vgainfo.usLinkStatusZeroTime = 0x00c8; //0; //? - vgainfo.usReserved = 0; - vgainfo.ulHighVoltageHTLinkFreq = 100 * 100; - vgainfo.ulLowVoltageHTLinkFreq = 100 * 100; - vgainfo.usMaxUpStreamHTLinkWidth = 16; - vgainfo.usMaxDownStreamHTLinkWidth = 16; - vgainfo.usMinUpStreamHTLinkWidth = 16; - vgainfo.usMinDownStreamHTLinkWidth = 16; - for(i=0; i<97; i++) - vgainfo.ulReserved3[i] = 0; + value = pci_read_config8(nb_dev, 0xcb); + vgainfo.usMinDownStreamHTLinkWidth = + vgainfo.usMaxDownStreamHTLinkWidth = + vgainfo.usMinUpStreamHTLinkWidth = + vgainfo.usMaxUpStreamHTLinkWidth = + vgainfo.usMinHTLinkWidth = + vgainfo.usMaxHTLinkWidth = ht_width_lookup [extractbits(value, 0, 2)];
+ if (is_family0Fh()) { + vgainfo.usUMASyncStartDelay = 322; + vgainfo.usUMADataReturnTime = 286; + } + + if (is_family10h()) { + static u16 t0mult_lookup [] = {10, 50, 200, 2000}; + int t0time, t0scale; + value = pci_read_config32(k8_f0, 0x16c); + t0time = extractbits(value, 0, 3); + t0scale = extractbits(value, 4, 5); + vgainfo.usLinkStatusZeroTime = t0mult_lookup [t0scale] * t0time; + vgainfo.usUMASyncStartDelay = 100; + if (vgainfo.ulHTLinkFreq < 1000 * 100) { // less than 1000 MHz + vgainfo.usUMADataReturnTime = 300; + vgainfo.usLinkStatusZeroTime = 6 * 100; // 6us for GH in HT1 mode + } + else { + int lssel; + value = pci_read_config32(nb_dev, 0xac); + lssel = extractbits (value, 7, 8); + vgainfo.usUMADataReturnTime = 1300; + if (lssel == 0) vgainfo.usUMADataReturnTime = 150; + } + } + /* Transfer the Table to VBIOS. */ pointer = (u32 *)&vgainfo; for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i+=4) { #if (CONFIG_GFXUMA == 1) - *GpuF0MMReg = 0x80000000 + 0x10000000 - 512 + i; + *GpuF0MMReg = 0x80000000 + uma_memory_size - 512 + i; #else *GpuF0MMReg = 0x80000000 + 0x8000000 - 512 + i; #endif @@ -497,11 +543,22 @@
/* GFX_InitLate. */ { - u8 temp8; - temp8 = pci_read_config8(dev, 0x4); - //temp8 &= ~1; /* CIM clears this bit. Strangely, I can'd. */ - temp8 |= 1<<1|1<<2; - pci_write_config8(dev, 0x4, temp8); + u32 temp; + temp = pci_read_config8(dev, 0x4); + //temp &= ~1; /* CIM clears this bit. Strangely, I can'd. */ + temp |= 1<<1|1<<2; + pci_write_config8(dev, 0x4, temp); + + // if the GFX debug bar is writable, then it has + // been programmed and can be safely enabled now + temp = pci_read_config32(nb_dev, 0x8c); + + // if bits 1 (intgfx_enable) and 9 (gfx_debug_bar_enable) + // then enable gfx debug bar (set gxf_debug_decode_enable) + if (temp & 0x202) + temp |= (1 << 10); + pci_write_config32(nb_dev, 0x8c, temp); + }
#ifdef DONT_TRUST_RESOURCE_ALLOCATION @@ -584,7 +641,6 @@ * Set registers in RS780 and CPU to enable the internal GFX. * Please refer to CIM source code and BKDG. */ -extern uint64_t uma_memory_base, uma_memory_size;
static void rs780_internal_gfx_enable(device_t dev) { @@ -637,7 +693,9 @@ #if (CONFIG_GFXUMA == 1) /* GFX_InitUMA. */ /* Copy CPU DDR Controller to NB MC. */ + device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1)); device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2)); + device_t k8_f4 = dev_find_slot(0, PCI_DEVFN(0x18, 4)); for (i = 0; i < 12; i++) { l_dword = pci_read_config32(k8_f2, 0x40 + i * 4); @@ -646,24 +704,40 @@
l_dword = pci_read_config32(k8_f2, 0x80); nbmc_write_index(nb_dev, 0x3c, l_dword); - l_dword = pci_read_config32(k8_f2, 0x94); - if(l_dword & (1<<22)) - set_nbmc_enable_bits(nb_dev, 0x3c, 0, 1<<16); - else - set_nbmc_enable_bits(nb_dev, 0x3c, 1<<16, 0); + set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<22))<<16); + set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<< 8))<<17); + l_dword = pci_read_config32(k8_f2, 0x90); + set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<10))<<18); + if (is_family10h()) + { + for (i = 0; i < 12; i++) + { + l_dword = pci_read_config32(k8_f2, 0x140 + i * 4); + nbmc_write_index(nb_dev, 0x3d + i, l_dword); + }
- if(l_dword & (1<<8)) - set_nbmc_enable_bits(nb_dev, 0x3c, 0, 1<<17); - else - set_nbmc_enable_bits(nb_dev, 0x3c, 1<<17, 0); + l_dword = pci_read_config32(k8_f2, 0x180); + nbmc_write_index(nb_dev, 0x49, l_dword); + l_dword = pci_read_config32(k8_f2, 0x194); + set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<22))<<16); + set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<< 8))<<17); + l_dword = pci_read_config32(k8_f2, 0x190); + set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<10))<<18);
- l_dword = pci_read_config32(k8_f2, 0x90); - if(l_dword & (1<<10)) - set_nbmc_enable_bits(nb_dev, 0x3c, 0, 1<<18); - else - set_nbmc_enable_bits(nb_dev, 0x3c, 1<<18, 0); + l_dword = pci_read_config32(k8_f2, 0x110); + nbmc_write_index(nb_dev, 0x4a, l_dword); + l_dword = pci_read_config32(k8_f2, 0x114); + nbmc_write_index(nb_dev, 0x4b, l_dword); + l_dword = pci_read_config32(k8_f4, 0x44); + set_nbmc_enable_bits(nb_dev, 0x4a, 0, !!(l_dword & (1<<22))<<24); + l_dword = pci_read_config32(k8_f1, 0x40); + nbmc_write_index(nb_dev, 0x4c, l_dword); + l_dword = pci_read_config32(k8_f1, 0xf0); + nbmc_write_index(nb_dev, 0x4d, l_dword); + }
+ /* Set UMA in the 780 side. */ /* UMA start address, size. */ /* The UMA starts at 0xC0000000 of internal RS780 address space @@ -672,7 +746,7 @@ nbmc_write_index(nb_dev, 0x10, ((uma_memory_size - 1 + 0xC0000000) & (~0xffff)) | 0xc000); nbmc_write_index(nb_dev, 0x11, uma_memory_base); nbmc_write_index(nb_dev, 0x12, 0); - nbmc_write_index(nb_dev, 0xf0, 256); + nbmc_write_index(nb_dev, 0xf0, uma_memory_size >> 20); /* GFX_InitUMA finished. */ #else /* GFX_InitSP. */ @@ -1016,7 +1090,7 @@ /* 5.9.1.1. Disables the GFX REFCLK transmitter so that the GFX * REFCLK PAD can be driven by an external source. */ /* 5.9.1.2. Enables GFX REFCLK receiver to receive the REFCLK from an external source. */ - set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28, 0 << 29 | 1 << 28); + set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28 | 1 << 26, 1 << 28);
/* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */ /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */ Index: src/southbridge/amd/rs780/rs780_pcie.c =================================================================== --- src/southbridge/amd/rs780/rs780_pcie.c (revision 6011) +++ src/southbridge/amd/rs780/rs780_pcie.c (working copy) @@ -221,6 +221,7 @@ printk(BIOS_DEBUG, "disable_pcie_bar3()\n"); pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */ set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */ + set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 0); /* disable bar3 decode */ ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS); }
Hi Scott,
I am not totally convinced that all changes are a net win.
On 03.11.2010 05:29, Scott Duplichan wrote:
(Re-submitting with correction to GFX debug bar setup procedure needed for use with AMD family 0Fh processor).
This patch solves crashes and BSODs that occur when booting Win7 with AMD RS780 uma graphics. Tested with frame buffer sizes 64m through 1GB by running dxdiag and Windows media player at 1600x1200 true color. Additional changes needed to boot Win7 on Mahogany_fam10 will follow.
-- Enable and program the debug bar as required by the ATI graphics driver. First, make the debug bar writable and allow resource allocation code to program it. Once programmed, enable its operation.
Good.
-- Disable the family 10h processor mmconf while the RS780 mmconf is in use.
I thought the family 10h processors need their own MMCONF for some configuration accesses. If this disable happens after all such config writes are done, I'm OK with it.
-- Make strap programming more closely follow the reference BIOS.
Good.
-- Disable PCIe bar 3 after using it.
This one is something I have reservations about. Isn't PCIe BAR 3 the one via which MMCONF accesses are done? How is MMCONF going to work after that?
-- UMA size is no longer hardcoded.
Nice.
-- Disable write combining for all steppings to eliminate stability problem.
This may have a performance impact, right? Do you know if any steppings with stable write combining exist?
-- Correct task file data. -- Improve the accuracy of the Atom table that passes information to the driver.
Yes, that's definitely needed.
Signed-off-by: Scott Duplichan scott@notabs.org
I think the patch looks good, but I'd like a few answers before I ack it.
Regards, Carl-Daniel
-----Original Message----- From: Carl-Daniel Hailfinger [mailto:c-d.hailfinger.devel.2006@gmx.net] Sent: Wednesday, November 03, 2010 01:14 PM To: Scott Duplichan Cc: coreboot@coreboot.org Subject: Re: [coreboot] [PATCH] Fix AMD HD 3200 uma graphics problems in Win7 (revised)
]Hi Scott, ] ]I am not totally convinced that all changes are a net win.
Hello Carl-Daniel,
Thanks for looking at it. The strategy I used is to try to make the code match the current AMD CIMx code as closely as possible. The existing RS780 code is based on an older CIMx version that does not support the family 10h processor. I actually did many experiments with a reference BIOS as a way to find what parts of the code are essential for getting Win7 booted. It is interesting to know that much of the code is not needed for Win7 boot or even for video playback using windows media player. An example is the code that copies some of the processor memory controller settings to the RS780. What is this code for then? Possibly it becomes important for some directX or 3D operation that I did not exercise. I did not test any 3D application.
]On 03.11.2010 05:29, Scott Duplichan wrote: ]> (Re-submitting with correction to GFX debug bar setup procedure needed ]> for use with AMD family 0Fh processor). ]> ]> This patch solves crashes and BSODs that occur when booting Win7 with ]> AMD RS780 uma graphics. Tested with frame buffer sizes 64m through 1GB ]> by running dxdiag and Windows media player at 1600x1200 true color. ]> Additional changes needed to boot Win7 on Mahogany_fam10 will follow. ]> ]> -- Enable and program the debug bar as required by the ATI graphics driver. ]> First, make the debug bar writable and allow resource allocation code ]> to program it. Once programmed, enable its operation. ]> ] ]Good. ] ] ]> -- Disable the family 10h processor mmconf while the RS780 mmconf is in use. ]> ] ]I thought the family 10h processors need their own MMCONF for some ]configuration accesses. If this disable happens after all such config ]writes are done, I'm OK with it.
The family 10h mmconf is disabled only temporarily, then restored to its previous state. I added this code because that is how the current CIMx code does it.
]> -- Make strap programming more closely follow the reference BIOS. ]> ] ]Good. ] ] ]> -- Disable PCIe bar 3 after using it. ]> ] ]This one is something I have reservations about. Isn't PCIe BAR 3 the ]one via which MMCONF accesses are done? How is MMCONF going to work ]after that?
Of the two reference BIOS binaries I can boot, neither appears to leave PCIe bar 3 enabled. I see zeros there after booting, although I am not 100% sure this means zero is its real value. Yet on the two reference BIOS images, along with the patched coreboot, I can still see the RS780 at mmconf+0. I assume the family 10h processor sends mmconf requests to the HT link if the address is not that of an internal device. I don't know how it works for family 0Fh processors.
The original coreboot RS780 code intended to disable BAR 3 after using it. The code comment reads, "We should disable bar3 when we want to exit rs780_enable, because bar3 will be remapped in set_resource later". However, the call to the disable function was removed and replaced by this comment: "Don't call disable_pcie_bar3(nb_dev) here, otherwise the screen will crash". I debugged this problem and found the disable function set the bar to zero, but did not disable it. So legacy video MMIO writes were being claimed by bar 3 and not reaching the video function. The patch corrects this problem and adds back the function call to disable bar 3 after PCIe training is complete. The reason I even looked at this code in the first place is this. With the unpatched code, the PCI resource allocation code finds bar 3 writable and assigns it a base address. In my case it assigned C0000000. This C000000 range is unusable because it is not the range set aside for mmconf. I have mmconf at F8000000.
In addition, I noticed the mahogany_fam10 and mahogany projects have no MCFG table, so Windows will never use mmconf for PCI config access. This is an area I would like to study more, but any improvement should probably be done in a separate patch. It is interesting to know that Microsoft planned for mmconf and the ACPI MCFG table to be required for Windows Vista. The early beta editions required it. But it proved too much trouble and the requirement was removed. The requirement was not added back for Win7. I don't know if it is planned for Win8.
]> -- UMA size is no longer hardcoded. ]> ] ]Nice. ] ] ]> -- Disable write combining for all steppings to eliminate stability problem. ]> ] ]This may have a performance impact, right? Do you know if any steppings ]with stable write combining exist?
Write combining should only be disabled for the early steppings. Why I have to disable it for A13 is an unsolved problem. Yes, I would assume there is a performance impact. On the otherhand, using the ATI driver with write combining disabled still gives a big performance boost when compared to the generic vga driver. I would like to solve this problem, but have run out of time for the moment.
]> -- Correct task file data. ]> -- Improve the accuracy of the Atom table that passes information to the driver. ]> ] ]Yes, that's definitely needed. ] ] ]> Signed-off-by: Scott Duplichan scott@notabs.org ]> ] ]I think the patch looks good, but I'd like a few answers before I ack it. ] ]Regards, ]Carl-Daniel
Scott Duplichan wrote:
With the unpatched code, the PCI resource allocation code finds bar 3 writable and assigns it a base address. In my case it assigned C0000000. This C000000 range is unusable because it is not the range set aside for mmconf. I have mmconf at F8000000.
Do we need a parameter for the resource allocator to know if a resource should go within or outside mmconf?
//Peter
Hi Scott,
I tried to boot with that on famF CPU and it went well. ruiktest:~# ruiktest:~# lspci -vvv -s 01:05.0
01:05.0 VGA compatible controller: ATI Technologies Inc RS880 [Radeon HD 4200] (prog-if 00 [VGA controller]) Subsystem: ATI Technologies Inc Device 0000 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 18 Region 0: Memory at e8000000 (32-bit, prefetchable) [size=128M] Region 1: I/O ports at 1000 [size=256] Region 2: Memory at f8100000 (32-bit, non-prefetchable) [size=64K] Region 5: Memory at f8000000 (32-bit, non-prefetchable) [size=1M] Expansion ROM at <unassigned> [disabled] Capabilities: [50] Power Management version 3 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME- Capabilities: [a0] MSI: Enable- Count=1/1 Maskable- 64bit+ Address: 0000000000000000 Data: 0000 Kernel driver in use: radeon
The BAR seems to be enabled. Btw I tried to boot Win7 but still got only logo animation forever. Not sure what it could be.
I agree that this patch is big improvement. We can fix the MMCONF later.
Thanks, Rudolf
On Wed, Nov 3, 2010 at 3:34 PM, Rudolf Marek r.marek@assembler.cz wrote:
Hi Scott,
I tried to boot with that on famF CPU and it went well. ruiktest:~# ruiktest:~# lspci -vvv -s 01:05.0
01:05.0 VGA compatible controller: ATI Technologies Inc RS880 [Radeon HD 4200] (prog-if 00 [VGA controller]) Subsystem: ATI Technologies Inc Device 0000 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 18 Region 0: Memory at e8000000 (32-bit, prefetchable) [size=128M] Region 1: I/O ports at 1000 [size=256] Region 2: Memory at f8100000 (32-bit, non-prefetchable) [size=64K] Region 5: Memory at f8000000 (32-bit, non-prefetchable) [size=1M] Expansion ROM at <unassigned> [disabled] Capabilities: [50] Power Management version 3 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME- Capabilities: [a0] MSI: Enable- Count=1/1 Maskable- 64bit+ Address: 0000000000000000 Data: 0000 Kernel driver in use: radeon
The BAR seems to be enabled. Btw I tried to boot Win7 but still got only logo animation forever. Not sure what it could be.
I agree that this patch is big improvement. We can fix the MMCONF later.
Was that an ack?
Maybe I misunderstand, but I don't think that there is an MMCONF issue. The bar disable prevents the 780 MMCONF from being moved, right?
Just curious, have you test this with Linux? I tried to load win7, but got a ACPI stop 0xA5. I suspect that my tables are not working at all. This is on iei kino. I will investigate more tomorrow.
Marc
-----Original Message----- From: coreboot-bounces@coreboot.org [mailto:coreboot-bounces@coreboot.org] On Behalf Of Marc Jones Sent: Wednesday, November 03, 2010 06:53 PM To: Rudolf Marek Cc: coreboot@coreboot.org Subject: Re: [coreboot] [PATCH] Fix AMD HD 3200 uma graphics problems inWin7 (revised)
]On Wed, Nov 3, 2010 at 3:34 PM, Rudolf Marek r.marek@assembler.cz wrote: ]> Hi Scott, ]> ]> I tried to boot with that on famF CPU and it went well. ]> ruiktest:~# ]> ruiktest:~# lspci -vvv -s 01:05.0 ]> ]> 01:05.0 VGA compatible controller: ATI Technologies Inc RS880 [Radeon HD ]> 4200] (prog-if 00 [VGA controller]) ]> Subsystem: ATI Technologies Inc Device 0000 ]> Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- ]> Stepping- SERR- FastB2B- DisINTx- ]> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- ]> <TAbort- <MAbort- >SERR- <PERR- INTx- ]> Latency: 0, Cache Line Size: 64 bytes ]> Interrupt: pin A routed to IRQ 18 ]> Region 0: Memory at e8000000 (32-bit, prefetchable) [size=128M] ]> Region 1: I/O ports at 1000 [size=256] ]> Region 2: Memory at f8100000 (32-bit, non-prefetchable) [size=64K] ]> Region 5: Memory at f8000000 (32-bit, non-prefetchable) [size=1M] ]> Expansion ROM at <unassigned> [disabled] ]> Capabilities: [50] Power Management version 3 ]> Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA ]> PME(D0-,D1-,D2-,D3hot-,D3cold-) ]> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME- ]> Capabilities: [a0] MSI: Enable- Count=1/1 Maskable- 64bit+ ]> Address: 0000000000000000 Data: 0000 ]> Kernel driver in use: radeon ]> ]> The BAR seems to be enabled. Btw I tried to boot Win7 but still got only ]> logo animation forever. Not sure what it could be. ]> ]> I agree that this patch is big improvement. We can fix the MMCONF later. ] ]Was that an ack? ] ]Maybe I misunderstand, but I don't think that there is an MMCONF ]issue. The bar disable prevents the 780 MMCONF from being moved, ]right? ] ]Just curious, have you test this with Linux?
Slax 6.12 live CD - Good. Using I/O APIC interrupts.
Linuxmint 9 live CD - Good. Using I/O APIC interrupts.
DSL linux live CD - Flood of "APIC error on CPU0: 40(40)" I believe if SB700 ioxapic mode is not enabled everything is good.
WinXP x64 SP2 setup CD - An unexpected error (805246152) occurred at line 1831 in d:\nt\base\boot\setup\arcdisp.c
WinXP x86 SP3 setup CD - An unexpected error (805246152) occurred at line 1831 in d:\nt\base\boot\setup\arcdisp.c
Win7 x64 Ultimate setup DVD - setup completed quickly with zero problems.
All testing is with UMA graphics. I build the mahogany_fam10 project and run it on an ECS A780GM-M3 board.
]I tried to load win7, but ]got a ACPI stop 0xA5. I suspect that my tables are not working at all. ]This is on iei kino. I will investigate more tomorrow.
The attached patch contains work in progress changes outside of the previously RS780 patch. Apply it to the latest trunk code along with the RS780 patch. This patch is good only for mahogany_fam10, not for mahogany (family 0Fh). The ACPI changes need to be ported from family 10h to family 0Fh. Based on what Rudolf said recently, the family 0Fh project method of passing TOM1 etc to ACPI is the preferred way, not the family 10h method.
Use 1 or 2 GB of memory. Three should also work, although I am not sure the memory init code can handle 3GB. As I recall memory above 4GB is not yet handled correctly for booting Win7.
Hopefully you can just build a mahogany_fam10 binary and run it on Kino. Probably any RS780 video option rom will get the job done.
Thanks, Scott
]Marc ] ]-- ]http://se-eng.com
Was that an ack?
Now it is Acked-by: Rudolf Marek r.marek@assembler.cz
Without this patch I got blank screen after KMS sets the mode.
Thanks, Rudolf
-----Original Message----- From: coreboot-bounces@coreboot.org [mailto:coreboot-bounces@coreboot.org] On Behalf Of Rudolf Marek Sent: Wednesday, November 03, 2010 04:34 PM To: coreboot@coreboot.org Subject: Re: [coreboot] [PATCH] Fix AMD HD 3200 uma graphics problems in Win7 (revised)
]Hi Scott, ] ]I tried to boot with that on famF CPU and it went well. ]ruiktest:~# ]ruiktest:~# lspci -vvv -s 01:05.0 ] ]01:05.0 VGA compatible controller: ATI Technologies Inc RS880 [Radeon HD 4200] ](prog-if 00 [VGA controller]) ] Subsystem: ATI Technologies Inc Device 0000 ] Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- ]SERR- FastB2B- DisINTx- ] Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- ]<MAbort- >SERR- <PERR- INTx- ] Latency: 0, Cache Line Size: 64 bytes ] Interrupt: pin A routed to IRQ 18 ] Region 0: Memory at e8000000 (32-bit, prefetchable) [size=128M] ] Region 1: I/O ports at 1000 [size=256] ] Region 2: Memory at f8100000 (32-bit, non-prefetchable) [size=64K] ] Region 5: Memory at f8000000 (32-bit, non-prefetchable) [size=1M] ] Expansion ROM at <unassigned> [disabled] ] Capabilities: [50] Power Management version 3 ] Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) ] Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME- ] Capabilities: [a0] MSI: Enable- Count=1/1 Maskable- 64bit+ ] Address: 0000000000000000 Data: 0000 ] Kernel driver in use: radeon ] ]The BAR seems to be enabled. Btw I tried to boot Win7 but still got only logo ]animation forever. Not sure what it could be.
Hello Rudolf,
I was able to get the mahogany coreboot to boot Win7 on an ECS A780GM-M3 board with a family 0Fh processor installed. Here are the steps, starting with trunk:
1) Apply the revised RS780 patch (patch-rs780-2.txt). 2) Apply the Win7 changes (win7-wip-1.txt). 3) Apply the additional attached changes for family 0Fh (win7-mahogany.txt). 4) Revert file ht_wrapper.c. That quick and dirty HT3 change is not good for family 0Fh.
Thanks, Scott
]I agree that this patch is big improvement. We can fix the MMCONF later. ] ]Thanks, ]Rudolf
"Scott Duplichan" scott@notabs.org writes:
-- Disable the family 10h processor mmconf while the RS780 mmconf is in use.
I'm not sure I understand how this is supposed to work. Shouldn't we just make sure the two mmconf regions don't overlap? (Or is the overlap intended?) To be frank, I'm not sure what the RS780 mmconf offers over the Fam10 mmconf at all. For Fam0f, I assume it is useful in order to reach extended config space, but as far as I know that should be covered by the Fam10 mmconf already.
- // disable processor pcie mmio, if enabled
- if (is_family10h()) {
msr_t temp;
pcie_mmio_save = temp = rdmsr (0xc0010058);
temp.lo &= ~1;
wrmsr (0xc0010058, temp);
- }
- /* Get PCIe configuration space. */ MMIOBase = pci_read_config32(nb_dev, 0x1c) & 0xfffffff0;
This pci_read_config32 is targeting the Fam10 mmconf area, which is now disabled. Are we relying on the rs780 mmconf to back this address region at this point? If so, we probably should take care to make sure the address assignments match (or rather, document that they need to match). If we need to do this at all, that is.
/* Temporarily disable PCIe configuration space. */ set_htiu_enable_bits(nb_dev, 0x32, 1<<28, 0);
But here we disable the rs780 mmconf, no? Who's backing the mmconf address region now:
- // 1E: NB_BIF_SPARE set_nbmisc_enable_bits(nb_dev, 0x1e, 0xffffffff, 1<<1 | 1<<4 | 1<<6 | 1<<7); /* Set a temporary Bus number. */ apc18 = pci_read_config32(dev, 0x18);
?
Apologies if I have misunderstood something, I haven't quite kept up with the discussion. I'm just a bit concerned about these changes.
-----Original Message----- From: coreboot-bounces@coreboot.org [mailto:coreboot-bounces@coreboot.org] On Behalf Of Arne Georg Gleditsch Sent: Thursday, November 04, 2010 04:38 AM To: Scott Duplichan Cc: 'Peter Stuge'; 'Carl-Daniel Hailfinger'; coreboot@coreboot.org Subject: Re: [coreboot] [PATCH] Fix AMD HD 3200 uma graphics problems inWin7 (revised)
"Scott Duplichan" scott@notabs.org writes:
-- Disable the family 10h processor mmconf while the RS780 mmconf is in use.
]I'm not sure I understand how this is supposed to work. Shouldn't we ]just make sure the two mmconf regions don't overlap? (Or is the overlap ]intended?) To be frank, I'm not sure what the RS780 mmconf offers over ]the Fam10 mmconf at all. For Fam0f, I assume it is useful in order to ]reach extended config space, but as far as I know that should be covered ]by the Fam10 mmconf already.
No doubt there different, and possibly simpler, ways to make this work. The patch I submitted attempts to follow the method used by the AMD CIMx reference code.
]> + // disable processor pcie mmio, if enabled ]> + if (is_family10h()) { ]> + msr_t temp; ]> + pcie_mmio_save = temp = rdmsr (0xc0010058); ]> + temp.lo &= ~1; ]> + wrmsr (0xc0010058, temp); ]> + } ]> + ]> /* Get PCIe configuration space. */ ]> MMIOBase = pci_read_config32(nb_dev, 0x1c) & 0xfffffff0; ] ]This pci_read_config32 is targeting the Fam10 mmconf area, which is now ]disabled. Are we relying on the rs780 mmconf to back this address ]region at this point?
When I step through this pci_read_config32 call (on simnow) I see it using the cf8/cfc method for config access, not the mmio method.
]If so, we probably should take care to make sure ]the address assignments match (or rather, document that they need to ]match). If we need to do this at all, that is. ] ]> /* Temporarily disable PCIe configuration space. */ ]> set_htiu_enable_bits(nb_dev, 0x32, 1<<28, 0); ] ]But here we disable the rs780 mmconf, no? Who's backing the mmconf ]address region now:
Again it looks like all config space access is done with cf8/cfc for these calls.
] ]> + // 1E: NB_BIF_SPARE ]> set_nbmisc_enable_bits(nb_dev, 0x1e, 0xffffffff, 1<<1 | 1<<4 | 1<<6 | 1<<7); ]> /* Set a temporary Bus number. */ ]> apc18 = pci_read_config32(dev, 0x18); ] ]? ] ]Apologies if I have misunderstood something, I haven't quite kept up ]with the discussion. I'm just a bit concerned about these changes. ]-- ] Arne.
"Scott Duplichan" scott@notabs.org writes:
When I step through this pci_read_config32 call (on simnow) I see it using the cf8/cfc method for config access, not the mmio method.
Ok, that sounds like CONFIG_MMCONF_SUPPORT_DEFAULT is not set, is that right? Presuming that's so, I'm worried that this code will break for boards where MMCONFIG is enabled per default.
On Thu, Nov 4, 2010 at 10:03 AM, Scott Duplichan scott@notabs.org wrote:
-----Original Message-----
]> + // disable processor pcie mmio, if enabled ]> + if (is_family10h()) { ]> + msr_t temp; ]> + pcie_mmio_save = temp = rdmsr (0xc0010058); ]> + temp.lo &= ~1; ]> + wrmsr (0xc0010058, temp); ]> + } ]> + ]> /* Get PCIe configuration space. */ ]> MMIOBase = pci_read_config32(nb_dev, 0x1c) & 0xfffffff0; ] ]This pci_read_config32 is targeting the Fam10 mmconf area, which is now ]disabled. Are we relying on the rs780 mmconf to back this address ]region at this point?
When I step through this pci_read_config32 call (on simnow) I see it using the cf8/cfc method for config access, not the mmio method.
This should be MMCONF with CONFIG_MMCONF_SUPPORT=y. Is that not the case? Did we miss something?
Marc
-----Original Message----- From: Marc Jones [mailto:marcj303@gmail.com] Sent: Thursday, November 04, 2010 12:35 PM To: Scott Duplichan Cc: Arne Georg Gleditsch; Peter Stuge; Carl-Daniel Hailfinger; coreboot@coreboot.org Subject: Re: [coreboot] [PATCH] Fix AMD HD 3200 uma graphics problems inWin7 (revised)
]On Thu, Nov 4, 2010 at 10:03 AM, Scott Duplichan scott@notabs.org wrote: ]> -----Original Message----- ] ]> ]> + // disable processor pcie mmio, if enabled ]> ]> + if (is_family10h()) { ]> ]> + msr_t temp; ]> ]> + pcie_mmio_save = temp = rdmsr (0xc0010058); ]> ]> + temp.lo &= ~1; ]> ]> + wrmsr (0xc0010058, temp); ]> ]> + } ]> ]> + ]> ]> /* Get PCIe configuration space. */ ]> ]> MMIOBase = pci_read_config32(nb_dev, 0x1c) & 0xfffffff0; ]> ] ]> ]This pci_read_config32 is targeting the Fam10 mmconf area, which is now ]> ]disabled. Are we relying on the rs780 mmconf to back this address ]> ]region at this point? ]> ]> When I step through this pci_read_config32 call (on simnow) I see it using ]> the cf8/cfc method for config access, not the mmio method. ] ] ]This should be MMCONF with CONFIG_MMCONF_SUPPORT=y. Is that not the ]case? Did we miss something?
Yes, CONFIG_MMCONF_SUPPORT=y for my test. OK, so let's step through pci_write_config32(). That sould be simple enough, probably 3 or 4 processor instructions? It turns out 112 instructions with the optimized build! Anyway, pci_read_config32() first calls get_pbus(dev). In the context above, get_pbus(dev) returns null. It then passes this null pointer to ops_pci_bus, which falls back to the cf8/cfc method because that is what pci_check_direct() found to work. I believe for whatever reasons, the fallback code is used for early execution. Once execution reaches post code 40, the mmconf method is used.
Thanks, Scott
]Marc ] ] ]-- ]http://se-eng.com
"Scott Duplichan" scott@notabs.org writes:
Yes, CONFIG_MMCONF_SUPPORT=y for my test.
This only indicates whether support for the mmconf facility should be compiled in. If CONFIG_MMCONF_SUPPORT_DEFAULT isn't also set, you'll only be using the mmconf facility if you explicitly do pci_mmconf_read_config32 or similar.
-----Original Message----- From: Arne Georg Gleditsch [mailto:arne@gledits.ch] On Behalf Of Arne Georg Gleditsch Sent: Thursday, November 04, 2010 02:25 PM To: Scott Duplichan Cc: 'Marc Jones'; 'Peter Stuge'; 'Carl-Daniel Hailfinger'; coreboot@coreboot.org Subject: Re: [PATCH] Fix AMD HD 3200 uma graphics problems inWin7 (revised)
"Scott Duplichan" scott@notabs.org writes:
Yes, CONFIG_MMCONF_SUPPORT=y for my test.
]This only indicates whether support for the mmconf facility should be ]compiled in. If CONFIG_MMCONF_SUPPORT_DEFAULT isn't also set, you'll ]only be using the mmconf facility if you explicitly do ]pci_mmconf_read_config32 or similar.
Hello Arne,
That is a good point. Here are the relevant items from my config.h: #define CONFIG_MMCONF_BUS_NUMBER 16 #define CONFIG_MMCONF_SUPPORT 1 #define CONFIG_MMCONF_BASE_ADDRESS 0xf8000000 #define CONFIG_MMCONF_SUPPORT_DEFAULT 1
]-- Arne.
"Scott Duplichan" scott@notabs.org writes:
Hello Arne,
That is a good point. Here are the relevant items from my config.h: #define CONFIG_MMCONF_BUS_NUMBER 16 #define CONFIG_MMCONF_SUPPORT 1 #define CONFIG_MMCONF_BASE_ADDRESS 0xf8000000 #define CONFIG_MMCONF_SUPPORT_DEFAULT 1
My apologies, I went back and followed your email re pci_write_config32 step through properly, and of course you're right. In this context this doesn't really matter, since the pci_ops_mmconf selected by the fam10 northbridge are not invoked. So provided we're not (inadvertently) making config space accesses that do so, switching the mapping around should be fairly safe.
(That said, if these accesses are not touching that address region, what accesses are? If none actually do, switching the mapping around wouldn't really seem to accomplish much? Anyway, it seems my understanding of this particular code is less complete than I thought, so I'll butt out of this discussion for now.)