This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Program gets stuck in _start (crt0) on Morello hardware on Angel command dissassembled to HLT #0xf000 at EL2

I'm running a baremetal EL2 program downloaded from Development Studio(DS) to the Morello hardware (which already has a branch-to-self loop running compiled as BL33 in the fip). I've modified the initialisation scripts to run at EL2 as per https://community.arm.com/support-forums/f/morello-forum/52923/baremetal-tfa-payload-built-for-capability-mode-still-in-pstate-a64-on-el2-entry and have a single c file with my main function. This works fine on the FVP when downloaded via DS, but when I download to the hardware and step through the code from entry it seems to stop after the first few instructions of crt0 on the HLT #0xF000 instruction which I believe is part of the Angel debug - AngelSVCAsm AngelSVC.

On the FVP this instruction populates the memory with the heap and stack addresses.

So this explains why when I by-passed HLT #0xF000 by moving on the program counter,  it falls over on the first use of the stack. It looks like there is no stack address value stored in memory, the code that reads the value reads in zero and hence causes a problem later.

What do I need to do differently to make it work on the hardware? as apposed to FVP?, is there a build setting I need to include?

Many thanks

  • Hi Jen

    The HLT instruction you see is a "semihosting" operation.  For general info about semihosting, see
    https://developer.arm.com/documentation/102234/2022-0M0/Controlling-Target-Execution/Using-semihosting-to-access-resources-on-the-host-computer

    Note the "Semihosting for AArch32 and AArch64" specification itself has moved to github.com/.../releases

    The first semihosting call you are seeing, as you have correctly deduced, asks the debugger where to place the stack and heap.  Semihosting is disabled by default in the debugger, which is why the call initially fails.  It can be enabled with the debugger CLI command "set semihosting enabled on".  The debugger has some default semihosting stack/heap addresses, which can be seen with the CLI command "info semihosting".  You'll probably need to change these defaults.  You can use a .ds script along the lines of:

    set semihosting heap-base 0
    set semihosting heap-limit 0x80800000
    set semihosting stack-limit 0x80800000
    set semihosting stack-base 0x81000000
    set semihosting enabled on

    This .ds script can be invoked automatically by adding it into the Debug Configuration (.launch file), in the Debug tab:
    https://developer.arm.com/documentation/102234/2022-0M0/Perspectives-and-Views/Debug-Configurations---Debugger-tab

    By contrast, when you used the FVP, the FVP handles the semihosting calls itself automatically.  The FVP also uses some default addresses for the stack & heap, unless overridden on the FVP command-line with switches such as "-C css.cluster0.cpu0.semihosting-stack_base=0x81000000"

    Hope this helps,

    Stephen

  • Many thanks, this worked perfectly in non capability mode, but as soon as I switched to pure cap mode, strange things started to happen. If I stepped through crt0 using 'stepi', all seemed well, but as soon as I tried 'run to selection' or advance to an address (over the same section of code that worked for stepi) the hardware would hang - even if it was just two instructions further on. After sending an interrupt to stop I would find the hardware in one of 3 random states, at EL3 in a WFI, B exception loop with ESR indicating access to Morello architecture was trapped, at EL2N 0x00000... address with an ESR indicating a capability tag fault, or at EL2 currSP0fiq with ESR capability bound fault.

    Is there something additional I need to set for capability mode?

    I did notice that the hardware breakpoint was indicated to be A64. (EL2N:0x00...0200 @(A64) [#2 HW]) From what I read from the links in your reply the hardware breakpoint for the semihosting is set automatically by the hardware but wasn't sure if this should change to c64 after the br c0 instruction when the system switches to capabilities?

    Any further help gratefully received. Thanks

  • Hi Jen

    Yes, I can reproduce similar strange behavior as what you see.  I'll investigate.

    Stephen

  • Hi Stephen.  Have you had chance to investigate this yet? I've tried a few different things but am still struggling to get to the bottom of the issue.

  • Sorry, I've also tried some different things, but have not yet got to the bottom of the instability I'm seeing on my set up.

  • I've been looking at this issue on and off for a while and have now found a solution to the problem so wanted to share it here, and hope it helps others.

    I found that adding cache flushing instructions ( isb ) to the modified crt0.S file (to run at EL2) before switching into capability mode resolved all the issues I had with trying to run capability code on the hardware.This might explain why stepping through the code worked, but running the code did not.

    Specifically I found I needed two of these instructions placed here as follows in crt0.S:

        //MODIFIED***comment out for EL2
        //mrs    x0, SCTLR_EL3
        //bic    x0, x0, #(1 << 20) /* clear CD0 */
        //bic    x0, x0, #(1 << 22) /* clear CD */
        //msr    SCTLR_EL3, x0

        //ADDED ISB HERE needed to avoid WFI B cpu hang
        isb

        //MODIFIED***modify for EL2
        /* Use c28 as the adrdp base, no DDC/PCC offsetting and seal CLR */
        mov    x0, #(1 << 4) | (1 << 7)
        msr    CCTLR_EL2, x0

        //ADDED ISB HERE needed to avoid WFI B cpu hang
        isb

    #endif
        //MODIFIED***comment out for EL2
        //mrs    x0, CPTR_EL3
        //bic    x0, x0, #(1 << 10) /* clear TFP */
        //msr    CPTR_EL3, x0

    #ifdef __ARM_FEATURE_C64
        /* Switch to C64 mode. */
        READSYS     c1, DDC    /* Default data capability */

  • Also just to add, it looks like this has been fixed in release 1.4