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