AM6422: AM64x CBASS Errors and Firewall Violation Registers

Part Number: AM6422

1. Please confirm that CBASS global registers (TRM Rev J) 
     Table 14-4. CBASS0_GLB Registers, Base Address=45B0 8000h, Length=1024
     Table 14-3887. CBASS_INFRA1_GLB Registers, Base Address=45B0 1000h, Length=1024
are used by the DMSC and software running on A53 and R5F should not use these registers.

2. When the software running on A53/R5F experience a synchronous load/store exception should it examine error registers in the exception handler: 
    CBASS0              Table 14-1. CBASS0_ERR Registers, Base Address=3A00 0000h, Length=1024
    CBASS_FW0        Table 14-3844. CBASS_ERR Registers, Base Address=0022 0000h, Length=1024
    CBASS_INFRA1   Table 14-3884. CBASS_INFRA1_ERR Registers, Base Address=0021 0000h, Length=1024
    CBASS_DBG0      Table 14-4429. CBASS_ERR Registers, Base Address=0020 0000h, Length=1024

  • Hello Dmitri,

    Thank you for your query !

    Please confirm that CBASS global registers (TRM Rev J) 
         Table 14-4. CBASS0_GLB Registers, Base Address=45B0 8000h, Length=1024
         Table 14-3887. CBASS_INFRA1_GLB Registers, Base Address=45B0 1000h, Length=1024
    are used by the DMSC and software running on A53 and R5F should not use these registers.

    A1: 
    The AM64x/243x TRM (Rev J / SPRUIM2J) does not contain an explicit statement that the registers within these two CBASS instances - CBASS0_GLB and CBASS_INFRA1_GLB are exclusively reserved for DMSC use, nor does it directly prohibit A53 or R5F software to access them.
    What the documentation does establish in related context:
    • DMSC controls CBASS infrastructure: The AM64x uses a DMSC (Device Management and Security Controller), a dedicated M3-based controller that manages system-level infrastructure including firewalls, CBASS configuration, and power/clock management. The CBASS GLB registers (exception logging control, destination ID) are system-infrastructure-level MMRs naturally under DMSC's supervision.
    • DMSC Firewall protects its own region (Errata i2245): The AM64x errata (SPRZ457J) confirms that by default, DMSC's internal ECC aggregator (DMSC0_ECC_AGGR) firewall blocks all transactions except from the M3 core inside DMSC, meaning access from A53/R5F to DMSC-managed regions is explicitly firewalled unless software explicitly reconfigures the firewall.
    • CBASS GLB registers are not application-software registers: The CBASS_GLB_DESTINATION_ID register is R/W (readable and writable as per its bitfield descriptions), but there is no documented use case in the TRM for A53 or R5F software to write to these registers. They are exception-logging infrastructure registers that DMSC and the system controller would manage.

    When the software running on A53/R5F experience a synchronous load/store exception should it examine error registers in the exception handler: 
        CBASS0              Table 14-1. CBASS0_ERR Registers, Base Address=3A00 0000h, Length=1024
        CBASS_FW0        Table 14-3844. CBASS_ERR Registers, Base Address=0022 0000h, Length=1024
        CBASS_INFRA1   Table 14-3884. CBASS_INFRA1_ERR Registers, Base Address=0021 0000h, Length=1024
        CBASS_DBG0      Table 14-4429. CBASS_ERR Registers, Base Address=0020 0000h, Length=1024

    A2:
    These registers are part of the asynchronous error interrupt path (default_err_intr), as described in the AM64x TRM / Section, Register MMR for default_err_intr. When a CBASS decode error occurs, the EXCEPTION_LOGGING_* registers in the relevant ERR block are updated and the default_err_intr interrupt is asserted toward the interrupt controller (GIC for A53 / VIM for R5F). This is a separate, asynchronous event from the synchronous load/store exception that the processor core takes.
    Therefore, the correct place to read and service these CBASS ERR registers is inside the dedicated default_err_intr interrupt handler, not inside the synchronous load/store exception handler. Attempting to poll the CBASS ERR registers from within the synchronous exception handler is not recommended, as the CBASS logging may not yet be complete at the point the synchronous exception handler executes, and doing so conflates two separate error-reporting paths.

    I hope this helps clarify.

    Best Regards,

    Anastas Yordanov

  • Hello Dmitri,

    I am just checking if you had the chance to review the answers.

    Let me know if you have any comments/questions ?

    Thank you !

    Best Regards,

    Anastas Yordanov


  • Hello Anastas,

    1. I found two additional blocks of the GLB registers undocumented in TRM: DMSC0_CBASS_GLB (0x45b0_0000) and DMASS0_CBASS_DMSC_GLB (0x45b0_3000). What are their purpose?

    2. I found an example of triggering a CBASS error exception in the Jacinto SDK:

    github.com/.../main_baremetal.c

    In this example the CBASS error registers are read in the external data abort data handler.

    I implemented a similar test on a AM64x platform. Also, I added the handler for VIM interrupt 133 mapped to the CBASS default_err_intr. I implemented the interrupt acknowledgment suggested in erratum i2235 "CBASS Null Error Interrupt Not Masked By Enable Register".

    When I executed the code after hitting the offending read instruction my code was stuck in the interrupt 133 handler, when I placed a breakpoint inside the interrupt handler the breakpoint was hit all the time. The external data abort interrupt was never reached in this case. Without the breakpoint inside the interrupt 133 handler the code failed and could not be stopped with the debugger.

    Interestingly, when I placed a breakpoint on the offending instruction and then did a "step into" the program behavior became normal: first I got the external data abort, then interrupt 133 and then the code continued without issues.

    In summary, using default_err_intr appears to be problematic while collecting diagnostic data in the external data abort handler seems to work.

    Thank you,

    Dmitri

  • Hi Dmitri,

    Thank you for your feedback !

    I found two additional blocks of the GLB registers undocumented in TRM: DMSC0_CBASS_GLB (0x45b0_0000) and DMASS0_CBASS_DMSC_GLB (0x45b0_3000). What are their purpose?

    I suspect they may not be intended for direct access by application processors and the TIFS firmware running on the M3 reads these registers to handle firewall exceptions internally.

    As the Chapter, System Interconnect / Section, Interrupt Condition for Interconnect of the AM64x/AM243x TRM sepcifies:

    The external data abort handler will be executed as part of the R5FSS/A53SS synchronous error processing path. The execution of this exception synchronously triggered handler occurs only once. Subsequently the asynchronous interrupt handler 133 (default_err_intr0) will be entered. Note that the default_err_intr0 is a LEVEL-sensitive interrupt which means that the default_err_intr_0 signal will stay asserted upon any A53/R5 null/illegal C-BASS access and trigger a continuous re-entry of the same default_err_intr R5FSS or A53SS cpu interrupt handler.

    Please consider that the default_err_intr asynchronous error path interrupt signal is also an OR-ed version of the LEVEL-sensitive 4 CBASS modules err_intr signals.

    According to the AM6422 applicable errata i2235 advisory, in current hardware there is no way to block this interrupt execution via disabling it through the ERR_INTR_ENABLE_SET [0] intr_enable_set  (address offset 0x58) within the IRQ133 handler.  You should implement the i2235 recommended workaround:

    I implemented the interrupt acknowledgment suggested in erratum i2235 "CBASS Null Error Interrupt Not Masked By Enable Register".

    Did you appropriately manipulated the bits in the order:

    1. disable the IRQ133 at the VIM/GICSS0 level in the beginning of the VIM/GICSS0 IRQ133 interrupt handler ?

    2. Clear the C-BASS status via:

    ERR_INTR_ENABLED_STAT and ERR_EOI

    3. monitor error collection registers

    4. Re-enable the IRQ133 interrupt at VIM/GICSS0 before exiting the interrupt once status is cleared

    More or less this becomes a complex routine, and also you need to identify one out of 4 possible source of the exception event (reading ERR_INTR_RAW_STAT per each of the 4 interrupt source instances).

    Why don't you consider using only the external data abort handler to collect the exception data ? (The exception collection values are more reliable, as they are latched at the time of the violation.)

    When I executed the code after hitting the offending read instruction my code was stuck in the interrupt 133 handler, when I placed a breakpoint inside the interrupt handler the breakpoint was hit all the time. The external data abort interrupt was never reached in this case. Without the breakpoint inside the interrupt 133 handler the code failed and could not be stopped with the debugger.

    Did you have a BP placed inside the external data abort handler before you hit the offending read ? I think you should be able to see the break point being hit at least once in the external R5/A53 data abort handler because as I understand this handler should be executed with priority than the default interrupt handler. 

    I am looking forward to your feedback !

    Thank you

    Best Regards,

    Anastas Yordanov