// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "InternalRoutines.h"
//
//
//             Functions
//
//             PhysicalPresencePreInstall_Init()
//
//       This function is used to initialize the array of commands that require confirmation with physical presence.
//       The array is an array of bits that has a correspondence with the command code.
//       This command should only ever be executable in a manufacturing setting or in a simulation.
//
void
PhysicalPresencePreInstall_Init(
     void
     )
{
     // Clear all the PP commands
     MemorySet(&gp.ppList, 0,
//
                ((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8);
   // TPM_CC_PP_Commands always requires PP
   if(CommandIsImplemented(TPM_CC_PP_Commands))
       PhysicalPresenceCommandSet(TPM_CC_PP_Commands);
   // Write PP list to NV
   NvWriteReserved(NV_PP_LIST, &gp.ppList);
   return;
}
//
//
//          PhysicalPresenceCommandSet()
//
//     This function is used to indicate a command that requires PP confirmation.
//
void
PhysicalPresenceCommandSet(
   TPM_CC               commandCode       // IN: command code
   )
{
   UINT32         bitPos;
   // Assume command is implemented. It should be checked before this
   // function is called
   pAssert(CommandIsImplemented(commandCode));
   // If the command is not a PP command, ignore it
   if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
       return;
   bitPos = commandCode - TPM_CC_PP_FIRST;
   // Set bit
   gp.ppList[bitPos/8] |= 1 << (bitPos % 8);
   return;
}
//
//
//          PhysicalPresenceCommandClear()
//
//     This function is used to indicate a command that no longer requires PP confirmation.
//
void
PhysicalPresenceCommandClear(
   TPM_CC               commandCode       // IN: command code
   )
{
   UINT32         bitPos;
   // Assume command is implemented. It should be checked before this
   // function is called
   pAssert(CommandIsImplemented(commandCode));
   // If the command is not a PP command, ignore it
   if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
       return;
   // if the input code is TPM_CC_PP_Commands, it can not be cleared
   if(commandCode == TPM_CC_PP_Commands)
       return;
   bitPos = commandCode - TPM_CC_PP_FIRST;
     // Set bit
     gp.ppList[bitPos/8] |= (1 << (bitPos % 8));
     // Flip it to off
     gp.ppList[bitPos/8] ^= (1 << (bitPos % 8));
     return;
}
//
//
//           PhysicalPresenceIsRequired()
//
//      This function indicates if PP confirmation is required for a command.
//
//      Return Value                      Meaning
//
//      TRUE                              if physical presence is required
//      FALSE                             if physical presence is not required
//
BOOL
PhysicalPresenceIsRequired(
     TPM_CC             commandCode           // IN: command code
     )
{
     UINT32        bitPos;
     // if the input commandCode is not a PP command, return FALSE
     if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST)
         return FALSE;
     bitPos = commandCode - TPM_CC_PP_FIRST;
     // Check the bit map. If the bit is SET, PP authorization is required
     return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0);
}
//
//
//           PhysicalPresenceCapGetCCList()
//
//      This function returns a list of commands that require PP confirmation. The list starts from the first
//      implemented command that has a command code that the same or greater than commandCode.
//
//      Return Value                      Meaning
//
//      YES                               if there are more command codes available
//      NO                                all the available command codes have been returned
//
TPMI_YES_NO
PhysicalPresenceCapGetCCList(
     TPM_CC             commandCode,          // IN: start command code
     UINT32             count,                // IN: count of returned TPM_CC
     TPML_CC           *commandList           // OUT: list of TPM_CC
     )
{
     TPMI_YES_NO       more = NO;
     UINT32            i;
     // Initialize output handle list
     commandList->count = 0;
     // The maximum count of command we may return is MAX_CAP_CC
     if(count > MAX_CAP_CC) count = MAX_CAP_CC;
     // Collect PP commands
     for(i = commandCode; i <= TPM_CC_PP_LAST; i++)
     {
         if(PhysicalPresenceIsRequired(i))
         {
             if(commandList->count < count)
             {
                 // If we have not filled up the return list, add this command
                 // code to it
                 commandList->commandCodes[commandList->count] = i;
                 commandList->count++;
             }
             else
             {
                 // If the return list is full but we still have PP command
                 // available, report this and stop iterating
                 more = YES;
                 break;
             }
         }
     }
     return more;
}
