1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MATH - demos
3   File:     main.c
4 
5   Copyright 2007-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 /*---------------------------------------------------------------------------*
18   Demo to confirm operation of digest functions in Math library.
19   Runs high-speed comparisons.
20  *---------------------------------------------------------------------------*/
21 
22 #ifdef SDK_TWL
23 #include <twl.h>
24 #else
25 #include <nitro.h>
26 #endif
27 
28 static void VBlankIntr(void);
29 static void DisplayInit(void);
30 static void CompareDigestSpeed(void);
31 static u16 CalcCRC16(void *datap, u32 size);
32 static u32 CalcCRC32(void *datap, u32 size);
33 
34 /*---------------------------------------------------------------------------*
35     Variable Definitions
36  *---------------------------------------------------------------------------*/
37 
38 /*---------------------------------------------------------------------------*
39     Function definitions
40  *---------------------------------------------------------------------------*/
41 
42 /*---------------------------------------------------------------------------*
43   Name:         NitroMain
44 
45   Description:  Initialization and main loop
46 
47   Arguments:    None
48 
49   Returns:      None
50  *---------------------------------------------------------------------------*/
51 #ifdef SDK_TWL
TwlMain(void)52 void TwlMain(void)
53 #else
54 void NitroMain(void)
55 #endif
56 {
57     // Various types of initialization
58     OS_Init();
59     OS_InitTick();
60 
61     DisplayInit();
62 
63     CompareDigestSpeed();
64 
65     // Main loop
66     while (TRUE)
67     {
68         // Waiting for the V-Blank
69         OS_WaitVBlankIntr();
70     }
71 }
72 
73 /*---------------------------------------------------------------------------*
74   Name:         VBlankIntr
75 
76   Description:  V-Blank interrupt vector
77 
78   Arguments:    None
79 
80   Returns:      None
81  *---------------------------------------------------------------------------*/
VBlankIntr(void)82 static void VBlankIntr(void)
83 {
84     // Sets the IRQ check flag
85     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
86 }
87 
88 /*---------------------------------------------------------------------------*
89   Name:         DisplayInit
90 
91   Description:  Graphics Initialization
92 
93   Arguments:    None
94 
95   Returns:      None
96  *---------------------------------------------------------------------------*/
DisplayInit(void)97 static void DisplayInit(void)
98 {
99 
100     GX_Init();
101     FX_Init();
102 
103     GX_DispOff();
104     GXS_DispOff();
105 
106     GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
107 
108     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
109     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
110     (void)GX_VBlankIntr(TRUE);         // To generate V-Blank interrupt request
111     (void)OS_EnableIrq();
112 
113 
114     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
115     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
116 
117     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);   // Clear OAM
118     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);     // Clear the standard palette
119 
120     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);     // Clear OAM
121     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);       // Clear the standard palette
122     MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
123 
124 
125     GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB);       // Set VRAM-A,B for OBJ
126 
127     GX_SetGraphicsMode(GX_DISPMODE_VRAM_C,      // VRAM mode
128                        (GXBGMode)0,    // Dummy
129                        (GXBG0As)0);    // Dummy
130 
131     GX_SetVisiblePlane(GX_PLANEMASK_OBJ);       // Make OBJs visible
132     GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K);   // 2D mapping OBJ
133 
134     OS_WaitVBlankIntr();               // Waiting for the end of the V-Blank interrupt
135     GX_DispOn();
136 
137 }
138 
139 
140 /*---------------------------------------------------------------------------*
141   Name:         CompareDigestSpeed
142 
143   Description:  Test routine for digest function
144 
145   Arguments:    None
146 
147   Returns:      None
148  *---------------------------------------------------------------------------*/
149 #define DATA_SIZE (1024*1024)
CompareDigestSpeed(void)150 static void CompareDigestSpeed(void)
151 {
152     static u8 data[DATA_SIZE] ATTRIBUTE_ALIGN(32);
153     static MATHCRC8Table table_crc8;
154     static MATHCRC16Table table_crc16, table_crc16_ccitt;
155     static MATHCRC32Table table_crc32, table_crc32_posix;
156 
157     int     i;
158     MATHRandContext32 rand;
159     OSTick  start, end;
160     u8      digest[20];
161 
162     OS_TPrintf("Initialize Array...\n");
163     // Initializes data
164     MATH_InitRand32(&rand, 0);
165     for (i = 0; i < DATA_SIZE; i++)
166     {
167         data[i] = (u8)MATH_Rand32(&rand, 0x100);
168     }
169 
170     OS_TPrintf("Initialize CRC Tables...\n");
171     // Initializes table
172     MATH_CRC8InitTable(&table_crc8);
173     MATH_CRC16InitTable(&table_crc16);
174     MATH_CRC16CCITTInitTable(&table_crc16_ccitt);
175     MATH_CRC32InitTable(&table_crc32);
176     MATH_CRC32POSIXInitTable(&table_crc32_posix);
177 
178     OS_TPrintf("Start Comparing...\n");
179 
180     OS_TPrintf("Checksum8:\t");
181     start = OS_GetTick();
182     (void)MATH_CalcChecksum8(data, sizeof(data));
183     end = OS_GetTick();
184     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
185 
186     OS_TPrintf("Checksum16:\t");
187     start = OS_GetTick();
188     (void)MATH_CalcChecksum16(data, sizeof(data));
189     end = OS_GetTick();
190     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
191 
192     OS_TPrintf("CRC-8:\t\t");
193     start = OS_GetTick();
194     (void)MATH_CalcCRC8(&table_crc8, data, sizeof(data));
195     end = OS_GetTick();
196     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
197 
198     OS_TPrintf("CRC-16:\t\t");
199     start = OS_GetTick();
200     (void)MATH_CalcCRC16(&table_crc16, data, sizeof(data));
201     end = OS_GetTick();
202     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
203 
204     OS_TPrintf("CRC-16/CCITT:\t");
205     start = OS_GetTick();
206     (void)MATH_CalcCRC16CCITT(&table_crc16_ccitt, data, sizeof(data));
207     end = OS_GetTick();
208     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
209 
210     OS_TPrintf("CRC-32:\t\t");
211     start = OS_GetTick();
212     (void)MATH_CalcCRC32(&table_crc32, data, sizeof(data));
213     end = OS_GetTick();
214     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
215 
216     OS_TPrintf("CRC-32/POSIX:\t");
217     start = OS_GetTick();
218     (void)MATH_CalcCRC32POSIX(&table_crc32_posix, data, sizeof(data));
219     end = OS_GetTick();
220     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
221 
222     OS_TPrintf("MD5:\t\t");
223     start = OS_GetTick();
224     MATH_CalcMD5(digest, data, sizeof(data));
225     end = OS_GetTick();
226     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
227 
228     OS_TPrintf("SHA-1:\t\t");
229     start = OS_GetTick();
230     MATH_CalcSHA1(digest, data, sizeof(data));
231     end = OS_GetTick();
232     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
233 
234     OS_TPrintf("SHA256:\t\t");
235     start = OS_GetTick();
236     MATH_CalcSHA256(digest, data, sizeof(data));
237     end = OS_GetTick();
238     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
239 
240     OS_TPrintf("HMAC-MD5:\t");
241     start = OS_GetTick();
242     MATH_CalcHMACMD5(digest, data, sizeof(data), data, 32);
243     end = OS_GetTick();
244     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
245 
246     OS_TPrintf("HMAC-SHA-1:\t");
247     start = OS_GetTick();
248     MATH_CalcHMACSHA1(digest, data, sizeof(data), data, 32);
249     end = OS_GetTick();
250     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
251 
252     OS_TPrintf("HMAC-SHA-256:\t");
253     start = OS_GetTick();
254     MATH_CalcHMACSHA256(digest, data, sizeof(data), data, 32);
255     end = OS_GetTick();
256     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
257 
258     OS_TPrintf("CRC-16(SVC):\t");
259     start = OS_GetTick();
260     (void)SVC_GetCRC16(0, data, sizeof(data));
261     end = OS_GetTick();
262     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
263 
264 #ifdef SDK_TWL
265     if ( OS_IsRunOnTwl() )
266     {
267         OS_TPrintf("SHA-1(SVC):\t");
268         start = OS_GetTick();
269         SVC_CalcSHA1(digest, data, sizeof(data));
270         end = OS_GetTick();
271         OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
272 
273         OS_TPrintf("HMAC-SHA-1(SVC):");
274         start = OS_GetTick();
275         SVC_CalcHMACSHA1(digest, data, sizeof(data), data, 32);
276         end = OS_GetTick();
277         OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
278     }
279 #endif
280 
281     // Reference mounting using a small table
282     OS_TPrintf("CRC-16(4bit):\t");
283     start = OS_GetTick();
284     (void)CalcCRC16(data, sizeof(data));
285     end = OS_GetTick();
286     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
287 
288     OS_TPrintf("CRC-32(4bit):\t");
289     start = OS_GetTick();
290     (void)CalcCRC32(data, sizeof(data));
291     end = OS_GetTick();
292     OS_Printf("%lld us/MB\n", OS_TicksToMicroSeconds(end - start));
293 
294     OS_TPrintf("Done.\n");
295 
296     return;
297 }
298 
299 // Reference mounting
300 /*---------------------------------------------------------------------------*
301   Name:         CalcCRC16
302 
303   Description:  Calculates CRC-16 using 4-bit units.
304                 Although the table size is small (32 bytes), this is 1.5 times slower than the MATH_CalcCRC16 function.
305 
306 
307   Arguments:    datap - Pointer to data
308                 size - Size of calculated data
309 
310   Returns:      u16   - Result of CRC calculation
311  *---------------------------------------------------------------------------*/
CalcCRC16(void * datap,u32 size)312 static u16 CalcCRC16(void *datap, u32 size)
313 {
314     // Table for CRC-16 calculation (for calculating in 4-bit units)
315     // It is the same as the table calculated by the MATH_CRC16InitTable function with the following values removed: 0, 0x10, 0x20, and so on up to 0xf0
316     //
317     // If the crc16_table is set by the u32 array, speed increases even more
318     static const u16 crc16_table[16] = {
319         0x0000, 0xCC01, 0xD801, 0x1400,
320         0xF001, 0x3C00, 0x2800, 0xE401,
321         0xA001, 0x6C00, 0x7800, 0xB401,
322         0x5000, 0x9C01, 0x8801, 0x4400,
323     };
324 
325     u32     r = 0;                     // Initializes CRC
326     u8     *p = (u8 *)datap;
327 
328     while (size--)
329     {
330         u32     data = *p;
331         p++;
332 
333         // Calculates CRC in 4-bit units
334         r = (r >> 4) ^ crc16_table[(r ^ data) & 0xf];
335         data >>= 4;
336 
337         r = (r >> 4) ^ crc16_table[(r ^ data) & 0xf];
338     }
339 
340     return (u16)r;
341 }
342 
343 /*---------------------------------------------------------------------------*
344   Name:         CalcCRC32
345 
346   Description:  Calculates CRC-32 using 4-bit units.
347                 Although the table size is small (64 bytes), this is 1.5 times slower than the MATH_CalcCRC32 function.
348 
349 
350   Arguments:    datap - Pointer to data
351                 size - Size of calculated data
352 
353   Returns:      u32   - CRC calculation results
354  *---------------------------------------------------------------------------*/
CalcCRC32(void * datap,u32 size)355 static u32 CalcCRC32(void *datap, u32 size)
356 {
357     // Table for CRC-32 calculation (for calculating in 4-bit units)
358     // It the same as the table calculated by the MATH_CRC32InitTable function with the following values removed: 0, 0x10, 0x20, and so on up to 0xf0
359     //
360     static const u32 crc32_table[16] = {
361         0x00000000U, 0x1DB71064U, 0x3B6E20C8U, 0x26D930ACU,
362         0x76DC4190U, 0x6B6B51F4U, 0x4DB26158U, 0x5005713CU,
363         0xEDB88320U, 0xF00F9344U, 0xD6D6A3E8U, 0xCB61B38CU,
364         0x9B64C2B0U, 0x86D3D2D4U, 0xA00AE278U, 0xBDBDF21CU,
365     };
366 
367     u32     r = 0xffffffffU;           // Initializes CRC
368     u8     *p = (u8 *)datap;
369 
370     while (size--)
371     {
372         u32     data = *p;
373         p++;
374 
375         // Calculates CRC in 4-bit units
376         r = (r >> 4) ^ crc32_table[(r ^ data) & 0xf];
377         data >>= 4;
378 
379         r = (r >> 4) ^ crc32_table[(r ^ data) & 0xf];
380     }
381 
382     return ~r;                         // Output is inverted
383 }
384 
385 /*---------------------------------------------------------------------------*
386   End of file
387  *---------------------------------------------------------------------------*/
388