From 4085ae3ddfbbf10c8ccbd3dccd43452c40a1fe40 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Fri, 13 Mar 2015 12:24:52 +0200 Subject: Add bootloader, nfclib and sensorlib --- boot_loader/bl_crc32.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 boot_loader/bl_crc32.c (limited to 'boot_loader/bl_crc32.c') diff --git a/boot_loader/bl_crc32.c b/boot_loader/bl_crc32.c new file mode 100644 index 0000000..9413987 --- /dev/null +++ b/boot_loader/bl_crc32.c @@ -0,0 +1,267 @@ +//***************************************************************************** +// +// bl_crc32.c - CRC32 calculation functions used in the boot loader. +// +// Copyright (c) 2013-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the Tiva Firmware Development Package. +// +//***************************************************************************** +#include +#include +#include "inc/hw_types.h" +#include "inc/hw_flash.h" +#include "inc/hw_sysctl.h" +#include "bl_config.h" +#include "boot_loader/bl_crc32.h" + +//***************************************************************************** +// +// Storage for the CRC32 calculation lookup table. +// +//***************************************************************************** +static uint32_t g_pui32CRC32Table[256]; + +//***************************************************************************** +// +// Initialize the CRC32 calculation table for the polynomial used. We pick +// the commonly used ANSI X 3.66 polymonial. This code was informed by an +// example found at http://www.createwindow.com/programming/crc32/index.htm. +// +//***************************************************************************** +static uint32_t +Reflect(uint32_t ui32Ref, uint8_t ui8Ch) +{ + uint_fast32_t ui32Value; + int_fast16_t i16Loop; + + // + // Clear our accumulator variable. + // + ui32Value = 0; + + // + // Swap bit 0 for bit 7, bit 1 for bit 6, etc. + // + for(i16Loop = 1; i16Loop < (ui8Ch + 1); i16Loop++) + { + if(ui32Ref & 1) + { + ui32Value |= 1 << (ui8Ch - i16Loop); + } + ui32Ref >>= 1; + } + + // + // Return the reflected value. + // + return(ui32Value); +} + +//***************************************************************************** +// +// Initialize the lookup table used in calculating the CRC32 value. +// +//***************************************************************************** +void +InitCRC32Table(void) +{ + uint_fast32_t ui32Polynomial; + int_fast16_t i16Loop, i16Bit; + + // + // This is the ANSI X 3.66 polynomial as required by the DFU + // specification. + // + ui32Polynomial = 0x04c11db7; + + for(i16Loop = 0; i16Loop <= 0xFF; i16Loop++) + { + g_pui32CRC32Table[i16Loop]=Reflect(i16Loop, 8) << 24; + for (i16Bit = 0; i16Bit < 8; i16Bit++) + { + g_pui32CRC32Table[i16Loop] = ((g_pui32CRC32Table[i16Loop] << 1) ^ + (g_pui32CRC32Table[i16Loop] & + ((uint32_t)1 << 31) ? + ui32Polynomial : 0)); + } + g_pui32CRC32Table[i16Loop] = Reflect(g_pui32CRC32Table[i16Loop], 32); + } +} + +//***************************************************************************** +// +// Calculate the CRC for the supplied block of data. +// +//***************************************************************************** +uint32_t +CalculateCRC32(uint8_t *pui8Data, uint32_t ui32Length, uint32_t ui32CRC) +{ + uint32_t ui32Count; + uint8_t *pui8Buffer; + uint8_t ui8Char; + + // + // Get a pointer to the start of the data and the number of bytes to + // process. + // + pui8Buffer = pui8Data; + ui32Count = ui32Length; + + // + // Perform the algorithm on each byte in the supplied buffer using the + // lookup table values calculated in InitCRC32Table(). + // + while(ui32Count--) + { + ui8Char = *pui8Buffer++; + ui32CRC = (ui32CRC >> 8) ^ g_pui32CRC32Table[(ui32CRC & 0xFF) ^ + ui8Char]; + } + + // + // Return the result. + // + return(ui32CRC); +} + +//***************************************************************************** +// +//! Checks that the embedded CRC in the image matches the expected value. +//! +//! \param pui32Image points to the start of the firmware image in memory. +//! +//! This function finds the firmware image information header and verifies that +//! the embedded CRC32 matches one calculated over the image. +//! +//! \return Returns \b CHECK_CRC_OK if the CRC calculated matches the value +//! embedded in the image, \b CHECK_CRC_NO_HEADER if no image information +//! header was found at the top of the vector table, \b CHECK_CRC_BAD_CRC if +//! an embedded CRC was found but did not match the calculated value or \b +//! CHECK_CRC_ZERO_LENGTH if the length field of the image information header +//! contains 0 (likely indicating that the image had not been run through the +//! binpack tool which inserts the length and CRC values into the header). +// +//***************************************************************************** +uint32_t +CheckImageCRC32(uint32_t *pui32Image) +{ + uint32_t ui32Loop, ui32FlashSize, ui32CRC; + + // + // Determine the size of flash (giving an upper bound for the image + // size). + // + if(CLASS_IS_TM4C129) + { + // + // Get the flash size from the FLASH_PP register. + // + ui32FlashSize = ((2048 * ((HWREG(FLASH_PP) & FLASH_PP_SIZE_M) + 1)) - + APP_START_ADDRESS); + } + else + { + // + // Compute the size of the flash. + // + ui32FlashSize = (((HWREG(SYSCTL_DC0) & SYSCTL_DC0_FLASHSZ_M) << 11) + + 0x800 - APP_START_ADDRESS); + } + + // + // Scan for the image information header marker bytes. Given that the + // largest possible vector table includes 16 system exceptions and 240 + // IC-specific vectors, we only need to search 257 words into memory before + // giving up. + // + for(ui32Loop = 0; ui32Loop < 257; ui32Loop++) + { + // + // Have we found the header marker words? + // + if((pui32Image[ui32Loop] == 0xFF01FF02) && + (pui32Image[ui32Loop + 1] == 0xFF03FF04)) + { + // + // Yes. Check to see if the length field is 0xFFFFFFFF. This + // likely indicates that the image has not been processed by the + // binpack tool which adds the length and CRC information to the + // image header. + // + if(pui32Image[ui32Loop + 2] == 0xFFFFFFFF) + { + // + // The header reports an image size of 0 so we can't go on and + // check the CRC. + // + return(CHECK_CRC_NO_LENGTH); + } + + // + // Extract the image length and ensure that it is sensible + // given the flash size. We assume the length is invalid if it + // is larger than the available flash size or smaller than the + // space taken up by the vector table and header we've already + // scanned through. + // + if((pui32Image[ui32Loop + 2] > ui32FlashSize) || + (pui32Image[ui32Loop + 2] < + ((ui32Loop + 4) * sizeof(uint32_t)))) + { + // + // The header reports an image size that is larger than the + // available flash so this is obviously incorrect. Fail the + // check. + // + return(CHECK_CRC_BAD_LENGTH); + } + + // + // Calculate the CRC32 value for the image. Note that we skip the + // 4 bytes that hold the check CRC. + // + ui32CRC = CalculateCRC32((uint8_t *)pui32Image, + (ui32Loop + 3) * sizeof(uint32_t), + 0xffffffff); + ui32CRC = CalculateCRC32((uint8_t *)&pui32Image[ui32Loop + 4], + (pui32Image[ui32Loop + 2] - + ((ui32Loop + 4) * sizeof(uint32_t))), + ui32CRC); + ui32CRC ^= 0xffffffff; + + // + // Determine whether the calculated CRC matches the value stored + // in the image information header. + // + if(ui32CRC == pui32Image[ui32Loop + 3]) + { + return(CHECK_CRC_OK); + } + else + { + return(CHECK_CRC_BAD_CRC); + } + } + } + + // + // If we drop out the loop, there was no image information header so + // fail the call. + // + return(CHECK_CRC_NO_HEADER); +} -- cgit v1.3.1