xref: /aosp_15_r20/external/ms-tpm-20-ref/TPMCmd/Platform/src/NVMem.c (revision 5c591343844d1f9da7da26467c4bf7efc8a7a413)
1*5c591343SA. Cody Schuffelen /* Microsoft Reference Implementation for TPM 2.0
2*5c591343SA. Cody Schuffelen  *
3*5c591343SA. Cody Schuffelen  *  The copyright in this software is being made available under the BSD License,
4*5c591343SA. Cody Schuffelen  *  included below. This software may be subject to other third party and
5*5c591343SA. Cody Schuffelen  *  contributor rights, including patent rights, and no such rights are granted
6*5c591343SA. Cody Schuffelen  *  under this license.
7*5c591343SA. Cody Schuffelen  *
8*5c591343SA. Cody Schuffelen  *  Copyright (c) Microsoft Corporation
9*5c591343SA. Cody Schuffelen  *
10*5c591343SA. Cody Schuffelen  *  All rights reserved.
11*5c591343SA. Cody Schuffelen  *
12*5c591343SA. Cody Schuffelen  *  BSD License
13*5c591343SA. Cody Schuffelen  *
14*5c591343SA. Cody Schuffelen  *  Redistribution and use in source and binary forms, with or without modification,
15*5c591343SA. Cody Schuffelen  *  are permitted provided that the following conditions are met:
16*5c591343SA. Cody Schuffelen  *
17*5c591343SA. Cody Schuffelen  *  Redistributions of source code must retain the above copyright notice, this list
18*5c591343SA. Cody Schuffelen  *  of conditions and the following disclaimer.
19*5c591343SA. Cody Schuffelen  *
20*5c591343SA. Cody Schuffelen  *  Redistributions in binary form must reproduce the above copyright notice, this
21*5c591343SA. Cody Schuffelen  *  list of conditions and the following disclaimer in the documentation and/or
22*5c591343SA. Cody Schuffelen  *  other materials provided with the distribution.
23*5c591343SA. Cody Schuffelen  *
24*5c591343SA. Cody Schuffelen  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25*5c591343SA. Cody Schuffelen  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*5c591343SA. Cody Schuffelen  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27*5c591343SA. Cody Schuffelen  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28*5c591343SA. Cody Schuffelen  *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29*5c591343SA. Cody Schuffelen  *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30*5c591343SA. Cody Schuffelen  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31*5c591343SA. Cody Schuffelen  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*5c591343SA. Cody Schuffelen  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*5c591343SA. Cody Schuffelen  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*5c591343SA. Cody Schuffelen  */
35*5c591343SA. Cody Schuffelen //** Description
36*5c591343SA. Cody Schuffelen //
37*5c591343SA. Cody Schuffelen //    This file contains the NV read and write access methods.  This implementation
38*5c591343SA. Cody Schuffelen //    uses RAM/file and does not manage the RAM/file as NV blocks.
39*5c591343SA. Cody Schuffelen //    The implementation may become more sophisticated over time.
40*5c591343SA. Cody Schuffelen //
41*5c591343SA. Cody Schuffelen 
42*5c591343SA. Cody Schuffelen //** Includes and Local
43*5c591343SA. Cody Schuffelen #include <memory.h>
44*5c591343SA. Cody Schuffelen #include <string.h>
45*5c591343SA. Cody Schuffelen #include <assert.h>
46*5c591343SA. Cody Schuffelen #include "Platform.h"
47*5c591343SA. Cody Schuffelen #if FILE_BACKED_NV
48*5c591343SA. Cody Schuffelen #   include         <stdio.h>
49*5c591343SA. Cody Schuffelen static FILE         *s_NvFile = NULL;
50*5c591343SA. Cody Schuffelen static int           s_NeedsManufacture = FALSE;
51*5c591343SA. Cody Schuffelen #endif
52*5c591343SA. Cody Schuffelen 
53*5c591343SA. Cody Schuffelen //**Functions
54*5c591343SA. Cody Schuffelen 
55*5c591343SA. Cody Schuffelen #if FILE_BACKED_NV
56*5c591343SA. Cody Schuffelen 
57*5c591343SA. Cody Schuffelen //*** NvFileOpen()
58*5c591343SA. Cody Schuffelen // This function opens the file used to hold the NV image.
59*5c591343SA. Cody Schuffelen //  Return Type: int
60*5c591343SA. Cody Schuffelen //  >= 0        success
61*5c591343SA. Cody Schuffelen //  -1          error
62*5c591343SA. Cody Schuffelen static int
NvFileOpen(const char * mode)63*5c591343SA. Cody Schuffelen NvFileOpen(
64*5c591343SA. Cody Schuffelen     const char      *mode
65*5c591343SA. Cody Schuffelen )
66*5c591343SA. Cody Schuffelen {
67*5c591343SA. Cody Schuffelen #if defined(NV_FILE_PATH)
68*5c591343SA. Cody Schuffelen #   define TO_STRING(s) TO_STRING_IMPL(s)
69*5c591343SA. Cody Schuffelen #   define TO_STRING_IMPL(s) #s
70*5c591343SA. Cody Schuffelen     const char* s_NvFilePath = TO_STRING(NV_FILE_PATH);
71*5c591343SA. Cody Schuffelen #   undef TO_STRING
72*5c591343SA. Cody Schuffelen #   undef TO_STRING_IMPL
73*5c591343SA. Cody Schuffelen #else
74*5c591343SA. Cody Schuffelen     const char* s_NvFilePath = "NVChip";
75*5c591343SA. Cody Schuffelen #endif
76*5c591343SA. Cody Schuffelen 
77*5c591343SA. Cody Schuffelen     // Try to open an exist NVChip file for read/write
78*5c591343SA. Cody Schuffelen #   if defined _MSC_VER && 1
79*5c591343SA. Cody Schuffelen     if(fopen_s(&s_NvFile, s_NvFilePath, mode) != 0)
80*5c591343SA. Cody Schuffelen         s_NvFile = NULL;
81*5c591343SA. Cody Schuffelen #   else
82*5c591343SA. Cody Schuffelen     s_NvFile = fopen(s_NvFilePath, mode);
83*5c591343SA. Cody Schuffelen #   endif
84*5c591343SA. Cody Schuffelen     return (s_NvFile == NULL) ? -1 : 0;
85*5c591343SA. Cody Schuffelen }
86*5c591343SA. Cody Schuffelen 
87*5c591343SA. Cody Schuffelen //*** NvFileCommit()
88*5c591343SA. Cody Schuffelen // Write all of the contents of the NV image to a file.
89*5c591343SA. Cody Schuffelen //  Return Type: int
90*5c591343SA. Cody Schuffelen //      TRUE(1)         success
91*5c591343SA. Cody Schuffelen //      FALSE(0)        failure
92*5c591343SA. Cody Schuffelen static int
NvFileCommit(void)93*5c591343SA. Cody Schuffelen NvFileCommit(
94*5c591343SA. Cody Schuffelen     void
95*5c591343SA. Cody Schuffelen )
96*5c591343SA. Cody Schuffelen {
97*5c591343SA. Cody Schuffelen     int         OK;
98*5c591343SA. Cody Schuffelen     // If NV file is not available, return failure
99*5c591343SA. Cody Schuffelen     if(s_NvFile == NULL)
100*5c591343SA. Cody Schuffelen         return 1;
101*5c591343SA. Cody Schuffelen     // Write RAM data to NV
102*5c591343SA. Cody Schuffelen     fseek(s_NvFile, 0, SEEK_SET);
103*5c591343SA. Cody Schuffelen     OK = (NV_MEMORY_SIZE == fwrite(s_NV, 1, NV_MEMORY_SIZE, s_NvFile));
104*5c591343SA. Cody Schuffelen     OK = OK && (0 == fflush(s_NvFile));
105*5c591343SA. Cody Schuffelen     assert(OK);
106*5c591343SA. Cody Schuffelen     return OK;
107*5c591343SA. Cody Schuffelen }
108*5c591343SA. Cody Schuffelen 
109*5c591343SA. Cody Schuffelen //*** NvFileSize()
110*5c591343SA. Cody Schuffelen // This function gets the size of the NV file and puts the file pointer where desired
111*5c591343SA. Cody Schuffelen // using the seek method values. SEEK_SET => beginning; SEEK_CUR => current position
112*5c591343SA. Cody Schuffelen // and SEEK_END => to the end of the file.
113*5c591343SA. Cody Schuffelen static long
NvFileSize(int leaveAt)114*5c591343SA. Cody Schuffelen NvFileSize(
115*5c591343SA. Cody Schuffelen     int         leaveAt
116*5c591343SA. Cody Schuffelen )
117*5c591343SA. Cody Schuffelen {
118*5c591343SA. Cody Schuffelen     long    fileSize;
119*5c591343SA. Cody Schuffelen     long    filePos = ftell(s_NvFile);
120*5c591343SA. Cody Schuffelen //
121*5c591343SA. Cody Schuffelen     assert(NULL != s_NvFile);
122*5c591343SA. Cody Schuffelen 
123*5c591343SA. Cody Schuffelen     int fseek_result = fseek(s_NvFile, 0, SEEK_END);
124*5c591343SA. Cody Schuffelen     NOT_REFERENCED(fseek_result); // Fix compiler warning for NDEBUG
125*5c591343SA. Cody Schuffelen     assert(fseek_result == 0);
126*5c591343SA. Cody Schuffelen     fileSize = ftell(s_NvFile);
127*5c591343SA. Cody Schuffelen     assert(fileSize >= 0);
128*5c591343SA. Cody Schuffelen     switch(leaveAt)
129*5c591343SA. Cody Schuffelen     {
130*5c591343SA. Cody Schuffelen         case SEEK_SET:
131*5c591343SA. Cody Schuffelen             filePos = 0;
132*5c591343SA. Cody Schuffelen         case SEEK_CUR:
133*5c591343SA. Cody Schuffelen             fseek(s_NvFile, filePos, SEEK_SET);
134*5c591343SA. Cody Schuffelen             break;
135*5c591343SA. Cody Schuffelen         case SEEK_END:
136*5c591343SA. Cody Schuffelen             break;
137*5c591343SA. Cody Schuffelen         default:
138*5c591343SA. Cody Schuffelen             assert(FALSE);
139*5c591343SA. Cody Schuffelen             break;
140*5c591343SA. Cody Schuffelen     }
141*5c591343SA. Cody Schuffelen     return fileSize;
142*5c591343SA. Cody Schuffelen }
143*5c591343SA. Cody Schuffelen #endif
144*5c591343SA. Cody Schuffelen 
145*5c591343SA. Cody Schuffelen //*** _plat__NvErrors()
146*5c591343SA. Cody Schuffelen // This function is used by the simulator to set the error flags in the NV
147*5c591343SA. Cody Schuffelen // subsystem to simulate an error in the NV loading process
148*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__NvErrors(int recoverable,int unrecoverable)149*5c591343SA. Cody Schuffelen _plat__NvErrors(
150*5c591343SA. Cody Schuffelen     int              recoverable,
151*5c591343SA. Cody Schuffelen     int              unrecoverable
152*5c591343SA. Cody Schuffelen     )
153*5c591343SA. Cody Schuffelen {
154*5c591343SA. Cody Schuffelen     s_NV_unrecoverable = unrecoverable;
155*5c591343SA. Cody Schuffelen     s_NV_recoverable = recoverable;
156*5c591343SA. Cody Schuffelen }
157*5c591343SA. Cody Schuffelen 
158*5c591343SA. Cody Schuffelen //***_plat__NVEnable()
159*5c591343SA. Cody Schuffelen // Enable NV memory.
160*5c591343SA. Cody Schuffelen //
161*5c591343SA. Cody Schuffelen // This version just pulls in data from a file. In a real TPM, with NV on chip,
162*5c591343SA. Cody Schuffelen // this function would verify the integrity of the saved context. If the NV
163*5c591343SA. Cody Schuffelen // memory was not on chip but was in something like RPMB, the NV state would be
164*5c591343SA. Cody Schuffelen // read in, decrypted and integrity checked.
165*5c591343SA. Cody Schuffelen //
166*5c591343SA. Cody Schuffelen // The recovery from an integrity failure depends on where the error occurred. It
167*5c591343SA. Cody Schuffelen // it was in the state that is discarded by TPM Reset, then the error is
168*5c591343SA. Cody Schuffelen // recoverable if the TPM is reset. Otherwise, the TPM must go into failure mode.
169*5c591343SA. Cody Schuffelen //  Return Type: int
170*5c591343SA. Cody Schuffelen //      0           if success
171*5c591343SA. Cody Schuffelen //      > 0         if receive recoverable error
172*5c591343SA. Cody Schuffelen //      <0          if unrecoverable error
173*5c591343SA. Cody Schuffelen LIB_EXPORT int
_plat__NVEnable(void * platParameter)174*5c591343SA. Cody Schuffelen _plat__NVEnable(
175*5c591343SA. Cody Schuffelen     void            *platParameter  // IN: platform specific parameters
176*5c591343SA. Cody Schuffelen     )
177*5c591343SA. Cody Schuffelen {
178*5c591343SA. Cody Schuffelen     NOT_REFERENCED(platParameter);          // to keep compiler quiet
179*5c591343SA. Cody Schuffelen //
180*5c591343SA. Cody Schuffelen     // Start assuming everything is OK
181*5c591343SA. Cody Schuffelen     s_NV_unrecoverable = FALSE;
182*5c591343SA. Cody Schuffelen     s_NV_recoverable = FALSE;
183*5c591343SA. Cody Schuffelen #if FILE_BACKED_NV
184*5c591343SA. Cody Schuffelen     if(s_NvFile != NULL)
185*5c591343SA. Cody Schuffelen         return 0;
186*5c591343SA. Cody Schuffelen     // Initialize all the bytes in the ram copy of the NV
187*5c591343SA. Cody Schuffelen     _plat__NvMemoryClear(0, NV_MEMORY_SIZE);
188*5c591343SA. Cody Schuffelen 
189*5c591343SA. Cody Schuffelen     // If the file exists
190*5c591343SA. Cody Schuffelen     if(NvFileOpen("r+b") >= 0)
191*5c591343SA. Cody Schuffelen     {
192*5c591343SA. Cody Schuffelen         long    fileSize = NvFileSize(SEEK_SET);    // get the file size and leave the
193*5c591343SA. Cody Schuffelen                                                     // file pointer at the start
194*5c591343SA. Cody Schuffelen //
195*5c591343SA. Cody Schuffelen         // If the size is right, read the data
196*5c591343SA. Cody Schuffelen         if (NV_MEMORY_SIZE == fileSize)
197*5c591343SA. Cody Schuffelen         {
198*5c591343SA. Cody Schuffelen             s_NeedsManufacture =
199*5c591343SA. Cody Schuffelen                 fread(s_NV, 1, NV_MEMORY_SIZE, s_NvFile) != NV_MEMORY_SIZE;
200*5c591343SA. Cody Schuffelen         }
201*5c591343SA. Cody Schuffelen         else
202*5c591343SA. Cody Schuffelen         {
203*5c591343SA. Cody Schuffelen             printf("acs 6\n");
204*5c591343SA. Cody Schuffelen             NvFileCommit();     // for any other size, initialize it
205*5c591343SA. Cody Schuffelen             s_NeedsManufacture = TRUE;
206*5c591343SA. Cody Schuffelen         }
207*5c591343SA. Cody Schuffelen     }
208*5c591343SA. Cody Schuffelen     // If NVChip file does not exist, try to create it for read/write.
209*5c591343SA. Cody Schuffelen     else if(NvFileOpen("w+b") >= 0)
210*5c591343SA. Cody Schuffelen     {
211*5c591343SA. Cody Schuffelen         NvFileCommit();             // Initialize the file
212*5c591343SA. Cody Schuffelen         s_NeedsManufacture = TRUE;
213*5c591343SA. Cody Schuffelen     }
214*5c591343SA. Cody Schuffelen     assert(NULL != s_NvFile);       // Just in case we are broken for some reason.
215*5c591343SA. Cody Schuffelen #endif
216*5c591343SA. Cody Schuffelen     // NV contents have been initialized and the error checks have been performed. For
217*5c591343SA. Cody Schuffelen     // simulation purposes, use the signaling interface to indicate if an error is
218*5c591343SA. Cody Schuffelen     // to be simulated and the type of the error.
219*5c591343SA. Cody Schuffelen     if(s_NV_unrecoverable)
220*5c591343SA. Cody Schuffelen         return -1;
221*5c591343SA. Cody Schuffelen     return s_NV_recoverable;
222*5c591343SA. Cody Schuffelen }
223*5c591343SA. Cody Schuffelen 
224*5c591343SA. Cody Schuffelen //***_plat__NVDisable()
225*5c591343SA. Cody Schuffelen // Disable NV memory
226*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__NVDisable(int delete)227*5c591343SA. Cody Schuffelen _plat__NVDisable(
228*5c591343SA. Cody Schuffelen     int              delete           // IN: If TRUE, delete the NV contents.
229*5c591343SA. Cody Schuffelen     )
230*5c591343SA. Cody Schuffelen {
231*5c591343SA. Cody Schuffelen #if  FILE_BACKED_NV
232*5c591343SA. Cody Schuffelen     if(NULL != s_NvFile)
233*5c591343SA. Cody Schuffelen     {
234*5c591343SA. Cody Schuffelen         fclose(s_NvFile);    // Close NV file
235*5c591343SA. Cody Schuffelen         // Alternative to deleting the file is to set its size to 0. This will not
236*5c591343SA. Cody Schuffelen         // match the NV size so the TPM will need to be remanufactured.
237*5c591343SA. Cody Schuffelen         if(delete)
238*5c591343SA. Cody Schuffelen         {
239*5c591343SA. Cody Schuffelen             // Open for writing at the start. Sets the size to zero.
240*5c591343SA. Cody Schuffelen             if(NvFileOpen("w") >= 0)
241*5c591343SA. Cody Schuffelen             {
242*5c591343SA. Cody Schuffelen                 fflush(s_NvFile);
243*5c591343SA. Cody Schuffelen                 fclose(s_NvFile);
244*5c591343SA. Cody Schuffelen             }
245*5c591343SA. Cody Schuffelen         }
246*5c591343SA. Cody Schuffelen     }
247*5c591343SA. Cody Schuffelen     s_NvFile = NULL;        // Set file handle to NULL
248*5c591343SA. Cody Schuffelen #endif
249*5c591343SA. Cody Schuffelen     return;
250*5c591343SA. Cody Schuffelen }
251*5c591343SA. Cody Schuffelen 
252*5c591343SA. Cody Schuffelen //***_plat__IsNvAvailable()
253*5c591343SA. Cody Schuffelen // Check if NV is available
254*5c591343SA. Cody Schuffelen //  Return Type: int
255*5c591343SA. Cody Schuffelen //      0               NV is available
256*5c591343SA. Cody Schuffelen //      1               NV is not available due to write failure
257*5c591343SA. Cody Schuffelen //      2               NV is not available due to rate limit
258*5c591343SA. Cody Schuffelen LIB_EXPORT int
_plat__IsNvAvailable(void)259*5c591343SA. Cody Schuffelen _plat__IsNvAvailable(
260*5c591343SA. Cody Schuffelen     void
261*5c591343SA. Cody Schuffelen     )
262*5c591343SA. Cody Schuffelen {
263*5c591343SA. Cody Schuffelen     int         retVal = 0;
264*5c591343SA. Cody Schuffelen     // NV is not available if the TPM is in failure mode
265*5c591343SA. Cody Schuffelen     if(!s_NvIsAvailable)
266*5c591343SA. Cody Schuffelen         retVal = 1;
267*5c591343SA. Cody Schuffelen #if FILE_BACKED_NV
268*5c591343SA. Cody Schuffelen     else
269*5c591343SA. Cody Schuffelen         retVal = (s_NvFile == NULL);
270*5c591343SA. Cody Schuffelen #endif
271*5c591343SA. Cody Schuffelen     return retVal;
272*5c591343SA. Cody Schuffelen }
273*5c591343SA. Cody Schuffelen 
274*5c591343SA. Cody Schuffelen //***_plat__NvMemoryRead()
275*5c591343SA. Cody Schuffelen // Function: Read a chunk of NV memory
276*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__NvMemoryRead(unsigned int startOffset,unsigned int size,void * data)277*5c591343SA. Cody Schuffelen _plat__NvMemoryRead(
278*5c591343SA. Cody Schuffelen     unsigned int     startOffset,   // IN: read start
279*5c591343SA. Cody Schuffelen     unsigned int     size,          // IN: size of bytes to read
280*5c591343SA. Cody Schuffelen     void            *data           // OUT: data buffer
281*5c591343SA. Cody Schuffelen     )
282*5c591343SA. Cody Schuffelen {
283*5c591343SA. Cody Schuffelen     assert(startOffset + size <= NV_MEMORY_SIZE);
284*5c591343SA. Cody Schuffelen     memcpy(data, &s_NV[startOffset], size);     // Copy data from RAM
285*5c591343SA. Cody Schuffelen     return;
286*5c591343SA. Cody Schuffelen }
287*5c591343SA. Cody Schuffelen 
288*5c591343SA. Cody Schuffelen //*** _plat__NvIsDifferent()
289*5c591343SA. Cody Schuffelen // This function checks to see if the NV is different from the test value. This is
290*5c591343SA. Cody Schuffelen // so that NV will not be written if it has not changed.
291*5c591343SA. Cody Schuffelen //  Return Type: int
292*5c591343SA. Cody Schuffelen //      TRUE(1)         the NV location is different from the test value
293*5c591343SA. Cody Schuffelen //      FALSE(0)        the NV location is the same as the test value
294*5c591343SA. Cody Schuffelen LIB_EXPORT int
_plat__NvIsDifferent(unsigned int startOffset,unsigned int size,void * data)295*5c591343SA. Cody Schuffelen _plat__NvIsDifferent(
296*5c591343SA. Cody Schuffelen     unsigned int     startOffset,   // IN: read start
297*5c591343SA. Cody Schuffelen     unsigned int     size,          // IN: size of bytes to read
298*5c591343SA. Cody Schuffelen     void            *data           // IN: data buffer
299*5c591343SA. Cody Schuffelen     )
300*5c591343SA. Cody Schuffelen {
301*5c591343SA. Cody Schuffelen     return (memcmp(&s_NV[startOffset], data, size) != 0);
302*5c591343SA. Cody Schuffelen }
303*5c591343SA. Cody Schuffelen 
304*5c591343SA. Cody Schuffelen //***_plat__NvMemoryWrite()
305*5c591343SA. Cody Schuffelen // This function is used to update NV memory. The "write" is to a memory copy of
306*5c591343SA. Cody Schuffelen // NV. At the end of the current command, any changes are written to
307*5c591343SA. Cody Schuffelen // the actual NV memory.
308*5c591343SA. Cody Schuffelen // NOTE: A useful optimization would be for this code to compare the current
309*5c591343SA. Cody Schuffelen // contents of NV with the local copy and note the blocks that have changed. Then
310*5c591343SA. Cody Schuffelen // only write those blocks when _plat__NvCommit() is called.
311*5c591343SA. Cody Schuffelen LIB_EXPORT int
_plat__NvMemoryWrite(unsigned int startOffset,unsigned int size,void * data)312*5c591343SA. Cody Schuffelen _plat__NvMemoryWrite(
313*5c591343SA. Cody Schuffelen     unsigned int     startOffset,   // IN: write start
314*5c591343SA. Cody Schuffelen     unsigned int     size,          // IN: size of bytes to write
315*5c591343SA. Cody Schuffelen     void            *data           // OUT: data buffer
316*5c591343SA. Cody Schuffelen     )
317*5c591343SA. Cody Schuffelen {
318*5c591343SA. Cody Schuffelen     if(startOffset + size <= NV_MEMORY_SIZE)
319*5c591343SA. Cody Schuffelen     {
320*5c591343SA. Cody Schuffelen         memcpy(&s_NV[startOffset], data, size);     // Copy the data to the NV image
321*5c591343SA. Cody Schuffelen         return TRUE;
322*5c591343SA. Cody Schuffelen     }
323*5c591343SA. Cody Schuffelen     return FALSE;
324*5c591343SA. Cody Schuffelen }
325*5c591343SA. Cody Schuffelen 
326*5c591343SA. Cody Schuffelen //***_plat__NvMemoryClear()
327*5c591343SA. Cody Schuffelen // Function is used to set a range of NV memory bytes to an implementation-dependent
328*5c591343SA. Cody Schuffelen // value. The value represents the erase state of the memory.
329*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__NvMemoryClear(unsigned int start,unsigned int size)330*5c591343SA. Cody Schuffelen _plat__NvMemoryClear(
331*5c591343SA. Cody Schuffelen     unsigned int     start,         // IN: clear start
332*5c591343SA. Cody Schuffelen     unsigned int     size           // IN: number of bytes to clear
333*5c591343SA. Cody Schuffelen     )
334*5c591343SA. Cody Schuffelen {
335*5c591343SA. Cody Schuffelen     assert(start + size <= NV_MEMORY_SIZE);
336*5c591343SA. Cody Schuffelen     // In this implementation, assume that the erase value for NV is all 1s
337*5c591343SA. Cody Schuffelen     memset(&s_NV[start], 0xff, size);
338*5c591343SA. Cody Schuffelen }
339*5c591343SA. Cody Schuffelen 
340*5c591343SA. Cody Schuffelen //***_plat__NvMemoryMove()
341*5c591343SA. Cody Schuffelen // Function: Move a chunk of NV memory from source to destination
342*5c591343SA. Cody Schuffelen //      This function should ensure that if there overlap, the original data is
343*5c591343SA. Cody Schuffelen //      copied before it is written
344*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__NvMemoryMove(unsigned int sourceOffset,unsigned int destOffset,unsigned int size)345*5c591343SA. Cody Schuffelen _plat__NvMemoryMove(
346*5c591343SA. Cody Schuffelen     unsigned int     sourceOffset,  // IN: source offset
347*5c591343SA. Cody Schuffelen     unsigned int     destOffset,    // IN: destination offset
348*5c591343SA. Cody Schuffelen     unsigned int     size           // IN: size of data being moved
349*5c591343SA. Cody Schuffelen     )
350*5c591343SA. Cody Schuffelen {
351*5c591343SA. Cody Schuffelen     assert(sourceOffset + size <= NV_MEMORY_SIZE);
352*5c591343SA. Cody Schuffelen     assert(destOffset + size <= NV_MEMORY_SIZE);
353*5c591343SA. Cody Schuffelen     memmove(&s_NV[destOffset], &s_NV[sourceOffset], size);      // Move data in RAM
354*5c591343SA. Cody Schuffelen     return;
355*5c591343SA. Cody Schuffelen }
356*5c591343SA. Cody Schuffelen 
357*5c591343SA. Cody Schuffelen //***_plat__NvCommit()
358*5c591343SA. Cody Schuffelen // This function writes the local copy of NV to NV for permanent store. It will write
359*5c591343SA. Cody Schuffelen // NV_MEMORY_SIZE bytes to NV. If a file is use, the entire file is written.
360*5c591343SA. Cody Schuffelen //  Return Type: int
361*5c591343SA. Cody Schuffelen //  0       NV write success
362*5c591343SA. Cody Schuffelen //  non-0   NV write fail
363*5c591343SA. Cody Schuffelen LIB_EXPORT int
_plat__NvCommit(void)364*5c591343SA. Cody Schuffelen _plat__NvCommit(
365*5c591343SA. Cody Schuffelen     void
366*5c591343SA. Cody Schuffelen     )
367*5c591343SA. Cody Schuffelen {
368*5c591343SA. Cody Schuffelen #if FILE_BACKED_NV
369*5c591343SA. Cody Schuffelen     return (NvFileCommit() ? 0 : 1);
370*5c591343SA. Cody Schuffelen #else
371*5c591343SA. Cody Schuffelen     return 0;
372*5c591343SA. Cody Schuffelen #endif
373*5c591343SA. Cody Schuffelen }
374*5c591343SA. Cody Schuffelen 
375*5c591343SA. Cody Schuffelen //***_plat__SetNvAvail()
376*5c591343SA. Cody Schuffelen // Set the current NV state to available.  This function is for testing purpose
377*5c591343SA. Cody Schuffelen // only.  It is not part of the platform NV logic
378*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__SetNvAvail(void)379*5c591343SA. Cody Schuffelen _plat__SetNvAvail(
380*5c591343SA. Cody Schuffelen     void
381*5c591343SA. Cody Schuffelen     )
382*5c591343SA. Cody Schuffelen {
383*5c591343SA. Cody Schuffelen     s_NvIsAvailable = TRUE;
384*5c591343SA. Cody Schuffelen     return;
385*5c591343SA. Cody Schuffelen }
386*5c591343SA. Cody Schuffelen 
387*5c591343SA. Cody Schuffelen //***_plat__ClearNvAvail()
388*5c591343SA. Cody Schuffelen // Set the current NV state to unavailable.  This function is for testing purpose
389*5c591343SA. Cody Schuffelen // only.  It is not part of the platform NV logic
390*5c591343SA. Cody Schuffelen LIB_EXPORT void
_plat__ClearNvAvail(void)391*5c591343SA. Cody Schuffelen _plat__ClearNvAvail(
392*5c591343SA. Cody Schuffelen     void
393*5c591343SA. Cody Schuffelen     )
394*5c591343SA. Cody Schuffelen {
395*5c591343SA. Cody Schuffelen     s_NvIsAvailable = FALSE;
396*5c591343SA. Cody Schuffelen     return;
397*5c591343SA. Cody Schuffelen }
398*5c591343SA. Cody Schuffelen 
399*5c591343SA. Cody Schuffelen //*** _plat__NVNeedsManufacture()
400*5c591343SA. Cody Schuffelen // This function is used by the simulator to determine when the TPM's NV state
401*5c591343SA. Cody Schuffelen // needs to be manufactured.
402*5c591343SA. Cody Schuffelen LIB_EXPORT int
_plat__NVNeedsManufacture(void)403*5c591343SA. Cody Schuffelen _plat__NVNeedsManufacture(
404*5c591343SA. Cody Schuffelen     void
405*5c591343SA. Cody Schuffelen     )
406*5c591343SA. Cody Schuffelen {
407*5c591343SA. Cody Schuffelen #if FILE_BACKED_NV
408*5c591343SA. Cody Schuffelen     return s_NeedsManufacture;
409*5c591343SA. Cody Schuffelen #else
410*5c591343SA. Cody Schuffelen     return FALSE;
411*5c591343SA. Cody Schuffelen #endif
412*5c591343SA. Cody Schuffelen }
413