TMS320F28075: DCSM secured code crashes with stack in secured zone!?

Part Number: TMS320F28075

Hi experts,

I observe the following with my DCSM secured code, where all the RAM / CLA sectors
and most of the FLASH sectors are in zone 1, I have GRABSECT FFF5D5D5, GRABRAM 10005555.

I have
a) Bootware running both if locked / unlocked, stack in unsecured RAMM1
b) Firmware running if unlocked, crashes if locked, stack in secured RAMD0.

With some tricky debugging (compiled in jumps to wait loop in an unsecured sector)
I found out, that the crash seems to happen as soon as interrupts are enabled and occur.
(I cannot look into secured code to find out the details.)

My questions:
- Can you confirm the behaviour?
- What is the reason for the crash? Is it the stack location or are there other reasons?
- If I am right, why is it not documented in the DCSM chapter of the TRM (SPRUHM9D, 2.13)?
- Is there a possibility to have stack in secured RAM too?

Thanks & regards
Frank

  • Hey Frank,
    Good find — I went and dug into the TRM and E2E threads on this and I think I can give you a more concrete answer.
    The crash is almost certainly SCCRESET — and here's why
    TRM section 3.3.7 (DCSM Safe Code Copy Reset / SCCRESET) explicitly states:
    "To prevent security breaches, interrupts must be disabled before calling these [secure copy/CRC ROM] functions. If a vector fetch occurs in a safe copy or CRC function, the DCSM triggers a reset."
    The SCCRESET behaves like a SYSRS, except it also resets the debug logic to deny attacker access. That's why you can't easily observe what's happening — by the time the device resets, your debug session is toast too.
    The key question: Is your PIE vector table in the same zone as your secure stack?
    This is what I'd check first. On the F28075, the PIE vector table lives in RAM. When an interrupt fires, the CPU fetches the vector from the PIE table. If the vector fetch itself — or the subsequent context save (PC/ST0 push to the stack in RAMD0) — triggers any interaction with the DCSM secure context, SCCRESET can fire. The DCSM documentation for the F2807x family confirms that "data reads and writes from secured memory are only allowed for code running from secured memory." If anything in the interrupt entry path crosses a zone boundary, you've got a problem.
    On the RAMM1 vs RAMD0 question
    Your bootware works because its stack is in RAMM1 — which is unsecured (not assigned to Zone 1 in your GRABRAM = 0x10005555 config). The firmware crashes with the stack in RAMD0 — which IS in Zone 1. The crash happening specifically at interrupt enable time is consistent with the PIE vector table or the interrupt service routine entry code being in a different security context than the stack.
    Practical things to check:
    1. Where is your PIE vector table allocated? It needs to be in Zone 1 (secured) or at minimum not crossing a zone boundary relative to where interrupts are being serviced from.
    2. Where does the ISR code itself live? If the ISR entry or any code it calls is running from unsecured memory while trying to push context to a secured stack in RAMD0, that's your zone mismatch.
    3. Check your RESC register right at boot (before things crash). If SCCRESETn is cleared, that confirms SCCRESET fired in a previous cycle.
    On whether stack-in-secure-RAM is supported at all
    Per the TRM's memory access rules: Zone-1-secured code has full R/W/X access to Zone-1 RAM. So a stack in RAMD0 should work — as long as everything touching that stack (ISR entry, context save, the ISR code itself) is also running from Zone-1-secured memory. The problem isn't the secured stack per se, it's zone coherence across the full interrupt entry path.
    On the documentation gap
    The SCCRESET note isn't in the DCSM chapter (§3.13) — it's in the resets chapter (§3.3.7). That's likely why you didn't catch it there.
    Hope this helps narrow it down.
    Best Regards,
    Zackary Fleenor
  • Hi Zackary,

    thank you very much for your prompt and detailed reply.

    AFAICS (As far as I can see), the PIE vector table on the F28075 resides at the fix address 0x0D00, and I did not find a way to move it otherwhere into secured memory. (Same situation with F2833x where we also plan to use DCSM, and probably with other F28xxx.)

    I think this implies that there is no way to get the stack into secured memory on F28xxx devices as soon as you want to use PIE interrupts - can you please check that? (I think that this is not a major restriction to code security if stack is not secure).

    My ISRs always were in Z1 flash.

    I do not use the secure copy ROM functions you mention (did not look for them). By the way, there's a typo in your reply: It's TRM section 2.3.7.

    I cannot check the SCCRESET bit in RESC at 0x5D380 - the JTAG connection gets lost with the crash, and I have to repower the device to reconnect. I guess my firmware ends up with some illegal instruction trap deep in the secured and hidden flash...

    Moving firmware stack to RAMM1 or leaving RAMD0 unsecured surely will prevent the crash. But would be good to know how this works with the PIE vector table etc.

    Thanks & regards

    Frank

  • Hi Frank,
    Thank you for the follow-up — and yes, you've identified a real and important limitation. Let me address your points directly.
    On the PIE vector table location — you are correct
    The PIE vector table on the F2807x resides at the fixed address 0x0D00 (within RAMM0), and there is no hardware mechanism to relocate it into a Zone 1 secured memory region. This is a fundamental architectural constraint of the C28x PIE architecture — the CPU always fetches interrupt vectors from that fixed address.
    This means that when an interrupt fires, the vector fetch occurs from unsecured memory (RAMM0), regardless of where your ISR code lives. Since the PIE table is not in Zone 1, the interrupt dispatch path inherently crosses a zone boundary whenever your ISR is executing from, or pushing context to, secured memory.
    Practical implication for your use case
    Your conclusion is essentially correct: if you are using PIE interrupts, placing the stack in secured RAM (RAMD0) is not reliably supported on the F2807x family due to this architectural constraint. The interrupt context save (pushing PC, ST0, etc. to the stack) occurs before the CPU is executing your Zone 1 ISR code — and that cross-zone operation is what triggers the issue. Moving the stack to RAMM1 (unsecured) or leaving RAMD0 unsecured are the practical workarounds, as you identified.
    On the F2833x comparison
    The same applies to the F2833x, which also uses the C28x PIE architecture with a fixed vector table location. The constraint is architectural rather than device-specific to the F2807x.
    On the typo — noted and thank you, the correct section reference is TRM 2.3.7, not 3.3.7 as I wrote.
    On the RESC/SCCRESET debugging challenge
    Your observation about losing JTAG on crash is consistent with SCCRESET behavior — it resets the debug logic as part of its security response, which is by design. Without visibility into the secured flash, indirect methods (like your compiled-in jump approach) are the right technique for narrowing down where the crash occurs.
    Summary / Recommendations
    Scenario Stack in RAMD0 (Zone 1) Stack in RAMM1 (Unsecured)
    No interrupts Should work Works
    PIE interrupts active Not supported Works
    For your application, the security-conscious approach while using PIE interrupts would be:
    • Keep the stack in RAMM1 (unsecured) — this is acceptable from a security standpoint since the stack contains runtime data rather than code IP, and DCSM's protection goal is primarily to prevent code/IP extraction
    • Keep your ISR code and sensitive data in Zone 1 Flash/RAM — this remains protected
    • If stack data confidentiality is a hard requirement, consider migrating to TMS320F2838x, which has an enhanced security architecture
    I'll flag this as a documentation gap to the TRM team — the DCSM chapter (2.13 in SPRUHM9D) should note the PIE vector table constraint explicitly so other users don't run into the same issue.
    Hope this fully resolves your questions.
    Best Regards,
    Zackary Fleenor
  • Hi Zackary,

    thanks again for the comprehensive reply, it's all clear now. "This resolved my issue button" does not work.

    Thanks & regards,

    Frank

    PS:

    Here my "compiled in breakpoints" (maybe someone finds it useful):

    /******************************************************************************/
    /*                               dcsm test functions                          */
    /******************************************************************************/
    
    
    /* variables to be set by the debugger, must reside in unsecured ram */
    
    volatile uint16_t       dcsm_do_wait = 1;       /* wait after each test action */
    volatile uint16_t       dcsm_continue = 0;      /* continue (break wait */
    
    /* place dcsm_test() to unsecured code section to be able to debug */
    #pragma CODE_SECTION(dcsm_wait, "dcsm_unsecured_code");
    
    void dcsm_wait(void) {
        if ( dcsm_do_wait ) {
            /* wait until dcsm_continue is set by user via debugger */
            while ( !dcsm_continue );
            dcsm_continue = 0;
        }
    }
    
    // "breakpoints" in secured code:
    
        dcsm_wait();
        /* initialise peripherals */
        tmr_init(); // prepares interrupt
        dcsm_wait();
    
       // enable global Interrupts and higher priority real-time debug events:
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
        dcsm_wait(); // not reached if interrupt fired
        
    // linker command file
    
    SECTIONS
    {
        /* special firmware sections in on-chip flash sectors */
        firmhead    		: > FLASHE00    PAGE = 0, ALIGN(4)
    	dcsm_unsecured_code	: > FLASHH      PAGE = 0 	/* for unlock */
    
    // configure dcsm with FLASHH not secured