/** Configure ECC scrub @param MrcData - MRC configuration **/ VOID EccScrubSetup( const MRC_PARAMS *MrcData ) { UINT32 BgnAdr = 0; UINT32 EndAdr = MrcData->mem_size; UINT32 BlkSize = GetEccScrubBlkSize() & SCRUB_CFG_BLOCKSIZE_MASK; UINT32 Interval = GetEccScrubInterval() & SCRUB_CFG_INTERVAL_MASK; if( MrcData->ecc_enables == 0 || MrcData->boot_mode == bmS3 || Interval == 0) { // No scrub configuration needed if ECC not enabled // On S3 resume reconfiguration is done as part of resume // script, see SNCS3Save.c ==> SaveRuntimeScriptTable() // Also if PCD disables scrub, then we do nothing. return; } QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_END_MEM_REG, EndAdr); QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_START_MEM_REG, BgnAdr); QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_NEXT_READ_REG, BgnAdr); QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG, Interval << SCRUB_CFG_INTERVAL_SHIFT | BlkSize << SCRUB_CFG_BLOCKSIZE_SHIFT); McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = SCRUB_RESUME_MSG(); }
EFI_STATUS SaveRuntimeScriptTable ( IN EFI_SMM_SYSTEM_TABLE2 *Smst ) { EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress; UINT32 Data32; UINT16 Data16; UINT8 Mask; UINTN Index; UINTN Offset; UINT16 DeviceId; // // Check what Soc we are running on (read Host bridge DeviceId) // DeviceId = QncGetSocDeviceId(); // // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM // and vital to S3 resume. That's why we put save code here // Index = 0; while (mPciCfgRegTable[Index] != PCI_DEVICE_END) { PciAddress.Bus = mPciCfgRegTable[Index++]; PciAddress.Device = mPciCfgRegTable[Index++]; PciAddress.Function = mPciCfgRegTable[Index++]; PciAddress.Register = 0; PciAddress.ExtendedRegister = 0; Data16 = PciRead16 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)); if (Data16 == 0xFFFF) { Index += 8; continue; } for (Offset = 0, Mask = 0x01; Offset < 256; Offset += 4, Mask <<= 1) { if (Mask == 0x00) { Mask = 0x01; } if (mPciCfgRegTable[Index + Offset / 32] & Mask) { PciAddress.Register = (UINT8) Offset; Data32 = PciRead32 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)); // // Save latest settings to runtime script table // S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)), 1, &Data32 ); } } Index += 8; } // // Save message bus registers // Index = 0; while (QNCS3SaveExtReg[Index] != 0xFF) { Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]); // // Save IMR settings with IMR protection disabled initially // HMBOUND and IMRs will be locked just before jumping to the OS waking vector // if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) { if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) { Data32 &= ~IMR_LOCK; if (DeviceId == QUARK2_MC_DEVICE_ID) { Data32 &= ~IMR_EN; } } if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) { Data32 = (UINT32)IMRX_ALL_ACCESS; } } // // Save latest settings to runtime script table // S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)), 1, &Data32 ); Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]); S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)), 1, &Data32 ); Index += 2; } Index = 0; while (QNCS3SaveExtReg[Index] != 0xFF) { // // Save IMR settings with IMR protection enabled (above script was to handle restoring all settings first - now we want to enable) // if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) { if (DeviceId == QUARK2_MC_DEVICE_ID) { if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) { Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]); Data32 &= ~IMR_LOCK; // // Save latest settings to runtime script table // S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)), 1, &Data32 ); Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]); S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)), 1, &Data32 ); } } else { if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) { Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]); // // Save latest settings to runtime script table // S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)), 1, &Data32 ); Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]); S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)), 1, &Data32 ); } } } Index += 2; } // Check if ECC scrub enabled and need re-enabling on resume // All scrub related configuration registers are saved on suspend // as part of QNCS3SaveExtReg configuration table script. // The code below extends the S3 resume script with scrub reactivation // message (if needed only) Data32 = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG); if( 0 != (Data32 & SCRUB_CFG_ACTIVE)) { Data32 = SCRUB_RESUME_MSG(); S3BootScriptSavePciCfgWrite ( S3BootScriptWidthUint32, PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)), 1, &Data32 ); } // // Save I/O ports to S3 script table // // // Important to trap Sx for SMM // Data32 = IoRead32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE); S3BootScriptSaveIoWrite(S3BootScriptWidthUint32, (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE), 1, &Data32); return EFI_SUCCESS; }