// 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

#define NV_C
#include "InternalRoutines.h"
#include "Platform.h"
//
//      NV Index/evict object iterator value
//
typedef        UINT32              NV_ITER;              // type of a NV iterator
#define        NV_ITER_INIT        0xFFFFFFFF            // initial value to start an
                                                        // iterator
//
//
//           NV Utility Functions
//
//           NvCheckState()
//
//     Function to check the NV state by accessing the platform-specific function to get the NV state. The result
//     state is registered in s_NvIsAvailable that will be reported by NvIsAvailable().
//     This function is called at the beginning of ExecuteCommand() before any potential call to NvIsAvailable().
//
void
NvCheckState(void)
{
    int        func_return;
    func_return = _plat__IsNvAvailable();
    if(func_return == 0)
    {
        s_NvStatus = TPM_RC_SUCCESS;
    }
    else if(func_return == 1)
    {
        s_NvStatus = TPM_RC_NV_UNAVAILABLE;
    }
    else
    {
        s_NvStatus = TPM_RC_NV_RATE;
    }
    return;
}
//
//
//           NvIsAvailable()
//
//     This function returns the NV availability parameter.
//
//     Error Returns                     Meaning
//
//     TPM_RC_SUCCESS                    NV is available
//     TPM_RC_NV_RATE                    NV is unavailable because of rate limit
//     TPM_RC_NV_UNAVAILABLE             NV is inaccessible
//
TPM_RC
NvIsAvailable(
    void
    )
{
    // Make sure that NV state is still good
    if (s_NvStatus == TPM_RC_SUCCESS)
	NvCheckState();

    return s_NvStatus;
}
//
//
//           NvCommit
//
//     This is a wrapper for the platform function to commit pending NV writes.
//
BOOL
NvCommit(
    void
    )
{
    BOOL    success = (_plat__NvCommit() == 0);
    return success;
}
//
//
//          NvReadMaxCount()
//
//     This function returns the max NV counter value.
//
static UINT64
NvReadMaxCount(
    void
    )
{
    UINT64      countValue;
    _plat__NvMemoryRead(s_maxCountAddr, sizeof(UINT64), &countValue);
    return countValue;
}
//
//
//          NvWriteMaxCount()
//
//     This function updates the max counter value to NV memory.
//
static void
NvWriteMaxCount(
    UINT64               maxCount
    )
{
    _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &maxCount);
    return;
}
//
//
//          NV Index and Persistent Object Access Functions
//
//          Introduction
//
//     These functions are used to access an NV Index and persistent object memory. In this implementation,
//     the memory is simulated with RAM. The data in dynamic area is organized as a linked list, starting from
//     address s_evictNvStart. The first 4 bytes of a node in this link list is the offset of next node, followed by
//     the data entry. A 0-valued offset value indicates the end of the list. If the data entry area of the last node
//     happens to reach the end of the dynamic area without space left for an additional 4 byte end marker, the
//     end address, s_evictNvEnd, should serve as the mark of list end
//
//          NvNext()
//
//     This function provides a method to traverse every data entry in NV dynamic area.
//     To begin with, parameter iter should be initialized to NV_ITER_INIT indicating the first element. Every
//     time this function is called, the value in iter would be adjusted pointing to the next element in traversal. If
//     there is no next element, iter value would be 0. This function returns the address of the 'data entry'
//     pointed by the iter. If there is no more element in the set, a 0 value is returned indicating the end of
//     traversal.
//
static UINT32
NvNext(
    NV_ITER             *iter
    )
{
   NV_ITER        currentIter;
   // If iterator is at the beginning of list
   if(*iter == NV_ITER_INIT)
   {
       // Initialize iterator
       *iter = s_evictNvStart;
   }
   // If iterator reaches the end of NV space, or iterator indicates list end
   if(*iter + sizeof(UINT32) > s_evictNvEnd || *iter == 0)
       return 0;
   // Save the current iter offset
   currentIter = *iter;
   // Adjust iter pointer pointing to next entity
   // Read pointer value
   _plat__NvMemoryRead(*iter, sizeof(UINT32), iter);
   if(!*iter || (*iter == NV_ITER_INIT)) return 0;
   return currentIter + sizeof(UINT32);                // entity stores after the pointer
}
//
//
//           NvGetEnd()
//
//      Function to find the end of the NV dynamic data list
//
static UINT32
NvGetEnd(
   void
   )
{
   NV_ITER             iter = NV_ITER_INIT;
   UINT32              endAddr = s_evictNvStart;
   UINT32              currentAddr;
   while((currentAddr = NvNext(&iter)) != 0)
       endAddr = currentAddr;
   if(endAddr != s_evictNvStart)
   {
       // Read offset
       endAddr -= sizeof(UINT32);
       _plat__NvMemoryRead(endAddr, sizeof(UINT32), &endAddr);
   }
   return endAddr;
}
//
//
//           NvGetFreeByte
//
//      This function returns the number of free octets in NV space.
//
static UINT32
NvGetFreeByte(
   void
   )
{
   return s_evictNvEnd - NvGetEnd();
}
//
//           NvGetEvictObjectSize
//
//      This function returns the size of an evict object in NV space
//
static UINT32
NvGetEvictObjectSize(
    void
    )
{
    return sizeof(TPM_HANDLE) + sizeof(OBJECT) + sizeof(UINT32);
}
//
//
//           NvGetCounterSize
//
//      This function returns the size of a counter index in NV space.
//
static UINT32
NvGetCounterSize(
    void
    )
{
    // It takes an offset field, a handle and the sizeof(NV_INDEX) and
    // sizeof(UINT64) for counter data
    return sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + sizeof(UINT64) + sizeof(UINT32);
}
//
//
//           NvTestSpace()
//
//      This function will test if there is enough space to add a new entity.
//
//      Return Value                      Meaning
//
//      TRUE                              space available
//      FALSE                             no enough space
//
static BOOL
NvTestSpace(
    UINT32               size,               // IN: size of the entity to be added
    BOOL                 isIndex             // IN: TRUE if the entity is an index
    )
{
    UINT32         remainByte = NvGetFreeByte();
    // For NV Index, need to make sure that we do not allocate and Index if this
    // would mean that the TPM cannot allocate the minimum number of evict
    // objects.
    if(isIndex)
    {
        // Get the number of persistent objects allocated
        UINT32      persistentNum = NvCapGetPersistentNumber();
         // If we have not allocated the requisite number of evict objects, then we
         // need to reserve space for them.
         // NOTE: some of this is not written as simply as it might seem because
         // the values are all unsigned and subtracting needs to be done carefully
         // so that an underflow doesn't cause problems.
         if(persistentNum < MIN_EVICT_OBJECTS)
         {
             UINT32      needed = (MIN_EVICT_OBJECTS - persistentNum)
                                 * NvGetEvictObjectSize();
             if(needed > remainByte)
                 remainByte = 0;
             else
                 remainByte -= needed;
         }
         // if the requisite number of evict objects have been allocated then
         // no need to reserve additional space
   }
   // This checks for the size of the value being added plus the index value.
   // NOTE: This does not check to see if the end marker can be placed in
   // memory because the end marker will not be written if it will not fit.
   return (size + sizeof(UINT32) <= remainByte);
}
//
//
//           NvAdd()
//
//      This function adds a new entity to NV.
//      This function requires that there is enough space to add a new entity (i.e., that NvTestSpace() has been
//      called and the available space is at least as large as the required space).
//
static void
NvAdd(
   UINT32                totalSize,       // IN: total size needed for this        entity For
                                          //     evict object, totalSize is        the same as
                                          //     bufferSize. For NV Index,         totalSize is
                                          //     bufferSize plus index data        size
   UINT32                bufferSize,      // IN: size of initial buffer
   BYTE                 *entity           // IN: initial buffer
   )
{
   UINT32               endAddr;
   UINT32               nextAddr;
   UINT32               listEnd = 0;
   // Get the end of data list
   endAddr = NvGetEnd();
   // Calculate the value of next pointer, which is the size of a pointer +
   // the entity data size
   nextAddr = endAddr + sizeof(UINT32) + totalSize;
   // Write next pointer
   _plat__NvMemoryWrite(endAddr, sizeof(UINT32), &nextAddr);
   // Write entity data
   _plat__NvMemoryWrite(endAddr + sizeof(UINT32), bufferSize, entity);
   // Write the end of list if it is not going to exceed the NV space
   if(nextAddr + sizeof(UINT32) <= s_evictNvEnd)
       _plat__NvMemoryWrite(nextAddr, sizeof(UINT32), &listEnd);
   // Set the flag so that NV changes are committed before the command completes.
   g_updateNV = TRUE;
}
//
//
//           NvDelete()
//
//      This function is used to delete an NV Index or persistent object from NV memory.
//
static void
NvDelete(
   UINT32                entityAddr       // IN: address of entity to be deleted
   )
{
   UINT32              next;
   UINT32              entrySize;
   UINT32              entryAddr = entityAddr - sizeof(UINT32);
   UINT32              listEnd = 0;
   // Get the offset of the next entry.
   _plat__NvMemoryRead(entryAddr, sizeof(UINT32), &next);
   // The size of this entry is the difference between the current entry and the
   // next entry.
   entrySize = next - entryAddr;
   //    Move each entry after the current one to fill the freed space.
   //    Stop when we have reached the end of all the indexes. There are two
   //    ways to detect the end of the list. The first is to notice that there
   //    is no room for anything else because we are at the end of NV. The other
   //    indication is that we find an end marker.
   // The loop condition checks for the end of NV.
   while(next + sizeof(UINT32) <= s_evictNvEnd)
   {
       UINT32      size, oldAddr, newAddr;
         // Now check for the end marker
         _plat__NvMemoryRead(next, sizeof(UINT32), &oldAddr);
         if(oldAddr == 0)
             break;
         size = oldAddr - next;
         // Move entry
         _plat__NvMemoryMove(next, next - entrySize, size);
         // Update forward link
         newAddr = oldAddr - entrySize;
         _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &newAddr);
         next = oldAddr;
   }
   // Mark the end of list
   _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &listEnd);
   // Set the flag so that NV changes are committed before the command completes.
   g_updateNV = TRUE;
}
//
//
//           RAM-based NV Index Data Access Functions
//
//           Introduction
//
//      The data layout in ram buffer is {size of(NV_handle() + data), NV_handle(), data} for each NV Index data
//      stored in RAM.
//      NV storage is updated when a NV Index is added or deleted. We do NOT updated NV storage when the
//      data is updated/
//
//           NvTestRAMSpace()
//
//      This function indicates if there is enough RAM space to add a data for a new NV Index.
//
//
//
//
//      Return Value                      Meaning
//
//      TRUE                              space available
//      FALSE                             no enough space
//
static BOOL
NvTestRAMSpace(
   UINT32                size                // IN: size of the data to be added to RAM
   )
{
   BOOL           success = (       s_ramIndexSize
                                  + size
                                  + sizeof(TPM_HANDLE) + sizeof(UINT32)
                                  <= RAM_INDEX_SPACE);
   return success;
}
//
//
//           NvGetRamIndexOffset
//
//      This function returns the offset of NV data in the RAM buffer
//      This function requires that NV Index is in RAM. That is, the index must be known to exist.
//
static UINT32
NvGetRAMIndexOffset(
   TPMI_RH_NV_INDEX           handle               // IN: NV handle
   )
{
   UINT32         currAddr = 0;
   while(currAddr < s_ramIndexSize)
   {
       TPMI_RH_NV_INDEX    currHandle;
       UINT32              currSize;
       memcpy(&currHandle, &s_ramIndex[currAddr + sizeof(UINT32)],
              sizeof(currHandle));
         // Found a match
         if(currHandle == handle)
              // data buffer follows the handle and size field
              break;
         memcpy(&currSize, &s_ramIndex[currAddr], sizeof(currSize));
         currAddr += sizeof(UINT32) + currSize;
   }
   // We assume the index data is existing in RAM space
   pAssert(currAddr < s_ramIndexSize);
   return currAddr + sizeof(TPMI_RH_NV_INDEX) + sizeof(UINT32);
}
//
//
//           NvAddRAM()
//
//      This function adds a new data area to RAM.
//      This function requires that enough free RAM space is available to add the new data.
//
static void
NvAddRAM(
   TPMI_RH_NV_INDEX           handle,              // IN: NV handle
   UINT32                     size                 // IN: size of data
   )
{
   // Add data space at the end of reserved RAM buffer
   UINT32 value = size + sizeof(TPMI_RH_NV_INDEX);
   memcpy(&s_ramIndex[s_ramIndexSize], &value,
          sizeof(s_ramIndex[s_ramIndexSize]));
   memcpy(&s_ramIndex[s_ramIndexSize + sizeof(UINT32)], &handle,
          sizeof(s_ramIndex[s_ramIndexSize + sizeof(UINT32)]));
   s_ramIndexSize += sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX) + size;
   pAssert(s_ramIndexSize <= RAM_INDEX_SPACE);
   // Update NV version of s_ramIndexSize
   _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
   // Write reserved RAM space to NV to reflect the newly added NV Index
   _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
   return;
}
//
//
//          NvDeleteRAM()
//
//      This function is used to delete a RAM-backed NV Index data area.
//      This function assumes the data of NV Index exists in RAM
//
static void
NvDeleteRAM(
   TPMI_RH_NV_INDEX          handle           // IN: NV handle
   )
{
   UINT32             nodeOffset;
   UINT32             nextNode;
   UINT32             size;
   nodeOffset = NvGetRAMIndexOffset(handle);
   // Move the pointer back to get the size field of this node
   nodeOffset -= sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX);
   // Get node size
   memcpy(&size, &s_ramIndex[nodeOffset], sizeof(size));
   // Get the offset of next node
   nextNode = nodeOffset + sizeof(UINT32) + size;
   // Move data
   MemoryMove(s_ramIndex + nodeOffset, s_ramIndex + nextNode,
              s_ramIndexSize - nextNode, s_ramIndexSize - nextNode);
   // Update RAM size
   s_ramIndexSize -= size + sizeof(UINT32);
   // Update NV version of s_ramIndexSize
   _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
   // Write reserved RAM space to NV to reflect the newly delete NV Index
   _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
   return;
}
//
//
//
//           Utility Functions
//
//           NvInitStatic()
//
//      This function initializes the static variables used in the NV subsystem.
//
static void
NvInitStatic(
    void
    )
{
    UINT16         i;
    UINT32         reservedAddr;
    s_reservedSize[NV_DISABLE_CLEAR] = sizeof(gp.disableClear);
    s_reservedSize[NV_OWNER_ALG] = sizeof(gp.ownerAlg);
    s_reservedSize[NV_ENDORSEMENT_ALG] = sizeof(gp.endorsementAlg);
    s_reservedSize[NV_LOCKOUT_ALG] = sizeof(gp.lockoutAlg);
    s_reservedSize[NV_OWNER_POLICY] = sizeof(gp.ownerPolicy);
    s_reservedSize[NV_ENDORSEMENT_POLICY] = sizeof(gp.endorsementPolicy);
    s_reservedSize[NV_LOCKOUT_POLICY] = sizeof(gp.lockoutPolicy);
    s_reservedSize[NV_OWNER_AUTH] = sizeof(gp.ownerAuth);
    s_reservedSize[NV_ENDORSEMENT_AUTH] = sizeof(gp.endorsementAuth);
    s_reservedSize[NV_LOCKOUT_AUTH] = sizeof(gp.lockoutAuth);
    s_reservedSize[NV_EP_SEED] = sizeof(gp.EPSeed);
    s_reservedSize[NV_SP_SEED] = sizeof(gp.SPSeed);
    s_reservedSize[NV_PP_SEED] = sizeof(gp.PPSeed);
    s_reservedSize[NV_PH_PROOF] = sizeof(gp.phProof);
    s_reservedSize[NV_SH_PROOF] = sizeof(gp.shProof);
    s_reservedSize[NV_EH_PROOF] = sizeof(gp.ehProof);
    s_reservedSize[NV_TOTAL_RESET_COUNT] = sizeof(gp.totalResetCount);
    s_reservedSize[NV_RESET_COUNT] = sizeof(gp.resetCount);
    s_reservedSize[NV_PCR_POLICIES] = sizeof(gp.pcrPolicies);
    s_reservedSize[NV_PCR_ALLOCATED] = sizeof(gp.pcrAllocated);
    s_reservedSize[NV_PP_LIST] = sizeof(gp.ppList);
    s_reservedSize[NV_FAILED_TRIES] = sizeof(gp.failedTries);
    s_reservedSize[NV_MAX_TRIES] = sizeof(gp.maxTries);
    s_reservedSize[NV_RECOVERY_TIME] = sizeof(gp.recoveryTime);
    s_reservedSize[NV_LOCKOUT_RECOVERY] = sizeof(gp.lockoutRecovery);
    s_reservedSize[NV_LOCKOUT_AUTH_ENABLED] = sizeof(gp.lockOutAuthEnabled);
    s_reservedSize[NV_ORDERLY] = sizeof(gp.orderlyState);
    s_reservedSize[NV_AUDIT_COMMANDS] = sizeof(gp.auditComands);
    s_reservedSize[NV_AUDIT_HASH_ALG] = sizeof(gp.auditHashAlg);
    s_reservedSize[NV_AUDIT_COUNTER] = sizeof(gp.auditCounter);
    s_reservedSize[NV_ALGORITHM_SET] = sizeof(gp.algorithmSet);
    s_reservedSize[NV_FIRMWARE_V1] = sizeof(gp.firmwareV1);
    s_reservedSize[NV_FIRMWARE_V2] = sizeof(gp.firmwareV2);
    s_reservedSize[NV_ORDERLY_DATA] = sizeof(go);
    s_reservedSize[NV_STATE_CLEAR] = sizeof(gc);
    s_reservedSize[NV_STATE_RESET] = sizeof(gr);
    // Initialize reserved data address. In this implementation, reserved data
    // is stored at the start of NV memory
    reservedAddr = 0;
    for(i = 0; i < NV_RESERVE_LAST; i++)
    {
        s_reservedAddr[i] = reservedAddr;
        reservedAddr += s_reservedSize[i];
    }
    // Initialize auxiliary variable space for index/evict implementation.
    // Auxiliary variables are stored after reserved data area
    // RAM index copy starts at the beginning
    s_ramIndexSizeAddr = reservedAddr;
    s_ramIndexAddr = s_ramIndexSizeAddr + sizeof(UINT32);
    // Maximum counter value
    s_maxCountAddr = s_ramIndexAddr + RAM_INDEX_SPACE;
    // dynamic memory start
    s_evictNvStart = s_maxCountAddr + sizeof(UINT64);
    // dynamic memory ends at the end of NV memory
    s_evictNvEnd = NV_MEMORY_SIZE;
    return;
}
//
//
//           NvInit()
//
//      This function initializes the NV system at pre-install time.
//      This function should only be called in a manufacturing environment or in a simulation.
//      The layout of NV memory space is an implementation choice.
//
void
NvInit(
    void
    )
{
    UINT32         nullPointer = 0;
    UINT64         zeroCounter = 0;
    // Initialize static variables
    NvInitStatic();
    // Initialize RAM index space as unused
    _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &nullPointer);
    // Initialize max counter value to 0
    _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &zeroCounter);
    // Initialize the next offset of the first entry in evict/index list to 0
    _plat__NvMemoryWrite(s_evictNvStart, sizeof(TPM_HANDLE), &nullPointer);
    return;
}
//
//
//           NvReadReserved()
//
//      This function is used to move reserved data from NV memory to RAM.
//
void
NvReadReserved(
    NV_RESERVE           type,               // IN: type of reserved data
    void                *buffer              // OUT: buffer receives the data.
    )
{
    // Input type should be valid
    pAssert(type >= 0 && type < NV_RESERVE_LAST);
    _plat__NvMemoryRead(s_reservedAddr[type], s_reservedSize[type], buffer);
    return;
}
//
//
//           NvWriteReserved()
//
//      This function is used to post a reserved data for writing to NV memory. Before the TPM completes the
//      operation, the value will be written.
//
void
NvWriteReserved(
   NV_RESERVE           type,              // IN: type of reserved data
   void                *buffer             // IN: data buffer
   )
{
   // Input type should be valid
   pAssert(type >= 0 && type < NV_RESERVE_LAST);
   _plat__NvMemoryWrite(s_reservedAddr[type], s_reservedSize[type], buffer);
   // Set the flag that a NV write happens
   g_updateNV = TRUE;
   return;
}
//
//
//           NvReadPersistent()
//
//      This function reads persistent data to the RAM copy of the gp structure.
//
void
NvReadPersistent(
   void
   )
{
   // Hierarchy persistent data
   NvReadReserved(NV_DISABLE_CLEAR, &gp.disableClear);
   NvReadReserved(NV_OWNER_ALG, &gp.ownerAlg);
   NvReadReserved(NV_ENDORSEMENT_ALG, &gp.endorsementAlg);
   NvReadReserved(NV_LOCKOUT_ALG, &gp.lockoutAlg);
   NvReadReserved(NV_OWNER_POLICY, &gp.ownerPolicy);
   NvReadReserved(NV_ENDORSEMENT_POLICY, &gp.endorsementPolicy);
   NvReadReserved(NV_LOCKOUT_POLICY, &gp.lockoutPolicy);
   NvReadReserved(NV_OWNER_AUTH, &gp.ownerAuth);
   NvReadReserved(NV_ENDORSEMENT_AUTH, &gp.endorsementAuth);
   NvReadReserved(NV_LOCKOUT_AUTH, &gp.lockoutAuth);
   NvReadReserved(NV_EP_SEED, &gp.EPSeed);
   NvReadReserved(NV_SP_SEED, &gp.SPSeed);
   NvReadReserved(NV_PP_SEED, &gp.PPSeed);
   NvReadReserved(NV_PH_PROOF, &gp.phProof);
   NvReadReserved(NV_SH_PROOF, &gp.shProof);
   NvReadReserved(NV_EH_PROOF, &gp.ehProof);
   // Time persistent data
   NvReadReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount);
   NvReadReserved(NV_RESET_COUNT, &gp.resetCount);
   // PCR persistent data
   NvReadReserved(NV_PCR_POLICIES, &gp.pcrPolicies);
   NvReadReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated);
   // Physical Presence persistent data
   NvReadReserved(NV_PP_LIST, &gp.ppList);
   // Dictionary attack values persistent data
   NvReadReserved(NV_FAILED_TRIES, &gp.failedTries);
   NvReadReserved(NV_MAX_TRIES, &gp.maxTries);
   NvReadReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
//
    NvReadReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
    NvReadReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
    // Orderly State persistent data
    NvReadReserved(NV_ORDERLY, &gp.orderlyState);
    // Command audit values persistent data
    NvReadReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
    NvReadReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
    NvReadReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
    // Algorithm selection persistent data
    NvReadReserved(NV_ALGORITHM_SET, &gp.algorithmSet);
    // Firmware version persistent data
#ifdef EMBEDDED_MODE
   _plat__GetFwVersion(&gp.firmwareV1, &gp.firmwareV2);
#else
    NvReadReserved(NV_FIRMWARE_V1, &gp.firmwareV1);
    NvReadReserved(NV_FIRMWARE_V2, &gp.firmwareV2);
#endif
    return;
}
//
//
//           NvIsPlatformPersistentHandle()
//
//      This function indicates if a handle references a persistent object in the range belonging to the platform.
//
//      Return Value                      Meaning
//
//      TRUE                              handle references a platform persistent object
//      FALSE                             handle does not reference platform persistent object and may
//                                        reference an owner persistent object either
//
BOOL
NvIsPlatformPersistentHandle(
    TPM_HANDLE           handle              // IN: handle
    )
{
    return (handle >= PLATFORM_PERSISTENT && handle <= PERSISTENT_LAST);
}
//
//
//           NvIsOwnerPersistentHandle()
//
//      This function indicates if a handle references a persistent object in the range belonging to the owner.
//
//      Return Value                      Meaning
//
//      TRUE                              handle is owner persistent handle
//      FALSE                             handle is not owner persistent handle and may not be a persistent
//                                        handle at all
//
BOOL
NvIsOwnerPersistentHandle(
    TPM_HANDLE           handle              // IN: handle
    )
{
    return (handle >= PERSISTENT_FIRST && handle < PLATFORM_PERSISTENT);
}
//
//
//           NvNextIndex()
//
//      This function returns the offset in NV of the next NV Index entry. A value of 0 indicates the end of the list.
//      Family "2.0"                                   TCG Published                                          Page 131
//      Level 00 Revision 01.16               Copyright © TCG 2006-2014                            October 30, 2014
//      Trusted Platform Module Library                                                Part 4: Supporting Routines
//
static UINT32
NvNextIndex(
   NV_ITER             *iter
   )
{
   UINT32         addr;
   TPM_HANDLE     handle;
   while((addr = NvNext(iter)) != 0)
   {
       // Read handle
       _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle);
       if(HandleGetType(handle) == TPM_HT_NV_INDEX)
           return addr;
   }
   pAssert(addr == 0);
   return addr;
}
//
//
//           NvNextEvict()
//
//      This function returns the offset in NV of the next evict object entry. A value of 0 indicates the end of the
//      list.
//
static UINT32
NvNextEvict(
   NV_ITER             *iter
   )
{
   UINT32         addr;
   TPM_HANDLE     handle;
   while((addr = NvNext(iter)) != 0)
   {
       // Read handle
       _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle);
       if(HandleGetType(handle) == TPM_HT_PERSISTENT)
           return addr;
   }
   pAssert(addr == 0);
   return addr;
}
//
//
//          NvFindHandle()
//
//      this function returns the offset in NV memory of the entity associated with the input handle. A value of
//      zero indicates that handle does not exist reference an existing persistent object or defined NV Index.
//
static UINT32
NvFindHandle(
   TPM_HANDLE            handle
   )
{
   UINT32              addr;
   NV_ITER             iter = NV_ITER_INIT;

   if ((addr = _plat__NvGetHandleVirtualOffset(handle)) != 0) {
     return addr;
   }

   while((addr = NvNext(&iter)) != 0)
   {
       TPM_HANDLE          entityHandle;
       // Read handle
//
          _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &entityHandle);
          if(entityHandle == handle)
              return addr;
    }
    pAssert(addr == 0);
    return addr;
}

//
//   NvCheckAndMigrateIfNeeded()
//
// Supported only in EMBEDDED_MODE.
//
// Check if the NVRAM storage format changed, and if so - reinitialize the
// NVRAM. No content migration yet, hopefully it will come one day.
//
// Note that the NV_FIRMWARE_V1 and NV_FIRMWARE_V2 values not used to store
// TPM versoion when in embedded mode are used for NVRAM format version
// instead.
//
//
static void
NvCheckAndMigrateIfNeeded(void)
{
#ifdef EMBEDDED_MODE
  UINT32 nv_vers1;
  UINT32 nv_vers2;

  NvReadReserved(NV_FIRMWARE_V1, &nv_vers1);
  NvReadReserved(NV_FIRMWARE_V2, &nv_vers2);

  if ((nv_vers1 == ~nv_vers2) && (nv_vers1 == NV_FORMAT_VERSION))
    return; // All is well.

  // This will reinitialize NVRAM to empty. Migration code will come here
  // later.
  NvInit();

  nv_vers1 = NV_FORMAT_VERSION;
  nv_vers2 = ~NV_FORMAT_VERSION;

  NvWriteReserved(NV_FIRMWARE_V1, &nv_vers1);
  NvWriteReserved(NV_FIRMWARE_V2, &nv_vers2);

  NvCommit();
#endif
}


//
//
//          NvPowerOn()
//
//      This function is called at _TPM_Init() to initialize the NV environment.
//
//      Return Value                      Meaning
//
//      TRUE                              all NV was initialized
//      FALSE                             the NV     containing saved     state    had   an   error   and
//                                        TPM2_Startup(CLEAR) is required
//
BOOL
NvPowerOn(
    void
    )
{
    int          nvError = 0;
    // If power was lost, need to re-establish the RAM data that is loaded from
    // NV and initialize the static variables
    if(_plat__WasPowerLost(TRUE))
    {
        if((nvError = _plat__NVEnable(0)) < 0)
            FAIL(FATAL_ERROR_NV_UNRECOVERABLE);
	NvInitStatic();
	NvCheckAndMigrateIfNeeded();
    }
    return nvError == 0;
}
//
//
//          NvStateSave()
//
//      This function is used to cause the memory containing the RAM backed NV Indices to be written to NV.
//
void
NvStateSave(
    void
    )
{
    // Write RAM backed NV Index info to NV
    // No need to save s_ramIndexSize because we save it to NV whenever it is
    // updated.
    _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
    // Set the flag so that an NV write happens before the command completes.
    g_updateNV = TRUE;
    return;
}
//
//
//
//           NvEntityStartup()
//
//      This function is called at TPM_Startup(). If the startup completes a TPM Resume cycle, no action is
//      taken. If the startup is a TPM Reset or a TPM Restart, then this function will:
//      a) clear read/write lock;
//      b) reset NV Index data that has TPMA_NV_CLEAR_STCLEAR SET; and
//      c) set the lower bits in orderly counters to 1 for a non-orderly startup
//      It is a prerequisite that NV be available for writing before this function is called.
//
void
NvEntityStartup(
    STARTUP_TYPE           type               // IN: start up type
    )
{
    NV_ITER                   iter = NV_ITER_INIT;
    UINT32                    currentAddr;         // offset points to the current entity
    // Restore RAM index data
    _plat__NvMemoryRead(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
    _plat__NvMemoryRead(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
    // If recovering from state save, do nothing
    if(type == SU_RESUME)
        return;
    // Iterate all the NV Index to clear the locks
    while((currentAddr = NvNextIndex(&iter)) != 0)
    {
        NV_INDEX    nvIndex;
        UINT32      indexAddr;              // NV address points to index info
        TPMA_NV     attributes;
        UINT32      attributesValue;
        UINT32      publicAreaAttributesValue;
          indexAddr = currentAddr + sizeof(TPM_HANDLE);
          // Read NV Index info structure
          _plat__NvMemoryRead(indexAddr, sizeof(NV_INDEX), &nvIndex);
          attributes = nvIndex.publicArea.attributes;
          // Clear read/write lock
          if(attributes.TPMA_NV_READLOCKED == SET)
              attributes.TPMA_NV_READLOCKED = CLEAR;
          if(         attributes.TPMA_NV_WRITELOCKED == SET
                 &&   (   attributes.TPMA_NV_WRITTEN == CLEAR
                      || attributes.TPMA_NV_WRITEDEFINE == CLEAR
                      )
                )
                 attributes.TPMA_NV_WRITELOCKED = CLEAR;
          // Reset NV data for TPMA_NV_CLEAR_STCLEAR
          if(attributes.TPMA_NV_CLEAR_STCLEAR == SET)
          {
              attributes.TPMA_NV_WRITTEN = CLEAR;
              attributes.TPMA_NV_WRITELOCKED = CLEAR;
          }
          // Reset NV data for orderly values that are not counters
          // NOTE: The function has already exited on a TPM Resume, so the only
          // things being processed are TPM Restart and TPM Reset
          if(     type == SU_RESET
              && attributes.TPMA_NV_ORDERLY == SET
              && attributes.TPMA_NV_COUNTER == CLEAR
             )
                 attributes.TPMA_NV_WRITTEN = CLEAR;
         // Write NV Index info back if it has changed
         memcpy(&attributesValue, &attributes, sizeof(attributesValue));
         memcpy(&publicAreaAttributesValue, &nvIndex.publicArea.attributes,
                sizeof(publicAreaAttributesValue));
         if(attributesValue != publicAreaAttributesValue)
         {
             nvIndex.publicArea.attributes = attributes;
             _plat__NvMemoryWrite(indexAddr, sizeof(NV_INDEX), &nvIndex);
                 // Set the flag that a NV write happens
                 g_updateNV = TRUE;
         }
         // Set the lower bits in an orderly counter to 1 for a non-orderly startup
         if(    g_prevOrderlyState == SHUTDOWN_NONE
             && attributes.TPMA_NV_WRITTEN == SET)
         {
              if(    attributes.TPMA_NV_ORDERLY == SET
                  && attributes.TPMA_NV_COUNTER == SET)
              {
                   TPMI_RH_NV_INDEX    nvHandle;
                   UINT64              counter;
                     // Read NV handle
                     _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle);
                     // Read the counter value saved to NV upon the last roll over.
                     // Do not use RAM backed storage for this once.
                     nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = CLEAR;
                     NvGetIntIndexData(nvHandle, &nvIndex, &counter);
                     nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = SET;
                     // Set the lower bits of counter to 1's
                     counter |= MAX_ORDERLY_COUNT;
                     // Write back to RAM
                     NvWriteIndexData(nvHandle, &nvIndex, 0, sizeof(counter), &counter);
                     // No write to NV because an orderly shutdown will update the
                     // counters.
                 }
         }
   }
   return;
}
//
//
//           NV Access Functions
//
//             Introduction
//
//      This set of functions provide accessing NV Index and persistent objects based using a handle for
//      reference to the entity.
//
//             NvIsUndefinedIndex()
//
//      This function is used to verify that an NV Index is not defined. This is only used by
//      TPM2_NV_DefineSpace().
//
//
//
//
//      Return Value                      Meaning
//
//      TRUE                              the handle points to an existing NV Index
//      FALSE                             the handle points to a non-existent Index
//
BOOL
NvIsUndefinedIndex(
   TPMI_RH_NV_INDEX         handle                 // IN: handle
   )
{
   UINT32             entityAddr;                  // offset points to the entity
   pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
   // Find the address of index
   entityAddr = NvFindHandle(handle);
   // If handle is not found, return TPM_RC_SUCCESS
   if(entityAddr == 0)
       return TPM_RC_SUCCESS;
   // NV Index is defined
   return TPM_RC_NV_DEFINED;
}
//
//
//          NvIndexIsAccessible()
//
//      This function validates that a handle references a defined NV Index and that the Index is currently
//      accessible.
//
//      Error Returns                     Meaning
//
//      TPM_RC_HANDLE                     the handle points to an undefined NV Index If shEnable is CLEAR,
//                                        this would include an index created using ownerAuth. If phEnableNV
//                                        is CLEAR, this would include and index created using platform auth
//      TPM_RC_NV_READLOCKED              Index is present but locked for reading and command does not write
//                                        to the index
//      TPM_RC_NV_WRITELOCKED             Index is present but locked for writing and command writes to the
//                                        index
//
TPM_RC
NvIndexIsAccessible(
   TPMI_RH_NV_INDEX         handle,                // IN: handle
   TPM_CC                   commandCode            // IN: the command
   )
{
   UINT32                  entityAddr;             // offset points to the entity
   NV_INDEX                nvIndex;                //
   pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
   // Find the address of index
   entityAddr = NvFindHandle(handle);
   // If handle is not found, return TPM_RC_HANDLE
   if(entityAddr == 0)
       return TPM_RC_HANDLE;
   // Read NV Index info structure
   _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
                           &nvIndex);
   if(gc.shEnable == FALSE || gc.phEnableNV == FALSE)
   {
       // if shEnable is CLEAR, an ownerCreate NV Index should not be
       // indicated as present
       if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR)
       {
           /*
            * FWMP is a Chrome OS specific object saved at address 0x100a, it
            * needs to be available for reading even before TPM2_Startup
            * command is issued.
            */
           UINT32 isFwmpRead = (handle == 0x100100a) &&
               IsReadOperation(commandCode);

           if((gc.shEnable == FALSE) && !isFwmpRead)
               return TPM_RC_HANDLE;
       }
       // if phEnableNV is CLEAR, a platform created Index should not
       // be visible
       else if(gc.phEnableNV == FALSE)
           return TPM_RC_HANDLE;
   }
   // If the Index is write locked and this is an NV Write operation...
   if(     nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED
       && IsWriteOperation(commandCode))
   {
       // then return a locked indication unless the command is TPM2_NV_WriteLock
       if(commandCode != TPM_CC_NV_WriteLock)
           return TPM_RC_NV_LOCKED;
       return TPM_RC_SUCCESS;
   }
   // If the Index is read locked and this is an NV Read operation...
   if(     nvIndex.publicArea.attributes.TPMA_NV_READLOCKED
       && IsReadOperation(commandCode))
   {
       // then return a locked indication unless the command is TPM2_NV_ReadLock
       if(commandCode != TPM_CC_NV_ReadLock)
           return TPM_RC_NV_LOCKED;
       return TPM_RC_SUCCESS;
   }
   // NV Index is accessible
   return TPM_RC_SUCCESS;
}
//
//
//           NvIsUndefinedEvictHandle()
//
//      This function indicates if a handle does not reference an existing persistent object. This function requires
//      that the handle be in the proper range for persistent objects.
//
//      Return Value                     Meaning
//
//      TRUE                             handle does not reference an existing persistent object
//      FALSE                            handle does reference an existing persistent object
//
static BOOL
NvIsUndefinedEvictHandle(
   TPM_HANDLE            handle             // IN: handle
   )
{
   UINT32           entityAddr;    // offset points to the entity
   pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
   // Find the address of evict object
   entityAddr = NvFindHandle(handle);
   // If handle is not found, return TRUE
   if(entityAddr == 0)
       return TRUE;
    else
        return FALSE;
}

//
//
//           NvUnmarshalObject()
//
//      This function accepts a buffer containing a marshaled OBJECT
//      structure, a pointer to the area where the input data should be
//      unmarshaled, and a pointer to the size of the output area.
//
//      No error checking is performed, unmarshaled data is guaranteed not to
//      spill over the allocated space.
//
static TPM_RC NvUnmarshalObject(OBJECT *o, BYTE **buf, INT32 *size)
{
    TPM_RC result;

    // There is no generated function to unmarshal the attributes field, do it
    // by hand.
    MemoryCopy(&o->attributes, *buf, sizeof(o->attributes), *size);
    *buf += sizeof(o->attributes);
    *size -= sizeof(o->attributes);

    result = TPMT_PUBLIC_Unmarshal(&o->publicArea, buf, size);
    if (result != TPM_RC_SUCCESS)
        return result;

    result = TPMT_SENSITIVE_Unmarshal(&o->sensitive, buf, size);
    if (result != TPM_RC_SUCCESS)
        return result;

#ifdef TPM_ALG_RSA
    result = TPM2B_PUBLIC_KEY_RSA_Unmarshal(&o->privateExponent, buf, size);
    if (result != TPM_RC_SUCCESS)
        return result;
#endif

    result = TPM2B_NAME_Unmarshal(&o->qualifiedName, buf, size);
    if (result != TPM_RC_SUCCESS)
        return result;

    result = TPMI_DH_OBJECT_Unmarshal(&o->evictHandle, buf, size, TRUE);
    if (result != TPM_RC_SUCCESS)
        return result;

    return TPM2B_NAME_Unmarshal(&o->name, buf, size);
}

//
//
//           NvGetEvictObject()
//
//      This function is used to dereference an evict object handle and get a pointer to the object.
//
//      Error Returns                     Meaning
//
//      TPM_RC_HANDLE                     the handle does not point to an existing persistent object
//
TPM_RC
NvGetEvictObject(
    TPM_HANDLE           handle,              // IN: handle
    OBJECT              *object               // OUT: object data
    )
{
    UINT32              entityAddr;         // offset points to the entity
    TPM_RC              result = TPM_RC_SUCCESS;
    pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
    // Find the address of evict object
    entityAddr = NvFindHandle(handle);
    // If handle is not found, return an error
    if(entityAddr == 0) {
        result = TPM_RC_HANDLE;
    } else {
        UINT32   storedSize;
        UINT32   nextEntryAddr;

        // Let's calculate the size of object as stored in NVMEM.
        _plat__NvMemoryRead(entityAddr - sizeof(UINT32),
                            sizeof(UINT32), &nextEntryAddr);

        storedSize = nextEntryAddr - entityAddr;

        if (storedSize == (sizeof(TPM_HANDLE) + sizeof(OBJECT))) {
            // Read evict object stored unmarshaled.
            _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE),
                                sizeof(OBJECT),
                                object);
        } else {
            // Must be stored marshaled, let's unmarshal it.
            BYTE marshaled[sizeof(OBJECT)];
            INT32 max_size = sizeof(marshaled);
            BYTE *marshaledPtr = marshaled;

            _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE),
                                storedSize, marshaled);
            result = NvUnmarshalObject(object,  &marshaledPtr, &max_size);
        }
    }
    // whether there is an error or not, make sure that the evict
    // status of the object is set so that the slot will get freed on exit
    object->attributes.evict = SET;
    return result;
}
//
//
//           NvGetIndexInfo()
//
//      This function is used to retrieve the contents of an NV Index.
//      An implementation is allowed to save the NV Index in a vendor-defined format. If the format is different
//      from the default used by the reference code, then this function would be changed to reformat the data into
//      the default format.
//      A prerequisite to calling this function is that the handle must be known to reference a defined NV Index.
//
void
NvGetIndexInfo(
    TPMI_RH_NV_INDEX          handle,              // IN: handle
    NV_INDEX                 *nvIndex              // OUT: NV index structure
    )
{
    NvReadIndexInfo(handle, 0, nvIndex);
    return;
}
//
//
//           NvReadIndexInfo()
//
//      This function is used to retrieve the contents of an NV Index from the
//      given address.
//      A prerequisite to calling this function is that either handle or
//      entityAddr must be valid value. If entityAddr is non-zero, then it will
//      be regarded as a valid address of NV data. If it is zero, then "handle"
//      shall be used to find its address.
//
void
NvReadIndexInfo(
    TPMI_RH_NV_INDEX          handle,             // IN: handle
    UINT32                    entityAddr,         // IN: Base address of NV data
    NV_INDEX                 *nvIndex             // OUT: NV index structure
    )
{
    if (!entityAddr) {
        pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
        // Find the address of NV index
        entityAddr = NvFindHandle(handle);
    }

    pAssert(entityAddr != 0);
    // This implementation uses the default format so just
    // read the data in
    _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
                        nvIndex);
    return;
}
//
//
//           NvInitialCounter()
//
//      This function returns the value to be used when a counter index is initialized. It will scan the NV counters
//      and find the highest value in any active counter. It will use that value as the starting point. If there are no
//      active counters, it will use the value of the previous largest counter.
//
UINT64
NvInitialCounter(
    void
    )
{
    UINT64              maxCount;
    NV_ITER             iter = NV_ITER_INIT;
    UINT32              currentAddr;
    // Read the maxCount value
    maxCount = NvReadMaxCount();
    // Iterate all existing counters
    while((currentAddr = NvNextIndex(&iter)) != 0)
    {
        TPMI_RH_NV_INDEX    nvHandle;
        NV_INDEX            nvIndex;
         // Read NV handle
         _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle);
         // Get NV Index
         NvGetIndexInfo(nvHandle, &nvIndex);
         if(    nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET
             && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
         {
             UINT64      countValue;
             // Read counter value
             NvGetIntIndexData(nvHandle, &nvIndex, &countValue);
             if(countValue > maxCount)
                 maxCount = countValue;
         }
    }
    // Initialize the new counter value to be maxCount + 1
    // A counter is only initialized the first time it is written. The
    // way to write a counter is with TPM2_NV_INCREMENT(). Since the
    // "initial" value of a defined counter is the largest count value that
    // may have existed in this index previously, then the first use would
    // add one to that value.
    return maxCount;
}
//
//
//           NvGetIndexData()
//
//      This function is used to access the data in an NV Index. The data is returned as a byte sequence. Since
//      counter values are kept in native format, they are converted to canonical form before being returned.
//      Family "2.0"                                  TCG Published                                         Page 139
//      Level 00 Revision 01.16               Copyright © TCG 2006-2014                            October 30, 2014
//      Trusted Platform Module Library                                                Part 4: Supporting Routines
//
//
//      This function requires that the NV Index be defined, and that the required data is within the data range. It
//      also requires that TPMA_NV_WRITTEN of the Index is SET.
//
void
NvGetIndexData(
    TPMI_RH_NV_INDEX          handle,            //   IN: handle
    NV_INDEX                 *nvIndex,           //   IN: RAM image of index header
    UINT32                    offset,            //   IN: offset of NV data
    UINT16                    size,              //   IN: size of NV data
    void                     *data               //   OUT: data buffer
    )
{
    NvReadIndexData(handle, nvIndex, 0, offset, size, data);
}
//
//
//           NvReadIndexData()
//
// This function is used to read the data in an NV Index from the given address.
// This function requires that the NV Index be defined, and that the required
// data is within the data range. It also requires that TPMA_NV_WRITTEN of the
//  Index is SET.
// entityAddr is optional. If the value is zero, then it will be retrieved
// by calling NvFindHandle() in this function.
//
void
NvReadIndexData(
    TPMI_RH_NV_INDEX       handle,            //   IN: handle
    NV_INDEX              *nvIndex,           //   IN: RAM image of index header
    UINT32                 entityAddr,        //   IN: Base address of NV data
    UINT32                 offset,            //   IN: offset of NV data
    UINT16                 size,              //   IN: size of NV data
    void                  *data               //   OUT: data buffer
    )
{
    pAssert(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET);
    if(   nvIndex->publicArea.attributes.TPMA_NV_BITS == SET
       || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET)
    {
        // Read bit or counter data in canonical form
        UINT64      dataInInt;
        NvGetIntIndexData(handle, nvIndex, &dataInInt);
        UINT64_TO_BYTE_ARRAY(dataInInt, (BYTE *)data);
    }
    else
    {
        if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
        {
            UINT32      ramAddr;
            // Get data from RAM buffer
            ramAddr = NvGetRAMIndexOffset(handle);
            MemoryCopy(data, s_ramIndex + ramAddr + offset, size, size);
        }
        else
        {
            if (!entityAddr)
                entityAddr = NvFindHandle(handle);
            pAssert(entityAddr != 0);
            // Get data from NV
            // Skip NV Index info, read data buffer
            entityAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset;
            // Read the data
            _plat__NvMemoryRead(entityAddr, size, data);
        }
    }
    return;
}
//
//
//           NvGetIntIndexData()
//
//      Get data in integer format of a bit or counter NV Index.
//      This function requires that the NV Index is defined and that the NV Index previously has been written.
//
void
NvGetIntIndexData(
    TPMI_RH_NV_INDEX          handle,            // IN: handle
    NV_INDEX                 *nvIndex,           // IN: RAM image of NV Index header
    UINT64                   *data               // IN: UINT64 pointer for counter or bit
    )
{
    // Validate that index has been written and is the right type
    pAssert(   nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET
            && (   nvIndex->publicArea.attributes.TPMA_NV_BITS == SET
                || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET
                   )
              );
    // bit and counter value is store in native format for TPM CPU.                  So we directly
    // copy the contents of NV to output data buffer
    if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
    {
        UINT32      ramAddr;
          // Get data from RAM buffer
          ramAddr = NvGetRAMIndexOffset(handle);
          MemoryCopy(data, s_ramIndex + ramAddr, sizeof(*data), sizeof(*data));
    }
    else
    {
        UINT32      entityAddr;
        entityAddr = NvFindHandle(handle);
          // Get data from NV
          // Skip NV Index info, read data buffer
          _plat__NvMemoryRead(
              entityAddr + sizeof(TPM_HANDLE) + sizeof(NV_INDEX),
              sizeof(UINT64), data);
    }
    return;
}
//
//
//           NvWriteIndexInfo()
//
//       This function is called to queue the write of NV Index data to persistent memory.
//       This function requires that NV Index is defined.
//
//       Error Returns                        Meaning
//
//       TPM_RC_NV_RATE                       NV is rate limiting so retry
//       TPM_RC_NV_UNAVAILABLE                NV is not available
//
TPM_RC
NvWriteIndexInfo(
    TPMI_RH_NV_INDEX            handle,                // IN: handle
    NV_INDEX                   *nvIndex                // IN: NV Index info to be written
    )
{
    UINT32             entryAddr;
    TPM_RC             result;
    // Get the starting offset for the index in the RAM image of NV
    entryAddr = NvFindHandle(handle);
    pAssert(entryAddr != 0);
    // Step over the link value
    entryAddr = entryAddr + sizeof(TPM_HANDLE);
    // If the index data is actually changed, then a write to NV is required
    if(_plat__NvIsDifferent(entryAddr, sizeof(NV_INDEX),nvIndex))
    {
        // Make sure that NV is available
        result = NvIsAvailable();
        if(result != TPM_RC_SUCCESS)
            return result;
        _plat__NvMemoryWrite(entryAddr, sizeof(NV_INDEX), nvIndex);
        g_updateNV = TRUE;
    }
    return TPM_RC_SUCCESS;
}
//
//
//            NvWriteIndexData()
//
//       This function is used to write NV index data.
//       This function requires that the NV Index is defined, and the data is within the defined data range for the
//       index.
//
//       Error Returns                     Meaning
//
//       TPM_RC_NV_RATE                    NV is rate limiting so retry
//       TPM_RC_NV_UNAVAILABLE             NV is not available
//
TPM_RC
NvWriteIndexData(
    TPMI_RH_NV_INDEX          handle,               //   IN: handle
    NV_INDEX                 *nvIndex,              //   IN: RAM copy of NV Index
    UINT32                    offset,               //   IN: offset of NV data
    UINT32                    size,                 //   IN: size of NV data
    void                     *data                  //   OUT: data buffer
    )
{
    TPM_RC               result;
    // Validate that write falls within range of the index
    pAssert(nvIndex->publicArea.dataSize >= offset + size);
    // Update TPMA_NV_WRITTEN bit if necessary
    if(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
    {
        nvIndex->publicArea.attributes.TPMA_NV_WRITTEN = SET;
        result = NvWriteIndexInfo(handle, nvIndex);
        if(result != TPM_RC_SUCCESS)
            return result;
    }
    // Check to see if process for an orderly index is required.
    if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
    {
        UINT32      ramAddr;
          // Write data to RAM buffer
          ramAddr = NvGetRAMIndexOffset(handle);
          MemoryCopy(s_ramIndex + ramAddr + offset, data, size,
                     sizeof(s_ramIndex) - ramAddr - offset);
          // NV update does not happen for orderly index. Have
          // to clear orderlyState to reflect that we have changed the
          // NV and an orderly shutdown is required. Only going to do this if we
          // are not processing a counter that has just rolled over
          if(g_updateNV == FALSE)
              g_clearOrderly = TRUE;
    }
    // Need to process this part if the Index isn't orderly or if it is
    // an orderly counter that just rolled over.
    if(g_updateNV || nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == CLEAR)
    {
        // Processing for an index with TPMA_NV_ORDERLY CLEAR
        UINT32      entryAddr = NvFindHandle(handle);
          pAssert(entryAddr != 0);
//
          // Offset into the index to the first byte of the data to be written
          entryAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset;
          // If the data is actually changed, then a write to NV is required
          if(_plat__NvIsDifferent(entryAddr, size, data))
          {
              // Make sure that NV is available
              result = NvIsAvailable();
              if(result != TPM_RC_SUCCESS)
                  return result;
              _plat__NvMemoryWrite(entryAddr, size, data);
              g_updateNV = TRUE;
          }
    }
    return TPM_RC_SUCCESS;
}
//
//
//            NvGetName()
//
//       This function is used to compute the Name of an NV Index.
//       The name buffer receives the bytes of the Name and the return value is the number of octets in the
//       Name.
//       This function requires that the NV Index is defined.
//
UINT16
NvGetName(
    TPMI_RH_NV_INDEX          handle,            // IN: handle of the index
    NAME                     *name               // OUT: name of the index
    )
{
    UINT16                    dataSize, digestSize;
    NV_INDEX                  nvIndex;
    BYTE                      marshalBuffer[sizeof(TPMS_NV_PUBLIC)];
    BYTE                     *buffer;
    INT32                     bufferSize;
    HASH_STATE                hashState;
    // Get NV public info
    NvGetIndexInfo(handle, &nvIndex);
    // Marshal public area
    buffer = marshalBuffer;
    bufferSize = sizeof(TPMS_NV_PUBLIC);
    dataSize = TPMS_NV_PUBLIC_Marshal(&nvIndex.publicArea, &buffer, &bufferSize);
    // hash public area
    digestSize = CryptStartHash(nvIndex.publicArea.nameAlg, &hashState);
    CryptUpdateDigest(&hashState, dataSize, marshalBuffer);
    // Complete digest leaving room for the nameAlg
    CryptCompleteHash(&hashState, digestSize, &((BYTE *)name)[2]);
    // Include the nameAlg
    UINT16_TO_BYTE_ARRAY(nvIndex.publicArea.nameAlg, (BYTE *)name);
    return digestSize + 2;
}
//
//
//            NvDefineIndex()
//
//       This function is used to assign NV memory to an NV Index.
//
//
//
//       Error Returns                     Meaning
//
//       TPM_RC_NV_SPACE                   insufficient NV space
//
TPM_RC
NvDefineIndex(
   TPMS_NV_PUBLIC      *publicArea,          // IN: A template for an area to create.
   TPM2B_AUTH          *authValue            // IN: The initial authorization value
   )
{
   // The buffer to be written to NV memory
   BYTE            nvBuffer[sizeof(TPM_HANDLE) + sizeof(NV_INDEX)];
   NV_INDEX            *nvIndex;                  // a pointer to the NV_INDEX data in
                                                  //   nvBuffer
   UINT16              entrySize;                 // size of entry
   entrySize = sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + publicArea->dataSize;
   // Check if we have enough space to create the NV Index
   // In this implementation, the only resource limitation is the available NV
   // space. Other implementation may have other limitation on counter or on
   // NV slot
   if(!NvTestSpace(entrySize, TRUE)) return TPM_RC_NV_SPACE;
   // if the index to be defined is RAM backed, check RAM space availability
   // as well
   if(publicArea->attributes.TPMA_NV_ORDERLY == SET
           && !NvTestRAMSpace(publicArea->dataSize))
       return TPM_RC_NV_SPACE;
   // Copy input value to nvBuffer
       // Copy handle
   memcpy(nvBuffer, &publicArea->nvIndex, sizeof(TPM_HANDLE));
       // Copy NV_INDEX
   nvIndex = (NV_INDEX *) (nvBuffer + sizeof(TPM_HANDLE));
   nvIndex->publicArea = *publicArea;
   nvIndex->authValue = *authValue;
   // Add index to NV memory
   NvAdd(entrySize, sizeof(TPM_HANDLE) + sizeof(NV_INDEX), nvBuffer);
   // If the data of NV Index is RAM backed, add the data area in RAM as well
   if(publicArea->attributes.TPMA_NV_ORDERLY == SET)
       NvAddRAM(publicArea->nvIndex, publicArea->dataSize);
   return TPM_RC_SUCCESS;
}

//
//
//           NvMarshalObject()
//
//      This function marshals the passed in OBJECT structure into a buffer. A
//      pointer to pointer to the buffer and a pointer to the size of the
//      buffer are passed in for this function to update as appropriate.
//
//      On top of marshaling the object, this function also modifies one of
//      the object's properties and sets the evictHandle field of the
//      marshaled object to the requested value.
//
//      Returns
//
//      Marshaled size of the object.
//
static UINT16 NvMarshalObject(OBJECT *o, TPMI_DH_OBJECT evictHandle,
                              BYTE **buf, INT32 *size)
{
    UINT16 marshaledSize;
    OBJECT_ATTRIBUTES stored_attributes;

    stored_attributes = o->attributes;
    stored_attributes.evict = SET;
    marshaledSize = sizeof(stored_attributes);
    MemoryCopy(*buf, &stored_attributes, marshaledSize, *size);
    *buf += marshaledSize;
    *size -= marshaledSize;

    marshaledSize += TPMT_PUBLIC_Marshal(&o->publicArea, buf, size);
    marshaledSize += TPMT_SENSITIVE_Marshal(&o->sensitive, buf, size);
#ifdef TPM_ALG_RSA
    marshaledSize += TPM2B_PUBLIC_KEY_RSA_Marshal(&o->privateExponent,
                                                  buf, size);
#endif
    marshaledSize += TPM2B_NAME_Marshal(&o->qualifiedName, buf, size);

    // Use the supplied handle instead of the object contents.
    marshaledSize += TPMI_DH_OBJECT_Marshal(&evictHandle, buf, size);
    marshaledSize += TPM2B_NAME_Marshal(&o->name, buf, size);

    return marshaledSize;
}

//
//
//           NvAddEvictObject()
//
//       This function is used to assign NV memory to a persistent object.
//
//       Error Returns                     Meaning
//
//       TPM_RC_NV_HANDLE                  the requested handle is already in use
//       TPM_RC_NV_SPACE                   insufficient NV space
//
TPM_RC
NvAddEvictObject(
   TPMI_DH_OBJECT       evictHandle,         // IN: new evict handle
//
    OBJECT              *object              // IN: object to be added
    )
{
    // The buffer to be written to NV memory
    BYTE            nvBuffer[sizeof(TPM_HANDLE) + sizeof(OBJECT)];
    UINT16              entrySize;                // size of entry
    BYTE                *marshalSpace;
    INT32               marshalRoom;

    // evict handle type should match the object hierarchy
    pAssert(   (   NvIsPlatformPersistentHandle(evictHandle)
                && object->attributes.ppsHierarchy == SET)
            || (   NvIsOwnerPersistentHandle(evictHandle)
                && (   object->attributes.spsHierarchy == SET
                    || object->attributes.epsHierarchy == SET)));

    // Do not attemp storing a duplicate handle.
    if(!NvIsUndefinedEvictHandle(evictHandle))
        return TPM_RC_NV_DEFINED;

        // Copy handle
    entrySize = sizeof(TPM_HANDLE);
    memcpy(nvBuffer, &evictHandle, entrySize);

    // Let's serialize the object before storing it in NVMEM
    marshalSpace = nvBuffer + entrySize;
    marshalRoom = sizeof(nvBuffer) - entrySize;
    entrySize += NvMarshalObject(object, evictHandle,
                                 &marshalSpace, &marshalRoom);

    // Check if we have enough space to add this evict object
    if(!NvTestSpace(entrySize, FALSE)) return TPM_RC_NV_SPACE;

    // Add evict to NV memory
    NvAdd(entrySize, entrySize, nvBuffer);
    return TPM_RC_SUCCESS;
}
//
//
//           NvDeleteEntity()
//
//       This function will delete a NV Index or an evict object.
//       This function requires that the index/evict object has been defined.
//
void
NvDeleteEntity(
    TPM_HANDLE           handle              // IN: handle of entity to be deleted
    )
{
    UINT32         entityAddr;         // pointer to entity

    // Deleting virtual NV indexes is not supported.
    if(_plat__NvGetHandleVirtualOffset(handle) != 0)
    {
        return;
    }

    entityAddr = NvFindHandle(handle);
    pAssert(entityAddr != 0);
    if(HandleGetType(handle) == TPM_HT_NV_INDEX)
    {
        NV_INDEX    nvIndex;
          // Read the NV Index info
          _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
                              &nvIndex);
          // If the entity to be deleted is a counter with the maximum counter
          // value, record it in NV memory
          if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET
                  && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
          {
              UINT64      countValue;
              UINT64      maxCount;
              NvGetIntIndexData(handle, &nvIndex, &countValue);
              maxCount = NvReadMaxCount();
              if(countValue > maxCount)
                  NvWriteMaxCount(countValue);
          }
          // If the NV Index is RAM back, delete the RAM data as well
          if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET)
              NvDeleteRAM(handle);
    }
    NvDelete(entityAddr);
    return;
}
//
//
//            NvFlushHierarchy()
//
//       This function will delete persistent objects belonging to the indicated If the storage hierarchy is selected,
//       the function will also delete any NV Index define using ownerAuth.
//
void
NvFlushHierarchy(
    TPMI_RH_HIERARCHY         hierarchy          // IN: hierarchy to be flushed.
    )
{
    NV_ITER             iter = NV_ITER_INIT;
    UINT32              currentAddr;
    while((currentAddr = NvNext(&iter)) != 0)
    {
        TPM_HANDLE      entityHandle;
          // Read handle information.
          _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
          if(HandleGetType(entityHandle) == TPM_HT_NV_INDEX)
          {
              // Handle NV Index
              NV_INDEX    nvIndex;
              // If flush endorsement or platform hierarchy, no NV Index would be
              // flushed
              if(hierarchy == TPM_RH_ENDORSEMENT || hierarchy == TPM_RH_PLATFORM)
                  continue;
              _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
                                  sizeof(NV_INDEX), &nvIndex);
              // For storage hierarchy, flush OwnerCreated index
               if(    nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR)
               {
                     if(_plat__ShallSurviveOwnerClear(nvIndex.publicArea.nvIndex))
                         continue;
                     // Delete the NV Index
                     NvDelete(currentAddr);
                     // Re-iterate from beginning after a delete
                     iter = NV_ITER_INIT;
                     // If the NV Index is RAM back, delete the RAM data as well
                     if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET)
                         NvDeleteRAM(entityHandle);
              }
          }
          else if(HandleGetType(entityHandle) == TPM_HT_PERSISTENT)
          {
              OBJECT          object;
               // Get evict object
               NvGetEvictObject(entityHandle, &object);
               // If the evict object belongs to the hierarchy to be flushed
               if(     (    hierarchy == TPM_RH_PLATFORM
                        && object.attributes.ppsHierarchy == SET)
                   || (     hierarchy == TPM_RH_OWNER
                        && object.attributes.spsHierarchy == SET)
                   || (     hierarchy == TPM_RH_ENDORSEMENT
                        && object.attributes.epsHierarchy == SET)
                   )
               {
                     // Delete the evict object
                     NvDelete(currentAddr);
                     // Re-iterate from beginning after a delete
                     iter = NV_ITER_INIT;
               }
          }
          else
          {
               pAssert(FALSE);
          }
   }
   return;
}
//
//
//              NvSetGlobalLock()
//
//       This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indices that have
//       TPMA_NV_GLOBALLOCK SET. This function is use by TPM2_NV_GlobalWriteLock().
//
void
NvSetGlobalLock(
   void
   )
{
   NV_ITER               iter = NV_ITER_INIT;
   UINT32                currentAddr;
   // Check all Indices
   while((currentAddr = NvNextIndex(&iter)) != 0)
   {
       NV_INDEX    nvIndex;
          // Read the index data
          _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
                              sizeof(NV_INDEX), &nvIndex);
          // See if it should be locked
          if(nvIndex.publicArea.attributes.TPMA_NV_GLOBALLOCK == SET)
          {
                // if so, lock it
                nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED = SET;
                _plat__NvMemoryWrite(currentAddr + sizeof(TPM_HANDLE),
                                     sizeof(NV_INDEX), &nvIndex);
                // Set the flag that a NV write happens
                g_updateNV = TRUE;
          }
   }
   return;
}
//
//
//              InsertSort()
//
//       Sort a handle into handle list in ascending order. The total handle number in the list should not exceed
//       MAX_CAP_HANDLES
//
static void
InsertSort(
   TPML_HANDLE           *handleList,     // IN/OUT: sorted handle list
   UINT32                 count,          // IN: maximum count in the handle list
   TPM_HANDLE             entityHandle    // IN: handle to be inserted
   )
{
   UINT32                i, j;
   UINT32                originalCount;
   // For a corner case that the maximum count is 0, do nothing
   if(count == 0) return;
   // For empty list, add the handle at the beginning and return
   if(handleList->count == 0)
   {
       handleList->handle[0] = entityHandle;
       handleList->count++;
       return;
   }
   // Check if the maximum of the list has been reached
   originalCount = handleList->count;
   if(originalCount < count)
       handleList->count++;
   // Insert the handle to the list
   for(i = 0; i < originalCount; i++)
   {
       if(handleList->handle[i] > entityHandle)
       {
           for(j = handleList->count - 1; j > i; j--)
           {
               handleList->handle[j] = handleList->handle[j-1];
           }
           break;
       }
   }
     // If a slot was found, insert the handle in this position
     if(i < originalCount || handleList->count > originalCount)
         handleList->handle[i] = entityHandle;
     return;
}
//
//
//            NvCapGetPersistent()
//
//       This function is used to get a list of handles of the persistent objects, starting at handle.
//       Handle must be in valid persistent object handle range, but does not have to reference an existing
//       persistent object.
//
//       Return Value                      Meaning
//
//       YES                               if there are more handles available
//       NO                                all the available handles has been returned
//
TPMI_YES_NO
NvCapGetPersistent(
     TPMI_DH_OBJECT       handle,            // IN: start handle
     UINT32               count,             // IN: maximum number of returned handle
     TPML_HANDLE         *handleList         // OUT: list of handle
     )
{
     TPMI_YES_NO               more = NO;
     NV_ITER                   iter = NV_ITER_INIT;
     UINT32                    currentAddr;
     pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
     // Initialize output handle list
     handleList->count = 0;
     // The maximum count of handles we may return is MAX_CAP_HANDLES
     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
     while((currentAddr = NvNextEvict(&iter)) != 0)
     {
         TPM_HANDLE      entityHandle;
          // Read handle information.
          _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
          // Ignore persistent handles that have values less than the input handle
          if(entityHandle < handle)
              continue;
          // if the handles in the list have reached the requested count, and there
          // are still handles need to be inserted, indicate that there are more.
          if(handleList->count == count)
              more = YES;
          // A handle with a value larger than start handle is a candidate
          // for return. Insert sort it to the return list. Insert sort algorithm
          // is chosen here for simplicity based on the assumption that the total
          // number of NV Indices is small. For an implementation that may allow
          // large number of NV Indices, a more efficient sorting algorithm may be
          // used here.
          InsertSort(handleList, count, entityHandle);
//
     }
     return more;
}
//
//
//            NvCapGetIndex()
//
//       This function returns a list of handles of NV Indices, starting from handle. Handle must be in the range of
//       NV Indices, but does not have to reference an existing NV Index.
//
//       Return Value                      Meaning
//
//       YES                               if there are more handles to report
//       NO                                all the available handles has been reported
//
TPMI_YES_NO
NvCapGetIndex(
     TPMI_DH_OBJECT     handle,              // IN: start handle
     UINT32             count,               // IN: maximum number of returned handle
     TPML_HANDLE       *handleList           // OUT: list of handle
     )
{
     TPMI_YES_NO             more = NO;
     NV_ITER                 iter = NV_ITER_INIT;
     UINT32                  currentAddr;
     pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
     // Initialize output handle list
     handleList->count = 0;
     // The maximum count of handles we may return is MAX_CAP_HANDLES
     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
     while((currentAddr = NvNextIndex(&iter)) != 0)
     {
         TPM_HANDLE      entityHandle;
          // Read handle information.
          _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
          // Ignore index handles that have values less than the 'handle'
          if(entityHandle < handle)
              continue;
          // if the count of handles in the list has reached the requested count,
          // and there are still handles to report, set more.
          if(handleList->count == count)
              more = YES;
          // A handle with a value larger than start handle is a candidate
          // for return. Insert sort it to the return list. Insert sort algorithm
          // is chosen here for simplicity based on the assumption that the total
          // number of NV Indices is small. For an implementation that may allow
          // large number of NV Indices, a more efficient sorting algorithm may be
          // used here.
          InsertSort(handleList, count, entityHandle);
     }
     return more;
}
//
//
//
//           NvCapGetIndexNumber()
//
//       This function returns the count of NV Indexes currently defined.
//
UINT32
NvCapGetIndexNumber(
   void
   )
{
   UINT32              num = 0;
   NV_ITER             iter = NV_ITER_INIT;
   while(NvNextIndex(&iter) != 0) num++;
   return num;
}
//
//
//           NvCapGetPersistentNumber()
//
//       Function returns the count of persistent objects currently in NV memory.
//
UINT32
NvCapGetPersistentNumber(
   void
   )
{
   UINT32              num = 0;
   NV_ITER             iter = NV_ITER_INIT;
   while(NvNextEvict(&iter) != 0) num++;
   return num;
}
//
//
//           NvCapGetPersistentAvail()
//
//       This function returns an estimate of the number of additional persistent objects that could be loaded into
//       NV memory.
//
UINT32
NvCapGetPersistentAvail(
   void
   )
{
   UINT32              availSpace;
   UINT32              objectSpace;
   // Compute the available space in NV storage
   availSpace = NvGetFreeByte();
   // Get the space needed to add a persistent object to NV storage
   objectSpace = NvGetEvictObjectSize();
   return availSpace / objectSpace;
}
//
//
//           NvCapGetCounterNumber()
//
//       Get the number of defined NV Indexes that have NV TPMA_NV_COUNTER attribute SET.
//
//
UINT32
NvCapGetCounterNumber(
   void
   )
{
   NV_ITER             iter = NV_ITER_INIT;
   UINT32              currentAddr;
   UINT32              num = 0;
   while((currentAddr = NvNextIndex(&iter)) != 0)
   {
       NV_INDEX    nvIndex;
          // Get NV Index info
          _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
                               sizeof(NV_INDEX), &nvIndex);
          if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET) num++;
   }
   return num;
}
//
//
//            NvCapGetCounterAvail()
//
//       This function returns an estimate of the number of additional counter type NV Indices that can be defined.
//
UINT32
NvCapGetCounterAvail(
   void
   )
{
   UINT32              availNVSpace;
   UINT32              availRAMSpace;
   UINT32              counterNVSpace;
   UINT32              counterRAMSpace;
   UINT32              persistentNum = NvCapGetPersistentNumber();
   // Get the available space in NV storage
   availNVSpace = NvGetFreeByte();
   if (persistentNum < MIN_EVICT_OBJECTS)
   {
       // Some space have to be reserved for evict object. Adjust availNVSpace.
       UINT32       reserved = (MIN_EVICT_OBJECTS - persistentNum)
                              * NvGetEvictObjectSize();
       if (reserved > availNVSpace)
            availNVSpace = 0;
       else
            availNVSpace -= reserved;
   }
   // Get the space needed to add a counter index to NV storage
   counterNVSpace = NvGetCounterSize();
   // Compute the available space in RAM
   availRAMSpace = RAM_INDEX_SPACE - s_ramIndexSize;
   // Compute the space needed to add a counter index to RAM storage
   // It takes an size field, a handle and sizeof(UINT64) for counter data
   counterRAMSpace = sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(UINT64);
   // Return the min of counter number in NV and in RAM
   if(availNVSpace / counterNVSpace > availRAMSpace / counterRAMSpace)
       return availRAMSpace / counterRAMSpace;
     else
         return availNVSpace / counterNVSpace;
}

//
// NvEarlyStageFindHandle
//
// This function checks if a certain handle is present in NVMEM, even before
// TPM_Startup was invoked.
//
// To facilitate NVMEM lookip this function initializes static variables if
// they are not yet initialized.
//
// Returns Non-zero if handle was found. The value is the offset in NV memory of
//         the entity associated with the input handle.
//         Zero if handle does not exist.

//
UINT32
NvEarlyStageFindHandle(
   TPM_HANDLE handle
   )

{
   if (!s_evictNvEnd)
      NvInitStatic();

   return NvFindHandle(handle);
}
//
//           NvIsDefinedHiddenObject()
//
//      This function indicates if a handle references an existing
//      hidden object.
//
//      Return Value                     Meaning
//
//      TRUE                             handle references an
//                                       existing hidden object
//      FALSE                            handle does not reference an
//                                       existing hidden object
//
BOOL
NvIsDefinedHiddenObject(
   TPM_HANDLE            handle             // IN: handle
   )
{
   return HandleGetType(handle) == TPM_HT_HIDDEN &&
       NvFindHandle(handle) != 0;
}
//
//
//           NvAddHiddenObject()
//
//       This function is used to assign NV memory to a new hidden object.
//
//       Error Returns                     Meaning
//
//       TPM_RC_NV_HANDLE                  the requested handle is already in use
//       TPM_RC_NV_SPACE                   insufficient NV space
//
TPM_RC
NvAddHiddenObject(
    TPM_HANDLE       handle,         // IN: new handle
    UINT16           object_size,
    void             *object         // IN: data to be stored
    )
{
    // The buffer to be written to NV memory
    BYTE            nvBuffer[sizeof(TPM_HANDLE) + object_size];
    BYTE            *buf = nvBuffer;

    if (HandleGetType(handle) != TPM_HT_HIDDEN)
        return TPM_RC_HANDLE;

    // Do not attemp storing a duplicate handle.
    if(NvIsDefinedHiddenObject(handle))
        return TPM_RC_NV_DEFINED;

    // Check if we have enough space to add this hidden object
    if(!NvTestSpace(sizeof(nvBuffer), FALSE))
        return TPM_RC_NV_SPACE;

    memcpy(buf, &handle, sizeof(TPM_HANDLE));
    buf += sizeof(TPM_HANDLE);

    memcpy(buf, object, object_size);

    NvAdd(sizeof(nvBuffer), sizeof(nvBuffer), nvBuffer);

    return TPM_RC_SUCCESS;
}

//
//
//           NvGetHiddenObjectAddrSize()
//
//      This function returns address (internal to nvmem) and size of
//      hidden object. It requires the index to be defined.
//
//       Error Returns                     Meaning
//
//       TPM_RC_HANDLE                  the requested handle could not be found
//       TPM_RC_TYPE                    handle is not a hidden object
static TPM_RC NvGetHiddenObjectAddrSize(
    TPM_HANDLE          handle,            //   IN: handle
    UINT32             *addr,              //   OUT: address of entity
    UINT16             *size               //   OUT: size of entity
    )
{
  UINT32      entityAddr;
  NV_ITER     iter;

  if (HandleGetType(handle) != TPM_HT_HIDDEN)
    return TPM_RC_TYPE;

  entityAddr = NvFindHandle(handle);
  if (entityAddr == 0)
    return TPM_RC_HANDLE;

  iter = entityAddr - sizeof(NV_ITER);

  // This will return the same address we already have in NvFindHandle,
  // (we discard this return value), and advance iter to point to the
  // start of next item in the list (its next pointer).
  NvNext(&iter);
  // Calculate size of this entity using position of next item.
  *size =
      iter                   // Points to beginning of next entry.
      - entityAddr           // Points to beginning of current item.
      - sizeof(TPM_HANDLE);  // Current item includes a handle.

  *addr = entityAddr;
  return TPM_RC_SUCCESS;
}

//
//
//           NvWriteHiddenObject()
//
//       This function is used to write new data to an existing hidden object.
//
//       Error Returns                     Meaning
//
//       TPM_RC_HANDLE                  the requested handle could not be found
//       TPM_RC_NV_SPACE                   size does not match NV space
//
TPM_RC NvWriteHiddenObject(TPM_HANDLE handle,  // IN: new evict handle
                           UINT16 size,
                           void *object        // IN: object to be added
                           ) {
   UINT32           entityAddr;    // offset points to the entity
   UINT16           entitySize;    // recorded size of the entity
   TPM_RC           rc;

   rc = NvGetHiddenObjectAddrSize(handle, &entityAddr, &entitySize);
   if (TPM_RC_SUCCESS != rc)
     return rc;
   if (size != entitySize) {
     return TPM_RC_NV_SPACE;
   }
   _plat__NvMemoryWrite(entityAddr + sizeof(TPM_HANDLE),
                       size, object);
   g_updateNV = TRUE;
   return TPM_RC_SUCCESS;
}
//
//
//           NvGetHiddenObject()
//
//      This function is used to access data stored as a hidden object.
//
//      This function requires that the index be defined, and that the
//      required data is within the data range.
//
//       Error Returns                     Meaning
//
//       TPM_RC_HANDLE                  the requested handle could not be found
TPM_RC
NvGetHiddenObject(
    TPM_HANDLE          handle,            //   IN: handle
    UINT16              size,              //   IN: size of NV data
    void                *data              //   OUT: data buffer
    )
{
  UINT32      entityAddr;
  UINT16      entitySize;
  TPM_RC           rc;

  rc = NvGetHiddenObjectAddrSize(handle, &entityAddr, &entitySize);
  if (TPM_RC_SUCCESS != rc)
    return rc;

  if (size > entitySize) {
    return TPM_RC_NV_SPACE;
  }

  _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), size, data);
  return TPM_RC_SUCCESS;
}
//
//
//           NvGetHiddenObjectSize()
//
//      This function is used to get size of data stored as a hidden object.
//
//      This function requires that the index be defined.
//
//       Error Returns                     Meaning
//
//       TPM_RC_HANDLE                  the requested handle could not be found
TPM_RC
NvGetHiddenObjectSize(
    TPM_HANDLE          handle,            //   IN: handle
    UINT16              *size              //   OUT: size of NV data
    )
{
  UINT32      entityAddr;

  return NvGetHiddenObjectAddrSize(handle, &entityAddr, size);
}
//
// NVWipeCache
//
// A function to call to wipe out SRAM cache of NVMEM. Most evictable objects'
// contents get overwritten with some random data. The passed in two element
// array communicates an inclusive range of NV indexes to preserve during
// wipeout.
//
void NvSelectivelyInvalidateCache(const UINT16 *keep_range)
{
   UINT32              addr;
   NV_ITER             iter = NV_ITER_INIT;
   TPMI_RH_NV_INDEX    bottom = NV_INDEX_FIRST + keep_range[0];
   TPMI_RH_NV_INDEX    top = NV_INDEX_FIRST + keep_range[1];

   if (!s_evictNvEnd)
       return; /* Cache not initialized, nothing to do here. */

   while((addr = NvNext(&iter)) != 0)
   {
       TPM_HANDLE entityHandle;
       size_t     space;

       /*
        * Read the object's handle. Note that TPMI_RH_NV_INDEX is a handle of
        * a certain type, the same size as TPM_HANDLE.
        */
       _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &entityHandle);

       /* Skip it if it is in the range to preserve. */
       if((entityHandle >= bottom) && (entityHandle <= top))
           continue;

       /*
        * Determine the space the object takes in the cache less the handle
        * size. Note that at this point 'iter' points at the location right
        * above the current object.
        */
       space = iter - addr - sizeof(TPMI_RH_NV_INDEX);

       /* Overwrite the cache space with junk data coped from text segment. */
       _plat__NvMemoryWrite(addr + sizeof(TPMI_RH_NV_INDEX), space,
                            NvCapGetCounterAvail);
    }
}

/*
 * A helper function which allows the caller to find out NVMEM cache offset
 * and size of all reserved objects AND of the RAM index space AND of the
 * maxCount value. The last two items are technically not reserved objects,
 * but are always present in the NVMEM cache and need to be preserved in
 * non-volatile storage.
 *
 * From the caller's perspective these two items are considered reserved
 * objects at indices NV_RAM_INDEX_SPACE and NV_MAX_COUNTER.
 */
void NvGetReserved(UINT32 index, NV_RESERVED_ITEM *ri)
{
  UINT32 indexSize;

  if (index < NV_RESERVE_LAST) {
    ri->size = s_reservedSize[index];
    ri->offset = s_reservedAddr[index];
    return;
  }

  switch (index) {
  case NV_RAM_INDEX_SPACE:
    /*
     * This is a request for the RAM index space, which is a concatenation of
     * the 4 byte size field and the actual RAM index contents field. For the
     * purposes of this function both fields are considered as single space
     * with the size equal 4 + the value stored at s_ramIndexSize.
     */
    _plat__NvMemoryRead(s_ramIndexSizeAddr, sizeof(UINT32), &indexSize);
    if (indexSize == ~0)
      indexSize = 0; /* Must be starting with empty flash memeory. */
    ri->offset = s_ramIndexSizeAddr;
    ri->size = indexSize + sizeof(indexSize);
    return;

  case NV_MAX_COUNTER:
    ri->size = sizeof(UINT64);
    ri->offset = s_maxCountAddr;
    return;
  }

  ri->size = 0;
}

