1 /** @file 2 Essential platform configuration. 3 4 Copyright (c) 2013 Intel Corporation. 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 15 **/ 16 17 #include "PlatformInitDxe.h" 18 19 // 20 // The protocols, PPI and GUID defintions for this module 21 // 22 23 // 24 // The Library classes this module consumes 25 // 26 27 // 28 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE 29 // Workaround to make default SMRAM UnCachable 30 // 31 #define SMM_DEFAULT_SMBASE 0x30000 // Default SMBASE address 32 #define SMM_DEFAULT_SMBASE_SIZE_BYTES 0x10000 // Size in bytes of default SMRAM 33 34 BOOLEAN mMemCfgDone = FALSE; 35 UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff}; 36 37 VOID 38 EFIAPI 39 PlatformInitializeUart0MuxGalileo ( 40 VOID 41 ) 42 /*++ 43 44 45 Routine Description: 46 47 This is the routine to initialize UART0 for DBG2 support. The hardware used in this process is a 48 Legacy Bridge (Legacy GPIO), I2C controller, a bi-directional MUX and a Cypress CY8C9540A chip. 49 50 Arguments: 51 52 None. 53 54 Returns: 55 56 None. 57 58 --*/ 59 { 60 EFI_STATUS Status; 61 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress; 62 UINTN Length; 63 UINT8 Buffer[2]; 64 65 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) { 66 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR; 67 } else { 68 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR; 69 } 70 71 // 72 // Set GPIO_SUS<2> as an output, raise voltage to Vdd. 73 // 74 PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, 2, TRUE); 75 76 // 77 // Select Port 3 78 // 79 Length = 2; 80 Buffer[0] = 0x18; //sub-address 81 Buffer[1] = 0x03; //data 82 83 Status = I2cWriteMultipleByte ( 84 I2CSlaveAddress, 85 EfiI2CSevenBitAddrMode, 86 &Length, 87 &Buffer 88 ); 89 ASSERT_EFI_ERROR (Status); 90 91 // 92 // Set "Pin Direction" bit4 and bit5 as outputs 93 // 94 Length = 2; 95 Buffer[0] = 0x1C; //sub-address 96 Buffer[1] = 0xCF; //data 97 98 Status = I2cWriteMultipleByte ( 99 I2CSlaveAddress, 100 EfiI2CSevenBitAddrMode, 101 &Length, 102 &Buffer 103 ); 104 ASSERT_EFI_ERROR (Status); 105 106 // 107 // Lower GPORT3 bit4 and bit5 to Vss 108 // 109 Length = 2; 110 Buffer[0] = 0x0B; //sub-address 111 Buffer[1] = 0xCF; //data 112 113 Status = I2cWriteMultipleByte ( 114 I2CSlaveAddress, 115 EfiI2CSevenBitAddrMode, 116 &Length, 117 &Buffer 118 ); 119 ASSERT_EFI_ERROR (Status); 120 } 121 122 VOID 123 EFIAPI 124 PlatformInitializeUart0MuxGalileoGen2 ( 125 VOID 126 ) 127 /*++ 128 129 130 Routine Description: 131 132 This is the routine to initialize UART0 on GalileoGen2. The hardware used in this process is 133 I2C controller and the configuring the following IO Expander signal. 134 135 EXP1.P1_5 should be configured as an output & driven high. 136 EXP1.P0_0 should be configured as an output & driven high. 137 EXP0.P1_4 should be configured as an output, driven low. 138 EXP1.P0_1 pullup should be disabled. 139 EXP0.P1_5 Pullup should be disabled. 140 141 Arguments: 142 143 None. 144 145 Returns: 146 147 None. 148 149 --*/ 150 151 { 152 // 153 // EXP1.P1_5 should be configured as an output & driven high. 154 // 155 PlatformPcal9555GpioSetDir ( 156 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1. 157 13, // P1-5. 158 TRUE 159 ); 160 PlatformPcal9555GpioSetLevel ( 161 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1. 162 13, // P1-5. 163 TRUE 164 ); 165 166 // 167 // EXP1.P0_0 should be configured as an output & driven high. 168 // 169 PlatformPcal9555GpioSetDir ( 170 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0. 171 0, // P0_0. 172 TRUE 173 ); 174 PlatformPcal9555GpioSetLevel ( 175 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0. 176 0, // P0_0. 177 TRUE 178 ); 179 180 // 181 // EXP0.P1_4 should be configured as an output, driven low. 182 // 183 PlatformPcal9555GpioSetDir ( 184 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0. 185 12, // P1-4. 186 FALSE 187 ); 188 PlatformPcal9555GpioSetLevel ( // IO Expander 0. 189 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // P1-4 190 12, 191 FALSE 192 ); 193 194 // 195 // EXP1.P0_1 pullup should be disabled. 196 // 197 PlatformPcal9555GpioDisablePull ( 198 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1. 199 1 // P0-1. 200 ); 201 202 // 203 // EXP0.P1_5 Pullup should be disabled. 204 // 205 PlatformPcal9555GpioDisablePull ( 206 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0. 207 13 // P1-5. 208 ); 209 } 210 211 VOID 212 EFIAPI 213 PlatformConfigOnSmmConfigurationProtocol ( 214 IN EFI_EVENT Event, 215 IN VOID *Context 216 ) 217 /*++ 218 219 Routine Description: 220 221 Function runs in PI-DXE to perform platform specific config when 222 SmmConfigurationProtocol is installed. 223 224 Arguments: 225 Event - The event that occured. 226 Context - For EFI compatiblity. Not used. 227 228 Returns: 229 None. 230 --*/ 231 232 { 233 EFI_STATUS Status; 234 UINT32 NewValue; 235 UINT64 BaseAddress; 236 UINT64 SmramLength; 237 VOID *SmmCfgProt; 238 239 Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt); 240 if (Status != EFI_SUCCESS){ 241 DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n")); 242 return; 243 } 244 if (mMemCfgDone) { 245 DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n")); 246 return; 247 } 248 249 // 250 // Disable eSram block (this will also clear/zero eSRAM) 251 // We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase 252 // 253 NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK); 254 NewValue |= BLOCK_DISABLE_PG; 255 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue); 256 257 // 258 // Update HMBOUND to top of DDR3 memory and LOCK 259 // We disabled eSRAM so now we move HMBOUND down to top of DDR3 260 // 261 QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength); 262 NewValue = (UINT32)(BaseAddress + SmramLength); 263 DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue)); 264 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK)); 265 266 // 267 // Lock IMR5 now that HMBOUND is locked (legacy S3 region) 268 // 269 NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL); 270 NewValue |= IMR_LOCK; 271 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue); 272 273 // 274 // Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved) 275 // 276 NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL); 277 NewValue |= IMR_LOCK; 278 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue); 279 280 // 281 // Disable IMR2 memory protection (RMU Main Binary) 282 // 283 QncImrWrite ( 284 QUARK_NC_MEMORY_MANAGER_IMR2, 285 (UINT32)(IMRL_RESET & ~IMR_EN), 286 (UINT32)IMRH_RESET, 287 (UINT32)IMRX_ALL_ACCESS, 288 (UINT32)IMRX_ALL_ACCESS 289 ); 290 291 // 292 // Disable IMR3 memory protection (Default SMRAM) 293 // 294 QncImrWrite ( 295 QUARK_NC_MEMORY_MANAGER_IMR3, 296 (UINT32)(IMRL_RESET & ~IMR_EN), 297 (UINT32)IMRH_RESET, 298 (UINT32)IMRX_ALL_ACCESS, 299 (UINT32)IMRX_ALL_ACCESS 300 ); 301 302 // 303 // Disable IMR4 memory protection (eSRAM). 304 // 305 QncImrWrite ( 306 QUARK_NC_MEMORY_MANAGER_IMR4, 307 (UINT32)(IMRL_RESET & ~IMR_EN), 308 (UINT32)IMRH_RESET, 309 (UINT32)IMRX_ALL_ACCESS, 310 (UINT32)IMRX_ALL_ACCESS 311 ); 312 313 // 314 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE 315 // Workaround to make default SMRAM UnCachable 316 // 317 Status = gDS->SetMemorySpaceAttributes ( 318 (EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE, 319 SMM_DEFAULT_SMBASE_SIZE_BYTES, 320 EFI_MEMORY_WB 321 ); 322 ASSERT_EFI_ERROR (Status); 323 324 mMemCfgDone = TRUE; 325 } 326 327 VOID 328 EFIAPI 329 PlatformConfigOnSpiReady ( 330 IN EFI_EVENT Event, 331 IN VOID *Context 332 ) 333 /*++ 334 335 Routine Description: 336 337 Function runs in PI-DXE to perform platform specific config when SPI 338 interface is ready. 339 340 Arguments: 341 Event - The event that occured. 342 Context - For EFI compatiblity. Not used. 343 344 Returns: 345 None. 346 347 --*/ 348 { 349 EFI_STATUS Status; 350 VOID *SpiReadyProt = NULL; 351 EFI_PLATFORM_TYPE Type; 352 EFI_BOOT_MODE BootMode; 353 354 BootMode = GetBootModeHob (); 355 356 Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt); 357 if (Status != EFI_SUCCESS){ 358 DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n")); 359 return; 360 } 361 362 // 363 // Lock regions SPI flash. 364 // 365 PlatformFlashLockPolicy (FALSE); 366 367 // 368 // Configurations and checks to be done when DXE tracing available. 369 // 370 371 // 372 // Platform specific Signal routing. 373 // 374 375 // 376 // Skip any signal not needed for recovery and flash update. 377 // 378 if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) { 379 380 // 381 // Galileo Platform UART0 support. 382 // 383 Type = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType); 384 if (Type == Galileo) { 385 // 386 // Use MUX to connect out UART0 pins. 387 // 388 PlatformInitializeUart0MuxGalileo (); 389 } 390 391 // 392 // GalileoGen2 Platform UART0 support. 393 // 394 if (Type == GalileoGen2) { 395 // 396 // Use route out UART0 pins. 397 // 398 PlatformInitializeUart0MuxGalileoGen2 (); 399 } 400 } 401 } 402 403 EFI_STATUS 404 EFIAPI 405 CreateConfigEvents ( 406 VOID 407 ) 408 /*++ 409 410 Routine Description: 411 412 Arguments: 413 None 414 415 Returns: 416 EFI_STATUS 417 418 --*/ 419 { 420 EFI_EVENT EventSmmCfg; 421 EFI_EVENT EventSpiReady; 422 VOID *RegistrationSmmCfg; 423 VOID *RegistrationSpiReady; 424 425 // 426 // Schedule callback for when SmmConfigurationProtocol installed. 427 // 428 EventSmmCfg = EfiCreateProtocolNotifyEvent ( 429 &gEfiSmmConfigurationProtocolGuid, 430 TPL_CALLBACK, 431 PlatformConfigOnSmmConfigurationProtocol, 432 NULL, 433 &RegistrationSmmCfg 434 ); 435 ASSERT (EventSmmCfg != NULL); 436 437 // 438 // Schedule callback to setup SPI Flash Policy when SPI interface ready. 439 // 440 EventSpiReady = EfiCreateProtocolNotifyEvent ( 441 &gEfiSmmSpiReadyProtocolGuid, 442 TPL_CALLBACK, 443 PlatformConfigOnSpiReady, 444 NULL, 445 &RegistrationSpiReady 446 ); 447 ASSERT (EventSpiReady != NULL); 448 return EFI_SUCCESS; 449 } 450