]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkPlatformPkg/Library/PlatformSecureLib/PlatformSecureLib.c
169980c1b87e03c80b0c759720e412e65d7c5c5a
[mirror_edk2.git] / QuarkPlatformPkg / Library / PlatformSecureLib / PlatformSecureLib.c
1 /** @file
2 Provides a secure platform-specific method to detect physically present user.
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 #include <PiDxe.h>
17 #include <Library/PlatformHelperLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/I2cLib.h>
21
22 #include <PlatformBoards.h>
23 #include <Pcal9555.h>
24 #include <QNCAccess.h>
25
26 //
27 // Global variable to cache pointer to I2C protocol.
28 //
29 EFI_PLATFORM_TYPE mPlatformType = TypeUnknown;
30
31 BOOLEAN
32 CheckResetButtonState (
33 VOID
34 )
35 {
36 EFI_STATUS Status;
37 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress;
38 UINTN Length;
39 UINTN ReadLength;
40 UINT8 Buffer[2];
41
42 DEBUG ((EFI_D_ERROR, "CheckResetButtonState(): mPlatformType == %d\n", mPlatformType));
43 if (mPlatformType == GalileoGen2) {
44 //
45 // Reset Button - EXP2.P1_7 should be configured as an input.
46 //
47 PlatformPcal9555GpioSetDir (
48 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
49 15, // P1-7.
50 FALSE
51 );
52
53 //
54 // Reset Button - EXP2.P1_7 pullup should be disabled.
55 //
56 PlatformPcal9555GpioDisablePull (
57 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
58 15 // P1-7.
59 );
60
61 //
62 // Read state of Reset Button - EXP2.P1_7
63 // This GPIO is pulled high when the button is not pressed
64 // This GPIO reads low when button is pressed
65 //
66 return PlatformPcal9555GpioGetState (
67 GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR, // IO Expander 2.
68 15 // P1-7.
69 );
70 }
71 if (mPlatformType == Galileo) {
72 //
73 // Detect the I2C Slave Address of the GPIO Expander
74 //
75 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
76 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
77 } else {
78 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
79 }
80
81 //
82 // Select Port 5
83 //
84 Length = 2;
85 Buffer[0] = 0x18;
86 Buffer[1] = 0x05;
87 Status = I2cWriteMultipleByte (
88 I2CSlaveAddress,
89 EfiI2CSevenBitAddrMode,
90 &Length,
91 &Buffer
92 );
93 ASSERT_EFI_ERROR (Status);
94
95 //
96 // Read "Pin Direction" of Port 5
97 //
98 Length = 1;
99 ReadLength = 1;
100 Buffer[1] = 0x1C;
101 Status = I2cReadMultipleByte (
102 I2CSlaveAddress,
103 EfiI2CSevenBitAddrMode,
104 &Length,
105 &ReadLength,
106 &Buffer[1]
107 );
108 ASSERT_EFI_ERROR (Status);
109
110 //
111 // Set "Pin Direction" of Port 5, Bit 0 as input
112 //
113 Length = 2;
114 Buffer[0] = 0x1C;
115 Buffer[1] = Buffer[1] | BIT0;
116
117 Status = I2cWriteMultipleByte (
118 I2CSlaveAddress,
119 EfiI2CSevenBitAddrMode,
120 &Length,
121 &Buffer
122 );
123 ASSERT_EFI_ERROR (Status);
124
125 //
126 // Read Port 5
127 //
128 Buffer[1] = 5;
129 Length = 1;
130 ReadLength = 1;
131
132 Status = I2cReadMultipleByte (
133 I2CSlaveAddress,
134 EfiI2CSevenBitAddrMode,
135 &Length,
136 &ReadLength,
137 &Buffer[1]
138 );
139 ASSERT_EFI_ERROR (Status);
140
141 //
142 // Return the state of Port 5, Bit 0
143 //
144 return ((Buffer[1] & BIT0) != 0);
145 }
146 return TRUE;
147 }
148
149 /**
150
151 This function provides a platform-specific method to detect whether the platform
152 is operating by a physically present user.
153
154 Programmatic changing of platform security policy (such as disable Secure Boot,
155 or switch between Standard/Custom Secure Boot mode) MUST NOT be possible during
156 Boot Services or after exiting EFI Boot Services. Only a physically present user
157 is allowed to perform these operations.
158
159 NOTE THAT: This function cannot depend on any EFI Variable Service since they are
160 not available when this function is called in AuthenticateVariable driver.
161
162 @retval TRUE The platform is operated by a physically present user.
163 @retval FALSE The platform is NOT operated by a physically present user.
164
165 **/
166 BOOLEAN
167 EFIAPI
168 UserPhysicalPresent (
169 VOID
170 )
171 {
172 EFI_STATUS Status;
173
174 //
175 // If user has already been detected as present, then return TRUE
176 //
177 if (PcdGetBool (PcdUserIsPhysicallyPresent)) {
178 return TRUE;
179 }
180
181 //
182 // Check to see if user is present now
183 //
184 if (CheckResetButtonState ()) {
185 //
186 // User is still not present, then return FALSE
187 //
188 return FALSE;
189 }
190
191 //
192 // User has gone from not present to present state, so set
193 // PcdUserIsPhysicallyPresent to TRUE
194 //
195 Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, TRUE);
196 ASSERT_EFI_ERROR (Status);
197
198 return TRUE;
199 }
200
201 /**
202 Determines if a user is physically present by reading the reset button state.
203
204 @param ImageHandle The image handle of this driver.
205 @param SystemTable A pointer to the EFI System Table.
206
207 @retval EFI_SUCCESS Install the Secure Boot Helper Protocol successfully.
208
209 **/
210 EFI_STATUS
211 EFIAPI
212 PlatformSecureLibInitialize (
213 IN EFI_HANDLE ImageHandle,
214 IN EFI_SYSTEM_TABLE *SystemTable
215 )
216 {
217 EFI_STATUS Status;
218
219 //
220 // Get the platform type
221 //
222 mPlatformType = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
223
224 //
225 // Read the state of the reset button when the library is initialized
226 //
227 Status = PcdSetBoolS (PcdUserIsPhysicallyPresent, !CheckResetButtonState ());
228 ASSERT_EFI_ERROR (Status);
229
230 return EFI_SUCCESS;
231 }