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