microsoft/mu_feature_ffa

Public

mirrored from https://github.com/microsoft/mu_feature_ffaAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
update

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/TpmServiceLib/TpmServiceLib.c

706lines · modeblame

dc263d2cRaymond-MS1 years ago1/** @file
f44455e7Raymond-MS1 years ago2Implementation for the TPM Service. This library is based
3off of the ARM spec: TPM Service Command Response Buffer
4Interface Over FF-A. The spec can be found here:
5
6https://developer.arm.com/documentation/den0138/0100/?lang=en
7
8The state flow is based off the TCG PC Client Specific Platform
9TPM Profile for TPM 2.0. The spec can be found here:
10
11https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
12
13Figure 4 - TPM State Diagram for CRB Interface
dc263d2cRaymond-MS1 years ago14
15Copyright (c), Microsoft Corporation.
16SPDX-License-Identifier: BSD-2-Clause-Patent
17
18**/
19
20#include <Uefi.h>
9d594c43Raymond-MS1 years ago21#include <Library/BaseLib.h>
22#include <Library/BaseMemoryLib.h>
dc263d2cRaymond-MS1 years ago23#include <Library/DebugLib.h>
24#include <Library/BaseMemoryLib.h>
25#include <Library/TpmServiceLib.h>
f44455e7Raymond-MS1 years ago26#include <Library/TpmServiceStateTranslationLib.h>
dc263d2cRaymond-MS1 years ago27#include <Guid/Tpm2ServiceFfa.h>
28#include <IndustryStandard/TpmPtp.h>
f44455e7Raymond-MS1 years ago29#include <IndustryStandard/Tpm20.h>
dc263d2cRaymond-MS1 years ago30
31/* TPM Service Defines */
9d594c43Raymond-MS1 years ago32#define TPM_MAJOR_VER (0x1)
33#define TPM_MINOR_VER (0x0)
dc263d2cRaymond-MS1 years ago34
1cf65721Raymond-MS1 years ago35/* TODO: Temporary Solution - May move to Tpm2ServiceFfa.h */
9d594c43Raymond-MS1 years ago36#define TPM_START_PROCESS_OPEN_LOC (0x100)
37#define TPM_START_PROCESS_CLOSE_LOC (0x101)
dc263d2cRaymond-MS1 years ago38
f44455e7Raymond-MS1 years ago39#define TPM_LOCALITY_OFFSET (0x1000)
dc263d2cRaymond-MS1 years ago40
f44455e7Raymond-MS1 years ago41/* TPM Service States */
42typedef enum {
43TPM_STATE_IDLE = 0,
44TPM_STATE_READY,
45TPM_STATE_COMPLETE,
46NUM_TPM_STATES
47} TpmState;
dc263d2cRaymond-MS1 years ago48
24b25e5crdiaz1 years ago49/* TPM Locality States */
50typedef enum {
51TPM_LOCALITY_CLOSED = 0,
52TPM_LOCALITY_OPEN,
53NUM_LOCALITY_STATES
54} TpmLocalityState;
55
dc263d2cRaymond-MS1 years ago56typedef UINTN TpmStatus;
57
f44455e7Raymond-MS1 years ago58/* TPM Service Variables */
59STATIC TpmState mCurrentState;
60STATIC UINT8 mActiveLocality;
61STATIC PTP_CRB_INTERFACE_IDENTIFIER mInterfaceIdDefault;
24b25e5crdiaz1 years ago62STATIC TpmLocalityState mLocalityStates[NUM_LOCALITIES];
f44455e7Raymond-MS1 years ago63
dc263d2cRaymond-MS1 years ago64/**
65Converts the passed in EFI_STATUS to a TPM_STATUS
66
67@param Status The EFI_STATUS to convert
68
69@retval TPM_STATUS_OK Success
70@retval TPM_STATUS_INVARG Invalid parameter
71@retval TPM_STATUS_DENIED Access denied
72@retval TPM_STATUS_NOMEM Insufficient memory
73
74**/
75STATIC
76TpmStatus
77ConvertEfiToTpmStatus (
78EFI_STATUS Status
79)
80{
81TpmStatus ReturnVal;
82
83switch (Status) {
84case EFI_SUCCESS:
85ReturnVal = TPM2_FFA_SUCCESS_OK;
86break;
87
88case EFI_DEVICE_ERROR:
89ReturnVal = TPM2_FFA_ERROR_DENIED;
90break;
91
92case EFI_BUFFER_TOO_SMALL:
93ReturnVal = TPM2_FFA_ERROR_NOMEM;
94break;
95
96default:
97ReturnVal = TPM2_FFA_ERROR_DENIED;
98break;
99}
100
101return ReturnVal;
102}
103
104/**
105Initializes the internal CRB
106
f44455e7Raymond-MS1 years ago107@param Locality The locality of the CRB
108
dc263d2cRaymond-MS1 years ago109**/
110STATIC
111VOID
112InitInternalCrb (
f44455e7Raymond-MS1 years ago113UINT8 Locality
dc263d2cRaymond-MS1 years ago114)
115{
116PTP_CRB_REGISTERS_PTR InternalTpmCrb;
117
f44455e7Raymond-MS1 years ago118InternalTpmCrb = (PTP_CRB_REGISTERS_PTR)(UINTN)(PcdGet64 (PcdTpmInternalBaseAddress) + (Locality * TPM_LOCALITY_OFFSET));
119DEBUG ((DEBUG_INFO, "Locality: %x - InternalTpmCrb Address: %lx\n", Locality, (UINTN)InternalTpmCrb));
dc263d2cRaymond-MS1 years ago120SetMem ((void *)InternalTpmCrb, sizeof (PTP_CRB_REGISTERS), 0x00);
f44455e7Raymond-MS1 years ago121InternalTpmCrb->InterfaceId = mInterfaceIdDefault.Uint32;
122InternalTpmCrb->CrbControlStatus = PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE;
9d594c43Raymond-MS1 years ago123
124/* Set the CRB Command/Response buffer address + size. */
125InternalTpmCrb->CrbControlCommandAddressHigh = (UINT32)RShiftU64 ((UINTN)InternalTpmCrb->CrbDataBuffer, 32);
126InternalTpmCrb->CrbControlCommandAddressLow = (UINT32)(UINTN)InternalTpmCrb->CrbDataBuffer;
03d3c59akuqin121 years ago127InternalTpmCrb->CrbControlCommandSize = sizeof (InternalTpmCrb->CrbDataBuffer);
9d594c43Raymond-MS1 years ago128InternalTpmCrb->CrbControlResponseAddrss = (UINTN)InternalTpmCrb->CrbDataBuffer;
03d3c59akuqin121 years ago129InternalTpmCrb->CrbControlResponseSize = sizeof (InternalTpmCrb->CrbDataBuffer);
dc263d2cRaymond-MS1 years ago130}
131
132/**
f44455e7Raymond-MS1 years ago133Cleans the internal CRB putting registers into a known good state
dc263d2cRaymond-MS1 years ago134
135**/
136STATIC
137VOID
f44455e7Raymond-MS1 years ago138CleanInternalCrb (
dc263d2cRaymond-MS1 years ago139VOID
140)
141{
142PTP_CRB_REGISTERS_PTR InternalTpmCrb;
143
f44455e7Raymond-MS1 years ago144/* If the user has never requested a locality, don't clean, no need.
145* We should only ever clean the active locality as when localities change
146* we clear the entire CRB region. */
147if (mActiveLocality == NUM_LOCALITIES) {
148return;
149}
dc263d2cRaymond-MS1 years ago150
f44455e7Raymond-MS1 years ago151InternalTpmCrb = (PTP_CRB_REGISTERS_PTR)(UINTN)(PcdGet64 (PcdTpmInternalBaseAddress) + (mActiveLocality * TPM_LOCALITY_OFFSET));
dc263d2cRaymond-MS1 years ago152
f44455e7Raymond-MS1 years ago153/* Set the locality state based on the active locality. */
154switch (mActiveLocality) {
155case 0:
156InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_ACTIVE_LOCALITY_0;
157break;
158
159case 1:
160InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_ACTIVE_LOCALITY_1;
161break;
162
163case 2:
164InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_ACTIVE_LOCALITY_2;
165break;
166
167case 3:
168InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_ACTIVE_LOCALITY_3;
169break;
dc263d2cRaymond-MS1 years ago170
f44455e7Raymond-MS1 years ago171case 4:
172InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_ACTIVE_LOCALITY_4;
173break;
174
175default:
176break;
177}
178
179InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_TPM_REG_VALID_STATUS;
180InternalTpmCrb->LocalityState |= PTP_CRB_LOCALITY_STATE_LOCALITY_ASSIGNED;
181InternalTpmCrb->LocalityStatus |= PTP_CRB_LOCALITY_STATUS_GRANTED;
dc263d2cRaymond-MS1 years ago182InternalTpmCrb->LocalityControl = 0;
f44455e7Raymond-MS1 years ago183InternalTpmCrb->InterfaceId = mInterfaceIdDefault.Uint32;
dc263d2cRaymond-MS1 years ago184InternalTpmCrb->CrbControlExtension = 0;
185InternalTpmCrb->CrbControlRequest = 0;
186InternalTpmCrb->CrbControlCancel = 0;
f44455e7Raymond-MS1 years ago187InternalTpmCrb->CrbControlStart = 0;
dc263d2cRaymond-MS1 years ago188InternalTpmCrb->CrbInterruptEnable = 0;
189InternalTpmCrb->CrbInterruptStatus = 0;
f44455e7Raymond-MS1 years ago190
191/* Set the current TPM Status based on the current state. */
192if (mCurrentState == TPM_STATE_IDLE) {
193InternalTpmCrb->CrbControlStatus = PTP_CRB_CONTROL_AREA_STATUS_TPM_IDLE;
194} else {
195InternalTpmCrb->CrbControlStatus = 0;
196}
197
9d594c43Raymond-MS1 years ago198/* Set the CRB Command/Response buffer address + size. */
199InternalTpmCrb->CrbControlCommandAddressHigh = (UINT32)RShiftU64 ((UINTN)InternalTpmCrb->CrbDataBuffer, 32);
200InternalTpmCrb->CrbControlCommandAddressLow = (UINT32)(UINTN)InternalTpmCrb->CrbDataBuffer;
03d3c59akuqin121 years ago201InternalTpmCrb->CrbControlCommandSize = sizeof (InternalTpmCrb->CrbDataBuffer);
9d594c43Raymond-MS1 years ago202InternalTpmCrb->CrbControlResponseAddrss = (UINTN)InternalTpmCrb->CrbDataBuffer;
03d3c59akuqin121 years ago203InternalTpmCrb->CrbControlResponseSize = sizeof (InternalTpmCrb->CrbDataBuffer);
9d594c43Raymond-MS1 years ago204
f44455e7Raymond-MS1 years ago205/* Remaining registers can be ignored. */
dc263d2cRaymond-MS1 years ago206}
207
208/**
209Handles commands for the TPM service
210
211@retval TPM_STATUS_OK Success
212@retval TPM_STATUS_INVARG Invalid parameter
213@retval TPM_STATUS_DENIED Access denied
214@retval TPM_STATUS_NOMEM Insufficient memory
215
216**/
217STATIC
218TpmStatus
219HandleCommand (
220VOID
221)
222{
f44455e7Raymond-MS1 years ago223EFI_STATUS Status;
dc263d2cRaymond-MS1 years ago224PTP_CRB_REGISTERS_PTR InternalTpmCrb;
225
f44455e7Raymond-MS1 years ago226InternalTpmCrb = (PTP_CRB_REGISTERS_PTR)(UINTN)(PcdGet64 (PcdTpmInternalBaseAddress) + (mActiveLocality * TPM_LOCALITY_OFFSET));
227
228/* Depending on our current state, we will investigate specific registers and
229* make state transitions or deny commands. */
230Status = EFI_ACCESS_DENIED;
231switch (mCurrentState) {
232/* The TPM can transition to IDLE from any state outside of command execution when the
233* SW sets the goIdle bit in the CrbControlRequest register. When the TPM transitions to
234* IDLE from COMPLETE it should clear the buffer. */
235case TPM_STATE_IDLE:
236/* Check the cmdReady bit in the CrbControlRequest register to see if we need to
237* transition to the READY state, otherwise, deny the request. */
238if (InternalTpmCrb->CrbControlRequest & PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY) {
239DEBUG ((DEBUG_INFO, "IDLE State - Handle TPM Command cmdReady Request\n"));
240Status = TpmSstCmdReady (mActiveLocality);
241if (Status == EFI_SUCCESS) {
242mCurrentState = TPM_STATE_READY;
243}
244}
dc263d2cRaymond-MS1 years ago245
f44455e7Raymond-MS1 years ago246break;
247
248/* The TPM can transition to READY from IDLE or COMPLETE when the SW sets the cmdReady bit
249* in the CrbControlRequest register. When the TPM transitions to READY from COMPLETE it
250* should clear the buffer. */
251case TPM_STATE_READY:
252/* Check the goIdle bit in the CrbControlRequest register to see if we need to
253* transition back to the IDLE state. */
254if (InternalTpmCrb->CrbControlRequest & PTP_CRB_CONTROL_AREA_REQUEST_GO_IDLE) {
255DEBUG ((DEBUG_INFO, "READY State - Handle TPM Command goIdle Request\n"));
256Status = TpmSstGoIdle (mActiveLocality);
257if (Status == EFI_SUCCESS) {
258mCurrentState = TPM_STATE_IDLE;
259}
260
261/* Check the cmdReady bit in the CrbControlRequest register, clear it if it has been
262* set again. */
263} else if (InternalTpmCrb->CrbControlRequest & PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY) {
264DEBUG ((DEBUG_INFO, "READY State - Handle TPM Command cmdReady Request\n"));
265Status = TpmSstCmdReady (mActiveLocality);
266
267/* Check the CrbControlStart register to see if we need to start executing a command.
268* Once the command completes, transition to the COMPLETE state. */
269} else if (InternalTpmCrb->CrbControlStart & PTP_CRB_CONTROL_START) {
270DEBUG ((DEBUG_INFO, "READY State - Handle TPM Command Start Request\n"));
271Status = TpmSstStart (mActiveLocality, InternalTpmCrb);
272if (Status == EFI_SUCCESS) {
273mCurrentState = TPM_STATE_COMPLETE;
274}
275}
dc263d2cRaymond-MS1 years ago276
f44455e7Raymond-MS1 years ago277break;
dc263d2cRaymond-MS1 years ago278
f44455e7Raymond-MS1 years ago279/* The TPM can transition to COMPLETE only from READY when the SW writes a 1 to the
280* CrbControlStart register and the command execution finishes. The SW can write more
281* data to the buffer and set the register again to trigger another command execution;
282* this is only if TPM_CapCRBIdleBypass is 1. */
283case TPM_STATE_COMPLETE:
284/* Check the goIdle bit in the CrbControlRequest register to see if we need to
285* transition to the IDLE state. */
286if (InternalTpmCrb->CrbControlRequest & PTP_CRB_CONTROL_AREA_REQUEST_GO_IDLE) {
287DEBUG ((DEBUG_INFO, "COMPLETE State - Handle TPM Command goIdle Request\n"));
288Status = TpmSstGoIdle (mActiveLocality);
289if (Status == EFI_SUCCESS) {
290mCurrentState = TPM_STATE_IDLE;
291SetMem ((void *)InternalTpmCrb->CrbDataBuffer, sizeof (InternalTpmCrb->CrbDataBuffer), 0x00);
292}
293
294/* Check the cmdReady bit in the CrbControlRequest register to see if we need to
295* transition back to the READY state. */
296} else if (InternalTpmCrb->CrbControlRequest & PTP_CRB_CONTROL_AREA_REQUEST_COMMAND_READY) {
297/* Transition to READY from COMPLETE is only supported if TPM_CapCRBIdleBypass is 1.*/
298if (TpmSstIsIdleBypassSupported ()) {
299DEBUG ((DEBUG_INFO, "COMPLETE State - Handle TPM Command cmdReady Request\n"));
300Status = TpmSstCmdReady (mActiveLocality);
301if (Status == EFI_SUCCESS) {
302mCurrentState = TPM_STATE_READY;
303SetMem ((void *)InternalTpmCrb->CrbDataBuffer, sizeof (InternalTpmCrb->CrbDataBuffer), 0x00);
304}
305}
306
307/* Check the CrbControlStart register to see if we need to execute another command. */
308} else if (InternalTpmCrb->CrbControlStart & PTP_CRB_CONTROL_START) {
309/* Execution of another command from COMPLETE is only supported if TPM_CapCRBIdleBypass
310* is 1. */
311if (TpmSstIsIdleBypassSupported ()) {
312DEBUG ((DEBUG_INFO, "COMPLETE State - Handle TPM Command Start Request\n"));
313Status = TpmSstStart (mActiveLocality, InternalTpmCrb);
314}
315}
19aafba4Raymond-MS1 years ago316
f44455e7Raymond-MS1 years ago317break;
19aafba4Raymond-MS1 years ago318
f44455e7Raymond-MS1 years ago319/* The normal state flow should be: IDLE -> READY -> COMPLETE -> IDLE. */
320default:
321DEBUG ((DEBUG_ERROR, "INVALID State - Attempting to transition to IDLE State\n"));
322Status = TpmSstGoIdle (mActiveLocality);
323if (Status == EFI_SUCCESS) {
324mCurrentState = TPM_STATE_IDLE;
325SetMem ((void *)InternalTpmCrb->CrbDataBuffer, sizeof (InternalTpmCrb->CrbDataBuffer), 0x00);
326}
dc263d2cRaymond-MS1 years ago327
f44455e7Raymond-MS1 years ago328break;
329}
19aafba4Raymond-MS1 years ago330
dc263d2cRaymond-MS1 years ago331/* Clear the internal CRB start register to indicate successful completion and response ready */
f44455e7Raymond-MS1 years ago332if (Status != EFI_SUCCESS) {
dc263d2cRaymond-MS1 years ago333DEBUG ((DEBUG_ERROR, "Command Failed w/ Status: %x\n", Status));
334}
335
336return ConvertEfiToTpmStatus (Status);
337}
338
339/**
340Handles locality requests for the TPM service
341
f44455e7Raymond-MS1 years ago342@param Locality The locality of the CRB
343
dc263d2cRaymond-MS1 years ago344@retval TPM_STATUS_OK Success
345@retval TPM_STATUS_INVARG Invalid parameter
346@retval TPM_STATUS_DENIED Access denied
347@retval TPM_STATUS_NOMEM Insufficient memory
348
349**/
350STATIC
351TpmStatus
352HandleLocalityRequest (
f44455e7Raymond-MS1 years ago353UINT8 Locality
dc263d2cRaymond-MS1 years ago354)
355{
24b25e5crdiaz1 years ago356EFI_STATUS Status;
357PTP_CRB_REGISTERS_PTR InternalTpmCrb;
358UINT8 ActiveLocality;
dc263d2cRaymond-MS1 years ago359
24b25e5crdiaz1 years ago360InternalTpmCrb = (PTP_CRB_REGISTERS_PTR)(UINTN)(PcdGet64 (PcdTpmInternalBaseAddress) + (Locality * TPM_LOCALITY_OFFSET));
361
e6e258bdrdiaz1 years ago362/* Check if we are doing a locality relinquish */
24b25e5crdiaz1 years ago363if (InternalTpmCrb->LocalityControl & PTP_CRB_LOCALITY_CONTROL_RELINQUISH) {
364/* Make sure the locality being relinquished is the active locality */
365if (Locality != mActiveLocality) {
366DEBUG ((DEBUG_ERROR, "Locality Relinquish Failed - Invalid Locality\n"));
367return TPM2_FFA_ERROR_DENIED;
368}
369
370DEBUG ((DEBUG_INFO, "Handle TPM Locality%x Relinquish\n", Locality));
03d3c59akuqin121 years ago371Status = TpmSstLocalityRelinquish (Locality);
24b25e5crdiaz1 years ago372ActiveLocality = NUM_LOCALITIES; // Invalid
03d3c59akuqin121 years ago373/* Check if we are doing a locality request */
e6e258bdrdiaz1 years ago374} else if (InternalTpmCrb->LocalityControl & PTP_CRB_LOCALITY_CONTROL_REQUEST_ACCESS) {
24b25e5crdiaz1 years ago375DEBUG ((DEBUG_INFO, "Handle TPM Locality%x Request\n", Locality));
03d3c59akuqin121 years ago376Status = TpmSstLocalityRequest (Locality);
24b25e5crdiaz1 years ago377ActiveLocality = Locality;
03d3c59akuqin121 years ago378/* Otherwise, the host didn't set the correct bits, invalid */
e6e258bdrdiaz1 years ago379} else {
380DEBUG ((DEBUG_ERROR, "Request/Relinquish Bit Not Set\n"));
381return TPM2_FFA_ERROR_DENIED;
24b25e5crdiaz1 years ago382}
dc263d2cRaymond-MS1 years ago383
384/* Update the internal TPM CRB */
385if (Status == EFI_SUCCESS) {
f44455e7Raymond-MS1 years ago386InitInternalCrb (Locality);
24b25e5crdiaz1 years ago387mActiveLocality = ActiveLocality;
dc263d2cRaymond-MS1 years ago388} else {
389DEBUG ((DEBUG_ERROR, "Locality Request Failed w/ Status: %x\n", Status));
390}
391
392return ConvertEfiToTpmStatus (Status);
393}
394
395/**
396Handler for TPM service GetInterfaceVersion command
397
398@param Request The incoming message
399@param Response The outgoing message
400
401@retval TPM_STATUS_OK Success
402
403**/
404STATIC
405TpmStatus
406GetInterfaceVersionHandler (
407DIRECT_MSG_ARGS_EX *Request,
408DIRECT_MSG_ARGS_EX *Response
409)
410{
411TpmStatus ReturnVal;
412
413ReturnVal = TPM2_FFA_SUCCESS_OK;
414Response->Arg0 = TPM2_FFA_SUCCESS_OK_RESULTS_RETURNED;
415Response->Arg1 = (TPM_MAJOR_VER << 16) | TPM_MINOR_VER;
416return ReturnVal;
417}
418
419/**
420Handler for TPM service GetFeatureInfo command
421
422@param Request The incoming message
423@param Response The outgoing message
424
425@retval TPM_STATUS_OK Success
426
427**/
428STATIC
429TpmStatus
430GetFeatureInfoHandler (
431DIRECT_MSG_ARGS_EX *Request,
432DIRECT_MSG_ARGS_EX *Response
433)
434{
435TpmStatus ReturnVal;
436
437ReturnVal = TPM2_FFA_SUCCESS_OK;
438Response->Arg0 = TPM2_FFA_ERROR_NOTSUP;
439DEBUG ((DEBUG_ERROR, "Unsupported Function\n"));
440return ReturnVal;
441}
442
443/**
444Handler for TPM service Start command
445
446@param Request The incoming message
447@param Response The outgoing message
448
449@retval TPM_STATUS_OK Success
450@retval TPM_STATUS_INVARG Invalid parameter
451@retval TPM_STATUS_DENIED Access denied
452@retval TPM_STATUS_NOMEM Insufficient memory
453
454**/
455STATIC
456TpmStatus
457StartHandler (
458DIRECT_MSG_ARGS_EX *Request,
459DIRECT_MSG_ARGS_EX *Response
460)
461{
462TpmStatus ReturnVal;
9d594c43Raymond-MS1 years ago463UINT16 Function;
dc263d2cRaymond-MS1 years ago464UINT8 Locality;
465
466ReturnVal = TPM2_FFA_SUCCESS_OK;
467Function = Request->Arg1;
468Locality = Request->Arg2;
469
9d594c43Raymond-MS1 years ago470/* Check to make sure we received a valid locality */
f44455e7Raymond-MS1 years ago471if (Locality >= NUM_LOCALITIES) {
dc263d2cRaymond-MS1 years ago472Response->Arg0 = TPM2_FFA_ERROR_INVARG;
473DEBUG ((DEBUG_ERROR, "Invalid Locality\n"));
9d594c43Raymond-MS1 years ago474ReturnVal = TPM2_FFA_ERROR_INVARG;
475goto exit;
dc263d2cRaymond-MS1 years ago476}
477
1cf65721Raymond-MS1 years ago478/* TODO: Temporary solution*/
479
9d594c43Raymond-MS1 years ago480/* NOTE: The following commands should only be coming
481* from TF-A. */
482/* Check if there was a request to open a locality */
483if (Function == TPM_START_PROCESS_OPEN_LOC) {
484/* Set the locality state to OPEN */
485mLocalityStates[Locality] = TPM_LOCALITY_OPEN;
486goto exit;
03d3c59akuqin121 years ago487/* Check if there was a request to close a locality */
9d594c43Raymond-MS1 years ago488} else if (Function == TPM_START_PROCESS_CLOSE_LOC) {
489/* Set the locality state to CLOSED */
490mLocalityStates[Locality] = TPM_LOCALITY_CLOSED;
491goto exit;
492}
493
494/* Check if the locality is open */
495if (mLocalityStates[Locality] == TPM_LOCALITY_CLOSED) {
496DEBUG ((DEBUG_ERROR, "Locality Closed\n"));
497ReturnVal = TPM2_FFA_ERROR_DENIED;
498goto exit;
499}
500
501/* Check if we are processing a command */
1cf65721Raymond-MS1 years ago502if (Function == TPM2_FFA_START_FUNC_QUALIFIER_COMMAND) {
f44455e7Raymond-MS1 years ago503/* We should only proceed if the locality being requested matches that of the
504* current locality that is active. */
505if (Locality == mActiveLocality) {
506ReturnVal = HandleCommand ();
507} else {
508ReturnVal = TPM2_FFA_ERROR_INVARG;
509DEBUG ((DEBUG_ERROR, "Locality Mismatch\n"));
510}
03d3c59akuqin121 years ago511
512/* Check if we are processing a locality request */
1cf65721Raymond-MS1 years ago513} else if (Function == TPM2_FFA_START_FUNC_QUALIFIER_LOCALITY) {
f44455e7Raymond-MS1 years ago514ReturnVal = HandleLocalityRequest (Locality);
03d3c59akuqin121 years ago515/* Otherwise, invalid function ID */
dc263d2cRaymond-MS1 years ago516} else {
517ReturnVal = TPM2_FFA_ERROR_INVARG;
518DEBUG ((DEBUG_ERROR, "Invalid Start Function\n"));
519}
520
9d594c43Raymond-MS1 years ago521exit:
dc263d2cRaymond-MS1 years ago522/* Clean up the internal CRB at the given locality */
523CleanInternalCrb ();
524
525Response->Arg0 = ReturnVal;
526return ReturnVal;
527}
528
529/**
530Handler for TPM service Register command
531
532@param Request The incoming message
533@param Response The outgoing message
534
535@retval TPM_STATUS_OK Success
536
537**/
538STATIC
539TpmStatus
540RegisterHandler (
541DIRECT_MSG_ARGS_EX *Request,
542DIRECT_MSG_ARGS_EX *Response
543)
544{
545TpmStatus ReturnVal;
546
547ReturnVal = TPM2_FFA_SUCCESS_OK;
548Response->Arg0 = TPM2_FFA_ERROR_NOTSUP;
549DEBUG ((DEBUG_ERROR, "Unsupported Function\n"));
550return ReturnVal;
551}
552
553/**
554Handler for TPM service Unregister command
555
556@param Request The incoming message
557@param Response The outgoing message
558
559@retval TPM_STATUS_OK Success
560
561**/
562STATIC
563TpmStatus
564UnregisterHandler (
565DIRECT_MSG_ARGS_EX *Request,
566DIRECT_MSG_ARGS_EX *Response
567)
568{
569TpmStatus ReturnVal;
570
571ReturnVal = TPM2_FFA_SUCCESS_OK;
572Response->Arg0 = TPM2_FFA_ERROR_NOTSUP;
573DEBUG ((DEBUG_ERROR, "Unsupported Function\n"));
574return ReturnVal;
575}
576
577/**
578Handler for TPM service Finish command
579
580@param Request The incoming message
581@param Response The outgoing message
582
583@retval TPM_STATUS_OK Success
584
585**/
586STATIC
587TpmStatus
588FinishHandler (
589DIRECT_MSG_ARGS_EX *Request,
590DIRECT_MSG_ARGS_EX *Response
591)
592{
593TpmStatus ReturnVal;
594
595ReturnVal = TPM2_FFA_SUCCESS_OK;
596Response->Arg0 = TPM2_FFA_ERROR_NOTSUP;
597DEBUG ((DEBUG_ERROR, "Unsupported Function\n"));
598return ReturnVal;
599}
600
601/**
602Initializes the TPM service
603
604**/
605VOID
606TpmServiceInit (
607VOID
608)
609{
f44455e7Raymond-MS1 years ago610UINT8 Locality;
611
612/* Initialize the default interface ID. */
613mInterfaceIdDefault.Uint32 = 0;
614mInterfaceIdDefault.Bits.InterfaceType = 1; // CRB active
615mInterfaceIdDefault.Bits.InterfaceVersion = 1; // CRB interface version
616mInterfaceIdDefault.Bits.CapLocality = 1; // 5 localities supported
617mInterfaceIdDefault.Bits.CapCRB = 1; // CRB supported
618
619/* Initializes all of the localities. */
620for (Locality = 0; Locality < NUM_LOCALITIES; Locality++) {
621InitInternalCrb (Locality);
622}
623
9d594c43Raymond-MS1 years ago624/* Default the locality states */
24b25e5crdiaz1 years ago625for (Locality = 0; Locality < NUM_LOCALITIES; Locality++) {
9d594c43Raymond-MS1 years ago626/* Locality 0 and 1 are open by default */
03d3c59akuqin121 years ago627if ((Locality == 0) || (Locality == 1)) {
9d594c43Raymond-MS1 years ago628mLocalityStates[Locality] = TPM_LOCALITY_OPEN;
629} else {
630mLocalityStates[Locality] = TPM_LOCALITY_CLOSED;
631}
24b25e5crdiaz1 years ago632}
633
f44455e7Raymond-MS1 years ago634/* Initialize the TPM Service State Translation Library. */
635TpmSstInit ();
636
637/* Initialize our default state information. */
638mCurrentState = TPM_STATE_IDLE;
639mActiveLocality = NUM_LOCALITIES; // Invalid - No active locality
dc263d2cRaymond-MS1 years ago640}
641
642/**
f44455e7Raymond-MS1 years ago643De-initializes the TPM service
dc263d2cRaymond-MS1 years ago644
645**/
646VOID
647TpmServiceDeInit (
648VOID
649)
650{
651/* Nothing to DeInit */
652}
653
654/**
655Handler for TPM service commands
656
657@param Request The incoming message
658@param Response The outgoing message
659
660**/
661VOID
662TpmServiceHandle (
663DIRECT_MSG_ARGS_EX *Request,
664DIRECT_MSG_ARGS_EX *Response
665)
666{
667UINT64 Opcode;
668
669/* Validate the input parameters before attempting to dereference or pass them along */
670if ((Request == NULL) || (Response == NULL)) {
671return;
672}
673
674Opcode = Request->Arg0;
675
676switch (Opcode) {
677case TPM2_FFA_GET_INTERFACE_VERSION:
678GetInterfaceVersionHandler (Request, Response);
679break;
680
681case TPM2_FFA_GET_FEATURE_INFO:
682GetFeatureInfoHandler (Request, Response);
683break;
684
685case TPM2_FFA_START:
686StartHandler (Request, Response);
687break;
688
689case TPM2_FFA_REGISTER_FOR_NOTIFICATION:
690RegisterHandler (Request, Response);
691break;
692
693case TPM2_FFA_UNREGISTER_FROM_NOTIFICATION:
694UnregisterHandler (Request, Response);
695break;
696
697case TPM2_FFA_FINISH_NOTIFIED:
698FinishHandler (Request, Response);
699break;
700
701default:
702Response->Arg0 = TPM2_FFA_ERROR_NOFUNC;
703DEBUG ((DEBUG_ERROR, "Invalid TPM Service Opcode\n"));
704break;
705}
706}