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