Added stdlib.h to include malloc and free functions
[keystone-rtos/mcsdk-tools.git] / post / src / post.c
1 /******************************************************************************
2  * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  *****************************************************************************/
34 #include <stdlib.h>
35 #include <string.h>
36 #include "platform.h"
37 #include "types.h"
38 #include "post.h"
40 /* The version string */
41 #pragma DATA_SECTION(post_version, ".version")
42 #pragma DATA_ALIGN(post_version, 16)
43 char post_version[] = POST_VERSION;
45 /* OSAL functions for Platform Library */
46 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
47 {
48         return malloc(num_bytes);
49 }
51 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
52 {
53     /* Free up the memory */
54     if (dataPtr)
55     {
56         free(dataPtr);
57     }
58 }
60 /******************************************************************************
61  * Function:    post_display_led_error
62  ******************************************************************************/
63 void
64 post_display_led_error
65 (
66     POST_TEST_ID     test_id
67 )
68 {
69     uint8_t     led_status[POST_MAX_NUM_LED];
70     uint32_t    i;
72     memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
73     while (TRUE)
74     {
75         for (i = 0; i < POST_MAX_NUM_LED; i++)
76         {
77             if (post_led_status[test_id][i] == POST_LED_BLINK)
78             {
79                 if (led_status[i] == POST_LED_ON)
80                 {
81                     led_status[i] = POST_LED_OFF;
82                 }
83                 else
84                 {
85                     led_status[i] = POST_LED_ON;
86                 }
87                 platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS);
88             }
89             else
90             {
91                 platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS);
92             }
93         }
94         platform_delay(POST_LED_BLINK_DELAY);
95         /* POST in the while(1) loop to display the LED error status */
96     }
97 }
99 /******************************************************************************
100  * Function:    post_write_uart
101  ******************************************************************************/
102 Bool
103 post_write_uart
105     char*      msg
108     uint32_t i;
109     uint32_t msg_len = strlen(msg);
111     /* Write the message to the UART */
112     for (i = 0; i < msg_len; i++)
113     {
114         if (platform_uart_write(msg[i]) != Platform_EOK)
115         {
116             return FALSE;
117         }
118     }
120     return TRUE;
123 /******************************************************************************
124  * Function:    post_display_status
125  ******************************************************************************/
126 void
127 post_display_status
129     POST_TEST_ID        test_id,
130     Bool                test_passed
133     uint32_t    i;
134     char        *msg;
135     char        msg1[40] = "\r\n\r\nPOST ";
136     char        msg2[] = " test passed!";
137     char        msg3[] = " test failed!";
139     msg = strcat(msg1, post_status[test_id]);
140     switch (test_id)
141     {
142     case POST_TEST_IN_PROGRESS:
143     case POST_TEST_COMPLETE:
144         /* Form the POST status message to write to the UART */
145         if (post_write_uart(msg) != TRUE)
146         {
147             post_display_led_error(POST_TEST_UART);   /* Never return from this function */
148         }
150         for (i = 0; i < POST_MAX_NUM_LED; i++)
151         {
152             if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK)
153             {
154                 post_write_uart("POST LED test failed \r\n");
155             }
156         }
157         break;
159     default:
160         /* Form the POST status message to write to the UART */
161         if (test_passed)
162         {
163             msg = strcat(msg, msg2);
164             if (post_write_uart(msg) != TRUE)
165             {
166                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
167             }
168         }
169         else
170         {
171             msg = strcat(msg, msg3);
172             if (post_write_uart(msg) != TRUE)
173             {
174                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
175             }
176             post_display_led_error(test_id);  /* Never return from this function */
177         }
178         break;
179     }
182 /******************************************************************************
183  * Function:    post_test_external_memory
184  ******************************************************************************/
185 Bool
186 post_test_external_memory
188     void
191     Bool    test_passed = TRUE;
193     if(platform_external_memory_test(0, 0) != Platform_EOK)
194     {
195         test_passed = FALSE;
196     }
198     return test_passed;
201 /******************************************************************************
202  * Function:    post_test_eeprom
203  ******************************************************************************/
204 Bool
205 post_test_eeprom
207     void
210     uint8_t                 test_buf[POST_EEPROM_TEST_READ_LENGTH];
211     Bool                    test_passed = TRUE;
212     PLATFORM_DEVICE_info    *p_device;
214     p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
215     if (p_device == NULL)
216     {
217         return FALSE;
218     }
220     if(platform_device_read(p_device->handle,
221                             POST_EEPROM_TEST_READ_ADDRESS,
222                             test_buf,
223                             POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK)
224     {
225         test_passed = FALSE;
226     }
228     platform_device_close(p_device->handle);
229     return test_passed;
232 /******************************************************************************
233  * Function:    post_test_nand
234  ******************************************************************************/
235 Bool
236 post_test_nand
238     void
241     uint8_t                 test_buf[POST_NAND_TEST_READ_LENGTH];
242     Bool                    test_passed = TRUE;
243     uint32_t                addr;
244     PLATFORM_DEVICE_info    *p_device;
246     p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
247     if (p_device == NULL)
248     {
249         return FALSE;
250     }
252     addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
253     if(platform_device_read(p_device->handle,
254                             addr,
255                             test_buf,
256                             POST_NAND_TEST_READ_LENGTH) != Platform_EOK)
257     {
258         test_passed = FALSE;
259     }
261     platform_device_close(p_device->handle);
262     return test_passed;
265 /******************************************************************************
266  * Function:    post_test_nor
267  ******************************************************************************/
268 Bool
269 post_test_nor
271     void
274     uint8_t                 test_buf[POST_NOR_TEST_READ_LENGTH];
275     Bool                    test_passed = TRUE;
276     PLATFORM_DEVICE_info    *p_device;
278     p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
279     if (p_device == NULL)
280     {
281         return FALSE;
282     }
284     if(platform_device_read(p_device->handle,
285                             POST_NOR_TEST_READ_ADDR,
286                             test_buf,
287                             POST_NOR_TEST_READ_LENGTH) != Platform_EOK)
288     {
289         test_passed = FALSE;
290     }
292     platform_device_close(p_device->handle);
293     return test_passed;
296 void
297 post_hex_to_string
299     uint32_t    hex,
300     uint32_t    nibbles,
301     char        *msg
304     int32_t     i;
305     uint8_t     nibble;
307     for (i = (nibbles-1); i >= 0; i--)
308     {
309         nibble = hex & 0xf;
310         if (nibble <= 0x9)
311         {
312             nibble += '0';
313         }
314         else
315         {
316             nibble += ('A' - 0xa);
317         }
319         msg[i] = nibble;
320         hex = hex >> 4;
321     }
322     msg[nibbles] = 0;
325 Bool
326 post_serial_num_isvalid
328     char    c
331     if (
332         ((c >= '0') && (c <= '9'))    ||
333         ((c >= 'a') && (c <= 'z'))    ||
334         ((c >= 'A') && (c <= 'Z'))
335        )
336     {
337         return TRUE;
338     }
339     else
340     {
341         return FALSE;
342     }
345 /******************************************************************************
346  * Function:    post_write_serial_no
347  ******************************************************************************/
348 void
349 post_write_serial_no
351     void
354     uint32_t                i, j;
355     uint8_t                 msg[20], msg2[2];
356     PLATFORM_DEVICE_info    *p_device;
358     /* Check if user key in the passcode "ti" to enter board serial number */
359     if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
360     {
361         return;
362     }
363     if (msg[0] != 't')
364     {
365         return;
366     }
368     if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
369     {
370         return;
371     }
372     if (msg[0] != 'i')
373     {
374         return;
375     }
377     /* Passcode verified, prompt the user to enter serial number */
378     p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
379     if (p_device == NULL)
380     {
381         return;
382     }
384     post_write_uart("\r\n\r\nPlease enter the 10 digit serial number for this board, and then press ENTER key:\r\n\r\n");
386     i = 0;
387     msg2[1] = 0;
388     while (TRUE)
389     {
390         if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK)
391         {
392             platform_device_close(p_device->handle);
393             post_write_uart("\r\n\r\nSerial number input time out!");
394             return;
395         }
397         if (msg[i] == '\r')
398         {
399             break;
400         }
401         if ((i < POST_MAX_SN_SIZE) &&  post_serial_num_isvalid(msg[i]))
402         {
403             msg2[0] = msg[i];
404             post_write_uart((char *)msg2);
405             i++;
406         }
407     }
409     if (i < POST_MAX_SN_SIZE)
410     {
411         for (j = i; j < POST_MAX_SN_SIZE; j++)
412         {
413             msg[j] = 0xff;
414         }
415     }
417     if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
418     {
419         post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
420     }
421     else
422     {
423         post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!");
424     }
425     platform_device_close(p_device->handle);
429 /******************************************************************************
430  * Function:    main function for POST
431  ******************************************************************************/
432 void
433 main
435     void
438     platform_init_flags     init_flags;
439     platform_init_config    init_config;
440     POST_TEST_ID            test_id = POST_TEST_IN_PROGRESS;
441     Bool                    test_passed = TRUE;
442     uint32_t                reset_type;
443     int32_t                 i;
444     char                    msg[9];
445     uint8_t                 mac_addr[6];
446     platform_info           info;
447     uint32_t                sa_enable;
449     /* Turn on all the platform initialize flags */
450     memset(&init_config, 0, sizeof(platform_init_config));
451     memset(&init_flags, 0x01, sizeof(platform_init_flags));
453     /* Initialize the platform */
454     if (platform_init(&init_flags, &init_config) != Platform_EOK)
455     {
456         switch (platform_errno)
457         {
458         case PLATFORM_ERRNO_PLL_SETUP:
459             test_id = POST_TEST_PLL_INIT;
460             break;
461         case PLATFORM_ERRNO_NAND:
462             test_id = POST_TEST_NAND_INIT;
463             break;
464         case PLATFORM_ERRNO_NOR:
465             test_id = POST_TEST_NOR_INIT;
466             break;
467         default:
468             test_id = POST_TEST_GENERAL;
469             break;
470         }
471         test_passed = FALSE;
472     }
474     platform_uart_init();
475     platform_uart_set_baudrate(POST_UART_BAUDRATE);
476     if (test_id != POST_TEST_PLL_INIT)
477     {
478         if (post_write_uart("\r\n\r\n") != TRUE)
479         {
480             post_display_led_error(POST_TEST_UART);   /* Never return from this function */
481         }
483         platform_get_info(&info);
485         /* Display the board name */
486         post_write_uart(info.board_name);
488         /* Display the POST version */
489         post_write_uart(POST_EVM_VERSION_MSG);
490         post_write_uart(post_version);
492         post_hex_to_string(info.board_rev, 4, msg);
493         post_write_uart("\r\n\r\nFPGA Version: ");
494         post_write_uart(msg);
496         if (info.serial_nbr[0] != 0)
497         {
498             post_write_uart("\r\n\r\nBoard Serial Number: ");
499             post_write_uart(info.serial_nbr);
500         }
502         /* Display the EFUSE MAC address */
503         platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr);
504         post_write_uart("\r\n\r\nEFUSE MAC ID is: ");
505         for (i = 0; i < 6; i++)
506         {
507             post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg);
508             msg[2] = ' ';
509             msg[3] = 0;
510             post_write_uart(msg);
511         }
513         sa_enable = *(volatile uint32_t *)0x20c0004;
514         sa_enable &= 0x1;
516         if (sa_enable)
517         {
518             post_write_uart("\r\n\r\nSA is enabled on this board.");
519         }
520         else
521         {
522             post_write_uart("\r\n\r\nSA is disabled on this board.");
523         }
525         /* Read the PLL Reset Type Status register and display on UART */
526         reset_type = PLL_CTRL_REG_RSTYPE;
527         post_hex_to_string(reset_type, 8, msg);
528         post_write_uart("\r\n\r\nPLL Reset Type Status Register: 0x");
529         post_write_uart(msg);
530     }
532     /* Display test in progress UART/LED status or init error */
533     post_display_status(test_id, test_passed);
535     test_passed = post_test_external_memory();
536     post_display_status(POST_TEST_DDR, test_passed);
538     test_passed = post_test_eeprom();
539     post_display_status(POST_TEST_EEPROM, test_passed);
541     test_passed = post_test_nor();
542     post_display_status(POST_TEST_NOR, test_passed);
544     test_passed = post_test_nand();
545     post_display_status(POST_TEST_NAND, test_passed);
547     post_display_status(POST_TEST_COMPLETE, TRUE);
549     post_write_serial_no();