SAMV71 Xplained Ultra Software Package 1.5

main.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /**
00031  *  \page icm Integrity Check Monitor Example
00032  *
00033  *  \section Purpose
00034  *  This application demonstrates The Integrity Check Monitor (ICM)
00035  *  peripheral integrated in some samv7 microcontrollers family. The ICM
00036  * controller integrates two modes of operation. The first one is used to hash
00037  * a list of memory regions and save the digests to memory (ICM Hash Area).
00038  * The second operation mode is an active monitoring of the memory.
00039  *
00040  * \section Requirements
00041  *
00042  *  This package can be used with SAMV71 Xplained Ultra board or SAME70 Xplained board.
00043  *
00044  * \section Description
00045  * This example shows how to configure ICM to performs SHA-based memory hashing
00046  * over memory regions. When the ICM module is enabled, it sequentially
00047  * retrieves a circular list of region descriptors from the memory. Up to 4
00048  * regions may be monitored.
00049  *
00050  *  \section Usage
00051  *
00052  *  -# Build the program and download it inside the board.
00053  *     Please refer to the Getting Started with SAM V71/E70 Microcontrollers.pdf
00054  *  -# On the computer, open and configure a terminal application
00055  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00056  *    - 115200 baud rate
00057  *    - 8 bits of data
00058  *    - No parity
00059  *    - 1 stop bit
00060  *    - No flow control
00061  *  -# In the terminal window, the
00062  *     following text should appear (values depend on the board and chip used):
00063  *     \code
00064  *      -- ICM Example xxx --
00065  *      -- SAMxxxxx-xx
00066  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00067  *      \endcode
00068  *  -# Input command according to the menu.
00069  *
00070  * \section References
00071  * - icm/main.c
00072  * - icm.h
00073  * - icm.h
00074  */
00075 
00076 /** \file
00077  *
00078  *  This file contains all the specific code for the ICM
00079  */
00080 
00081 /*----------------------------------------------------------------------------
00082  *        Headers
00083  *----------------------------------------------------------------------------*/
00084 #include <board.h>
00085 #include <string.h>
00086 
00087 /*----------------------------------------------------------------------------
00088  *        Local definitions
00089  *----------------------------------------------------------------------------*/
00090 #define LEN_STRING_0      3
00091 #define LEN_STRING_1      56
00092 #define LEN_STRING_LONG   (1000000)
00093 
00094 #define MSG_0_LENGTH      16
00095 #define MSG_1_LENGTH      32
00096 #define MSG_LONG_LENGTH   15626
00097 
00098 #define ID_REGION0      0x01
00099 #define ID_REGION1      0x02
00100 #define ID_REGION2      0x04
00101 #define ID_REGION3      0x08
00102 
00103 /*----------------------------------------------------------------------------
00104  *        Local variables
00105  *----------------------------------------------------------------------------*/
00106 static uint32_t *bufOutput;
00107 static uint32_t *bufContext;
00108 static volatile uint32_t regionHashCompleted, regionDigestMismatch;
00109 
00110 static uint8_t msgRegion_0[LEN_STRING_0]   = "abc";
00111 static uint8_t msgRegion_1[LEN_STRING_1]   =
00112     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
00113 static uint8_t msgRegion_mis1[LEN_STRING_1] =
00114     "aacdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
00115 /* Let the message M be the binary-coded form of the ASCII string which consists
00116     of 1,000,000 repetitions of the character Ħ°aĦħ. */
00117 static uint8_t msgRegion_2 = 'a';
00118 
00119 /*----------------------------------------------------------------------------
00120  *        Local functions
00121  *----------------------------------------------------------------------------*/
00122 
00123 /**
00124  * \brief ICM interrupt hander.
00125  */
00126 void ICM_Handler(void)
00127 {
00128     uint32_t status;
00129     status = ICM_GetIntStatus();
00130 
00131     if (status & ICM_ISR_RHC_Msk) {
00132         regionHashCompleted |= (status & ICM_ISR_RHC_Msk);
00133         ICM_DisableIt(status & ICM_ISR_RHC_Msk);
00134     }
00135 
00136     if (status & ICM_ISR_RDM_Msk) {
00137         regionDigestMismatch |= ((status & ICM_ISR_RDM_Msk) >> ICM_ISR_RDM_Pos);
00138         ICM_DisableIt((status & ICM_ISR_RDM_Msk) >> ICM_ISR_RDM_Pos);
00139     }
00140 }
00141 
00142 /**
00143  * \brief Generate message for given ASCII string.
00144  * \param M pointer to string
00145  * \param message pointer to buffer to store generated message.
00146  * \param length string length in byte.
00147  * \param longMsg 1: long message otherwise 0.
00148  * \note Maximum length is 32-bits only.
00149  */
00150 static void _buildMessage32(uint8_t *M, uint32_t *message, uint32_t length,
00151                             uint8_t longMsg)
00152 {
00153     uint32_t l;
00154     uint32_t l_high, l_low;
00155     uint32_t k;
00156     uint8_t *pBuf;
00157     pBuf = (uint8_t *)message;
00158     l = length * 8;
00159     k = ((512 + 448) - ( (l % 512) + 1)) % 512;
00160 
00161     if (longMsg)
00162         memset(pBuf, (*M), length);
00163     else
00164         memcpy(pBuf, M, length);
00165 
00166     pBuf += length;
00167     /* Append the bit '0' to the end of the message*/
00168     *pBuf++ = 0x80;
00169     /* followed by  k zero bits */
00170     memset(pBuf, 0, (k - 7) / 8 );
00171     /* Then append the 64-bit block length*/
00172     pBuf += (k - 7 ) / 8;
00173     l_high = 0;
00174     l_low = (uint32_t)(l & 0xffffffff);
00175     *pBuf++ = (l_high >> 24) & 0xFF;
00176     *pBuf++ = (l_high >> 16) & 0xFF;
00177     *pBuf++ = (l_high >> 8) & 0xFF;
00178     *pBuf++ = (l_high ) & 0xFF;
00179     *pBuf++ = (l_low >> 24) & 0xFF;
00180     *pBuf++ = (l_low >> 16) & 0xFF;
00181     *pBuf++ = (l_low >> 8) & 0xFF;
00182     *pBuf++ = (l_low ) & 0xFF;
00183 }
00184 
00185 /*----------------------------------------------------------------------------
00186  *        Exported functions
00187  *----------------------------------------------------------------------------*/
00188 
00189 /**
00190  *  \brief ICM Application entry point.
00191  *
00192  *  \return Unused (ANSI-C compatibility).
00193  *  \callgraph
00194  */
00195 int main(void)
00196 {
00197     uint32_t mainListAddr;
00198 
00199     LinkedListDescriporIcmRegion *pMainList;
00200     /* Disable watchdog */
00201     WDT_Disable(WDT);
00202 
00203     /* Output example information */
00204     printf("-- ICM Example %s --\n\r", SOFTPACK_VERSION );
00205     printf("-- %s\n\r", BOARD_NAME);
00206     printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ ,
00207             COMPILER_NAME);
00208 
00209     /* Enable SDRAM */
00210     BOARD_ConfigureSdram();
00211 
00212     bufOutput = (uint32_t *)SDRAM_CS_ADDR;
00213     bufContext = (uint32_t *)(SDRAM_CS_ADDR + 0x100000);
00214     pMainList = (LinkedListDescriporIcmRegion *)((uint32_t *)(
00215                     SDRAM_CS_ADDR + 0x20000));
00216     mainListAddr = (uint32_t)pMainList;
00217 
00218     /* Enable ICM peripheral clock */
00219     PMC_EnablePeripheral(ID_ICM);
00220 
00221     /* A software triggered hardware reset of the ICM interface is performed */
00222     ICM_SoftReset();
00223     /* Configure and enable ICM interrupt */
00224     NVIC_ClearPendingIRQ(ICM_IRQn);
00225     NVIC_EnableIRQ(ICM_IRQn);
00226 
00227     ICM_GetIntStatus();
00228     ICM_GetStatus();
00229 
00230     /* Build message */
00231     _buildMessage32(msgRegion_0, bufContext, LEN_STRING_0, 0);
00232     _buildMessage32(msgRegion_1, bufContext + MSG_0_LENGTH, LEN_STRING_1, 0);
00233     _buildMessage32(&msgRegion_2, bufContext + MSG_0_LENGTH + MSG_1_LENGTH, \
00234                     LEN_STRING_LONG, 1);
00235 
00236     ICM_Configure(ICM_CFG_UALGO_SHA1 | ICM_CFG_SLBDIS);
00237     pMainList->icm_raddr = (uint32_t)bufContext;
00238     pMainList->icm_rcfg = ICM_RCFG_ALGO_SHA1;
00239     pMainList->icm_rctrl = MSG_0_LENGTH / 16 - 1;
00240     pMainList->icm_rnext = 0;
00241     pMainList++;
00242     pMainList->icm_raddr = (uint32_t)(bufContext + MSG_0_LENGTH);
00243     pMainList->icm_rcfg = ICM_RCFG_ALGO_SHA1;
00244     pMainList->icm_rctrl = MSG_1_LENGTH / 16 - 1;
00245     pMainList->icm_rnext = 0;
00246     pMainList++;
00247     pMainList->icm_raddr = (uint32_t)(bufContext + MSG_0_LENGTH + MSG_1_LENGTH);
00248     pMainList->icm_rcfg = ICM_RCFG_EOM | ICM_RCFG_ALGO_SHA1;
00249     pMainList->icm_rctrl = LEN_STRING_LONG / 4 / 16 - 1;
00250     pMainList->icm_rnext = 0;
00251 
00252     ICM_SetDescStartAddress((uint32_t)mainListAddr);
00253     ICM_SetHashStartAddress((uint32_t)bufOutput);
00254     regionHashCompleted = 0;
00255     regionDigestMismatch = 0;
00256     printf("-I- Enable ICM region(0-2)...\n\r");
00257     ICM_EnableIt(ICM_IER_RHC(ID_REGION0 | ID_REGION1 | ID_REGION2));
00258     ICM_Enable();
00259 
00260     while (regionHashCompleted != (ID_REGION0 | ID_REGION1 | ID_REGION2));
00261 
00262     printf("-I- When the desired number of blocks have been transferred, \
00263     the digest is whether moved to memory (write-back function) \n\r");
00264     ICM_Disable();
00265 
00266     regionHashCompleted = 0;
00267     regionDigestMismatch = 0;
00268     printf("-I- Configure ICM region(0-2) with compare function\n\r");
00269     printf("-I- When the desired number of blocks have been transferred, the \
00270     digest is compared with a digest reference located in system memory. \n\r");
00271     ICM_Configure(ICM_CFG_UALGO_SHA1 | ICM_CFG_SLBDIS | ICM_CFG_WBDIS);
00272     ICM_EnableIt(ICM_IER_RHC(ID_REGION0 | ID_REGION1 | ID_REGION2)
00273                     | ICM_IER_RDM(ID_REGION0 | ID_REGION1 | ID_REGION2));
00274     printf("-I- Enable ICM region(0-2)...\n\r");
00275     ICM_Enable();
00276 
00277     while (regionHashCompleted != (ID_REGION0 | ID_REGION1 | ID_REGION2));
00278 
00279     if (regionDigestMismatch == 0)
00280         printf("-I- No digest mismatch occurs!\n\r");
00281 
00282     ICM_Disable();
00283 
00284     printf("-I- Change the context in region 1 for test...\n\r");
00285     _buildMessage32(msgRegion_mis1, bufContext + MSG_0_LENGTH, LEN_STRING_1, 0);
00286     ICM_Configure(ICM_CFG_UALGO_SHA1 | ICM_CFG_SLBDIS | ICM_CFG_WBDIS);
00287     regionHashCompleted = 0;
00288     regionDigestMismatch = 0;
00289     ICM_EnableMonitor((ID_REGION0 | ID_REGION1 | ID_REGION2));
00290     ICM_EnableIt(ICM_IER_RHC(ID_REGION0 | ID_REGION1 | ID_REGION2)
00291                     | ICM_IER_RDM(ID_REGION0 | ID_REGION1 | ID_REGION2));
00292     ICM_Enable();
00293 
00294     while (regionHashCompleted != (ID_REGION0 | ID_REGION1 | ID_REGION2));
00295 
00296     printf("-I- Digest mismatch occurs @ region(s) %x \n\r",
00297             (unsigned int)regionDigestMismatch);
00298     ICM_Disable();
00299 
00300     printf("\n\r-I- ICM test done!\n\r");
00301 
00302     while (1);
00303 }
00304 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines