+++ /dev/null
-/** @file\r
-QNC Smm Library Services that implements SMM Region access, S/W SMI generation and detection.\r
-\r
-Copyright (c) 2013-2016 Intel Corporation.\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-\r
-#include <Base.h>\r
-#include <IntelQNCRegs.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/QNCAccessLib.h>\r
-\r
-#define BOOT_SERVICE_SOFTWARE_SMI_DATA 0\r
-#define RUNTIME_SOFTWARE_SMI_DATA 1\r
-\r
-/**\r
- Triggers a run time or boot time SMI.\r
-\r
- This function triggers a software SMM interrupt and set the APMC status with an 8-bit Data.\r
-\r
- @param Data The value to set the APMC status.\r
-\r
-**/\r
-VOID\r
-InternalTriggerSmi (\r
- IN UINT8 Data\r
- )\r
-{\r
- UINT16 GPE0BLK_Base;\r
- UINT32 NewValue;\r
-\r
- //\r
- // Get GPE0BLK_Base\r
- //\r
- GPE0BLK_Base = (UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF);\r
-\r
-\r
- //\r
- // Enable APM SMI\r
- //\r
- IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIE), B_QNC_GPE0BLK_SMIE_APM);\r
-\r
- //\r
- // Enable SMI globally\r
- //\r
- NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);\r
- NewValue |= SMI_EN;\r
- QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);\r
-\r
- //\r
- // Set APM_STS\r
- //\r
- IoWrite8 (PcdGet16 (PcdSmmDataPort), Data);\r
-\r
- //\r
- // Generate the APM SMI\r
- //\r
- IoWrite8 (PcdGet16 (PcdSmmActivationPort), PcdGet8 (PcdSmmActivationData));\r
-\r
- //\r
- // Clear the APM SMI Status Bit\r
- //\r
- IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);\r
-\r
- //\r
- // Set the EOS Bit\r
- //\r
- IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);\r
-}\r
-\r
-\r
-/**\r
- Triggers an SMI at boot time.\r
-\r
- This function triggers a software SMM interrupt at boot time.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-TriggerBootServiceSoftwareSmi (\r
- VOID\r
- )\r
-{\r
- InternalTriggerSmi (BOOT_SERVICE_SOFTWARE_SMI_DATA);\r
-}\r
-\r
-\r
-/**\r
- Triggers an SMI at run time.\r
-\r
- This function triggers a software SMM interrupt at run time.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-TriggerRuntimeSoftwareSmi (\r
- VOID\r
- )\r
-{\r
- InternalTriggerSmi (RUNTIME_SOFTWARE_SMI_DATA);\r
-}\r
-\r
-\r
-/**\r
- Gets the software SMI data.\r
-\r
- This function tests if a software SMM interrupt happens. If a software SMI happens,\r
- it retrieves the SMM data and returns it as a non-negative value; otherwise a negative\r
- value is returned.\r
-\r
- @return Data The data retrieved from SMM data port in case of a software SMI;\r
- otherwise a negative value.\r
-\r
-**/\r
-INTN\r
-InternalGetSwSmiData (\r
- VOID\r
- )\r
-{\r
- UINT8 SmiStatus;\r
- UINT8 Data;\r
-\r
- SmiStatus = IoRead8 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS);\r
- if (((SmiStatus & B_QNC_GPE0BLK_SMIS_APM) != 0) &&\r
- (IoRead8 (PcdGet16 (PcdSmmActivationPort)) == PcdGet8 (PcdSmmActivationData))) {\r
- Data = IoRead8 (PcdGet16 (PcdSmmDataPort));\r
- return (INTN)(UINTN)Data;\r
- }\r
-\r
- return -1;\r
-}\r
-\r
-\r
-/**\r
- Test if a boot time software SMI happened.\r
-\r
- This function tests if a software SMM interrupt happened. If a software SMM interrupt happened and\r
- it was triggered at boot time, it returns TRUE. Otherwise, it returns FALSE.\r
-\r
- @retval TRUE A software SMI triggered at boot time happened.\r
- @retval FLASE No software SMI happened or the software SMI was triggered at run time.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsBootServiceSoftwareSmi (\r
- VOID\r
- )\r
-{\r
- return (BOOLEAN) (InternalGetSwSmiData () == BOOT_SERVICE_SOFTWARE_SMI_DATA);\r
-}\r
-\r
-\r
-/**\r
- Test if a run time software SMI happened.\r
-\r
- This function tests if a software SMM interrupt happened. If a software SMM interrupt happened and\r
- it was triggered at run time, it returns TRUE. Otherwise, it returns FALSE.\r
-\r
- @retval TRUE A software SMI triggered at run time happened.\r
- @retval FLASE No software SMI happened or the software SMI was triggered at boot time.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-IsRuntimeSoftwareSmi (\r
- VOID\r
- )\r
-{\r
- return (BOOLEAN) (InternalGetSwSmiData () == RUNTIME_SOFTWARE_SMI_DATA);\r
-}\r
-\r
-\r
-\r
-/**\r
-\r
- Clear APM SMI Status Bit; Set the EOS bit.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ClearSmi (\r
- VOID\r
- )\r
-{\r
-\r
- UINT16 GPE0BLK_Base;\r
-\r
- //\r
- // Get GpeBase\r
- //\r
- GPE0BLK_Base = (UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF);\r
-\r
- //\r
- // Clear the APM SMI Status Bit\r
- //\r
- IoOr16 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIS, B_QNC_GPE0BLK_SMIS_APM);\r
-\r
- //\r
- // Set the EOS Bit\r
- //\r
- IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIS, B_QNC_GPE0BLK_SMIS_EOS);\r
-}\r
-\r
-/**\r
- This routine is the chipset code that accepts a request to "open" a region of SMRAM.\r
- The region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.\r
- The use of "open" means that the memory is visible from all boot-service\r
- and SMM agents.\r
-\r
- @retval FALSE Cannot open a locked SMRAM region\r
- @retval TRUE Success to open SMRAM region.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-QNCOpenSmramRegion (\r
- VOID\r
- )\r
-{\r
- UINT32 Smram;\r
-\r
- // Read the SMRAM register\r
- Smram = QncHsmmcRead ();\r
-\r
- //\r
- // Is the platform locked?\r
- //\r
- if (Smram & SMM_LOCKED) {\r
- // Cannot Open a locked region\r
- DEBUG ((EFI_D_WARN, "Cannot open a locked SMRAM region\n"));\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Open all SMRAM regions for Host access only\r
- //\r
- Smram |= (SMM_WRITE_OPEN | SMM_READ_OPEN); // Open for Host.\r
- Smram &= ~(NON_HOST_SMM_WR_OPEN | NON_HOST_SMM_RD_OPEN); // Not for others.\r
-\r
- //\r
- // Write the SMRAM register\r
- //\r
- QncHsmmcWrite (Smram);\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- This routine is the chipset code that accepts a request to "close" a region of SMRAM.\r
- The region could be legacy AB or TSEG near top of physical memory.\r
- The use of "close" means that the memory is only visible from SMM agents,\r
- not from BS or RT code.\r
-\r
- @retval FALSE Cannot open a locked SMRAM region\r
- @retval TRUE Success to open SMRAM region.\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-QNCCloseSmramRegion (\r
- VOID\r
- )\r
-{\r
- UINT32 Smram;\r
-\r
- // Read the SMRAM register.\r
- Smram = QncHsmmcRead ();\r
-\r
- //\r
- // Is the platform locked?\r
- //\r
- if(Smram & SMM_LOCKED) {\r
- // Cannot Open a locked region\r
- DEBUG ((EFI_D_WARN, "Cannot close a locked SMRAM region\n"));\r
- return FALSE;\r
- }\r
-\r
- Smram &= (~(SMM_WRITE_OPEN | SMM_READ_OPEN | NON_HOST_SMM_WR_OPEN | NON_HOST_SMM_RD_OPEN));\r
-\r
- QncHsmmcWrite (Smram);\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- This routine is the chipset code that accepts a request to "lock" SMRAM.\r
- The region could be legacy AB or TSEG near top of physical memory.\r
- The use of "lock" means that the memory can no longer be opened\r
- to BS state.\r
-**/\r
-VOID\r
-EFIAPI\r
-QNCLockSmramRegion (\r
- VOID\r
- )\r
-{\r
- UINT32 Smram;\r
-\r
- // Read the SMRAM register.\r
- Smram = QncHsmmcRead ();\r
- if(Smram & SMM_LOCKED) {\r
- DEBUG ((EFI_D_WARN, "SMRAM region already locked!\n"));\r
- }\r
- Smram |= SMM_LOCKED;\r
-\r
- QncHsmmcWrite (Smram);\r
-\r
- return;\r
-}\r