New update to errata will be published regarding the vendor_usage field in the PFR. In ROM, the 16-bit monotonic counter is implemented in the upper 16 bits of the 32-bit VENDOR_USAGE field and the inverse of the monotonic counter is in the lower 16 bits. Users must take care when using the ROM API to increment the upper end of this field and write the inverse on the lower 16 bits in order for ROM to validate the value correctly.
The initial value that shall be written is 0x0000FFFF. Then the updates will be as follows: 0x0001FFFE 0x0002FFFD . . 0x0005FFFA . . 0x1010EFEF . . 0xFFFF0000
Example Code using ROM API:
*This example demonstrates the increment of the version in CFPA page as well as the vendor usage, it does not cover all use cases, so please use this as a reference only*
case APP_INCREASE_VENDOR_USAGE_ONLY:
PRINTF("Disable Flash Protect...\r\n");
/* Initialize flash driver */
FLASH_Init(&flashInstance);
if (FFR_Init(&flashInstance) == kStatus_Success)
{
PRINTF("Flash init successfull!!. Halting...\r\n");
}
else
{
error_trap();
}
status = FFR_GetCustomerInfieldData(&flashInstance, (uint8_t *)g_CFPAData, 0x0, FLASH_FFR_MAX_PAGE_SIZE);
PRINTF("\r\n");
PRINTF("Header 0x%08x , Version 0x%08x , SecureFW Version 0x%08x , NonSecureFW Version 0x%08x\r\n", g_CFPAData[0], g_CFPAData[1], g_CFPAData[2], g_CFPAData[3]);
PRINTF("ImageKey Revoke 0x%08x , Reserved 0x%08x , RothRevoke 0x%08x , Vendor Usage 0x%08x\r\n", g_CFPAData[4], g_CFPAData[5], g_CFPAData[6], g_CFPAData[7]);
PRINTF("NS PIN 0x%08x , NS DFLT 0x%08x , Enable FA Mode 0x%08x , Reserved1 0x%08x\r\n", g_CFPAData[8], g_CFPAData[9], g_CFPAData[10], g_CFPAData[11]);
PRINTF("\r\n");
/* Clean-up CFPA area */
g_CFPAData[8] = 0;
g_CFPAData[9] = 0;
/*Increase Monotonic counter*/
p32 = (uint32_t *)(uint32_t)g_CFPAData;
version = p32[1];
if (version == 0xFFFFFFFFu)
{
return kStatus_Fail;
}
version++;
p32[1] = version;
PRINTF("Version to write: 0x%08x \r\n", version);
/*Increase Vendor Usage*/
uint32_t vendor_usage = p32[7];
if(vendor_usage == 0x0)
{
vendorUsage_right = 0xFFFF;
vendorUsage_left = 0x0000;
}
else
{
vendorUsage_right = vendor_usage & 0xFFFF;
vendorUsage_left = vendor_usage >> 16;
}
vendorUsage_left += 0x1;
vendorUsage_right -= 0x1;
vendor_usage = (vendorUsage_left << 16) | vendorUsage_right;
p32[7] = vendor_usage;
PRINTF("Vendor_Usage to write: 0x%08x \r\n", vendor_usage);
Status = FFR_InfieldPageWrite(&flashInstance, (uint8_t *)g_CFPAData, FLASH_FFR_MAX_PAGE_SIZE);
if (kStatus_FLASH_Success == Status)
{
status = kStatus_Success;
PRINTF("CFPA Write Done!\r\n");
}
else
{
status = kStatus_Fail;
}
View full article