📄 otp_publickey.c
字号:
/*******************************************************************
Analog Devices, Inc. All Rights Reserved.
This software is proprietary and confidential. By using this software
you agree to the terms of the associated Analog Devices License Agreement.
Project Name: Power_On_Self_Test
Hardware: ADSP-BF518F EZ-Board
Description: This file contains tests which program the public key in OTP
and verifies that the public key has been programmed.
*******************************************************************/
/*******************************************************************
* include files
*******************************************************************/
#include <otp_helper_functions.h> /* otp helper file */
#include <otp_basic.h> /* basic otp driver interface */
#include "timer_isr.h"
#include "pbled_test.h"
#include "post_common.h"
/*#define READ_ONLY 1*/ /* if you wish to only read the key, uncomment this */
tOTP_public_key New_Public_Key = /* contains the customer public key to be programmed in OTP memory */
{ 0xA6,0xC0,0x9B,0x8A,0xA0,0x5D,0x1D,0xBB,
0x76,0xCE,0x39,0x1E,0x00,0x3D,0x19,0x43,
0xF2,0x8A,0x36,0x69,0x03,0x00,0x00,0x00,
0x1B,0x25,0x2E,0xCD,0xF7,0x6E,0x7F,0x16,
0x0F,0xE7,0x05,0xB0,0xE1,0xF1,0xD4,0x41,
0xC8,0x90,0x7A,0x5F,0x01,0x00,0x00,0x00
};
u64 Public_Key_Compare[6] =
{
0xbb1d5da08a9bc0a6,
0x43193d001e39ce76,
0x0000000369368af2,
0x167f6ef7cd2e251b,
0x41d4f1e1b005e70f,
0x000000015f7a90c8
};
extern int g_nPORTHIO;
/*******************************************************************
* function prototypes
*******************************************************************/
int PROGRAM_PUBLIC_KEY(void);
int CHECK_PUBLIC_KEY(void);
void DoneProgramPublicKey(int nResult);
void ClearOTPEnableFlag(void);
void SetOTPEnableFlag(void);
void InitOTPEnableFlag(void);
/*******************************************************************
* Function: ClearOTPEnableFlag
* Description: Clear the OTP enable flag
*******************************************************************/
void ClearOTPEnableFlag( void )
{
/* turn off PH3 for OTP enable flag */
*pPORTHIO_CLEAR = PH3;
}
/*******************************************************************
* Function: SetOTPEnableFlag
* Description: Set the OTP enable flag
*******************************************************************/
void SetOTPEnableFlag( void )
{
/* turn on PH3 for OTP enable flag*/
*pPORTHIO_SET = PH3;
}
/*******************************************************************
* Function: InitOTPEnableFlag
* Description: Init the OTP enable flag
*******************************************************************/
void InitOTPEnableFlag( void )
{
/* setup PH3 as an output */
*pPORTHIO_INEN &= ~PH3; /* disable */
*pPORTHIO_DIR |= PH3; /* output */
/* clear interrupt settings */
*pPORTHIO_EDGE &= ~PH3;
*pPORTHIO_MASKA_CLEAR = PH3;
/* now clear the flag */
*pPORTHIO_CLEAR = PH3;
}
/*******************************************************************
* Function: PROGRAM_PUBLIC_KEY
* Description: Main routine that will get launched from the POST
* framework to program the public key.
*******************************************************************/
int PROGRAM_PUBLIC_KEY(void)
{
u32 Result = 1;
u32 access_mode = ADI_OTP_ACCESS_READ;
u32 isempty;
u32 islocked;
u32 isunlocked;
u32 i = 0;
u64 store;
u32 compareIndex = 0;
bool bKeyDoesNotMatch = false;
int pbPressed = 0x0;
bool bTimeout = false;
/* init OTP enable flag */
InitOTPEnableFlag();
/* wait here until the user configures for OTP writes then presses PB1 (PH0);
if not pressed after ~30 secs, break out anyway so we don't supply the
OTP write voltage for too long */
unsigned int nTimer = SetTimeout(0x100000);
if( ((unsigned int)-1) != nTimer )
{
/* LED1 is shared with the OTP_EN so this shouldn't be toggled
we'll toggle LED2 and LED3 to indicate the tester
is able to configure jumper JP14 ON */
ClearSet_LED( LED2, 0x1);
ClearSet_LED( LED3, 0x0);
do
{
ClearSet_LED( LED2, 0x2); /* toggle */
ClearSet_LED( LED3, 0x2); /* toggle */
Delay(BLINK_SLOW); /* blink a little slower than cleanup */
bTimeout = IsTimedout(nTimer);
}while( ((g_nPORTHIO & 0x1) != 0x1) && (!bTimeout) );
}
ClearTimeout(nTimer);
/* clear global mirror register */
g_nPORTHIO &= ~PH0;
/* if there was a timeout make sure we clear
the OTP enable flash first and then fail */
if( bTimeout )
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
return 0;
}
/* turn on the OTP enable flag */
SetOTPEnableFlag();
/* give some time for OTP write voltage to settle */
Delay(BLINK_SLOW);
/* clear the timeout flag */
bTimeout = false;
/* open the basic OTP driver */
Result = otp_basic_Open();
if (Result != ADI_OTP_RESULT_SUCCESS)
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
DoneProgramPublicKey(0);
}
/* set the access mode for OTP read or write */
access_mode = ADI_OTP_ACCESS_READWRITE;
Result = otp_basic_Control( ADI_OTP_CMD_SET_ACCESS_MODE, &access_mode );
if (Result != ADI_OTP_RESULT_SUCCESS)
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
otp_basic_Close();
DoneProgramPublicKey(0);
}
/* check if the public key page is already programmed */
otp_gp_isempty (OTP_PUBLIC_KEY_PAGE, ADI_OTP_LOWER_HALF, OTP_PUBLIC_KEY_SIZE_IN_HALFPAGES, &isempty);
if (Result != ADI_OTP_RESULT_SUCCESS)
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
otp_basic_Close();
DoneProgramPublicKey(0);
}
/* check if the public key page is unlocked */
otp_gp_isunlocked (OTP_PUBLIC_KEY_PAGE, OTP_PUBLIC_KEY_SIZE_IN_PAGES, &isunlocked);
if (Result != ADI_OTP_RESULT_SUCCESS)
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
otp_basic_Close();
DoneProgramPublicKey(0);
}
#ifndef READ_ONLY
if (!isempty || !isunlocked)
#else
if ( 0 )
#endif
{
if(!isempty && !isunlocked)
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
/* we are alreay programmed and locked so just return */
otp_basic_Close();
DoneProgramPublicKey(1);
}
else
{
/* clear OTP enable flag */
ClearOTPEnableFlag();
/* the public key is either programmed or locked so
put up a warning flag because that should not be the case */
otp_basic_Close();
DoneProgramPublicKey(0);
}
}
else
{
#ifndef READ_ONLY
/* write the new public key */
OTP_ERROR_CATCH( otp_write_PublicKey (&New_Public_Key) , "otp_write_PublicKey" );
#endif
/* check the contents of the public key page and make sure it
matches what we expect */
for (i= OTP_PUBLIC_KEY_PAGE; (i< (OTP_PUBLIC_KEY_PAGE + OTP_PUBLIC_KEY_SIZE_IN_PAGES)) && !bKeyDoesNotMatch; i++)
{
if( Result == ADI_OTP_RESULT_SUCCESS )
{
Result = otp_read_page(i, ADI_OTP_LOWER_HALF, &store);
if( store != Public_Key_Compare[compareIndex++] )
bKeyDoesNotMatch = true;
}
if( (Result == ADI_OTP_RESULT_SUCCESS) && !bKeyDoesNotMatch )
{
Result = otp_read_page(i, ADI_OTP_UPPER_HALF, &store);
if( store != Public_Key_Compare[compareIndex++] )
bKeyDoesNotMatch = true;
}
}
/* we don't want to lock the key if it did not match */
if( bKeyDoesNotMatch )
{
otp_basic_Close();
DoneProgramPublicKey(0);
}
#ifndef READ_ONLY
/* we had a match so lock the public key page */
OTP_ERROR_CATCH( otp_lock_PublicKey () , "otp_lock_PublicKey" );
#endif
/* clear OTP enable flag */
ClearOTPEnableFlag();
}
if( Result != ADI_OTP_RESULT_SUCCESS )
DoneProgramPublicKey(0);
else
DoneProgramPublicKey(1);
/* close our driver */
otp_basic_Close();
return Result;
}
/*******************************************************************
* Function: DoneProgramPublicKey(int nResult)
* Description: This function toggles LED1 and LED2 to indicate to the user
* that the programming is complete, allowing the user to
* remove the OTP_FLAG_ENABLE jumper. Leaving that jumper on
* for an extended time may damage the processor.
*
* We do not want to risk driving the flag longer than necessary,
* so we do not allow a return from PROGRAM_PUBLIC_KEY() back
* to PerformTest() or main().
*******************************************************************/
void DoneProgramPublicKey(int nResult)
{
bool bTimeout = false;
unsigned int nTimer = SetTimeout(0x100000);
if( ((unsigned int)-1) != nTimer )
{
/* we'll toggle LED1 and LED2 to indicate the tester
is able to reconfigure jumper and switch
*** REMOVE OTP FLAG ENABLE JUMPER NOW!!! ***
*/
ClearSet_LED( LED2, 0x0);
ClearSet_LED( LED3, 0x1);
do
{
ClearSet_LED( LED2, 0x2); /* toggle */
ClearSet_LED( LED3, 0x2); /* toggle */
Delay(BLINK_SLOW*2); /* blink a little faster than setup */
bTimeout = IsTimedout(nTimer);
}while( ((g_nPORTHIO & 0x1) != 0x1) && (!bTimeout) );
}
ClearTimeout(nTimer);
/* clear global mirror register */
g_nPORTHIO &= ~PH0;
}
/*******************************************************************
* Function: CHECK_PUBLIC_KEY
* Description: Main routine that will get launched from the POST
* framework to check if the public key is programmed
* with the correct value and locked.
*******************************************************************/
int CHECK_PUBLIC_KEY(void)
{
u32 Result = ADI_DEV_RESULT_SUCCESS;
u32 access_mode = ADI_OTP_ACCESS_READ;
u32 isempty;
u32 islocked;
u32 isunlocked;
u32 i = 0;
u64 store;
u32 compareIndex = 0;
bool bKeyDoesNotMatch = false;
/* open the basic OTP driver */
Result = otp_basic_Open();
if (Result != ADI_OTP_RESULT_SUCCESS)
return 0;
access_mode = ADI_OTP_ACCESS_READWRITE;
Result = otp_basic_Control( ADI_OTP_CMD_SET_ACCESS_MODE, &access_mode );
if (Result != ADI_OTP_RESULT_SUCCESS)
{
otp_basic_Close();
return 0;
}
/* check if the public key is already programmed */
otp_gp_isempty (OTP_PUBLIC_KEY_PAGE, ADI_OTP_LOWER_HALF, OTP_PUBLIC_KEY_SIZE_IN_HALFPAGES, &isempty);
if (Result != ADI_OTP_RESULT_SUCCESS)
{
otp_basic_Close();
return 0;
}
otp_gp_isunlocked (OTP_PUBLIC_KEY_PAGE, OTP_PUBLIC_KEY_SIZE_IN_PAGES, &isunlocked);
if (Result != ADI_OTP_RESULT_SUCCESS)
{
otp_basic_Close();
return 0;
}
if (!isempty && !isunlocked)
{
/* read it back */
for (i= OTP_PUBLIC_KEY_PAGE; (i< (OTP_PUBLIC_KEY_PAGE + OTP_PUBLIC_KEY_SIZE_IN_PAGES)) && !bKeyDoesNotMatch; i++)
{
if( Result == ADI_OTP_RESULT_SUCCESS )
{
Result = otp_read_page(i, ADI_OTP_LOWER_HALF, &store);
if( Result != ADI_OTP_RESULT_SUCCESS )
break;
if( store != Public_Key_Compare[compareIndex++] )
bKeyDoesNotMatch = true;
}
if( (Result == ADI_OTP_RESULT_SUCCESS) && !bKeyDoesNotMatch )
{
Result = otp_read_page(i, ADI_OTP_UPPER_HALF, &store);
if( Result != ADI_OTP_RESULT_SUCCESS )
break;
if( store != Public_Key_Compare[compareIndex++] )
bKeyDoesNotMatch = true;
}
}
/* the key is either unlocked or not programmed */
otp_basic_Close();
if( bKeyDoesNotMatch || ( Result != ADI_OTP_RESULT_SUCCESS ) )
return 0;
else
return 1;
}
else
{
/* the key is either unlocked or not programmed */
otp_basic_Close();
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -