2902574a9e300f90fe1b792bdcd07d7a0c7b9b53
[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 /******************************************************************************
45  * Function:    post_display_led_error  
46  ******************************************************************************/
47 void 
48 post_display_led_error
49 (
50     POST_TEST_ID     test_id
51 )
52 {
53     uint8_t     led_status[POST_MAX_NUM_LED];
54     uint32_t    i;
55         
56     memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
57     while (TRUE)
58     {
59         for (i = 0; i < POST_MAX_NUM_LED; i++)
60         {
61             if (post_led_status[test_id][i] == POST_LED_BLINK)
62             {
63                 if (led_status[i] == POST_LED_ON)
64                 {
65                     led_status[i] = POST_LED_OFF;
66                 }
67                 else
68                 {
69                     led_status[i] = POST_LED_ON;
70                 }
71                 platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS);
72             }
73             else
74             {
75                 platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS);
76             }
77         }
78         platform_delay(POST_LED_BLINK_DELAY);
79         /* POST in the while(1) loop to display the LED error status */
80     }
81 }
83 /******************************************************************************
84  * Function:    post_write_uart  
85  ******************************************************************************/
86 Bool 
87 post_write_uart
88 (
89     char*      msg
90 )
91 {
92     uint32_t i;
93     uint32_t msg_len = strlen(msg);
95     /* Write the message to the UART */
96     for (i = 0; i < msg_len; i++)
97     {
98         if (platform_uart_write(msg[i]) != Platform_EOK)
99         {
100             return FALSE;
101         }
102     }
104     return TRUE;
107 /******************************************************************************
108  * Function:    post_display_status  
109  ******************************************************************************/
110 void 
111 post_display_status
113     POST_TEST_ID        test_id,
114     Bool                test_passed
117     uint32_t    i;
118     char        *msg;
119     char        msg1[40] = "\r\n\r\nPOST ";
120     char        msg2[] = " test passed!";
121     char        msg3[] = " test failed!";
123     msg = strcat(msg1, post_status[test_id]);
124     switch (test_id)
125     {
126     case POST_TEST_IN_PROGRESS:
127     case POST_TEST_COMPLETE:
128         /* Form the POST status message to write to the UART */
129         if (post_write_uart(msg) != TRUE)
130         {
131             post_display_led_error(POST_TEST_UART);   /* Never return from this function */
132         }
134         for (i = 0; i < POST_MAX_NUM_LED; i++)
135         {
136             if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK)
137             {
138                 post_write_uart("POST LED test failed \r\n");
139             }
140         }
141         break;
143     default:
144         /* Form the POST status message to write to the UART */
145         if (test_passed)
146         {
147             msg = strcat(msg, msg2);
148             if (post_write_uart(msg) != TRUE)
149             {
150                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
151             }
152         }
153         else
154         {
155             msg = strcat(msg, msg3);
156             if (post_write_uart(msg) != TRUE)
157             {
158                 post_display_led_error(POST_TEST_UART);   /* Never return from this function */
159             }      
160             post_display_led_error(test_id);  /* Never return from this function */
161         }
162         break;
163     }
166 /******************************************************************************
167  * Function:    post_test_external_memory  
168  ******************************************************************************/
169 Bool 
170 post_test_external_memory
172     void
175     Bool    test_passed = TRUE;
177     if(platform_external_memory_test(0, 0) != Platform_EOK) 
178     {
179         test_passed = FALSE;
180     }
182     return test_passed;
185 /******************************************************************************
186  * Function:    post_test_eeprom  
187  ******************************************************************************/
188 Bool 
189 post_test_eeprom
191     void
194     uint8_t                 test_buf[POST_EEPROM_TEST_READ_LENGTH];
195     Bool                    test_passed = TRUE;
196     PLATFORM_DEVICE_info    *p_device;
198     p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
199     if (p_device == NULL) 
200     {
201         return FALSE;
202     }
204     if(platform_device_read(p_device->handle, 
205                             POST_EEPROM_TEST_READ_ADDRESS, 
206                             test_buf, 
207                             POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK) 
208     {
209         test_passed = FALSE;
210     }
212     platform_device_close(p_device->handle);
213     return test_passed;
216 /******************************************************************************
217  * Function:    post_test_nand  
218  ******************************************************************************/
219 Bool 
220 post_test_nand
222     void
225     uint8_t                 test_buf[POST_NAND_TEST_READ_LENGTH];
226     Bool                    test_passed = TRUE;
227     uint32_t                addr;
228     PLATFORM_DEVICE_info    *p_device;
230     p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
231     if (p_device == NULL) 
232     {
233         return FALSE;
234     }
236     addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
237     if(platform_device_read(p_device->handle, 
238                             addr, 
239                             test_buf, 
240                             POST_NAND_TEST_READ_LENGTH) != Platform_EOK) 
241     {
242         test_passed = FALSE;
243     }
245     platform_device_close(p_device->handle);
246     return test_passed;
249 /******************************************************************************
250  * Function:    post_test_nor 
251  ******************************************************************************/
252 Bool 
253 post_test_nor
255     void
258     uint8_t                 test_buf[POST_NOR_TEST_READ_LENGTH];
259     Bool                    test_passed = TRUE;
260     PLATFORM_DEVICE_info    *p_device;
262     p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
263     if (p_device == NULL) 
264     {
265         return FALSE;
266     }
268     if(platform_device_read(p_device->handle, 
269                             POST_NOR_TEST_READ_ADDR, 
270                             test_buf, 
271                             POST_NOR_TEST_READ_LENGTH) != Platform_EOK) 
272     {
273         test_passed = FALSE;
274     }
276     platform_device_close(p_device->handle);
277     return test_passed;
280 void
281 post_hex_to_string
283     uint32_t    hex,
284     uint32_t    nibbles,
285     char        *msg
288     int32_t     i;
289     uint8_t     nibble;
291     for (i = (nibbles-1); i >= 0; i--)
292     {
293         nibble = hex & 0xf;
294         if (nibble <= 0x9)
295         {
296             nibble += '0';
297         }
298         else
299         {
300             nibble += ('A' - 0xa);
301         }
303         msg[i] = nibble;
304         hex = hex >> 4;
305     }
306     msg[nibbles] = 0;
309 Bool
310 post_serial_num_isvalid
312     char    c
315     if (
316         ((c >= '0') && (c <= '9'))    ||
317         ((c >= 'a') && (c <= 'z'))    ||
318         ((c >= 'A') && (c <= 'Z'))
319        )
320     {
321         return TRUE;
322     }
323     else
324     {
325         return FALSE;
326     }
329 /******************************************************************************
330  * Function:    post_write_serial_no  
331  ******************************************************************************/
332 void 
333 post_write_serial_no
335     void
338     uint32_t                i, j;
339     uint8_t                 msg[20], msg2[2];
340     PLATFORM_DEVICE_info    *p_device;
341    
342     /* Check if user key in the passcode "ti" to enter board serial number */
343     if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) 
344     {
345         return;
346     }
347     if (msg[0] != 't')
348     {
349         return;
350     }
352     if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK) 
353     {
354         return;
355     }
356     if (msg[0] != 'i')
357     {
358         return;
359     }
361     /* Passcode verified, prompt the user to enter serial number */
362     p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
363     if (p_device == NULL) 
364     {
365         return;
366     }
368     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");
370     i = 0;
371     msg2[1] = 0;
372     while (TRUE)
373     {
374         if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK)
375         {
376             platform_device_close(p_device->handle);
377             post_write_uart("\r\n\r\nSerial number input time out!");
378             return;
379         }
381         if (msg[i] == '\r')
382         {
383             break;
384         }
385         if ((i < POST_MAX_SN_SIZE) &&  post_serial_num_isvalid(msg[i]))
386         {
387             msg2[0] = msg[i];
388             post_write_uart((char *)msg2);
389             i++;
390         }
391     }
393     if (i < POST_MAX_SN_SIZE)
394     {
395         for (j = i; j < POST_MAX_SN_SIZE; j++)
396         {
397             msg[j] = 0xff;
398         }
399     }
400     
401     if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
402     {
403         post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
404     }
405     else
406     {
407         post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!");
408     }
409     platform_device_close(p_device->handle);
413 /******************************************************************************
414  * Function:    main function for POST
415  ******************************************************************************/
416 void 
417 main
419     void
422     platform_init_flags     init_flags;
423     platform_init_config    init_config;
424     POST_TEST_ID            test_id = POST_TEST_IN_PROGRESS;
425     Bool                    test_passed = TRUE;
426     uint32_t                reset_type;
427     int32_t                 i;
428     char                    msg[9];
429     uint8_t                 mac_addr[6];
430     platform_info           info;
431     uint32_t                sa_enable;
433     /* Turn on all the platform initialize flags */
434     memset(&init_config, 0, sizeof(platform_init_config));
435     memset(&init_flags, 0x01, sizeof(platform_init_flags));
437     /* Initialize the platform */
438     if (platform_init(&init_flags, &init_config) != Platform_EOK)
439     {
440         switch (platform_errno)
441         {
442         case PLATFORM_ERRNO_PLL_SETUP:
443             test_id = POST_TEST_PLL_INIT;
444             break;
445         case PLATFORM_ERRNO_NAND:
446             test_id = POST_TEST_NAND_INIT;
447             break;
448         case PLATFORM_ERRNO_NOR:
449             test_id = POST_TEST_NOR_INIT;
450             break;
451         default:
452             test_id = POST_TEST_GENERAL;
453             break;
454         }
455         test_passed = FALSE;
456     }
458     platform_uart_init();
459     platform_uart_set_baudrate(POST_UART_BAUDRATE);
460     if (test_id != POST_TEST_PLL_INIT)
461     {
462         if (post_write_uart("\r\n\r\n") != TRUE)
463         {
464             post_display_led_error(POST_TEST_UART);   /* Never return from this function */
465         }
467         platform_get_info(&info);
469         /* Display the board name */
470         post_write_uart(info.board_name);
472         /* Display the POST version */
473         post_write_uart(POST_EVM_VERSION_MSG);
474         post_write_uart(post_version);
476         post_hex_to_string(info.board_rev, 4, msg);
477         post_write_uart("\r\n\r\nFPGA Version: ");
478         post_write_uart(msg);
480         if (info.serial_nbr[0] != 0)
481         {
482             post_write_uart("\r\n\r\nBoard Serial Number: ");
483             post_write_uart(info.serial_nbr);
484         }
486         /* Display the EFUSE MAC address */
487         platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr);
488         post_write_uart("\r\n\r\nEFUSE MAC ID is: ");
489         for (i = 0; i < 6; i++)
490         {
491             post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg);
492             msg[2] = ' ';
493             msg[3] = 0;
494             post_write_uart(msg);
495         }
497         sa_enable = *(volatile uint32_t *)0x20c0000;
498         sa_enable &= 0x1;
500         if (sa_enable)
501         {
502             post_write_uart("\r\n\r\nSA is enabled on this board.");
503         }
504         else
505         {
506             post_write_uart("\r\n\r\nSA is disabled on this board.");
507         }
509         /* Read the PLL Reset Type Status register and display on UART */
510         reset_type = PLL_CTRL_REG_RSTYPE;
511         post_hex_to_string(reset_type, 8, msg);
512         post_write_uart("\r\n\r\nPLL Reset Type Status Register: 0x");
513         post_write_uart(msg);
514     }
516     /* Display test in progress UART/LED status or init error */
517     post_display_status(test_id, test_passed);
519     test_passed = post_test_external_memory();
520     post_display_status(POST_TEST_DDR, test_passed);
522     test_passed = post_test_eeprom();
523     post_display_status(POST_TEST_EEPROM, test_passed);
525     test_passed = post_test_nor();
526     post_display_status(POST_TEST_NOR, test_passed);
528     test_passed = post_test_nand();
529     post_display_status(POST_TEST_NAND, test_passed);
531     post_display_status(POST_TEST_COMPLETE, TRUE);
533     post_write_serial_no();