]> git.proxmox.com Git - mirror_edk2.git/blobdiff - QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
QuarkPlatformPkg: Add new package for Galileo boards
[mirror_edk2.git] / QuarkPlatformPkg / Library / PlatformSecureLib / PlatformSecureLib.c
diff --git a/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c b/QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
new file mode 100644 (file)
index 0000000..169980c
--- /dev/null
@@ -0,0 +1,231 @@
+/** @file\r
+Provides a secure platform-specific method to detect physically present user.\r
+\r
+Copyright (c) 2013 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/PlatformHelperLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/I2cLib.h>\r
+\r
+#include <PlatformBoards.h>\r
+#include <Pcal9555.h>\r
+#include <QNCAccess.h>\r
+\r
+//\r
+// Global variable to cache pointer to I2C protocol.\r
+//\r
+EFI_PLATFORM_TYPE mPlatformType = TypeUnknown;\r
+\r
+BOOLEAN\r
+CheckResetButtonState (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_I2C_DEVICE_ADDRESS  I2CSlaveAddress;\r
+  UINTN                   Length;\r
+  UINTN                   ReadLength;\r
+  UINT8                   Buffer[2];\r
+\r
+  DEBUG ((EFI_D_ERROR, "CheckResetButtonState(): mPlatformType == %d\n", mPlatformType));\r
+  if (mPlatformType == GalileoGen2) {\r
+    //\r
+    //  Reset Button - EXP2.P1_7 should be configured as an input.\r
+    //\r
+    PlatformPcal9555GpioSetDir (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      15,                                   // P1-7.\r
+      FALSE\r
+      );\r
+\r
+    //\r
+    // Reset Button - EXP2.P1_7 pullup should be disabled.\r
+    //\r
+    PlatformPcal9555GpioDisablePull (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      15                                    // P1-7.\r
+      );\r
+\r
+    //\r
+    // Read state of Reset Button - EXP2.P1_7\r
+    // This GPIO is pulled high when the button is not pressed\r
+    // This GPIO reads low when button is pressed\r
+    //\r
+    return PlatformPcal9555GpioGetState (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      15                                    // P1-7.\r
+      );\r
+  }\r
+  if (mPlatformType == Galileo) {\r
+    //\r
+    // Detect the I2C Slave Address of the GPIO Expander\r
+    //\r
+    if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {\r
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;\r
+    } else {\r
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;\r
+    }\r
+\r
+    //\r
+    // Select Port 5\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x18;\r
+    Buffer[1] = 0x05;\r
+    Status = I2cWriteMultipleByte (\r
+               I2CSlaveAddress,\r
+               EfiI2CSevenBitAddrMode,\r
+               &Length,\r
+               &Buffer\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Read "Pin Direction" of Port 5\r
+    //\r
+    Length = 1;\r
+    ReadLength = 1;\r
+    Buffer[1] = 0x1C;\r
+    Status = I2cReadMultipleByte (\r
+               I2CSlaveAddress,\r
+               EfiI2CSevenBitAddrMode,\r
+               &Length,\r
+               &ReadLength,\r
+               &Buffer[1]\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Set "Pin Direction" of Port 5, Bit 0 as input\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x1C;\r
+    Buffer[1] = Buffer[1] | BIT0;\r
+\r
+    Status = I2cWriteMultipleByte (\r
+               I2CSlaveAddress,\r
+               EfiI2CSevenBitAddrMode,\r
+               &Length,\r
+               &Buffer\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Read Port 5\r
+    //\r
+    Buffer[1] = 5;\r
+    Length = 1;\r
+    ReadLength = 1;\r
+\r
+    Status = I2cReadMultipleByte (\r
+               I2CSlaveAddress,\r
+               EfiI2CSevenBitAddrMode,\r
+               &Length,\r
+               &ReadLength,\r
+               &Buffer[1]\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Return the state of Port 5, Bit 0\r
+    //\r
+    return ((Buffer[1] & BIT0) != 0);\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+\r
+  This function provides a platform-specific method to detect whether the platform\r
+  is operating by a physically present user.\r
+\r
+  Programmatic changing of platform security policy (such as disable Secure Boot,\r
+  or switch between Standard/Custom Secure Boot mode) MUST NOT be possible during\r
+  Boot Services or after exiting EFI Boot Services. Only a physically present user\r
+  is allowed to perform these operations.\r
+\r
+  NOTE THAT: This function cannot depend on any EFI Variable Service since they are\r
+  not available when this function is called in AuthenticateVariable driver.\r
+\r
+  @retval  TRUE       The platform is operated by a physically present user.\r
+  @retval  FALSE      The platform is NOT operated by a physically present user.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+UserPhysicalPresent (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // If user has already been detected as present, then return TRUE\r
+  //\r
+  if (PcdGetBool (PcdUserIsPhysicallyPresent)) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Check to see if user is present now\r
+  //\r
+  if (CheckResetButtonState ()) {\r
+    //\r
+    // User is still not present, then return FALSE\r
+    //\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // User has gone from not present to present state, so set\r
+  // PcdUserIsPhysicallyPresent to TRUE\r
+  //\r
+  Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, TRUE);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Determines if a user is physically present by reading the reset button state.\r
+\r
+  @param  ImageHandle  The image handle of this driver.\r
+  @param  SystemTable  A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS   Install the Secure Boot Helper Protocol successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformSecureLibInitialize (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Get the platform type\r
+  //\r
+  mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);\r
+\r
+  //\r
+  // Read the state of the reset button when the library is initialized\r
+  //\r
+  Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, !CheckResetButtonState ());\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r