SAMV71 Xplained Ultra Software Package 1.3

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT ICMLL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
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 samv7 ultra 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 SAM V71 Xplained Ultra board. 
00053  *     Please refer to the Getting Started with SAM V71 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 rates
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  *      -- SAMxxxxxx-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     uint32_t status;
00128     status = ICM_GetIntStatus();
00129     if (status & ICM_ISR_RHC_Msk) {
00130         regionHashCompleted |= (status & ICM_ISR_RHC_Msk);
00131         ICM_DisableIt(status & ICM_ISR_RHC_Msk);
00132     }
00133     if (status & ICM_ISR_RDM_Msk) {
00134         regionDigestMismatch |= ((status & ICM_ISR_RDM_Msk)>> ICM_ISR_RDM_Pos);
00135         ICM_DisableIt((status & ICM_ISR_RDM_Msk) >> ICM_ISR_RDM_Pos);
00136     }
00137 }
00138 
00139 /**
00140  * \brief Generate message for given ASCII string.
00141  * \param M pointer to string
00142  * \param message pointer to buffer to store generated message.
00143  * \param length string length in byte.
00144  * \param longMsg 1: long message otherwise 0.
00145  * \note Maximum length is 32-bits only.
00146  */
00147 static void _buildMessage32(uint8_t *M, uint32_t *message, uint32_t length, 
00148         uint8_t longMsg)
00149 {
00150     uint32_t l;
00151     uint32_t l_high,l_low;
00152     uint32_t k;
00153     uint8_t *pBuf; 
00154     pBuf = (uint8_t *)message;
00155     l = length * 8;
00156     k = ((512 + 448) - ( (l % 512) + 1)) % 512;
00157     if (longMsg)
00158         memset (pBuf, (*M), length);
00159     else
00160         memcpy (pBuf, M, length);
00161     pBuf+= length;
00162     /* Append the bit '0' to the end of the message*/
00163     *pBuf++ = 0x80;
00164     /* followed by  k zero bits */
00165     memset (pBuf, 0, (k - 7) / 8 );
00166     /* Then append the 64-bit block length*/
00167     pBuf += (k - 7 ) / 8;
00168     l_high = 0;
00169     l_low = (uint32_t)(l & 0xffffffff);
00170     *pBuf++ = (l_high >> 24) & 0xFF;
00171     *pBuf++ = (l_high >> 16) & 0xFF;
00172     *pBuf++ = (l_high >> 8) & 0xFF;
00173     *pBuf++ = (l_high ) & 0xFF;
00174     *pBuf++ = (l_low >> 24) & 0xFF;
00175     *pBuf++ = (l_low >> 16) & 0xFF;
00176     *pBuf++ = (l_low >> 8) & 0xFF;
00177     *pBuf++ = (l_low ) & 0xFF;
00178 }
00179 
00180 /*----------------------------------------------------------------------------
00181  *        Exported functions
00182  *----------------------------------------------------------------------------*/
00183 
00184 /**
00185  *  \brief ICM Application entry point.
00186  *
00187  *  \return Unused (ANSI-C compatibility).
00188  *  \callgraph
00189  */
00190 int main( void )
00191 {
00192     uint32_t mainListAddr;
00193     LinkedListDescriporIcmRegion *pMainList;
00194     /* Disable watchdog */
00195     WDT_Disable( WDT ) ;
00196 
00197     /* Output example information */
00198     printf("-- ICM Example %s --\n\r", SOFTPACK_VERSION ) ;
00199     printf("-- %s\n\r", BOARD_NAME);
00200     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00201 
00202         /* Enable SDRAM */
00203     BOARD_ConfigureSdram();
00204     
00205     bufOutput = (uint32_t*)SDRAM_CS_ADDR;
00206     bufContext= (uint32_t*)(SDRAM_CS_ADDR + 0x100000);
00207     pMainList = (LinkedListDescriporIcmRegion*)((uint32_t*)(SDRAM_CS_ADDR + 0x20000));
00208     mainListAddr = (uint32_t)pMainList;
00209 
00210     /* Enable ICM peripheral clock */
00211     PMC_EnablePeripheral(ID_ICM);
00212 
00213     /* A software triggered hardware reset of the ICM interface is performed */
00214     ICM_SoftReset();
00215     /* Configure and enable ICM interrupt */ 
00216     NVIC_ClearPendingIRQ(ICM_IRQn);
00217     NVIC_EnableIRQ(ICM_IRQn);
00218 
00219     ICM_GetIntStatus();
00220     ICM_GetStatus();
00221 
00222     /* Build message */
00223     _buildMessage32(msgRegion_0, bufContext, LEN_STRING_0, 0);
00224     _buildMessage32(msgRegion_1, bufContext + MSG_0_LENGTH, LEN_STRING_1, 0);
00225     _buildMessage32(&msgRegion_2, bufContext + MSG_0_LENGTH + MSG_1_LENGTH, \
00226             LEN_STRING_LONG, 1);
00227 
00228     ICM_Configure(ICM_CFG_UALGO_SHA1|ICM_CFG_SLBDIS);
00229     pMainList->icm_raddr = (uint32_t)bufContext;
00230     pMainList->icm_rcfg = ICM_RCFG_ALGO_SHA1;
00231     pMainList->icm_rctrl = MSG_0_LENGTH /16 -1;
00232     pMainList->icm_rnext = 0;
00233     pMainList++;
00234     pMainList->icm_raddr = (uint32_t)(bufContext + MSG_0_LENGTH);
00235     pMainList->icm_rcfg = ICM_RCFG_ALGO_SHA1;
00236     pMainList->icm_rctrl = MSG_1_LENGTH /16 -1;;
00237     pMainList->icm_rnext = 0;
00238     pMainList++;
00239     pMainList->icm_raddr = (uint32_t)(bufContext + MSG_0_LENGTH + MSG_1_LENGTH);
00240     pMainList->icm_rcfg = ICM_RCFG_EOM | ICM_RCFG_ALGO_SHA1;
00241     pMainList->icm_rctrl = LEN_STRING_LONG / 4 /16 - 1;
00242     pMainList->icm_rnext = 0;
00243 
00244     ICM_SetDescStartAddress((uint32_t)mainListAddr);
00245     ICM_SetHashStartAddress((uint32_t)bufOutput);
00246     regionHashCompleted = 0;
00247     regionDigestMismatch = 0;
00248     printf("-I- Enable ICM region(0-2)...\n\r");
00249     ICM_EnableIt(ICM_IER_RHC(ID_REGION0 | ID_REGION1 | ID_REGION2));
00250     ICM_Enable();
00251     while(regionHashCompleted != (ID_REGION0 | ID_REGION1 | ID_REGION2));
00252     printf("-I- When the desired number of blocks have been transferred, \
00253     the digest is whether moved to memory (write-back function) \n\r");
00254     ICM_Disable();
00255 
00256     regionHashCompleted = 0;
00257     regionDigestMismatch = 0;
00258     printf("-I- Configure ICM region(0-2) with compare function\n\r");
00259     printf("-I- When the desired number of blocks have been transferred, the \
00260     digest is compared with a digest reference located in system memory. \n\r");
00261     ICM_Configure(ICM_CFG_UALGO_SHA1 | ICM_CFG_SLBDIS | ICM_CFG_WBDIS);
00262     ICM_EnableIt(ICM_IER_RHC(ID_REGION0 | ID_REGION1 | ID_REGION2)
00263             |ICM_IER_RDM(ID_REGION0 | ID_REGION1 | ID_REGION2));
00264     printf("-I- Enable ICM region(0-2)...\n\r");
00265     ICM_Enable();
00266     while(regionHashCompleted != (ID_REGION0 | ID_REGION1 | ID_REGION2));
00267     if (regionDigestMismatch == 0) 
00268         printf("-I- No digest mismatch occurs!\n\r");
00269     ICM_Disable();
00270 
00271     printf("-I- Change the context in region 1 for test...\n\r");
00272     _buildMessage32(msgRegion_mis1, bufContext + MSG_0_LENGTH, LEN_STRING_1, 0);
00273     ICM_Configure(ICM_CFG_UALGO_SHA1 |ICM_CFG_SLBDIS | ICM_CFG_WBDIS);
00274     regionHashCompleted = 0;
00275     regionDigestMismatch = 0;
00276     ICM_EnableMonitor((ID_REGION0 | ID_REGION1 | ID_REGION2));
00277     ICM_EnableIt(ICM_IER_RHC(ID_REGION0 | ID_REGION1 | ID_REGION2)
00278                 |ICM_IER_RDM(ID_REGION0 | ID_REGION1 | ID_REGION2));
00279     ICM_Enable();
00280     while(regionHashCompleted != (ID_REGION0 | ID_REGION1 | ID_REGION2));
00281     printf ("-I- Digest mismatch occurs @ region(s) %x \n\r", 
00282             (unsigned int)regionDigestMismatch);
00283     ICM_Disable();
00284 
00285     printf("\n\r-I- ICM test done!\n\r");
00286     while(1);
00287 }
00288 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines