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

#include "InternalRoutines.h"
#include "Startup_fp.h"
//
//
//     Error Returns                     Meaning
//
//     TPM_RC_LOCALITY                   a Startup(STATE) does not have the same H-CRTM state as the
//                                       previous Startup() or the locality of the startup is not 0 pr 3
//     TPM_RC_NV_UNINITIALIZED           the saved state cannot be recovered and a Startup(CLEAR) is
//                                       requried.
//     TPM_RC_VALUE                      start up type is not compatible with previous shutdown sequence
//
TPM_RC
TPM2_Startup(
   Startup_In        *in                 // IN: input parameter list
   )
{
   STARTUP_TYPE            startup;
   TPM_RC                  result;
   BOOL                    prevDrtmPreStartup;
   BOOL                    prevStartupLoc3;
   BYTE                    locality = _plat__LocalityGet();

   // In the PC Client specification, only locality 0 and 3 are allowed
   if(locality != 0 && locality != 3)
       return TPM_RC_LOCALITY;
   // Indicate that the locality was 3 unless there was an H-CRTM
   if(g_DrtmPreStartup)
       locality = 0;
   g_StartupLocality3 = (locality == 3);

   // The command needs NV update. Check if NV is available.
   // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
   // this point
   result = NvIsAvailable();
   if(result != TPM_RC_SUCCESS)
       return result;

// Input Validation

   // Read orderly shutdown states from previous power cycle
   NvReadReserved(NV_ORDERLY, &g_prevOrderlyState);

   // See if the orderly state indicates that state was saved
   if(     (g_prevOrderlyState & ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3))
       == TPM_SU_STATE)
   {
       // If so, extrat the saved flags (HACK)
       prevDrtmPreStartup = (g_prevOrderlyState & PRE_STARTUP_FLAG) != 0;
       prevStartupLoc3 = (g_prevOrderlyState & STARTUP_LOCALITY_3) != 0;
       g_prevOrderlyState = TPM_SU_STATE;
   }
   else
   {
       prevDrtmPreStartup = 0;
       prevStartupLoc3 = 0;
   }
   // if this startup is a TPM Resume, then the H-CRTM states have to match.
   if(in->startupType == TPM_SU_STATE)
  {
         if(g_DrtmPreStartup != prevDrtmPreStartup)
             return TPM_RC_VALUE + RC_Startup_startupType;
         if(g_StartupLocality3 != prevStartupLoc3)
             return TPM_RC_LOCALITY;
  }

  // if the previous power cycle was shut down with no StateSave command, or
  // with StateSave command for CLEAR, or the part of NV used for TPM_SU_STATE
  // cannot be recovered, then this cycle can not startup up with STATE
  if(in->startupType == TPM_SU_STATE)
  {
      if(     g_prevOrderlyState == SHUTDOWN_NONE
         ||   g_prevOrderlyState == TPM_SU_CLEAR)
          return TPM_RC_VALUE + RC_Startup_startupType;

         if(g_nvOk == FALSE)
             return TPM_RC_NV_UNINITIALIZED;
  }

// Internal Date Update

  // Translate the TPM2_ShutDown and TPM2_Startup sequence into the startup
  // types. Will only be a SU_RESTART if the NV is OK
  if(     in->startupType == TPM_SU_CLEAR
      && g_prevOrderlyState == TPM_SU_STATE
      && g_nvOk == TRUE)
  {
      startup = SU_RESTART;
      // Read state reset data
      NvReadReserved(NV_STATE_RESET, &gr);
  }
  // In this check, we don't need to look at g_nvOk because that was checked
  // above
  else if(in->startupType == TPM_SU_STATE && g_prevOrderlyState == TPM_SU_STATE)
  {
      // Read state clear and state reset data
      NvReadReserved(NV_STATE_CLEAR, &gc);
      NvReadReserved(NV_STATE_RESET, &gr);
      startup = SU_RESUME;
  }
  else
  {
      startup = SU_RESET;
  }

  // Read persistent data from NV
  NvReadPersistent();

  // Crypto Startup
  CryptUtilStartup(startup);

  // Read the platform unique value that is used as VENDOR_PERMANENT auth value
  g_platformUniqueDetails.t.size = (UINT16)_plat__GetUnique(1,
                                     sizeof(g_platformUniqueDetails.t.buffer),
                                     g_platformUniqueDetails.t.buffer);

  // Start up subsystems
  // Start counters and timers
  TimeStartup(startup);

  // Start dictionary attack subsystem
  DAStartup(startup);

  // Enable hierarchies
  HierarchyStartup(startup);

   // Restore/Initialize PCR
   PCRStartup(startup, locality);

   // Restore/Initialize command audit information
   CommandAuditStartup(startup);

   // Object context variables
   if(startup == SU_RESET)
   {
       // Reset object context ID to 0
       gr.objectContextID = 0;
       // Reset clearCount to 0
       gr.clearCount= 0;
   }

   // Initialize session table
   SessionStartup(startup);

   // Initialize index/evict data.   This function clear read/write locks
   // in NV index
   NvEntityStartup(startup);

   // Initialize the orderly shut down flag for this cycle to SHUTDOWN_NONE.
   gp.orderlyState = SHUTDOWN_NONE;
   NvWriteReserved(NV_ORDERLY, &gp.orderlyState);

   // Update TPM internal states if command succeeded.
   // Record a TPM2_Startup command has been received.
   TPMRegisterStartup();

   // The H-CRTM state no longer matters
   g_DrtmPreStartup = FALSE;

   return TPM_RC_SUCCESS;

}
