1 /** @file 2 3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR> 4 5 This program and the accompanying materials are licensed and made available under 7 the terms and conditions of the BSD License that accompanies this distribution. 9 The full text of the license may be found at 11 http://opensource.org/licenses/bsd-license.php. 13 15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 21 23 24 Module Name: 25 26 IchS3Save.c 27 28 Abstract: 29 30 SMM S3 handler Driver implementation file 31 32 Revision History 33 34 **/ 35 #include "SmmPlatform.h" 36 37 extern UINT16 mAcpiBaseAddr; 38 EFI_PHYSICAL_ADDRESS mRuntimeScriptTableBase; 39 40 EFI_STATUS 41 InitRuntimeScriptTable ( 42 IN EFI_SYSTEM_TABLE *SystemTable 43 ) 44 { 45 EFI_STATUS Status; 46 UINT32 VarAttrib; 47 UINTN VarSize; 48 ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase; 49 50 // 51 // Allocate runtime ACPI script table space. We need it to save some 52 // settings done by CSM, which runs after normal script table closed 53 // 54 Status = gBS->AllocatePages ( 55 AllocateAnyPages, 56 EfiACPIReclaimMemory, 57 1, 58 &mRuntimeScriptTableBase 59 ); 60 if (EFI_ERROR(Status)) { 61 return EFI_OUT_OF_RESOURCES ; 62 } 63 64 // 65 // Save runtime script table base into global ACPI variable 66 // 67 VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS 68 | EFI_VARIABLE_NON_VOLATILE; 69 VarSize = sizeof (UINTN); 70 Status = SystemTable->RuntimeServices->GetVariable ( 71 ACPI_GLOBAL_VARIABLE, 72 &gEfiAcpiVariableCompatiblityGuid, 73 &VarAttrib, 74 &VarSize, 75 &AcpiVariableBase 76 ); 77 if (EFI_ERROR(Status)) { 78 return Status; 79 } 80 81 AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase; 82 83 return EFI_SUCCESS; 84 } 85 86 EFI_STATUS 87 SaveRuntimeScriptTable ( 88 VOID 89 ) 90 { 91 SMM_PCI_IO_ADDRESS PciAddress; 92 UINT32 Data32; 93 UINT16 Data16; 94 UINT8 Data8; 95 UINT8 Mask; 96 UINTN Index; 97 UINTN Offset; 98 UINT8 RegTable[] = { 99 100 // 101 //Bus , Dev, Func, DMI 102 // 103 0x00 , 0x00, 0x00, 104 105 // 106 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 107 // 108 0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0, 109 110 // 111 //Bus , Dev, Func, LPC device 112 // 113 0x00 , 0x1F, 0x00, 114 115 // 116 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 117 // 118 0x00 , 0x08, 0x00, 0x07, 0x00, 0x00, 0x90, 0x00, 119 120 // 121 //Bus , Dev, Func, PCIE device 122 // 123 0x00 , 0x1C, 0x00, 124 125 // 126 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 127 // 128 0xC0 , 0x83, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 129 130 // 131 //Bus , Dev, Func, PCIE device 132 // 133 0x00 , 0x1C, 0x00, 134 135 // 136 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 137 // 138 0x03 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 139 140 // 141 //Bus , Dev, Func, SATA device 142 // 143 0x00 , 0x13, 0x00, 144 145 // 146 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 147 // 148 0xf4 , 0xab, 0x27, 0x10, 0xf1, 0x1d, 0x00, 0x40, 149 150 // 151 //Bus , Dev, Func, EHCI device 152 // 153 0x00 , 0x1D, 0x00, 154 155 // 156 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 157 // 158 0x10 , 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 159 160 // 161 //Bus , Dev, Func, SMBUS device 162 // 163 0x00 , 0x1f, 0x03, 164 165 // 166 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 167 // 168 0x10 , 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 170 // 171 //Bus , Dev, Func, SMBUS device 172 // 173 0x00 , 0x1f, 0x03, 174 175 // 176 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 177 // 178 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 179 180 // 181 //Bus , Dev, Func, VGA bus1 182 // 183 0x01 , 0x00, 0x00, 184 185 // 186 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 187 // 188 0x58 , 0x81, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00, 189 190 // 191 //Bus , Dev, Func, VGA bus1 192 // 193 0x01 , 0x00, 0x00, 194 195 // 196 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 197 // 198 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 200 // 201 //Bus , Dev, Func, VGA bus1 function 1 202 // 203 0x01 , 0x00, 0x01, 204 205 // 206 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 207 // 208 0x51 , 0x80, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 209 210 // 211 //Bus , Dev, Func, VGA bus1 function 1 212 // 213 0x01 , 0x00, 0x01, 214 215 // 216 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 217 // 218 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 220 // 221 //Bus , Dev, Func, IGD bus0 function 0 222 // 223 0x00 , 0x02, 0x00, 224 225 // 226 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 227 // 228 0x42 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 229 230 // 231 //Bus , Dev, Func, USB bus0 function 0 232 // 233 0x00 , 0x16, 0x00, 234 235 // 236 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 237 // 238 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 239 240 // 241 //Bus , Dev, Func, HD Audio bus0 function 0 242 // 243 0x00 , 0x1B, 0x00, 244 245 // 246 //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF 247 // 248 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 249 250 // 251 //0xFF indicates the end of the table 252 // 253 0xFF 254 }; 255 256 // 257 // These registers have to set in byte order 258 // 259 UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings 260 261 262 263 // 264 // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM 265 // and vital to S3 resume. That's why we put save code here 266 // 267 PciAddress.Bus = 0; 268 PciAddress.Device = 0; 269 PciAddress.Function = 0; 270 PciAddress.ExtendedRegister = 0; 271 272 for (Index = 0; Index < 2; Index++) { 273 // 274 // Read SRAM setting from Pci(0, 0, 0) 275 // 276 PciAddress.Register = ExtReg[Index]; 277 Data8 = MmioRead8 ( 278 MmPciAddress (0, 279 PciAddress.Bus, 280 PciAddress.Device, 281 PciAddress.Function, 282 PciAddress.Register 283 ) 284 ); 285 286 // 287 // Save latest settings to runtime script table 288 // 289 S3BootScriptSavePciCfgWrite( 290 S3BootScriptWidthUint8, 291 *(UINT64*)&PciAddress, 292 1, 293 &Data8 294 ); 295 } 296 297 298 // 299 // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM 300 // and vital to S3 resume. That's why we put save code here 301 // 302 Index = 0; 303 while (RegTable[Index] != 0xFF) { 304 305 PciAddress.Bus = RegTable[Index++]; 306 PciAddress.Device = RegTable[Index++]; 307 PciAddress.Function = RegTable[Index++]; 308 PciAddress.Register = 0; 309 PciAddress.ExtendedRegister = 0; 310 311 Data16 = MmioRead16 ( 312 MmPciAddress (0, 313 PciAddress.Bus, 314 PciAddress.Device, 315 PciAddress.Function, 316 PciAddress.Register 317 ) 318 ); 319 320 if (Data16 == 0xFFFF) { 321 Index+=8; 322 continue; 323 } 324 325 for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) { 326 327 if (Mask == 0x00) { 328 Mask = 0x01; 329 } 330 331 if (RegTable[Index + Offset/32] & Mask ) { 332 333 PciAddress.Register = (UINT8)Offset; 334 Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)); 335 336 // 337 // Save latest settings to runtime script table 338 // 339 S3BootScriptSavePciCfgWrite ( 340 S3BootScriptWidthUint32, 341 *(UINT64*)&PciAddress, 342 1, 343 &Data32 344 ); 345 } 346 } 347 348 Index += 8; 349 350 } 351 352 353 // 354 // Save I/O ports to S3 script table 355 // 356 357 // 358 // Selftest KBC 359 // 360 Data8 = 0xAA; 361 S3BootScriptSaveIoWrite ( 362 S3BootScriptWidthUint8, 363 0x64, 364 (UINTN)1, 365 &Data8 366 ); 367 368 Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN); 369 370 S3BootScriptSaveIoWrite ( 371 S3BootScriptWidthUint32, 372 (mAcpiBaseAddr + R_PCH_SMI_EN), 373 1, 374 &Data32 375 ); 376 377 // 378 // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path. 379 // 380 Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT); 381 382 S3BootScriptSaveIoWrite ( 383 S3BootScriptWidthUint16, 384 mAcpiBaseAddr + R_PCH_TCO_CNT, 385 1, 386 &Data16 387 ); 388 389 390 return EFI_SUCCESS; 391 } 392