This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

U-boot hangs for custom board design

Other Parts Discussed in Thread: AM3352

Hi all,

We have a custom board design based on the AM3352, and we're attempting to bring it up by pushing u-boot-spl.bin over to the serial bootloader. This is working to a point - via some puts() statements, we've verified that the s_init function happens, and that it calls both the DDR configuration and pin-muxing functions. So as far as I know, pinmuxing and memory are both set up.

However, at this point I get no other output on the console - the puts() functions in board_init never get called (or at least never output to the console), and the system appears to hang. What could prevent board_init from being called? What else should I be doing to try and debug where this hang is happening?

Thanks,

Ben

  • Hi Ben,
     
    Have you configured your DDR correctly? This wiki page explains how to do it: http://processors.wiki.ti.com/index.php/AM335x_EMIF_Configuration_tips
    And if you have DDR3 memory there is also a memory tuning tutorial based on Beaglebone Black:
  • Hi Biser,

    As far as we know, we have. We had some discussions with our local TI FAE about how to configure DDR and they helped us with the process.

    Does it switch over to using DDR between s_init and board_init? If it does and we've still got a problem there, that would explain our hang. Please confirm that it does switch to using DDR between these functions?

    Meanwhile, I'll go over the information our FAE shared about our memory and make sure those things are correct.

    Thanks,

    Ben

  • Ben,
     
    Can you tell me the type/part number of memory that you use and post your memory settings?
  • Or could it be that the serial boot is simply waiting for u-boot to be sent? Do you see CCCC... on the terminal?
  • What I'm sure of is that u-boot is loaded into external memory and executed from there, but I'm not sure when exactly SPL tries to acces external memory first.
  • Hi Biser,

    We do not see the CCC on the terminal. That's what we assume we'll see if we're successful.

    I have to leave on a business trip right now, but if I can't get it working by Monday morning I'll post our memory type and settings.

    Thanks,

    Ben

  • OK Ben, we'll take it up on Monday then.
  • Hi Benjamin,

             From which device are you  trying to boot from, is it MMC0, MMC1 or NAND Flash  

    Is your hard ware  pins from LCD_DATA0 to LCD_DATA15  are selected as per boot mode selection pins.

    Regards

    Rajeev.

  • Hi Biser,

    We were unsuccessful in getting this to work correctly. We are still seeing it halt between the s_init and board_init functions, at least according to our terminal output.

    The memory type we are using is Micron MT41K128M16JT-125. This is very similar to what the Beaglebone Black uses, but we found we needed to alter some options.

    #define MT41K128MJT125_EMIF_READ_LATENCY 0x06
    #define MT41K128MJT125_EMIF_TIM1 0x0888A3AB 
    #define MT41K128MJT125_EMIF_TIM2 0x26337FDA 
    #define MT41K128MJT125_EMIF_TIM3 0x501F830F /* "validated" */
    #define MT41K128MJT125_EMIF_SDCFG 0x61C04AB2
    #define MT41K128MJT125_EMIF_SDREF 0x0000093B
    #define MT41K128MJT125_ZQ_CFG 0x50074BE4
    #define MT41K128MJT125_DLL_LOCK_DIFF 0x1
    #define MT41K128MJT125_RATIO 0x80 
    #define MT41K128MJT125_INVERT_CLKOUT 0x00 
    #define MT41K128MJT125_RD_DQS 0x40 
    #define MT41K128MJT125_WR_DQS 0x03 
    #define MT41K128MJT125_PHY_WR_DATA 0xC1 
    #define MT41K128MJT125_PHY_FIFO_WE 0x6E 
    #define MT41K128MJT125_IOCTRL_VALUE 0x18B

    These are the values we established initially. Our FAE told us that the EMIF_TIM1 was incorrect, that it was instead 0x0888A39B, because tRRD was 3 instead of 5. 

    We tried both our values and the FAE's change, initially at 400MHz, and then we realized our timings were set up for 303MHz so we changed to using that, but we never got past s_init. 

    Is there any way to tell whether it's our DDR, our pin muxing, or something else that's holding us up?

    Here's the output I see on the command line:

    U-Boot SPL 2013.07 (Sep 30 2013 - 14:31:59)
    Pre pinmux
    Post pinmux, pre DDR
    Post DDR

    We never see "starting board_init" which should come out when the board_init function is called, assuming puts() still works there.

    Thanks,

    Ben

  • Rajeev,

    Right now we are not booting from any of those devices, we are booting via the serial link. I'm afraid I don't understand your next statement about LCD_DATA0 through DATA15. Can you clarify?

    Thanks,

    Ben

  • Hi Ben,
     
    In between I have discussed your issue locally, and another possible source for failure was suggested: the software is trying to access a peripheral whose clock hasn't been enabled. Do you have JTAG access, so that the exact place where code fails can be located? And another question: have you tried to boot the same SPL on a TI EVM (I don't know if you have one)?
  • Hi Biser,

    We do have a TI EVM, but would booting the same SPL there work? The memory and pin-muxing settings we're using are completely custom-tailored to our new board design, so I'm not sure how booting our SPL on any other board would be a good idea.

    JTAG access actually touches on a sore point for us, we have been trying to get our TI representatives to share with us a way to connect a JTAG device to a running program so we can perform memory accesses and look at register settings, but they seem to be unwilling or unable to share with us how that can be done. We also asked if there was a way we could take a binary that was not made in CCS and load it using the JTAG from within CCS, but they didn't have a solution to that either. Can you tell us how to do this? We would really like to be able to step through the code and we bought a JTAG emulator to do so, but due to corporate mandate we are not developing our bootloader project within CCS.

    Thanks,

    Ben

  • Hi Ben,
     
    I'm not a software expert, but I will try to get some help from someone who has experience on the bootloader process.
  • Ben,

    This wiki page may be of some use to you. It discusses setting up CCS for connection (as well as building u-boot) for debug.

  • Hi Tim,

    Thanks for the wiki page, we were aware of it though. As far as I can tell, this requires u-boot to be built within CCS - we're currently building inside another build system, and it would be a lot of time required to pull u-boot and our patches and changes out and get them compiling within CCS.

    Do you know if there's a way to debug using CCS without building within CCS?

    Thanks,

    Ben

  • Ben,

    Take a look at Section 7 (Build U-boot for Debug). You do not have to build in CCS in order to debug with it (thankfully!).

    As long as you are building a u-boot/spl image with the debug symbols you can use that inside the IDE. For spl this is the spl/u-boot-spl file, and for u-boot this is the u-boot file. No extension on either file. This is what allows the debugger to interpret the code currently running.

    You may want to load the binary files yourself as well (this is all outlined in that wiki) so that you can see everything from start to finish.

  • Just to provide an update on this:

    We tried to get this running under Linux, but we encountered a problem where a Linux virtual machine on my laptop could not see the XDS200 emulator, and we don't have any portable systems running Linux available. Instead of debugging the virtual machine problem, we chose to try and bring our Linux-based U-boot code over to the windows laptop, and then connect to the emulator.

    We managed to get further, "Test Connection" on the Target Configuration page now is able to read information out of the controller, but we get the following:

    The value is '-233' (0xffffff17).
    The title is 'SC_ERR_PATH_BROKEN'.
    The explanation is:
    The JTAG IR and DR scan-paths cannot circulate bits, they may be broken.
    An attempt to scan the JTAG scan-path has failed.
    The target's JTAG scan-path appears to be broken
    with a stuck-at-ones or stuck-at-zero fault.

    We're working on tracking down why this might be. It seems some other users have had this issue, so we're researching on the forums and elsewhere on the Internet.

  • That sounds like a hardware issue to me. I'd suggest taking a look at the JTAG pins to see if you can find the break.

  • Hi Tim,

    We have some updates on this issue. The unable-to-connect problem was a hardware issue, as you (and our hardware engineer) thought. We managed to fix that, and test our connection successfully, and today tried to move on to source level debugging of u-boot.

    We ended up with two problems. The first problem is that when we tried to follow step 6, "Set a hardware breakpoint", we got "Cannot set breakpoint: there is no symbol matching this code location". Since the line we were trying to set it on was at the start of s_init, I don't see how this can be the case, unless CCS is getting confused since we have copied out linux source & output files onto this Windows machine.

    However, we discovered that we had disassembly level debugging, so we proceeded using that. We found that our s_init function executes properly, but at the end of s_init we lose control - it seems to be returning to _main at that point. If we disconnect and reconnect, we find that we're in a little loop near the end of _start, where we roll over the end of _start, into "_TEXT_BASE, _end_vect", and then into "_bss_start_ofs", which deposits us about halfway through _start, and then we continue down _start and the loop continues. We followed this for a while and think this is our problem - it seems like this might be an infinite loop. Of course, it would be easier to tell with source debugging.

    Any ideas on either problem?

  • Benjamin Fitzpatrick said:
    We ended up with two problems. The first problem is that when we tried to follow step 6, "Set a hardware breakpoint", we got "Cannot set breakpoint: there is no symbol matching this code location". Since the line we were trying to set it on was at the start of s_init, I don't see how this can be the case, unless CCS is getting confused since we have copied out linux source & output files onto this Windows machine.

    I think your hunch is correct that CCS is getting lost. If you open the source files inside CCS though I would hope that it would be able to correlate the symbol name to the open file. I'll check on this.

    Benjamin Fitzpatrick said:
    However, we discovered that we had disassembly level debugging, so we proceeded using that. We found that our s_init function executes properly, but at the end of s_init we lose control - it seems to be returning to _main at that point. If we disconnect and reconnect, we find that we're in a little loop near the end of _start, where we roll over the end of _start, into "_TEXT_BASE, _end_vect", and then into "_bss_start_ofs", which deposits us about halfway through _start, and then we continue down _start and the loop continues. We followed this for a while and think this is our problem - it seems like this might be an infinite loop. Of course, it would be easier to tell with source debugging.
    Can you see where the return pointer is taking you? Is it actually returning to main, or is it an erroneous branch? Not sure on this one...

  • Hi Ben,
     
    A bit offtopic, maybe a stupid idea, but have you checked if your SYSBOOT[15:14] settings correspond to the crystal frequency used?
  • Hi Biser,

    Excellent question actually. We have already looked at this, and the settings were incorrect. Fortunately our hardware engineer caught it before we started debugging the boards and we have manually corrected it.

    Thanks,

    Ben

  • Hi Tim,

    Checking on that would be appreciated. We figured CCS wouldn't care if we were on windows so long as we had the binaries and the source that corresponds to them, but it doesn't seem to be working.

    I think the pointer at the end of s_init is taking us back to _main, but I'm not sure. I'll try and find out some more on this today.

    Thanks,

    Ben

  • Hi Gents,

    The pointer at the end of s_init was in fact taking us to _main, and I was able to put some breakpoints in there and find the location where things go funny. It looks like eventually we get into a function called spl_board_init, which I had removed from the code we have because it looks like it was pulled into u-boot common code. 

    Sure enough it's in there, and it performs two functions- gpmc_init and arch_misc_init. A few instructions into gpmc_init, it enters the infinite loop that I was pointing to yesterday.

    We don't use the GPMC on this particular board, is it possible to override the generic spl_board_init with our own, which I assume would still need to call arch_misc_init? Does it sound likely that calling gpmc_init while not using the GPMC bus would cause the board to not boot?

    Thanks,

    Ben

  • We tried compiling without CONFIG_SPL_NAND_SUPPORT, and it did go ahead and get through the spl_board_init function. It then called spl_boot_device, and just after that it branched to "hang" and printed the "ERROR Please reset the board" message.

    I can't tell what value is being returned from spl_boot_device, but it looks like it may be invalid? The next piece of code after this seems to be the _load_image code for mmc, ymodem, spi, etc, so I think we've almost got this fixed... Any suggestions on how to set/determine the value spl_boot_device is returning would be appreciated.

  • We determined that if we use the JTAG emulator to alter the spl_boot_device return value, we can set it to the right number and get the YMODEM prompt. We're just not sure how to get spl_boot_device to return the right thing...

    We're going to see if we can use the YMODEM prompt to boot u-boot and keep going.

  • We figured out the issue, with the help of Tim Sloper at TI.

    In u-boot 2013.07, there is a line in the am335x_evm board.c "save_omap_boot_params" - this is not present in TI's version from the SDK, or in some other previous versions of u-boot. Apparently it has the effect of saving the results of the ROM code so that it's accessible from the SPL, including the spl_boot_device parameter.

    We merged a few versions of u-boot together to make the board.c for our custom board, but we didn't include that line, so our spl_boot_device always showed up as 0.

    Our other problem, source-level debug not working, is still not functioning. Tim is looking into this for us.

    Thanks,

    Ben

  • Actually, it has been around in TI's SDK u-boot for quite some time now. If you look at arch/arm/cpu/armv7/omap-common/lowlevel_init.S you'll find

     33 ENTRY(save_boot_params)
     34         /*
     35          * See if the rom code passed pointer is valid:
     36          * It is not valid if it is not in non-secure SRAM
     37          * This may happen if you are booting with the help of
     38          * debugger
     39          */
     40         ldr     r2, =NON_SECURE_SRAM_START
     41         cmp     r2, r0
     42         bgt     1f
     43         ldr     r2, =NON_SECURE_SRAM_END
     44         cmp     r2, r0
     45         blt     1f
     46
     47         /*
     48          * store the boot params passed from rom code or saved
     49          * and passed by SPL
     50          */
     51         cmp     r0, #0
     52         beq     1f
     53         ldr     r1, =boot_params
     54         str     r0, [r1]
     55 #ifdef CONFIG_SPL_BUILD
     56         /* Store the boot device in spl_boot_device */
     57         ldrb    r2, [r0, #BOOT_DEVICE_OFFSET]   @ r1 <- value of boot device
     58         and     r2, #BOOT_DEVICE_MASK
     59         ldr     r3, =boot_params
     60         strb    r2, [r3, #BOOT_DEVICE_OFFSET]   @ spl_boot_device <- r1

    Looking at the Initialization chapter of the TRM you'll find in section 26.1.10.2 the description of the Booting Parameters. When the Boot ROM transfers control to the SPL code, register R0 contains a pointer to this structure. The code above saves the byte at offset 8 which contains the device you booted from.

    The only time I've seen it 0 or incorrect is when I've used JTAG to  load the SPL and bypass the boot ROM.

    Steve K.

  • Hi Steve,

    You are technically correct - the best kind of correct - but if you look at the initial question you can see that we were using a JTAG debugger to load the code, and therefore bypassing lowlevel_init.S.

    Similarly, when I said "it isn't in the SDK", I was referring to the board.c files which we merged together to make our own, which do not contain a call to this function. The standard U-boot lowlevel_init.S also does not include it.

    The solution we chose was to leave U-boot's ASM code the way it was, and copy the call directly into board.c, which does cause it to work.

    Thanks,

    Ben