Merge branch 'next' of gtgit01.gt.design.ti.com:git/projects/mcsdk-tools into next
[keystone-rtos/mcsdk-tools.git] / otp_writer / main.c
1 /**
2  *   @file  main.c
3  *
4  *   @brief   
5  *      OTP Writer main.  Used to unlock JTAG and write customer SMEK and SMPK keys
6  *      to the EFUSE.
7  *
8  *  \par
9  *  ============================================================================
10  *  @n   (C) Copyright 2012, Texas Instruments, Inc.
11  * 
12  *  Redistribution and use in source and binary forms, with or without 
13  *  modification, are permitted provided that the following conditions 
14  *  are met:
15  *
16  *    Redistributions of source code must retain the above copyright 
17  *    notice, this list of conditions and the following disclaimer.
18  *
19  *    Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the 
21  *    documentation and/or other materials provided with the   
22  *    distribution.
23  *
24  *    Neither the name of Texas Instruments Incorporated nor the names of
25  *    its contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
29  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
30  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
32  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
33  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
34  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
37  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
38  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  *  \par
41 */
43 /* Standard includes */
44 #include <stdio.h>
45 #include <string.h>
47 /* CSL types */
48 #include <ti/csl/tistdtypes.h>
50 /* OTP includes */
51 #include "otp.h"
53 extern Uint32 dataArr_smpk[];
54 extern Uint32 dataArr_smek[];
56 /* TOC Header Defines */
57 #define TOC_HEADER_ADDRESS ((Uint32) 0x0C000000)
58 #define TOC_HEADER_IMAGE_SIZE_FIELD  ((Uint32) 4)
59 #define TOC_HEADER_RESERVED_FIELD  ((Uint32) 8)
60 #define TOC_HEADER_LOAD_ADDR_FIELD  ((Uint32) 16)
61 #define TOC_HEADER_STRING_FIELD  ((Uint32) 20)
63 /* Key File Defines */
64 #define KEY_FILE_ID_JTAG  ((Uint32) 0x00000001)
65 #define KEY_FILE_ID_SMEK  ((Uint32) 0x00000002)
66 #define KEY_FILE_ID_SMPK  ((Uint32) 0x00000003)
68 #define KEY_FILE_OPEN_JTAG ((Uint32) 0x00000001)
70 /* JTAG unlock address */
71 #define SEC_TAP_EN  *((volatile unsigned int *)0x02500028)
73 void main (void)
74 {
75     Uint32 *tocHdrPtr = &testTocHeader[0];  /* (Uint32 *) TOC_HEADER_ADDRESS; */
76     Char *tocHdrStrPtr;
77     Char *tocHdrName = "2ND";
78     Uint32 *tocHdrResFields = tocHdrPtr + (TOC_HEADER_RESERVED_FIELD/4);
79     Uint32 *keyFilePtr;
80     Uint32 keyFileSizeBytes; 
81     Uint32 keyFileEndAddr;
82     Otp_writeCfg otpWrCfg;
83     Otp_Status otpStatus;
85     /* Image data load address (4th 32-bit word) */
86     if (*(tocHdrPtr + (TOC_HEADER_LOAD_ADDR_FIELD/4)))
87     {
88         /* Return if the load address field of the image data is populated.  When the
89           * load address field is populated an image is to be run.  Keys are not supposed
90           * to be written */
91         return;
92     }
94     /* Assign the TOC header string pointer to the first string section in the 
95      * TOC header (5th 32-bit word) */
96     tocHdrStrPtr = (Char *) (TOC_HEADER_ADDRESS + TOC_HEADER_STRING_FIELD);
98     /* Return if "2ND" string is not in the TOC header */
99     if (strncmp(tocHdrStrPtr, tocHdrName, 3))
100     {
101         return;
102     }
104     /* Key file offset is first entry in TOC header (1st 32-bit word) */
105     /* Initialize to start of TOC header prior to adding offset and 
106       * add offset from TOC header */
107     keyFilePtr = (Uint32 *) (TOC_HEADER_ADDRESS + *tocHdrPtr);
108     
109     /* Key file size is second entry in TOC header (2nd 32-bit word) */
110     tocHdrPtr++;
111     keyFileSizeBytes = *tocHdrPtr;
113     if ((keyFileSizeBytes % 4) != 0)
114     {
115         /* Key file should be multiple of four bytes */
116         return;
117     }
119     /* Get end of Key File for parsing */
120     keyFileEndAddr = (Uint32) keyFilePtr + keyFileSizeBytes;
122     /* Parse key file and program keys */
123     while (((Uint32) keyFilePtr) != keyFileEndAddr)
124     {
125         /* Clear the OTP status */
126         otpStatus = Otp_status_INSTRUCTION_SUCCESSFUL;
127       
128         if (*keyFilePtr == KEY_FILE_ID_JTAG)
129         {
130             /* Check length */
131             keyFilePtr++;
132             if ((*keyFilePtr) != 0x1)
133             {
134                 /* Should only be 1 byte for JTAG command */
135                 return;
136             }
138             /* Get JTAG command */
139             keyFilePtr++;
140             if ((*keyFilePtr) == KEY_FILE_OPEN_JTAG)
141             {
142                 /* Allow emulation access */
143                 SEC_TAP_EN = 0xffffffff;
145                 /* Also allow ARM debug access */
146                 *((unsigned int *)0x2620630) = 0x1fff;
147             }
149             /* Go to next Key File entry */
150             keyFilePtr++;
151         }
152         else if ((*keyFilePtr) == KEY_FILE_ID_SMEK)
153         {
154             /* Check length */
155             keyFilePtr++;
156             if ((*keyFilePtr) != (OTP_SMEK_SIZE_32BIT_WORDS * 4))
157             {
158                 /* WIPE IF ERROR?! */
159               
160                 /* SMEK should be 20 bytes total - 4 bytes ECC + 16 data bytes */
161                 return;
162             }
164             /* Send the data to the OTP driver */
165             keyFilePtr++;
166             /* FOR TESTING DO NOT WRITE OR READ PROTECT */
167 #if 0            
168             otpWrCfg.maxWrAttempts = 7;
169             otpWrCfg.writeProtect = 0;
170             otpWrCfg.readProtect = 0;
171             otpStatus = Otp_smekWrite (&keyFilePtr[0], &otpWrCfg);
172 #endif
173             /* Use first of reserved fields to return SMEK status to Host */
174             *tocHdrResFields = (Uint32) otpStatus;
176             /* Wipe SMEK out of memory */
177             memset((void *)&keyFilePtr[0], 0, (OTP_SMEK_SIZE_32BIT_WORDS * 4));
179             /* Go to next Key File entry */
180             keyFilePtr += OTP_SMEK_SIZE_32BIT_WORDS;
181         }
182         else if ((*keyFilePtr) == KEY_FILE_ID_SMPK)
183         {
184             /* Check length */
185             keyFilePtr++;
186             if ((*keyFilePtr) != (OTP_SMPK_SIZE_32BIT_WORDS * 4))
187             {
188                 /* WIPE IF ERROR?! */
189               
190                 /* SMPK should be 40 bytes total - 8 bytes ECC + 32 data bytes */
191                 return;
192             }
194             /* Send the data to the OTP driver */
195             keyFilePtr++;
196             /* FOR TESTING DO NOT WRITE OR READ PROTECT */
197 #if 0            
198             otpWrCfg.maxWrAttempts = 7;
199             otpWrCfg.writeProtect = 0;
200             otpWrCfg.readProtect = 0;
201             otpStatus = Otp_smpkWrite (&keyFilePtr[0], &otpWrCfg);
202 #endif
203             /* Use second of reserved fields to return SMEK status to Host */
204             tocHdrResFields++;
205             *tocHdrResFields = (Uint32) otpStatus;
207             /* Wipe SMPK out of memory */
208             memset((void *)&keyFilePtr[0], 0, (OTP_SMPK_SIZE_32BIT_WORDS * 4));
209            
210             /* Go to next Key File entry */
211             keyFilePtr += OTP_SMPK_SIZE_32BIT_WORDS;
212         }
213         else
214         { 
215             /* Skip any other types */
216             Uint32 keyFileEntrySizeWords;
218             /* Get entry size and round up to nearest 32-bit word */
219             keyFilePtr++;
220             keyFileEntrySizeWords = (*keyFilePtr) / 4;
221             if (((*keyFilePtr) % 4) != 0)
222             {
223                 keyFileEntrySizeWords++;
224             }
226             /* Jump to next Key File entry */
227             keyFilePtr++;
228             keyFilePtr += keyFileEntrySizeWords;
229         }
230     }
233     for (;;){}