17de6fd1e52109fabf087ab77316bd09ab273ac8
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
103 (
104 char* msg
105 )
106 {
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;
120 }
122 /******************************************************************************
123 * Function: post_display_status
124 ******************************************************************************/
125 void
126 post_display_status
127 (
128 POST_TEST_ID test_id,
129 Bool test_passed
130 )
131 {
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 }
179 }
181 /******************************************************************************
182 * Function: post_test_external_memory
183 ******************************************************************************/
184 Bool
185 post_test_external_memory
186 (
187 void
188 )
189 {
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;
198 }
200 /******************************************************************************
201 * Function: post_test_eeprom
202 ******************************************************************************/
203 Bool
204 post_test_eeprom
205 (
206 void
207 )
208 {
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;
229 }
231 /******************************************************************************
232 * Function: post_test_nand
233 ******************************************************************************/
234 Bool
235 post_test_nand
236 (
237 void
238 )
239 {
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;
262 }
264 /******************************************************************************
265 * Function: post_test_nor
266 ******************************************************************************/
267 Bool
268 post_test_nor
269 (
270 void
271 )
272 {
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;
293 }
295 void
296 post_hex_to_string
297 (
298 uint32_t hex,
299 uint32_t nibbles,
300 char *msg
301 )
302 {
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;
322 }
324 Bool
325 post_serial_num_isvalid
326 (
327 char c
328 )
329 {
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 }
342 }
344 /******************************************************************************
345 * Function: post_write_serial_no
346 ******************************************************************************/
347 void
348 post_write_serial_no
349 (
350 void
351 )
352 {
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);
426 }
428 /******************************************************************************
429 * Function: main function for POST
430 ******************************************************************************/
431 void
432 main
433 (
434 void
435 )
436 {
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();
549 }