15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 4: Supporting Routines
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#define NV_C
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h"
106c73a9e66b59c69893bc28fef90e6d34ab06385eVadim Bendebury#include "Platform.h"
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NV Index/evict object iterator value
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
145679752bf24c21135884e987c4077e2f7184897Vadim Bendeburytypedef        UINT32              NV_ITER;              // type of a NV iterator
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#define        NV_ITER_INIT        0xFFFFFFFF            // initial value to start an
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                        // iterator
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NV Utility Functions
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvCheckState()
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Function to check the NV state by accessing the platform-specific function to get the NV state. The result
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     state is registered in s_NvIsAvailable that will be reported by NvIsAvailable().
255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function is called at the beginning of ExecuteCommand() before any potential call to NvIsAvailable().
265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
275679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
285679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCheckState(void)
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    int        func_return;
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    func_return = _plat__IsNvAvailable();
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(func_return == 0)
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        s_NvStatus = TPM_RC_SUCCESS;
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else if(func_return == 1)
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        s_NvStatus = TPM_RC_NV_UNAVAILABLE;
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        s_NvStatus = TPM_RC_NV_RATE;
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvIsAvailable()
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function returns the NV availability parameter.
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Error Returns                     Meaning
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SUCCESS                    NV is available
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_RATE                    NV is unavailable because of rate limit
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_UNAVAILABLE             NV is inaccessible
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
585679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
595679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvIsAvailable(
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return s_NvStatus;
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvCommit
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This is a wrapper for the platform function to commit pending NV writes.
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
715679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCommit(
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BOOL    success = (_plat__NvCommit() == 0);
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return success;
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvReadMaxCount()
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function returns the max NV counter value.
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
855679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT64
865679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvReadMaxCount(
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT64      countValue;
915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryRead(s_maxCountAddr, sizeof(UINT64), &countValue);
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return countValue;
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvWriteMaxCount()
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function updates the max counter value to NV memory.
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
1015679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvWriteMaxCount(
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT64               maxCount
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &maxCount);
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NV Index and Persistent Object Access Functions
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          Introduction
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     These functions are used to access an NV Index and persistent object memory. In this implementation,
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     the memory is simulated with RAM. The data in dynamic area is organized as a linked list, starting from
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     address s_evictNvStart. The first 4 bytes of a node in this link list is the offset of next node, followed by
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     the data entry. A 0-valued offset value indicates the end of the list. If the data entry area of the last node
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     happens to reach the end of the dynamic area without space left for an additional 4 byte end marker, the
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     end address, s_evictNvEnd, should serve as the mark of list end
1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvNext()
1225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     This function provides a method to traverse every data entry in NV dynamic area.
1245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     To begin with, parameter iter should be initialized to NV_ITER_INIT indicating the first element. Every
1255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     time this function is called, the value in iter would be adjusted pointing to the next element in traversal. If
1265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     there is no next element, iter value would be 0. This function returns the address of the 'data entry'
1275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     pointed by the iter. If there is no more element in the set, a 0 value is returned indicating the end of
1285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     traversal.
1295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1305679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
1315679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvNext(
1325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_ITER             *iter
1335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER        currentIter;
1365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If iterator is at the beginning of list
1375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(*iter == NV_ITER_INIT)
1385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Initialize iterator
1405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       *iter = s_evictNvStart;
1415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
1425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If iterator reaches the end of NV space, or iterator indicates list end
1435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(*iter + sizeof(UINT32) > s_evictNvEnd || *iter == 0)
1445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return 0;
1455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Save the current iter offset
1465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   currentIter = *iter;
1475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Adjust iter pointer pointing to next entity
1485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Read pointer value
1495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryRead(*iter, sizeof(UINT32), iter);
1505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(*iter == 0) return 0;
1515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return currentIter + sizeof(UINT32);                // entity stores after the pointer
1525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetEnd()
1565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Function to find the end of the NV dynamic data list
1585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1595679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
1605679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetEnd(
1615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
1625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
1635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             iter = NV_ITER_INIT;
1655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              endAddr = s_evictNvStart;
1665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              currentAddr;
1675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while((currentAddr = NvNext(&iter)) != 0)
1685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       endAddr = currentAddr;
1695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(endAddr != s_evictNvStart)
1705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
1715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Read offset
1725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       endAddr -= sizeof(UINT32);
1735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       _plat__NvMemoryRead(endAddr, sizeof(UINT32), &endAddr);
1745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
1755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return endAddr;
1765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetFreeByte
1805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the number of free octets in NV space.
1825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1835679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
1845679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetFreeByte(
1855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
1865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
1875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
1885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return s_evictNvEnd - NvGetEnd();
1895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetEvictObjectSize
1925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the size of an evict object in NV space
1945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
1955679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
1965679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetEvictObjectSize(
1975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
1985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
1995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return sizeof(TPM_HANDLE) + sizeof(OBJECT) + sizeof(UINT32);
2015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetCounterSize
2055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the size of a counter index in NV space.
2075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2085679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
2095679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetCounterSize(
2105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
2115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // It takes an offset field, a handle and the sizeof(NV_INDEX) and
2145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // sizeof(UINT64) for counter data
2155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + sizeof(UINT64) + sizeof(UINT32);
2165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvTestSpace()
2205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function will test if there is enough space to add a new entity.
2225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
2245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                              space available
2265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                             no enough space
2275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2285679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL
2295679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvTestSpace(
2305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32               size,               // IN: size of the entity to be added
2315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BOOL                 isIndex             // IN: TRUE if the entity is an index
2325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
2335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32         remainByte = NvGetFreeByte();
2355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // For NV Index, need to make sure that we do not allocate and Index if this
2365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // would mean that the TPM cannot allocate the minimum number of evict
2375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // objects.
2385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(isIndex)
2395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
2405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Get the number of persistent objects allocated
2415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT32      persistentNum = NvCapGetPersistentNumber();
2425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // If we have not allocated the requisite number of evict objects, then we
2435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // need to reserve space for them.
2445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // NOTE: some of this is not written as simply as it might seem because
2455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // the values are all unsigned and subtracting needs to be done carefully
2465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // so that an underflow doesn't cause problems.
2475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(persistentNum < MIN_EVICT_OBJECTS)
2485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
2495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             UINT32      needed = (MIN_EVICT_OBJECTS - persistentNum)
2505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                 * NvGetEvictObjectSize();
2515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(needed > remainByte)
2525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 remainByte = 0;
2535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             else
2545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 remainByte -= needed;
2555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
2565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // if the requisite number of evict objects have been allocated then
2575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // no need to reserve additional space
2585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
2595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // This checks for the size of the value being added plus the index value.
2605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // NOTE: This does not check to see if the end marker can be placed in
2615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // memory because the end marker will not be written if it will not fit.
2625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return (size + sizeof(UINT32) <= remainByte);
2635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
2645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvAdd()
2675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function adds a new entity to NV.
2695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that there is enough space to add a new entity (i.e., that NvTestSpace() has been
2705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      called and the available space is at least as large as the required space).
2715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
2725679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
2735679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvAdd(
2745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                totalSize,       // IN: total size needed for this        entity For
2755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          //     evict object, totalSize is        the same as
2765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          //     bufferSize. For NV Index,         totalSize is
2775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                          //     bufferSize plus index data        size
2785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                bufferSize,      // IN: size of initial buffer
2795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE                 *entity           // IN: initial buffer
2805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
2815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
2825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               endAddr;
2835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               nextAddr;
2845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32               listEnd = 0;
2855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get the end of data list
2865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   endAddr = NvGetEnd();
2875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Calculate the value of next pointer, which is the size of a pointer +
2885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the entity data size
2895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nextAddr = endAddr + sizeof(UINT32) + totalSize;
2905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Write next pointer
2915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(endAddr, sizeof(UINT32), &nextAddr);
2925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Write entity data
2935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(endAddr + sizeof(UINT32), bufferSize, entity);
2945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Write the end of list if it is not going to exceed the NV space
2955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(nextAddr + sizeof(UINT32) <= s_evictNvEnd)
2965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       _plat__NvMemoryWrite(nextAddr, sizeof(UINT32), &listEnd);
2975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set the flag so that NV changes are committed before the command completes.
2985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   g_updateNV = TRUE;
2995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvDelete()
3035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to delete an NV Index or persistent object from NV memory.
3055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3065679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
3075679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvDelete(
3085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                entityAddr       // IN: address of entity to be deleted
3095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              next;
3125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              entrySize;
3135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              entryAddr = entityAddr - sizeof(UINT32);
3145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              listEnd = 0;
3155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get the offset of the next entry.
3165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryRead(entryAddr, sizeof(UINT32), &next);
3175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The size of this entry is the difference between the current entry and the
3185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // next entry.
3195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   entrySize = next - entryAddr;
3205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //    Move each entry after the current one to fill the freed space.
3215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //    Stop when we have reached the end of all the indexes. There are two
3225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //    ways to detect the end of the list. The first is to notice that there
3235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //    is no room for anything else because we are at the end of NV. The other
3245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   //    indication is that we find an end marker.
3255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The loop condition checks for the end of NV.
3265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(next + sizeof(UINT32) <= s_evictNvEnd)
3275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       UINT32      size, oldAddr, newAddr;
3295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Now check for the end marker
3305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         _plat__NvMemoryRead(next, sizeof(UINT32), &oldAddr);
3315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(oldAddr == 0)
3325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             break;
3335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         size = oldAddr - next;
3345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Move entry
3355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         _plat__NvMemoryMove(next, next - entrySize, size);
3365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Update forward link
3375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         newAddr = oldAddr - entrySize;
3385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &newAddr);
3395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         next = oldAddr;
3405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
3415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Mark the end of list
3425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(next - entrySize, sizeof(UINT32), &listEnd);
3435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set the flag so that NV changes are committed before the command completes.
3445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   g_updateNV = TRUE;
3455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           RAM-based NV Index Data Access Functions
3495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           Introduction
3515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The data layout in ram buffer is {size of(NV_handle() + data), NV_handle(), data} for each NV Index data
3535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      stored in RAM.
3545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      NV storage is updated when a NV Index is added or deleted. We do NOT updated NV storage when the
3555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      data is updated/
3565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvTestRAMSpace()
3585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function indicates if there is enough RAM space to add a data for a new NV Index.
3605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
3655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                              space available
3675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                             no enough space
3685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3695679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL
3705679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvTestRAMSpace(
3715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                size                // IN: size of the data to be added to RAM
3725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BOOL           success = (       s_ramIndexSize
3755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  + size
3765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  + sizeof(TPM_HANDLE) + sizeof(UINT32)
3775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  <= RAM_INDEX_SPACE);
3785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return success;
3795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
3805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetRamIndexOffset
3835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the offset of NV data in the RAM buffer
3855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that NV Index is in RAM. That is, the index must be known to exist.
3865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
3875679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
3885679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetRAMIndexOffset(
3895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_RH_NV_INDEX           handle               // IN: NV handle
3905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
3915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
3925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32         currAddr = 0;
3935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(currAddr < s_ramIndexSize)
3945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
3955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TPMI_RH_NV_INDEX    currHandle;
3965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       UINT32              currSize;
39771e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr       memcpy(&currHandle, &s_ramIndex[currAddr + sizeof(UINT32)],
39871e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr              sizeof(currHandle));
3995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Found a match
4005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(currHandle == handle)
4015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // data buffer follows the handle and size field
4025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              break;
40371e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr         memcpy(&currSize, &s_ramIndex[currAddr], sizeof(currSize));
4045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         currAddr += sizeof(UINT32) + currSize;
4055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
4065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // We assume the index data is existing in RAM space
4075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(currAddr < s_ramIndexSize);
4085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return currAddr + sizeof(TPMI_RH_NV_INDEX) + sizeof(UINT32);
4095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvAddRAM()
4135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function adds a new data area to RAM.
4155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that enough free RAM space is available to add the new data.
4165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4175679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
4185679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvAddRAM(
4195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_RH_NV_INDEX           handle,              // IN: NV handle
4205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                     size                 // IN: size of data
4215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Add data space at the end of reserved RAM buffer
42471e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr   UINT32 value = size + sizeof(TPMI_RH_NV_INDEX);
42571e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr   memcpy(&s_ramIndex[s_ramIndexSize], &value,
42671e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr          sizeof(s_ramIndex[s_ramIndexSize]));
42771e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr   memcpy(&s_ramIndex[s_ramIndexSize + sizeof(UINT32)], &handle,
42871e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr          sizeof(s_ramIndex[s_ramIndexSize + sizeof(UINT32)]));
4295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_ramIndexSize += sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX) + size;
4305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(s_ramIndexSize <= RAM_INDEX_SPACE);
4315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Update NV version of s_ramIndexSize
4325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
4335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Write reserved RAM space to NV to reflect the newly added NV Index
4345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
4355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
4365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvDeleteRAM()
4405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to delete a RAM-backed NV Index data area.
4425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function assumes the data of NV Index exists in RAM
4435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4445679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
4455679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvDeleteRAM(
4465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_RH_NV_INDEX          handle           // IN: NV handle
4475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
4485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             nodeOffset;
4505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             nextNode;
4515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             size;
4525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nodeOffset = NvGetRAMIndexOffset(handle);
4535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Move the pointer back to get the size field of this node
4545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nodeOffset -= sizeof(UINT32) + sizeof(TPMI_RH_NV_INDEX);
4555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get node size
45671e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr   memcpy(&size, &s_ramIndex[nodeOffset], sizeof(size));
4575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get the offset of next node
4585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nextNode = nodeOffset + sizeof(UINT32) + size;
4595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Move data
4605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   MemoryMove(s_ramIndex + nodeOffset, s_ramIndex + nextNode,
4615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              s_ramIndexSize - nextNode, s_ramIndexSize - nextNode);
4625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Update RAM size
4635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   s_ramIndexSize -= size + sizeof(UINT32);
4645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Update NV version of s_ramIndexSize
4655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
4665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Write reserved RAM space to NV to reflect the newly delete NV Index
4675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
4685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
4695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
4705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           Utility Functions
4745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvInitStatic()
4765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function initializes the static variables used in the NV subsystem.
4785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
4795679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
4805679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvInitStatic(
4815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
4825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
4835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
4845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16         i;
4855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32         reservedAddr;
4865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_DISABLE_CLEAR] = sizeof(gp.disableClear);
4875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_OWNER_ALG] = sizeof(gp.ownerAlg);
4885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_ENDORSEMENT_ALG] = sizeof(gp.endorsementAlg);
4895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_LOCKOUT_ALG] = sizeof(gp.lockoutAlg);
4905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_OWNER_POLICY] = sizeof(gp.ownerPolicy);
4915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_ENDORSEMENT_POLICY] = sizeof(gp.endorsementPolicy);
4925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_LOCKOUT_POLICY] = sizeof(gp.lockoutPolicy);
4935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_OWNER_AUTH] = sizeof(gp.ownerAuth);
4945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_ENDORSEMENT_AUTH] = sizeof(gp.endorsementAuth);
4955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_LOCKOUT_AUTH] = sizeof(gp.lockoutAuth);
4965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_EP_SEED] = sizeof(gp.EPSeed);
4975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_SP_SEED] = sizeof(gp.SPSeed);
4985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_PP_SEED] = sizeof(gp.PPSeed);
4995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_PH_PROOF] = sizeof(gp.phProof);
5005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_SH_PROOF] = sizeof(gp.shProof);
5015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_EH_PROOF] = sizeof(gp.ehProof);
5025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_TOTAL_RESET_COUNT] = sizeof(gp.totalResetCount);
5035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_RESET_COUNT] = sizeof(gp.resetCount);
5045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_PCR_POLICIES] = sizeof(gp.pcrPolicies);
5055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_PCR_ALLOCATED] = sizeof(gp.pcrAllocated);
5065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_PP_LIST] = sizeof(gp.ppList);
5075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_FAILED_TRIES] = sizeof(gp.failedTries);
5085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_MAX_TRIES] = sizeof(gp.maxTries);
5095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_RECOVERY_TIME] = sizeof(gp.recoveryTime);
5105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_LOCKOUT_RECOVERY] = sizeof(gp.lockoutRecovery);
5115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_LOCKOUT_AUTH_ENABLED] = sizeof(gp.lockOutAuthEnabled);
5125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_ORDERLY] = sizeof(gp.orderlyState);
5135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_AUDIT_COMMANDS] = sizeof(gp.auditComands);
5145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_AUDIT_HASH_ALG] = sizeof(gp.auditHashAlg);
5155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_AUDIT_COUNTER] = sizeof(gp.auditCounter);
5165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_ALGORITHM_SET] = sizeof(gp.algorithmSet);
5175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_FIRMWARE_V1] = sizeof(gp.firmwareV1);
5185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_FIRMWARE_V2] = sizeof(gp.firmwareV2);
5195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_ORDERLY_DATA] = sizeof(go);
5205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_STATE_CLEAR] = sizeof(gc);
5215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_reservedSize[NV_STATE_RESET] = sizeof(gr);
5225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize reserved data address. In this implementation, reserved data
5235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // is stored at the start of NV memory
5245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    reservedAddr = 0;
5255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    for(i = 0; i < NV_RESERVE_LAST; i++)
5265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
5275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        s_reservedAddr[i] = reservedAddr;
5285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        reservedAddr += s_reservedSize[i];
5295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
5305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize auxiliary variable space for index/evict implementation.
5315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Auxiliary variables are stored after reserved data area
5325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // RAM index copy starts at the beginning
5335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_ramIndexSizeAddr = reservedAddr;
5345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_ramIndexAddr = s_ramIndexSizeAddr + sizeof(UINT32);
5355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Maximum counter value
5365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_maxCountAddr = s_ramIndexAddr + RAM_INDEX_SPACE;
5375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // dynamic memory start
5385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_evictNvStart = s_maxCountAddr + sizeof(UINT64);
5395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // dynamic memory ends at the end of NV memory
5405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    s_evictNvEnd = NV_MEMORY_SIZE;
5415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
5425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvInit()
5465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function initializes the NV system at pre-install time.
5485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function should only be called in a manufacturing environment or in a simulation.
5495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      The layout of NV memory space is an implementation choice.
5505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5515679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
5525679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvInit(
5535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
5545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
5555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32         nullPointer = 0;
5575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT64         zeroCounter = 0;
5585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize static variables
5595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvInitStatic();
5605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize RAM index space as unused
5615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryWrite(s_ramIndexSizeAddr, sizeof(UINT32), &nullPointer);
5625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize max counter value to 0
5635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryWrite(s_maxCountAddr, sizeof(UINT64), &zeroCounter);
5645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize the next offset of the first entry in evict/index list to 0
5655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryWrite(s_evictNvStart, sizeof(TPM_HANDLE), &nullPointer);
5665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
5675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvReadReserved()
5715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to move reserved data from NV memory to RAM.
5735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5745679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
5755679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvReadReserved(
5765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_RESERVE           type,               // IN: type of reserved data
5775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                *buffer              // OUT: buffer receives the data.
5785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
5795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Input type should be valid
5815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(type >= 0 && type < NV_RESERVE_LAST);
5825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryRead(s_reservedAddr[type], s_reservedSize[type], buffer);
5835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
5845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
5855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvWriteReserved()
5885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to post a reserved data for writing to NV memory. Before the TPM completes the
5905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      operation, the value will be written.
5915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
5925679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
5935679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvWriteReserved(
5945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_RESERVE           type,              // IN: type of reserved data
5955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void                *buffer             // IN: data buffer
5965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
5975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
5985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Input type should be valid
5995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(type >= 0 && type < NV_RESERVE_LAST);
6005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryWrite(s_reservedAddr[type], s_reservedSize[type], buffer);
6015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Set the flag that a NV write happens
6025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   g_updateNV = TRUE;
6035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
6045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvReadPersistent()
6085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function reads persistent data to the RAM copy of the gp structure.
6105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6115679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
6125679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvReadPersistent(
6135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
6145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
6155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Hierarchy persistent data
6175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_DISABLE_CLEAR, &gp.disableClear);
6185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_OWNER_ALG, &gp.ownerAlg);
6195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_ENDORSEMENT_ALG, &gp.endorsementAlg);
6205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_LOCKOUT_ALG, &gp.lockoutAlg);
6215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_OWNER_POLICY, &gp.ownerPolicy);
6225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_ENDORSEMENT_POLICY, &gp.endorsementPolicy);
6235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_LOCKOUT_POLICY, &gp.lockoutPolicy);
6245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_OWNER_AUTH, &gp.ownerAuth);
6255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_ENDORSEMENT_AUTH, &gp.endorsementAuth);
6265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_LOCKOUT_AUTH, &gp.lockoutAuth);
6275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_EP_SEED, &gp.EPSeed);
6285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_SP_SEED, &gp.SPSeed);
6295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_PP_SEED, &gp.PPSeed);
6305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_PH_PROOF, &gp.phProof);
6315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_SH_PROOF, &gp.shProof);
6325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_EH_PROOF, &gp.ehProof);
6335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Time persistent data
6345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_TOTAL_RESET_COUNT, &gp.totalResetCount);
6355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_RESET_COUNT, &gp.resetCount);
6365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // PCR persistent data
6375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_PCR_POLICIES, &gp.pcrPolicies);
6385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_PCR_ALLOCATED, &gp.pcrAllocated);
6395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Physical Presence persistent data
6405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_PP_LIST, &gp.ppList);
6415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Dictionary attack values persistent data
6425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_FAILED_TRIES, &gp.failedTries);
6435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_MAX_TRIES, &gp.maxTries);
6445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvReadReserved(NV_RECOVERY_TIME, &gp.recoveryTime);
6455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_LOCKOUT_RECOVERY, &gp.lockoutRecovery);
6475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_LOCKOUT_AUTH_ENABLED, &gp.lockOutAuthEnabled);
6485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Orderly State persistent data
6495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_ORDERLY, &gp.orderlyState);
6505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Command audit values persistent data
6515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_AUDIT_COMMANDS, &gp.auditComands);
6525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_AUDIT_HASH_ALG, &gp.auditHashAlg);
6535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_AUDIT_COUNTER, &gp.auditCounter);
6545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Algorithm selection persistent data
6555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_ALGORITHM_SET, &gp.algorithmSet);
6565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Firmware version persistent data
6575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_FIRMWARE_V1, &gp.firmwareV1);
6585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvReadReserved(NV_FIRMWARE_V2, &gp.firmwareV2);
6595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
6605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvIsPlatformPersistentHandle()
6645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function indicates if a handle references a persistent object in the range belonging to the platform.
6665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
6685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                              handle references a platform persistent object
6705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                             handle does not reference platform persistent object and may
6715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        reference an owner persistent object either
6725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6735679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
6745679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvIsPlatformPersistentHandle(
6755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE           handle              // IN: handle
6765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
6775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return (handle >= PLATFORM_PERSISTENT && handle <= PERSISTENT_LAST);
6795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvIsOwnerPersistentHandle()
6835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function indicates if a handle references a persistent object in the range belonging to the owner.
6855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
6875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                              handle is owner persistent handle
6895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                             handle is not owner persistent handle and may not be a persistent
6905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        handle at all
6915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
6925679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
6935679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvIsOwnerPersistentHandle(
6945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE           handle              // IN: handle
6955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
6965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
6975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return (handle >= PERSISTENT_FIRST && handle < PLATFORM_PERSISTENT);
6985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
6995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvNextIndex()
7025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the offset in NV of the next NV Index entry. A value of 0 indicates the end of the list.
7045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Family "2.0"                                   TCG Published                                          Page 131
7055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Level 00 Revision 01.16               Copyright © TCG 2006-2014                            October 30, 2014
7065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Trusted Platform Module Library                                                Part 4: Supporting Routines
7075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7085679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
7095679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvNextIndex(
7105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             *iter
7115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
7125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32         addr;
7145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE     handle;
7155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while((addr = NvNext(iter)) != 0)
7165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
7175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Read handle
7185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle);
7195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(HandleGetType(handle) == TPM_HT_NV_INDEX)
7205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return addr;
7215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
7225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(addr == 0);
7235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return addr;
7245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvNextEvict()
7285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the offset in NV of the next evict object entry. A value of 0 indicates the end of the
7305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      list.
7315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7325679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
7335679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvNextEvict(
7345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             *iter
7355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
7365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32         addr;
7385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE     handle;
7395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while((addr = NvNext(iter)) != 0)
7405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
7415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Read handle
7425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &handle);
7435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(HandleGetType(handle) == TPM_HT_PERSISTENT)
7445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return addr;
7455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
7465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(addr == 0);
7475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return addr;
7485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvFindHandle()
7525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      this function returns the offset in NV memory of the entity associated with the input handle. A value of
7545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      zero indicates that handle does not exist reference an existing persistent object or defined NV Index.
7555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7565679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic UINT32
7575679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvFindHandle(
7585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE            handle
7595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
7605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              addr;
7625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             iter = NV_ITER_INIT;
7635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while((addr = NvNext(&iter)) != 0)
7645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
7655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       TPM_HANDLE          entityHandle;
7665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Read handle
7675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(addr, sizeof(TPM_HANDLE), &entityHandle);
7695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(entityHandle == handle)
7705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              return addr;
7715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
7725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(addr == 0);
7735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return addr;
7745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
7755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvPowerOn()
7785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called at _TPM_Init() to initialize the NV environment.
7805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
7825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                              all NV was initialized
7845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                             the NV     containing saved     state    had   an   error   and
7855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        TPM2_Startup(CLEAR) is required
7865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
7875679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
7885679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvPowerOn(
7895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
7905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
7915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
7925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    int          nvError = 0;
7935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // If power was lost, need to re-establish the RAM data that is loaded from
7945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // NV and initialize the static variables
7955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(_plat__WasPowerLost(TRUE))
7965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
7975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if((nvError = _plat__NVEnable(0)) < 0)
7985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            FAIL(FATAL_ERROR_NV_UNRECOVERABLE);
7995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          NvInitStatic();
8005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
8015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return nvError == 0;
8025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvStateSave()
8065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to cause the memory containing the RAM backed NV Indices to be written to NV.
8085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8095679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
8105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvStateSave(
8115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
8125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
8135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Write RAM backed NV Index info to NV
8155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // No need to save s_ramIndexSize because we save it to NV whenever it is
8165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // updated.
8175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryWrite(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
8185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Set the flag so that an NV write happens before the command completes.
8195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    g_updateNV = TRUE;
8205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
8215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
8225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvEntityStartup()
8265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is called at TPM_Startup(). If the startup completes a TPM Resume cycle, no action is
8285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      taken. If the startup is a TPM Reset or a TPM Restart, then this function will:
8295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      a) clear read/write lock;
8305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      b) reset NV Index data that has TPMA_NV_CLEAR_STCLEAR SET; and
8315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      c) set the lower bits in orderly counters to 1 for a non-orderly startup
8325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      It is a prerequisite that NV be available for writing before this function is called.
8335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
8345679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
8355679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvEntityStartup(
8365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    STARTUP_TYPE           type               // IN: start up type
8375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
8385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
8395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_ITER                   iter = NV_ITER_INIT;
8405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                    currentAddr;         // offset points to the current entity
8415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Restore RAM index data
8425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryRead(s_ramIndexSizeAddr, sizeof(UINT32), &s_ramIndexSize);
8435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryRead(s_ramIndexAddr, RAM_INDEX_SPACE, s_ramIndex);
8445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // If recovering from state save, do nothing
8455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(type == SU_RESUME)
8465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        return;
8475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Iterate all the NV Index to clear the locks
8485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    while((currentAddr = NvNextIndex(&iter)) != 0)
8495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
8505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        NV_INDEX    nvIndex;
8515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT32      indexAddr;              // NV address points to index info
8525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        TPMA_NV     attributes;
85371e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr        UINT32      attributesValue;
85471e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr        UINT32      publicAreaAttributesValue;
8555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          indexAddr = currentAddr + sizeof(TPM_HANDLE);
8565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Read NV Index info structure
8575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(indexAddr, sizeof(NV_INDEX), &nvIndex);
8585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          attributes = nvIndex.publicArea.attributes;
8595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Clear read/write lock
8605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(attributes.TPMA_NV_READLOCKED == SET)
8615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              attributes.TPMA_NV_READLOCKED = CLEAR;
8625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(         attributes.TPMA_NV_WRITELOCKED == SET
8635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 &&   (   attributes.TPMA_NV_WRITTEN == CLEAR
8645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      || attributes.TPMA_NV_WRITEDEFINE == CLEAR
8655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                      )
8665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                )
8675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 attributes.TPMA_NV_WRITELOCKED = CLEAR;
8685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Reset NV data for TPMA_NV_CLEAR_STCLEAR
8695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(attributes.TPMA_NV_CLEAR_STCLEAR == SET)
8705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
8715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              attributes.TPMA_NV_WRITTEN = CLEAR;
8725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              attributes.TPMA_NV_WRITELOCKED = CLEAR;
8735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
8745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Reset NV data for orderly values that are not counters
8755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // NOTE: The function has already exited on a TPM Resume, so the only
8765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // things being processed are TPM Restart and TPM Reset
8775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(     type == SU_RESET
8785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              && attributes.TPMA_NV_ORDERLY == SET
8795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              && attributes.TPMA_NV_COUNTER == CLEAR
8805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             )
8815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 attributes.TPMA_NV_WRITTEN = CLEAR;
8825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Write NV Index info back if it has changed
88371e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr         memcpy(&attributesValue, &attributes, sizeof(attributesValue));
88471e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr         memcpy(&publicAreaAttributesValue, &nvIndex.publicArea.attributes,
88571e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr                sizeof(publicAreaAttributesValue));
88671e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr         if(attributesValue != publicAreaAttributesValue)
8875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
8885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             nvIndex.publicArea.attributes = attributes;
8895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             _plat__NvMemoryWrite(indexAddr, sizeof(NV_INDEX), &nvIndex);
8905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 // Set the flag that a NV write happens
8915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 g_updateNV = TRUE;
8925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
8935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Set the lower bits in an orderly counter to 1 for a non-orderly startup
8945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(    g_prevOrderlyState == SHUTDOWN_NONE
8955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             && attributes.TPMA_NV_WRITTEN == SET)
8965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
8975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              if(    attributes.TPMA_NV_ORDERLY == SET
8985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  && attributes.TPMA_NV_COUNTER == SET)
8995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              {
9005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   TPMI_RH_NV_INDEX    nvHandle;
9015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   UINT64              counter;
9025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Read NV handle
9035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle);
9045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Read the counter value saved to NV upon the last roll over.
9055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Do not use RAM backed storage for this once.
9065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = CLEAR;
9075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     NvGetIntIndexData(nvHandle, &nvIndex, &counter);
9085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     nvIndex.publicArea.attributes.TPMA_NV_ORDERLY = SET;
9095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Set the lower bits of counter to 1's
9105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     counter |= MAX_ORDERLY_COUNT;
9115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Write back to RAM
9125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     NvWriteIndexData(nvHandle, &nvIndex, 0, sizeof(counter), &counter);
9135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // No write to NV because an orderly shutdown will update the
9145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // counters.
9155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 }
9165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
9175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
9185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
9195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
9205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NV Access Functions
9235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//             Introduction
9255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This set of functions provide accessing NV Index and persistent objects based using a handle for
9275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      reference to the entity.
9285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//             NvIsUndefinedIndex()
9305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to verify that an NV Index is not defined. This is only used by
9325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM2_NV_DefineSpace().
9335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                      Meaning
9385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                              the handle points to an existing NV Index
9405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                             the handle points to a non-existent Index
9415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9425679752bf24c21135884e987c4077e2f7184897Vadim BendeburyBOOL
9435679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvIsUndefinedIndex(
9445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_RH_NV_INDEX         handle                 // IN: handle
9455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
9465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
9475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32             entityAddr;                  // offset points to the entity
9485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
9495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Find the address of index
9505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   entityAddr = NvFindHandle(handle);
9515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If handle is not found, return TPM_RC_SUCCESS
9525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(entityAddr == 0)
9535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SUCCESS;
9545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // NV Index is defined
9555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_NV_DEFINED;
9565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
9575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//          NvIndexIsAccessible()
9605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function validates that a handle references a defined NV Index and that the Index is currently
9625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      accessible.
9635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                     Meaning
9655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_HANDLE                     the handle points to an undefined NV Index If shEnable is CLEAR,
9675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        this would include an index created using ownerAuth. If phEnableNV
9685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        is CLEAR, this would include and index created using platform auth
9695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_NV_READLOCKED              Index is present but locked for reading and command does not write
9705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        to the index
9715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_NV_WRITELOCKED             Index is present but locked for writing and command writes to the
9725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                        index
9735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
9745679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
9755679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvIndexIsAccessible(
9765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_RH_NV_INDEX         handle,                // IN: handle
9775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_CC                   commandCode            // IN: the command
9785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
9795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
9805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                  entityAddr;             // offset points to the entity
9815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_INDEX                nvIndex;                //
9825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
9835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Find the address of index
9845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   entityAddr = NvFindHandle(handle);
9855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If handle is not found, return TPM_RC_HANDLE
9865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(entityAddr == 0)
9875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_HANDLE;
9885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Read NV Index info structure
9895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
9905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                           &nvIndex);
9915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(gc.shEnable == FALSE || gc.phEnableNV == FALSE)
9925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
9935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // if shEnable is CLEAR, an ownerCreate NV Index should not be
9945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // indicated as present
9955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR)
9965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
9975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           if(gc.shEnable == FALSE)
9985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               return TPM_RC_HANDLE;
9995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
10005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // if phEnableNV is CLEAR, a platform created Index should not
10015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // be visible
10025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       else if(gc.phEnableNV == FALSE)
10035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_HANDLE;
10045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
10055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the Index is write locked and this is an NV Write operation...
10065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(     nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED
10075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       && IsWriteOperation(commandCode))
10085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
10095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // then return a locked indication unless the command is TPM2_NV_WriteLock
10105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(commandCode != TPM_CC_NV_WriteLock)
10115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_NV_LOCKED;
10125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SUCCESS;
10135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
10145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the Index is read locked and this is an NV Read operation...
10155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(     nvIndex.publicArea.attributes.TPMA_NV_READLOCKED
10165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       && IsReadOperation(commandCode))
10175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
10185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // then return a locked indication unless the command is TPM2_NV_ReadLock
10195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(commandCode != TPM_CC_NV_ReadLock)
10205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return TPM_RC_NV_LOCKED;
10215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_SUCCESS;
10225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
10235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // NV Index is accessible
10245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
10255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
10265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvIsUndefinedEvictHandle()
10295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function indicates if a handle does not reference an existing persistent object. This function requires
10315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      that the handle be in the proper range for persistent objects.
10325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Return Value                     Meaning
10345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TRUE                             handle does not reference an existing persistent object
10365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      FALSE                            handle does reference an existing persistent object
10375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10385679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic BOOL
10395679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvIsUndefinedEvictHandle(
10405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE            handle             // IN: handle
10415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
10425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
10435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32           entityAddr;    // offset points to the entity
10445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
10455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Find the address of evict object
10465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   entityAddr = NvFindHandle(handle);
10475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If handle is not found, return TRUE
10485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(entityAddr == 0)
10495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TRUE;
10505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
10515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        return FALSE;
10525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
10535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetEvictObject()
10565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to dereference an evict object handle and get a pointer to the object.
10585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Error Returns                     Meaning
10605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      TPM_RC_HANDLE                     the handle does not point to an existing persistent object
10625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10635679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
10645679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetEvictObject(
10655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE           handle,              // IN: handle
10665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    OBJECT              *object               // OUT: object data
10675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
10685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
10695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32              entityAddr;         // offset points to the entity
10705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_RC              result = TPM_RC_SUCCESS;
10715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
10725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Find the address of evict object
10735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    entityAddr = NvFindHandle(handle);
10745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // If handle is not found, return an error
10755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(entityAddr == 0)
10765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        result = TPM_RC_HANDLE;
10775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
10785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Read evict object
10795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE),
10805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             sizeof(OBJECT),
10815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                             object);
10825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // whether there is an error or not, make sure that the evict
10835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // status of the object is set so that the slot will get freed on exit
10845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    object->attributes.evict = SET;
10855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return result;
10865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
10875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetIndexInfo()
10905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to retrieve the contents of an NV Index.
10925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      An implementation is allowed to save the NV Index in a vendor-defined format. If the format is different
10935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      from the default used by the reference code, then this function would be changed to reformat the data into
10945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      the default format.
10955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      A prerequisite to calling this function is that the handle must be known to reference a defined NV Index.
10965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
10975679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
10985679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetIndexInfo(
10995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_NV_INDEX          handle,              // IN: handle
11005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_INDEX                 *nvIndex              // OUT: NV index structure
11015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
11025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
11035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                    entityAddr;          // offset points to the entity
11045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
11055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Find the address of NV index
11065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    entityAddr = NvFindHandle(handle);
11075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(entityAddr != 0);
11085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // This implementation uses the default format so just
11095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // read the data in
11105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
11115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        nvIndex);
11125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
11135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
11145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvInitialCounter()
11175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function returns the value to be used when a counter index is initialized. It will scan the NV counters
11195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      and find the highest value in any active counter. It will use that value as the starting point. If there are no
11205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      active counters, it will use the value of the previous largest counter.
11215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11225679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT64
11235679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvInitialCounter(
11245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void
11255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
11265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
11275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT64              maxCount;
11285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_ITER             iter = NV_ITER_INIT;
11295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32              currentAddr;
11305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Read the maxCount value
11315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    maxCount = NvReadMaxCount();
11325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Iterate all existing counters
11335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    while((currentAddr = NvNextIndex(&iter)) != 0)
11345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
11355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        TPMI_RH_NV_INDEX    nvHandle;
11365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        NV_INDEX            nvIndex;
11375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Read NV handle
11385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &nvHandle);
11395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         // Get NV Index
11405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         NvGetIndexInfo(nvHandle, &nvIndex);
11415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         if(    nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET
11425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
11435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
11445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             UINT64      countValue;
11455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             // Read counter value
11465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             NvGetIntIndexData(nvHandle, &nvIndex, &countValue);
11475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury             if(countValue > maxCount)
11485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 maxCount = countValue;
11495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
11505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
11515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Initialize the new counter value to be maxCount + 1
11525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // A counter is only initialized the first time it is written. The
11535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // way to write a counter is with TPM2_NV_INCREMENT(). Since the
11545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // "initial" value of a defined counter is the largest count value that
11555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // may have existed in this index previously, then the first use would
11565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // add one to that value.
11575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return maxCount;
11585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
11595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetIndexData()
11625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function is used to access the data in an NV Index. The data is returned as a byte sequence. Since
11645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      counter values are kept in native format, they are converted to canonical form before being returned.
11655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Family "2.0"                                  TCG Published                                         Page 139
11665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Level 00 Revision 01.16               Copyright © TCG 2006-2014                            October 30, 2014
11675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Trusted Platform Module Library                                                Part 4: Supporting Routines
11685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that the NV Index be defined, and that the required data is within the data range. It
11715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      also requires that TPMA_NV_WRITTEN of the Index is SET.
11725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
11735679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
11745679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetIndexData(
11755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_NV_INDEX          handle,            //   IN: handle
11765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_INDEX                 *nvIndex,           //   IN: RAM image of index header
11775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                    offset,            //   IN: offset of NV data
11785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16                    size,              //   IN: size of NV data
11795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                     *data               //   OUT: data buffer
11805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
11815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
11825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET);
11835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(   nvIndex->publicArea.attributes.TPMA_NV_BITS == SET
11845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET)
11855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
11865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Read bit or counter data in canonical form
11875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT64      dataInInt;
11885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        NvGetIntIndexData(handle, nvIndex, &dataInInt);
11895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT64_TO_BYTE_ARRAY(dataInInt, (BYTE *)data);
11905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
11915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
11925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
11935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
11945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        {
11955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            UINT32      ramAddr;
11965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Get data from RAM buffer
11975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              ramAddr = NvGetRAMIndexOffset(handle);
11985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              MemoryCopy(data, s_ramIndex + ramAddr + offset, size, size);
11995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         }
12005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         else
12015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         {
12025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              UINT32      entityAddr;
12035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              entityAddr = NvFindHandle(handle);
12045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Get data from NV
12055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Skip NV Index info, read data buffer
12065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              entityAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset;
12075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Read the data
12085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              _plat__NvMemoryRead(entityAddr, size, data);
12095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        }
12105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
12115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
12125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvGetIntIndexData()
12165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      Get data in integer format of a bit or counter NV Index.
12185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//      This function requires that the NV Index is defined and that the NV Index previously has been written.
12195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12205679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
12215679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetIntIndexData(
12225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_NV_INDEX          handle,            // IN: handle
12235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_INDEX                 *nvIndex,           // IN: RAM image of NV Index header
12245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT64                   *data               // IN: UINT64 pointer for counter or bit
12255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
12265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
12275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Validate that index has been written and is the right type
12285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(   nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == SET
12295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            && (   nvIndex->publicArea.attributes.TPMA_NV_BITS == SET
12305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                || nvIndex->publicArea.attributes.TPMA_NV_COUNTER == SET
12315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   )
12325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              );
12335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // bit and counter value is store in native format for TPM CPU.                  So we directly
12345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // copy the contents of NV to output data buffer
12355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
12365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
12375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT32      ramAddr;
12385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Get data from RAM buffer
12395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          ramAddr = NvGetRAMIndexOffset(handle);
12405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          MemoryCopy(data, s_ramIndex + ramAddr, sizeof(*data), sizeof(*data));
12415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
12425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    else
12435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
12445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT32      entityAddr;
12455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        entityAddr = NvFindHandle(handle);
12465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Get data from NV
12475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Skip NV Index info, read data buffer
12485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(
12495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              entityAddr + sizeof(TPM_HANDLE) + sizeof(NV_INDEX),
12505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              sizeof(UINT64), data);
12515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
12525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
12535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvWriteIndexInfo()
12575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is called to queue the write of NV Index data to persistent memory.
12595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function requires that NV Index is defined.
12605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                        Meaning
12625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_RATE                       NV is rate limiting so retry
12645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_UNAVAILABLE                NV is not available
12655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12665679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
12675679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvWriteIndexInfo(
12685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_NV_INDEX            handle,                // IN: handle
12695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_INDEX                   *nvIndex                // IN: NV Index info to be written
12705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
12715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
12725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32             entryAddr;
12735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_RC             result;
12745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Get the starting offset for the index in the RAM image of NV
12755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    entryAddr = NvFindHandle(handle);
12765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(entryAddr != 0);
12775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Step over the link value
12785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    entryAddr = entryAddr + sizeof(TPM_HANDLE);
12795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // If the index data is actually changed, then a write to NV is required
12805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(_plat__NvIsDifferent(entryAddr, sizeof(NV_INDEX),nvIndex))
12815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
12825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Make sure that NV is available
12835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        result = NvIsAvailable();
12845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(result != TPM_RC_SUCCESS)
12855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return result;
12865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        _plat__NvMemoryWrite(entryAddr, sizeof(NV_INDEX), nvIndex);
12875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        g_updateNV = TRUE;
12885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
12895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return TPM_RC_SUCCESS;
12905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
12915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvWriteIndexData()
12945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to write NV index data.
12965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function requires that the NV Index is defined, and the data is within the defined data range for the
12975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       index.
12985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
12995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
13005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_RATE                    NV is rate limiting so retry
13025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_UNAVAILABLE             NV is not available
13035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13045679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
13055679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvWriteIndexData(
13065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_NV_INDEX          handle,               //   IN: handle
13075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_INDEX                 *nvIndex,              //   IN: RAM copy of NV Index
13085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                    offset,               //   IN: offset of NV data
13095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32                    size,                 //   IN: size of NV data
13105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    void                     *data                  //   OUT: data buffer
13115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
13125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
13135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_RC               result;
13145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Validate that write falls within range of the index
13155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(nvIndex->publicArea.dataSize >= offset + size);
13165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Update TPMA_NV_WRITTEN bit if necessary
13175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(nvIndex->publicArea.attributes.TPMA_NV_WRITTEN == CLEAR)
13185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
13195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        nvIndex->publicArea.attributes.TPMA_NV_WRITTEN = SET;
13205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        result = NvWriteIndexInfo(handle, nvIndex);
13215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        if(result != TPM_RC_SUCCESS)
13225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            return result;
13235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
13245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Check to see if process for an orderly index is required.
13255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == SET)
13265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
13275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT32      ramAddr;
13285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Write data to RAM buffer
13295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          ramAddr = NvGetRAMIndexOffset(handle);
13305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          MemoryCopy(s_ramIndex + ramAddr + offset, data, size,
13315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     sizeof(s_ramIndex) - ramAddr - offset);
13325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // NV update does not happen for orderly index. Have
13335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // to clear orderlyState to reflect that we have changed the
13345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // NV and an orderly shutdown is required. Only going to do this if we
13355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // are not processing a counter that has just rolled over
13365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(g_updateNV == FALSE)
13375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              g_clearOrderly = TRUE;
13385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
13395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Need to process this part if the Index isn't orderly or if it is
13405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // an orderly counter that just rolled over.
13415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(g_updateNV || nvIndex->publicArea.attributes.TPMA_NV_ORDERLY == CLEAR)
13425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
13435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Processing for an index with TPMA_NV_ORDERLY CLEAR
13445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        UINT32      entryAddr = NvFindHandle(handle);
13455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          pAssert(entryAddr != 0);
13465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Offset into the index to the first byte of the data to be written
13485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          entryAddr += sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + offset;
13495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // If the data is actually changed, then a write to NV is required
13505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(_plat__NvIsDifferent(entryAddr, size, data))
13515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
13525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Make sure that NV is available
13535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              result = NvIsAvailable();
13545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              if(result != TPM_RC_SUCCESS)
13555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  return result;
13565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              _plat__NvMemoryWrite(entryAddr, size, data);
13575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              g_updateNV = TRUE;
13585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
13595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
13605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return TPM_RC_SUCCESS;
13615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
13625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvGetName()
13655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to compute the Name of an NV Index.
13675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       The name buffer receives the bytes of the Name and the return value is the number of octets in the
13685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Name.
13695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function requires that the NV Index is defined.
13705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13715679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT16
13725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvGetName(
13735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_NV_INDEX          handle,            // IN: handle of the index
13745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NAME                     *name               // OUT: name of the index
13755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
13765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
13775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16                    dataSize, digestSize;
13785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_INDEX                  nvIndex;
13795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE                      marshalBuffer[sizeof(TPMS_NV_PUBLIC)];
13805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE                     *buffer;
138132be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr    INT32                     bufferSize;
13825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    HASH_STATE                hashState;
13835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Get NV public info
13845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvGetIndexInfo(handle, &nvIndex);
13855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Marshal public area
13865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    buffer = marshalBuffer;
138732be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr    bufferSize = sizeof(TPMS_NV_PUBLIC);
138832be40450906cd2c80dee4a83204931f7f3a2daaJocelyn Bohr    dataSize = TPMS_NV_PUBLIC_Marshal(&nvIndex.publicArea, &buffer, &bufferSize);
13895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // hash public area
13905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    digestSize = CryptStartHash(nvIndex.publicArea.nameAlg, &hashState);
13915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CryptUpdateDigest(&hashState, dataSize, marshalBuffer);
13925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Complete digest leaving room for the nameAlg
13935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    CryptCompleteHash(&hashState, digestSize, &((BYTE *)name)[2]);
13945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Include the nameAlg
139599e88835efdddfb4e01ebfe07f668379d64dda64Vadim Bendebury    UINT16_TO_BYTE_ARRAY(nvIndex.publicArea.nameAlg, (BYTE *)name);
13965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return digestSize + 2;
13975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
13985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
13995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvDefineIndex()
14015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to assign NV memory to an NV Index.
14035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
14075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_SPACE                   insufficient NV space
14095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
14115679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvDefineIndex(
14125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_NV_PUBLIC      *publicArea,          // IN: A template for an area to create.
14135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM2B_AUTH          *authValue            // IN: The initial authorization value
14145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
14155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
14165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // The buffer to be written to NV memory
14175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   BYTE            nvBuffer[sizeof(TPM_HANDLE) + sizeof(NV_INDEX)];
14185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_INDEX            *nvIndex;                  // a pointer to the NV_INDEX data in
14195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                  //   nvBuffer
14205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT16              entrySize;                 // size of entry
14215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   entrySize = sizeof(TPM_HANDLE) + sizeof(NV_INDEX) + publicArea->dataSize;
14225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Check if we have enough space to create the NV Index
14235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // In this implementation, the only resource limitation is the available NV
14245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // space. Other implementation may have other limitation on counter or on
14255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // NV slot
14265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(!NvTestSpace(entrySize, TRUE)) return TPM_RC_NV_SPACE;
14275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // if the index to be defined is RAM backed, check RAM space availability
14285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // as well
14295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(publicArea->attributes.TPMA_NV_ORDERLY == SET
14305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           && !NvTestRAMSpace(publicArea->dataSize))
14315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_NV_SPACE;
14325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Copy input value to nvBuffer
14335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Copy handle
143471e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr   memcpy(nvBuffer, &publicArea->nvIndex, sizeof(TPM_HANDLE));
14355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Copy NV_INDEX
14365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nvIndex = (NV_INDEX *) (nvBuffer + sizeof(TPM_HANDLE));
14375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nvIndex->publicArea = *publicArea;
14385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   nvIndex->authValue = *authValue;
14395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Add index to NV memory
14405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvAdd(entrySize, sizeof(TPM_HANDLE) + sizeof(NV_INDEX), nvBuffer);
14415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // If the data of NV Index is RAM backed, add the data area in RAM as well
14425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(publicArea->attributes.TPMA_NV_ORDERLY == SET)
14435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       NvAddRAM(publicArea->nvIndex, publicArea->dataSize);
14445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
14455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
14465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvAddEvictObject()
14495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to assign NV memory to a persistent object.
14515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Error Returns                     Meaning
14535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_HANDLE                  the requested handle is already in use
14555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPM_RC_NV_SPACE                   insufficient NV space
14565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14575679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
14585679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvAddEvictObject(
14595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMI_DH_OBJECT       evictHandle,         // IN: new evict handle
14605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
14615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    OBJECT              *object              // IN: object to be added
14625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
14635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
14645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // The buffer to be written to NV memory
14655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    BYTE            nvBuffer[sizeof(TPM_HANDLE) + sizeof(OBJECT)];
14665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    OBJECT              *nvObject;                // a pointer to the OBJECT data in
14675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                                  // nvBuffer
14685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT16              entrySize;                // size of entry
14695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // evict handle type should match the object hierarchy
14705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(   (   NvIsPlatformPersistentHandle(evictHandle)
14715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                && object->attributes.ppsHierarchy == SET)
14725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            || (   NvIsOwnerPersistentHandle(evictHandle)
14735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                && (   object->attributes.spsHierarchy == SET
14745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                    || object->attributes.epsHierarchy == SET)));
14755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // An evict needs 4 bytes of handle + sizeof OBJECT
14765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    entrySize = sizeof(TPM_HANDLE) + sizeof(OBJECT);
14775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Check if we have enough space to add the evict object
14785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // An evict object needs 8 bytes in index table + sizeof OBJECT
14795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // In this implementation, the only resource limitation is the available NV
14805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // space. Other implementation may have other limitation on evict object
14815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // handle space
14825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(!NvTestSpace(entrySize, FALSE)) return TPM_RC_NV_SPACE;
14835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Allocate a new evict handle
14845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(!NvIsUndefinedEvictHandle(evictHandle))
14855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        return TPM_RC_NV_DEFINED;
14865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Copy evict object to nvBuffer
14875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy handle
148871e3b99f0af42b8fbc6024232dcf968e5cdc665aJocelyn Bohr    memcpy(nvBuffer, &evictHandle, sizeof(TPM_HANDLE));
14895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        // Copy OBJECT
14905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    nvObject = (OBJECT *) (nvBuffer + sizeof(TPM_HANDLE));
14915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    *nvObject = *object;
14925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Set evict attribute and handle
14935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    nvObject->attributes.evict = SET;
14945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    nvObject->evictHandle = evictHandle;
14955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    // Add evict to NV memory
14965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvAdd(entrySize, entrySize, nvBuffer);
14975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return TPM_RC_SUCCESS;
14985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
14995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvDeleteEntity()
15025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function will delete a NV Index or an evict object.
15045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function requires that the index/evict object has been defined.
15055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15065679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
15075679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvDeleteEntity(
15085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPM_HANDLE           handle              // IN: handle of entity to be deleted
15095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
15105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
15115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32         entityAddr;         // pointer to entity
15125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    entityAddr = NvFindHandle(handle);
15135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    pAssert(entityAddr != 0);
15145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    if(HandleGetType(handle) == TPM_HT_NV_INDEX)
15155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
15165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        NV_INDEX    nvIndex;
15175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Read the NV Index info
15185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(entityAddr + sizeof(TPM_HANDLE), sizeof(NV_INDEX),
15195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                              &nvIndex);
15205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // If the entity to be deleted is a counter with the maximum counter
15215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // value, record it in NV memory
15225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET
15235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  && nvIndex.publicArea.attributes.TPMA_NV_WRITTEN == SET)
15245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
15255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              UINT64      countValue;
15265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              UINT64      maxCount;
15275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              NvGetIntIndexData(handle, &nvIndex, &countValue);
15285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              maxCount = NvReadMaxCount();
15295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              if(countValue > maxCount)
15305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  NvWriteMaxCount(countValue);
15315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
15325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // If the NV Index is RAM back, delete the RAM data as well
15335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET)
15345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              NvDeleteRAM(handle);
15355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    }
15365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NvDelete(entityAddr);
15375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    return;
15385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
15395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvFlushHierarchy()
15425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function will delete persistent objects belonging to the indicated If the storage hierarchy is selected,
15445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       the function will also delete any NV Index define using ownerAuth.
15455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
15465679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
15475679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvFlushHierarchy(
15485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    TPMI_RH_HIERARCHY         hierarchy          // IN: hierarchy to be flushed.
15495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    )
15505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
15515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    NV_ITER             iter = NV_ITER_INIT;
15525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    UINT32              currentAddr;
15535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    while((currentAddr = NvNext(&iter)) != 0)
15545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury    {
15555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury        TPM_HANDLE      entityHandle;
15565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Read handle information.
15575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
15585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(HandleGetType(entityHandle) == TPM_HT_NV_INDEX)
15595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
15605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // Handle NV Index
15615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              NV_INDEX    nvIndex;
15625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // If flush endorsement or platform hierarchy, no NV Index would be
15635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // flushed
15645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              if(hierarchy == TPM_RH_ENDORSEMENT || hierarchy == TPM_RH_PLATFORM)
15655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                  continue;
15665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
15675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                  sizeof(NV_INDEX), &nvIndex);
15685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              // For storage hierarchy, flush OwnerCreated index
15695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               if(    nvIndex.publicArea.attributes.TPMA_NV_PLATFORMCREATE == CLEAR)
15705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
15715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Delete the NV Index
15725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     NvDelete(currentAddr);
15735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Re-iterate from beginning after a delete
15745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     iter = NV_ITER_INIT;
15755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // If the NV Index is RAM back, delete the RAM data as well
15765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     if(nvIndex.publicArea.attributes.TPMA_NV_ORDERLY == SET)
15775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                         NvDeleteRAM(entityHandle);
15785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              }
15795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
15805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          else if(HandleGetType(entityHandle) == TPM_HT_PERSISTENT)
15815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
15825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              OBJECT          object;
15835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               // Get evict object
15845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               NvGetEvictObject(entityHandle, &object);
15855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               // If the evict object belongs to the hierarchy to be flushed
15865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               if(     (    hierarchy == TPM_RH_PLATFORM
15875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        && object.attributes.ppsHierarchy == SET)
15885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   || (     hierarchy == TPM_RH_OWNER
15895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        && object.attributes.spsHierarchy == SET)
15905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   || (     hierarchy == TPM_RH_ENDORSEMENT
15915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                        && object.attributes.epsHierarchy == SET)
15925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                   )
15935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               {
15945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Delete the evict object
15955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     NvDelete(currentAddr);
15965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     // Re-iterate from beginning after a delete
15975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                     iter = NV_ITER_INIT;
15985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               }
15995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
16005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          else
16015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
16025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               pAssert(FALSE);
16035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
16045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
16055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
16065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//              NvSetGlobalLock()
16105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indices that have
16125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       TPMA_NV_GLOBALLOCK SET. This function is use by TPM2_NV_GlobalWriteLock().
16135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16145679752bf24c21135884e987c4077e2f7184897Vadim Bendeburyvoid
16155679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvSetGlobalLock(
16165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
16175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
16185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
16195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER               iter = NV_ITER_INIT;
16205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                currentAddr;
16215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Check all Indices
16225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while((currentAddr = NvNextIndex(&iter)) != 0)
16235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
16245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       NV_INDEX    nvIndex;
16255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Read the index data
16265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
16275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                              sizeof(NV_INDEX), &nvIndex);
16285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // See if it should be locked
16295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(nvIndex.publicArea.attributes.TPMA_NV_GLOBALLOCK == SET)
16305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          {
16315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                // if so, lock it
16325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                nvIndex.publicArea.attributes.TPMA_NV_WRITELOCKED = SET;
16335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                _plat__NvMemoryWrite(currentAddr + sizeof(TPM_HANDLE),
16345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                                     sizeof(NV_INDEX), &nvIndex);
16355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                // Set the flag that a NV write happens
16365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                g_updateNV = TRUE;
16375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          }
16385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
16395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return;
16405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//              InsertSort()
16445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Sort a handle into handle list in ascending order. The total handle number in the list should not exceed
16465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       MAX_CAP_HANDLES
16475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16485679752bf24c21135884e987c4077e2f7184897Vadim Bendeburystatic void
16495679752bf24c21135884e987c4077e2f7184897Vadim BendeburyInsertSort(
16505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPML_HANDLE           *handleList,     // IN/OUT: sorted handle list
16515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                 count,          // IN: maximum count in the handle list
16525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_HANDLE             entityHandle    // IN: handle to be inserted
16535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
16545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
16555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                i, j;
16565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32                originalCount;
16575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // For a corner case that the maximum count is 0, do nothing
16585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(count == 0) return;
16595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // For empty list, add the handle at the beginning and return
16605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(handleList->count == 0)
16615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
16625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       handleList->handle[0] = entityHandle;
16635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       handleList->count++;
16645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return;
16655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
16665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Check if the maximum of the list has been reached
16675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   originalCount = handleList->count;
16685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(originalCount < count)
16695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       handleList->count++;
16705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Insert the handle to the list
16715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   for(i = 0; i < originalCount; i++)
16725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
16735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(handleList->handle[i] > entityHandle)
16745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       {
16755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           for(j = handleList->count - 1; j > i; j--)
16765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           {
16775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury               handleList->handle[j] = handleList->handle[j-1];
16785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           }
16795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           break;
16805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       }
16815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
16825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // If a slot was found, insert the handle in this position
16835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(i < originalCount || handleList->count > originalCount)
16845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         handleList->handle[i] = entityHandle;
16855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return;
16865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
16875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvCapGetPersistent()
16905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function is used to get a list of handles of the persistent objects, starting at handle.
16925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Handle must be in valid persistent object handle range, but does not have to reference an existing
16935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       persistent object.
16945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                      Meaning
16965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
16975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       YES                               if there are more handles available
16985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NO                                all the available handles has been returned
16995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17005679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMI_YES_NO
17015679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetPersistent(
17025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_DH_OBJECT       handle,            // IN: start handle
17035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32               count,             // IN: maximum number of returned handle
17045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPML_HANDLE         *handleList         // OUT: list of handle
17055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
17065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
17075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_YES_NO               more = NO;
17085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     NV_ITER                   iter = NV_ITER_INIT;
17095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32                    currentAddr;
17105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     pAssert(HandleGetType(handle) == TPM_HT_PERSISTENT);
17115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Initialize output handle list
17125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     handleList->count = 0;
17135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // The maximum count of handles we may return is MAX_CAP_HANDLES
17145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
17155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     while((currentAddr = NvNextEvict(&iter)) != 0)
17165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
17175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         TPM_HANDLE      entityHandle;
17185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Read handle information.
17195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
17205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Ignore persistent handles that have values less than the input handle
17215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(entityHandle < handle)
17225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              continue;
17235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // if the handles in the list have reached the requested count, and there
17245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // are still handles need to be inserted, indicate that there are more.
17255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(handleList->count == count)
17265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              more = YES;
17275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // A handle with a value larger than start handle is a candidate
17285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // for return. Insert sort it to the return list. Insert sort algorithm
17295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // is chosen here for simplicity based on the assumption that the total
17305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // number of NV Indices is small. For an implementation that may allow
17315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // large number of NV Indices, a more efficient sorting algorithm may be
17325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // used here.
17335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          InsertSort(handleList, count, entityHandle);
17345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
17365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return more;
17375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
17385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvCapGetIndex()
17415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns a list of handles of NV Indices, starting from handle. Handle must be in the range of
17435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NV Indices, but does not have to reference an existing NV Index.
17445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Return Value                      Meaning
17465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       YES                               if there are more handles to report
17485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NO                                all the available handles has been reported
17495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17505679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPMI_YES_NO
17515679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetIndex(
17525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_DH_OBJECT     handle,              // IN: start handle
17535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32             count,               // IN: maximum number of returned handle
17545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPML_HANDLE       *handleList           // OUT: list of handle
17555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     )
17565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
17575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     TPMI_YES_NO             more = NO;
17585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     NV_ITER                 iter = NV_ITER_INIT;
17595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     UINT32                  currentAddr;
17605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     pAssert(HandleGetType(handle) == TPM_HT_NV_INDEX);
17615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // Initialize output handle list
17625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     handleList->count = 0;
17635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     // The maximum count of handles we may return is MAX_CAP_HANDLES
17645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     if(count > MAX_CAP_HANDLES) count = MAX_CAP_HANDLES;
17655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     while((currentAddr = NvNextIndex(&iter)) != 0)
17665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     {
17675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         TPM_HANDLE      entityHandle;
17685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Read handle information.
17695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(currentAddr, sizeof(TPM_HANDLE), &entityHandle);
17705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Ignore index handles that have values less than the 'handle'
17715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(entityHandle < handle)
17725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              continue;
17735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // if the count of handles in the list has reached the requested count,
17745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // and there are still handles to report, set more.
17755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(handleList->count == count)
17765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury              more = YES;
17775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // A handle with a value larger than start handle is a candidate
17785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // for return. Insert sort it to the return list. Insert sort algorithm
17795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // is chosen here for simplicity based on the assumption that the total
17805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // number of NV Indices is small. For an implementation that may allow
17815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // large number of NV Indices, a more efficient sorting algorithm may be
17825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // used here.
17835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          InsertSort(handleList, count, entityHandle);
17845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     }
17855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     return more;
17865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
17875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvCapGetIndexNumber()
17915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns the count of NV Indexes currently defined.
17935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
17945679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
17955679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetIndexNumber(
17965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
17975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
17985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
17995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              num = 0;
18005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             iter = NV_ITER_INIT;
18015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(NvNextIndex(&iter) != 0) num++;
18025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return num;
18035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
18045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvCapGetPersistentNumber()
18075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Function returns the count of persistent objects currently in NV memory.
18095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18105679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
18115679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetPersistentNumber(
18125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
18135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
18145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
18155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              num = 0;
18165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             iter = NV_ITER_INIT;
18175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while(NvNextEvict(&iter) != 0) num++;
18185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return num;
18195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
18205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvCapGetPersistentAvail()
18235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns an estimate of the number of additional persistent objects that could be loaded into
18255679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       NV memory.
18265679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18275679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
18285679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetPersistentAvail(
18295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
18305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
18315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
18325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              availSpace;
18335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              objectSpace;
18345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute the available space in NV storage
18355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   availSpace = NvGetFreeByte();
18365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get the space needed to add a persistent object to NV storage
18375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   objectSpace = NvGetEvictObjectSize();
18385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return availSpace / objectSpace;
18395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
18405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//           NvCapGetCounterNumber()
18435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       Get the number of defined NV Indexes that have NV TPMA_NV_COUNTER attribute SET.
18455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18475679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
18485679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetCounterNumber(
18495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
18505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
18515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
18525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_ITER             iter = NV_ITER_INIT;
18535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              currentAddr;
18545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              num = 0;
18555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   while((currentAddr = NvNextIndex(&iter)) != 0)
18565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
18575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       NV_INDEX    nvIndex;
18585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          // Get NV Index info
18595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          _plat__NvMemoryRead(currentAddr + sizeof(TPM_HANDLE),
18605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                               sizeof(NV_INDEX), &nvIndex);
18615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          if(nvIndex.publicArea.attributes.TPMA_NV_COUNTER == SET) num++;
18625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
18635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return num;
18645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
18655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//            NvCapGetCounterAvail()
18685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//       This function returns an estimate of the number of additional counter type NV Indices that can be defined.
18705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
18715679752bf24c21135884e987c4077e2f7184897Vadim BendeburyUINT32
18725679752bf24c21135884e987c4077e2f7184897Vadim BendeburyNvCapGetCounterAvail(
18735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   void
18745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
18755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
18765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              availNVSpace;
18775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              availRAMSpace;
18785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              counterNVSpace;
18795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              counterRAMSpace;
18805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   UINT32              persistentNum = NvCapGetPersistentNumber();
18815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get the available space in NV storage
18825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   availNVSpace = NvGetFreeByte();
18835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if (persistentNum < MIN_EVICT_OBJECTS)
18845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
18855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // Some space have to be reserved for evict object. Adjust availNVSpace.
18865679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       UINT32       reserved = (MIN_EVICT_OBJECTS - persistentNum)
18875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                              * NvGetEvictObjectSize();
18885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if (reserved > availNVSpace)
18895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            availNVSpace = 0;
18905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       else
18915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury            availNVSpace -= reserved;
18925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
18935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get the space needed to add a counter index to NV storage
18945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   counterNVSpace = NvGetCounterSize();
18955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute the available space in RAM
18965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   availRAMSpace = RAM_INDEX_SPACE - s_ramIndexSize;
18975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Compute the space needed to add a counter index to RAM storage
18985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // It takes an size field, a handle and sizeof(UINT64) for counter data
18995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   counterRAMSpace = sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(UINT64);
19005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Return the min of counter number in NV and in RAM
19015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(availNVSpace / counterNVSpace > availRAMSpace / counterRAMSpace)
19025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return availRAMSpace / counterRAMSpace;
19035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury     else
19045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury         return availNVSpace / counterNVSpace;
19055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
1906