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.

CCS/EVMK2EX: Undefined instruction in startup code with -mfloat-abi=hard -mfpu=neon when booting from NAND/Bare Metal

Part Number: EVMK2EX
Other Parts Discussed in Thread: AM5K2E02, 66AK2E05, AM5728

Tool/software: Code Composer Studio

Hi,

I am having an issue enabling and using the VPF/Neon instructions on an EVMK2E Development board when running from NAND boot/bare metal during TI provided startup code. The issue may not be isolated to just booting from NAND, see details below. I can also see this issue on an AM5K2E02 processor on a custom board.

Using windows, I created a new Empty CCS project (with main.c) targeted at the 66AK2E05 with GNU v7.2.1 compiler and using the 66AK2Gxx.lds linker file. Similarly to how it is described in section 9.9.3 of http://software-dl.ti.com/processor-sdk-rtos/esd/docs/latest/rtos/index_examples_demos.html

I downloaded the shared device support package from here http://processors.wiki.ti.com/index.php/Device_support_files#Sitara_AMxxxx as the updater is writing a zero byte fil(econfirmed here https://e2e.ti.com/support/tools/ccs/f/81/p/780727/2894728)  to startup_ARMCA15.S, so I copied it from the package location shared_device_support_1.1.1\arm\include instead.

-mfloat-abi=hard was already specified but I had to add -mfpu=neon for compilation to succeed.

The project contained a target configuration 66AK2E05.ccxml which I used to create a debug configuration. This was connected using the XDS200 onboard debugger.

There is no initialization .gel file as I am running bare metal and all setup is intended to be done by the code itself.

I set the EVMK2E in “no boot” mode and connected to the A15 Core 0.

What I see and how to replicate:

-          Connect to A15 core 0 using XDS200 onboard debug probe

-          Set a breakpoint at line 87 of startup_ ARMCA15.S (may need to load symbols for this)

-          System reset (ctrl+shift+s)

-          Suspend Processor

-          Run->Load->Load Program… TestVFP.out

-          Program pauses at ln 87. Step through and on ln 100 the code will jump to undefined instruction vector ln 161.

There is a hint to what is happening as the CPACR registers are not able to be changed and it appears the processor is in non-secure mode. So the VFP co-processor enabling is not succeeding as the processor is not in secure mode.

Also if you trigger a cpu reset (Ctrl + Shift + R) via the debugger, after the system reset, but before loading the code, then the CPACR registers are able to be changed and the VFP enable and fmxr instruction are executed without issue and the program continues on to main. This is because the processor resets to be in secure mode. This is not a solution though.

When booting from NAND when the RBL (Rom Boot Loader) jumps to the start address of the program, it is also in non-secure mode. I have verified this by reading the Secure Configuration Register (SCR) register when the RBL hits the program start address breakpoint. It has a value of 0x00000031 instead of its reset value of 0x00000030. I can get the NAND booted code to run by resetting the CPU and manually changing the PC to the start address (skipping the RBL). This proves that nothing is wrong with the startup code itself but again is not a solution.

This means that the program encounters an undefined instruction when trying to enable VFP/Neon from NAND boot.

  1. Can someone confirm that the RBL causes the A15 to enter non-secure mode before executing the code it reads (from any interface? NAND, UART etc).
  2. If so, is there a way for it to keep the processor in secure mode for the executing code? Or to enter secure mode without causing an exception (I'm still looking into this myself)?
  3. If not, is there a way to enable the VFP/Neon when booting from NAND? I cannot imagine that this functionality is unavailable from certain boot modes, so how can I enable it on a bare metal system for this processor?

I should mention that I did not have this issue with the AM5728 which uses A15 cores when booting and running bare metal code from eMMC memory.

Thanks,

Jasvinder

Tool Version Information:

Code Composer Studio Version: 8.3.0.00009

Keystone2 PDK 3.1.4.7

Sitara device support 1.4.5             

Shared device support 1.1.1

TI Emulators 8.0.903.2

GCC ARM Compiler Tools 7.2.1.2017-q4-major

Compilation Flags:

-mcpu=cortex-a15 -mtune=cortex-a15 -marm -mfloat-abi=hard -mfpu=neon -I"C:/ti/ccsv8/tools/compiler/gcc-arm-none-eabi-7-2017-q4-major-win32/arm-none-eabi/include" -Og -g -gdwarf-3 -gstrict-dwarf -Wall -specs="nosys.specs"

  • These two threads may be of assistance

    e2e.ti.com/.../487376 Seems to imply that it can be done using an SMC call and r0? but I cant seem to get this to work.
    e2e.ti.com/.../345672 Seems to imply that maybe it cannot be done on a device not intended to boot into a secure mode?
  • Actually, it appears a loading the address of the code to be executed into r0 and calling SMC #0 does allow the code to reach main in secure mode and with the VFP enabled. I will post full results here on Monday with startup code changes once I have verified with my full code tests from boot. If someone could still confirm the questions I have asked above regarding intended operation in the meantime, and whether this is the correct way of going about it, please let me know.
  • Jasvinder,

    Yes, RBL puts A15 in no-secure state before exiting boot.  IF you are working on your own secondary bootloader code, we highly recommend that you refer to the code that we provide in secondary boot loader in Processor SDK RTOS:

    Refer to following files:

    pdk_k2e_4_0_12\packages\ti\boot\sbl\soc\a15\sbl_a15.c

    pdk_k2e_4_0_12\packages\ti\boot\sbl\soc\k2e\sbl_soc.c

    The first file contains assembly code to enable VFP and the second file shows how boot monitor function in ROM can be leveraged to put the code in secure state to configure VFP.   The code in sbl_soc.c that enables VFP is shown here:

    #if defined(A15_CORE)
        void (*monitorFunction) (void (*)(void), ...);
    
        /* A15 startup calls */
        monitorFunction = (void (*)) 0x1000;
        (*monitorFunction)(SBL_setNSMode);
        (*monitorFunction)(SBL_a15EnableNeon);
        (*monitorFunction)(SBL_a15EnableSMP);
        SBL_a15EnableVFP11co();
    #endif

    Please review the code and let me know if you have any further questions regarding the same.

    Regards,

    Rahul

  • So I added these lines to the startup code.

    		LDR   r0, = Startup
    		SMC #0 @ Monitor jumps to address located in r0
    
    Startup:

    To put the processor into a secure mode, with some additional register changes I was able to run my full code base. Regardless of whether this is the correct way, it solved my issue so I am marking this as solved.

  • Responded as you posted this. It would resolve my issue in a more elegant way. I will mark this as the solution.