17de6fd1e52109fabf087ab77316bd09ab273ac8
[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 <string.h>
35 #include "platform.h"
36 #include "types.h"
37 #include "post.h"
39 /* The version string */
40 #pragma DATA_SECTION(post_version, ".version")
41 #pragma DATA_ALIGN(post_version, 16)
42 char post_version[] = POST_VERSION;
44 /* OSAL functions for Platform Library */
45 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
46 {
47         return malloc(num_bytes);
48 }
50 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
51 {
52     /* Free up the memory */
53     if (dataPtr)
54     {
55         free(dataPtr);
56     }
57 }
59 /******************************************************************************
60  * Function:    post_display_led_error
61  ******************************************************************************/
62 void
63 post_display_led_error
64 (
65     POST_TEST_ID     test_id
66 )
67 {
68     uint8_t     led_status[POST_MAX_NUM_LED];
69     uint32_t    i;
71     memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
72     while (TRUE)
73     {
74         for (i = 0; i < POST_MAX_NUM_LED; i++)
75         {
76             if (post_led_status[test_id][i] == POST_LED_BLINK)
77             {
78                 if (led_status[i] == POST_LED_ON)
79                 {
80                     led_status[i] = POST_LED_OFF;
81                 }
82                 else
83                 {
84                     led_status[i] = POST_LED_ON;
85                 }
86                 platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS);
87             }
88             else
89             {
90                 platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS);
91             }
92         }
93         platform_delay(POST_LED_BLINK_DELAY);
94         /* POST in the while(1) loop to display the LED error status */
95     }
96 }
98 /******************************************************************************
99  * Function:    post_write_uart
100  ******************************************************************************/
101 Bool
102 post_write_uart
104     char*      msg
107     uint32_t i;
108     uint32_t msg_len = strlen(msg);
110     /* Write the message to the UART */
111     for (i = 0; i < msg_len; i++)
112     {
113         if (platform_uart_write(msg[i]) != Platform_EOK)
114         {
115             return FALSE;
116         }
117     }
119     return TRUE;
122 /******************************************************************************
123  * Function:    post_display_status
124  ******************************************************************************/
125 void
126 post_display_status
128     POST_TEST_ID        test_id,
129     Bool                test_passed
132     uint32_t    i;
133     char        *msg;
134     char        msg1[40] = "\r\n\r\nPOST ";
135     char        msg2[] = " test passed!";
136     char        msg3[] = " test failed!";
138     msg = strcat(msg1, post_status[test_id]);
139     switch (test_id)
140     {
141     case POST_TEST_IN_PROGRESS:
142     case POST_TEST_COMPLETE:
143         /* Form the POST status message to write to the UART */
144         if (post_write_uart(msg) != TRUE)
145         {
146             post_display_led_error(POST_TEST_UART);   /* Never return from this function */
147         }
149         for (i = 0; i < POST_MAX_NUM_LED; i++)
150         {
151             if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK)
152             {
153                 post_write_uart("POST LED test failed \r\n");
154             }
155         }
156         break;
158     default:
159         /* Form the POST status message to write to the UART */
160         if (test_passed)
161         {
162             msg = strcat(msg, msg2);
163             if (post_write_uart(msg) != TRUE)
164             {
165                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
166             }
167         }
168         else
169         {
170             msg = strcat(msg, msg3);
171             if (post_write_uart(msg) != TRUE)
172             {
173                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
174             }
175             post_display_led_error(test_id);  /* Never return from this function */
176         }
177         break;
178     }
181 /******************************************************************************
182  * Function:    post_test_external_memory
183  ******************************************************************************/
184 Bool
185 post_test_external_memory
187     void
190     Bool    test_passed = TRUE;
192     if(platform_external_memory_test(0, 0) != Platform_EOK)
193     {
194         test_passed = FALSE;
195     }
197     return test_passed;
200 /******************************************************************************
201  * Function:    post_test_eeprom
202  ******************************************************************************/
203 Bool
204 post_test_eeprom
206     void
209     uint8_t                 test_buf[POST_EEPROM_TEST_READ_LENGTH];
210     Bool                    test_passed = TRUE;
211     PLATFORM_DEVICE_info    *p_device;
213     p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
214     if (p_device == NULL)
215     {
216         return FALSE;
217     }
219     if(platform_device_read(p_device->handle,
220                             POST_EEPROM_TEST_READ_ADDRESS,
221                             test_buf,
222                             POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK)
223     {
224         test_passed = FALSE;
225     }
227     platform_device_close(p_device->handle);
228     return test_passed;
231 /******************************************************************************
232  * Function:    post_test_nand
233  ******************************************************************************/
234 Bool
235 post_test_nand
237     void
240     uint8_t                 test_buf[POST_NAND_TEST_READ_LENGTH];
241     Bool                    test_passed = TRUE;
242     uint32_t                addr;
243     PLATFORM_DEVICE_info    *p_device;
245     p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
246     if (p_device == NULL)
247     {
248         return FALSE;
249     }
251     addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
252     if(platform_device_read(p_device->handle,
253                             addr,
254                             test_buf,
255                             POST_NAND_TEST_READ_LENGTH) != Platform_EOK)
256     {
257         test_passed = FALSE;
258     }
260     platform_device_close(p_device->handle);
261     return test_passed;
264 /******************************************************************************
265  * Function:    post_test_nor
266  ******************************************************************************/
267 Bool
268 post_test_nor
270     void
273     uint8_t                 test_buf[POST_NOR_TEST_READ_LENGTH];
274     Bool                    test_passed = TRUE;
275     PLATFORM_DEVICE_info    *p_device;
277     p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
278     if (p_device == NULL)
279     {
280         return FALSE;
281     }
283     if(platform_device_read(p_device->handle,
284                             POST_NOR_TEST_READ_ADDR,
285                             test_buf,
286                             POST_NOR_TEST_READ_LENGTH) != Platform_EOK)
287     {
288         test_passed = FALSE;
289     }
291     platform_device_close(p_device->handle);
292     return test_passed;
295 void
296 post_hex_to_string
298     uint32_t    hex,
299     uint32_t    nibbles,
300     char        *msg
303     int32_t     i;
304     uint8_t     nibble;
306     for (i = (nibbles-1); i >= 0; i--)
307     {
308         nibble = hex & 0xf;
309         if (nibble <= 0x9)
310         {
311             nibble += '0';
312         }
313         else
314         {
315             nibble += ('A' - 0xa);
316         }
318         msg[i] = nibble;
319         hex = hex >> 4;
320     }
321     msg[nibbles] = 0;
324 Bool
325 post_serial_num_isvalid
327     char    c
330     if (
331         ((c >= '0') && (c <= '9'))    ||
332         ((c >= 'a') && (c <= 'z'))    ||
333         ((c >= 'A') && (c <= 'Z'))
334        )
335     {
336         return TRUE;
337     }
338     else
339     {
340         return FALSE;
341     }
344 /******************************************************************************
345  * Function:    post_write_serial_no
346  ******************************************************************************/
347 void
348 post_write_serial_no
350     void
353     uint32_t                i, j;
354     uint8_t                 msg[20], msg2[2];
355     PLATFORM_DEVICE_info    *p_device;
357     /* Check if user key in the passcode "ti" to enter board serial number */
358     if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
359     {
360         return;
361     }
362     if (msg[0] != 't')
363     {
364         return;
365     }
367     if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
368     {
369         return;
370     }
371     if (msg[0] != 'i')
372     {
373         return;
374     }
376     /* Passcode verified, prompt the user to enter serial number */
377     p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
378     if (p_device == NULL)
379     {
380         return;
381     }
383     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");
385     i = 0;
386     msg2[1] = 0;
387     while (TRUE)
388     {
389         if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK)
390         {
391             platform_device_close(p_device->handle);
392             post_write_uart("\r\n\r\nSerial number input time out!");
393             return;
394         }
396         if (msg[i] == '\r')
397         {
398             break;
399         }
400         if ((i < POST_MAX_SN_SIZE) &&  post_serial_num_isvalid(msg[i]))
401         {
402             msg2[0] = msg[i];
403             post_write_uart((char *)msg2);
404             i++;
405         }
406     }
408     if (i < POST_MAX_SN_SIZE)
409     {
410         for (j = i; j < POST_MAX_SN_SIZE; j++)
411         {
412             msg[j] = 0xff;
413         }
414     }
416     if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
417     {
418         post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
419     }
420     else
421     {
422         post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!");
423     }
424     platform_device_close(p_device->handle);
428 /******************************************************************************
429  * Function:    main function for POST
430  ******************************************************************************/
431 void
432 main
434     void
437     platform_init_flags     init_flags;
438     platform_init_config    init_config;
439     POST_TEST_ID            test_id = POST_TEST_IN_PROGRESS;
440     Bool                    test_passed = TRUE;
441     uint32_t                reset_type;
442     int32_t                 i;
443     char                    msg[9];
444     uint8_t                 mac_addr[6];
445     platform_info           info;
446     uint32_t                sa_enable;
448     /* Turn on all the platform initialize flags */
449     memset(&init_config, 0, sizeof(platform_init_config));
450     memset(&init_flags, 0x01, sizeof(platform_init_flags));
452     /* Initialize the platform */
453     if (platform_init(&init_flags, &init_config) != Platform_EOK)
454     {
455         switch (platform_errno)
456         {
457         case PLATFORM_ERRNO_PLL_SETUP:
458             test_id = POST_TEST_PLL_INIT;
459             break;
460         case PLATFORM_ERRNO_NAND:
461             test_id = POST_TEST_NAND_INIT;
462             break;
463         case PLATFORM_ERRNO_NOR:
464             test_id = POST_TEST_NOR_INIT;
465             break;
466         default:
467             test_id = POST_TEST_GENERAL;
468             break;
469         }
470         test_passed = FALSE;
471     }
473     platform_uart_init();
474     platform_uart_set_baudrate(POST_UART_BAUDRATE);
475     if (test_id != POST_TEST_PLL_INIT)
476     {
477         if (post_write_uart("\r\n\r\n") != TRUE)
478         {
479             post_display_led_error(POST_TEST_UART);   /* Never return from this function */
480         }
482         platform_get_info(&info);
484         /* Display the board name */
485         post_write_uart(info.board_name);
487         /* Display the POST version */
488         post_write_uart(POST_EVM_VERSION_MSG);
489         post_write_uart(post_version);
491         post_hex_to_string(info.board_rev, 4, msg);
492         post_write_uart("\r\n\r\nFPGA Version: ");
493         post_write_uart(msg);
495         if (info.serial_nbr[0] != 0)
496         {
497             post_write_uart("\r\n\r\nBoard Serial Number: ");
498             post_write_uart(info.serial_nbr);
499         }
501         /* Display the EFUSE MAC address */
502         platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr);
503         post_write_uart("\r\n\r\nEFUSE MAC ID is: ");
504         for (i = 0; i < 6; i++)
505         {
506             post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg);
507             msg[2] = ' ';
508             msg[3] = 0;
509             post_write_uart(msg);
510         }
512         sa_enable = *(volatile uint32_t *)0x20c0004;
513         sa_enable &= 0x1;
515         if (sa_enable)
516         {
517             post_write_uart("\r\n\r\nSA is enabled on this board.");
518         }
519         else
520         {
521             post_write_uart("\r\n\r\nSA is disabled on this board.");
522         }
524         /* Read the PLL Reset Type Status register and display on UART */
525         reset_type = PLL_CTRL_REG_RSTYPE;
526         post_hex_to_string(reset_type, 8, msg);
527         post_write_uart("\r\n\r\nPLL Reset Type Status Register: 0x");
528         post_write_uart(msg);
529     }
531     /* Display test in progress UART/LED status or init error */
532     post_display_status(test_id, test_passed);
534     test_passed = post_test_external_memory();
535     post_display_status(POST_TEST_DDR, test_passed);
537     test_passed = post_test_eeprom();
538     post_display_status(POST_TEST_EEPROM, test_passed);
540     test_passed = post_test_nor();
541     post_display_status(POST_TEST_NOR, test_passed);
543     test_passed = post_test_nand();
544     post_display_status(POST_TEST_NAND, test_passed);
546     post_display_status(POST_TEST_COMPLETE, TRUE);
548     post_write_serial_no();