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.

PROCESSOR-SDK-J784S4: lock R5f TCM access

Part Number: PROCESSOR-SDK-J784S4

Tool/software:

Hi experts,

I am using j784s4_evm with SDK10.

I would like to access TCM memory only from the R5F which it bellongs to for safety reasons.

I would like that other cores (R5F, C7X and A72) couldn't access this memory.

Could you provide any example.

Thanks for your help

Charles

  • I setup a firewall on the BTCM memory.

    I setup region 0 as background region over all BTCM memory and enable every access.

    Then I setup region 1 as foreground region on the first 4Ko and disable every access.

    But when I write in the memory after setting the firewall, the core crash instead of reaching the error handler function.

    This is my code :

    #include <ti/board/board.h>
    #include <ti/board/board_cfg.h>
    #include <ti/board/src/j784s4_evm/include/board_utils.h>
    #include <ti/board/src/j784s4_evm/include/board_internal.h>
    #include <ti/drv/sciclient/sciclient.h>
    #include <ti\csl\arch\csl_arch.h>
    #include <ti/osal/osal.h>
    #include <ti/csl/soc.h>
    #include <ti/csl/soc/j784s4/src/csl_soc_firewalls.h>
    
    /*######################################################
     *  DEFINES
     *  ----------------------------------------------------*/
    #define SCICLIENT_APP_SEC_SUPV_WRITE_MASK         (0x00000001U)
    #define SCICLIENT_APP_SEC_SUPV_READ_MASK          (0x00000002U)
    #define SCICLIENT_APP_SEC_SUPV_CACHEABLE_MASK     (0x00000004U)
    #define SCICLIENT_APP_SEC_SUPV_DEBUG_MASK         (0x00000008U)
    #define SCICLIENT_APP_SEC_USER_WRITE_MASK         (0x00000010U)
    #define SCICLIENT_APP_SEC_USER_READ_MASK          (0x00000020U)
    #define SCICLIENT_APP_SEC_USER_CACHEABLE_MASK     (0x00000040U)
    #define SCICLIENT_APP_SEC_USER_DEBUG_MASK         (0x00000080U)
    #define SCICLIENT_APP_NONSEC_SUPV_WRITE_MASK      (0x00000100U)
    #define SCICLIENT_APP_NONSEC_SUPV_READ_MASK       (0x00000200U)
    #define SCICLIENT_APP_NONSEC_SUPV_CACHEABLE_MASK  (0x00000400U)
    #define SCICLIENT_APP_NONSEC_SUPV_DEBUG_MASK      (0x00000800U)
    #define SCICLIENT_APP_NONSEC_USER_WRITE_MASK      (0x00001000U)
    #define SCICLIENT_APP_NONSEC_USER_READ_MASK       (0x00002000U)
    #define SCICLIENT_APP_NONSEC_USER_CACHEABLE_MASK  (0x00004000U)
    #define SCICLIENT_APP_NONSEC_USER_DEBUG_MASK      (0x00008000U)
    
    #define SCICLIENT_APP_ENABLE_ALL                  (0xffffU)
    
    #define APP_R5F_HOST_ID      (TISCI_HOST_ID_MAIN_0_R5_0)
    #define APP_PRIVID           (212)
    #define APP_FWL_ID           (CSL_STD_FW_R5FSS0_CORE0_BTCM0_ID)
    #define APP_ADDRESS_START    (CSL_STD_FW_R5FSS0_CORE0_BTCM0_CORE0_BTCM_START)
    #define APP_ADDRESS_END      (CSL_STD_FW_R5FSS0_CORE0_BTCM0_CORE0_BTCM_END)
    
    
    #define APP_SIZE             (1024)
    
    /*######################################################
     *  GLOBAL VARIABLES
     *  ----------------------------------------------------*/
    
    volatile uint32_t gAbortRecieved = 0U;
    
    /*######################################################
     *  STATIC FUNCTIONS
     *  ----------------------------------------------------*/
    
    static void Sciclient_fw_abort_C_handler()
    {
        gAbortRecieved++;
    }
    
    /*######################################################
     *  FUNCTIONS
     *  ----------------------------------------------------*/
    
    void firewall_init()
    {
        const uint32_t permForNoAccess = 0;
    
        const uint32_t permForAccess =
                SCICLIENT_APP_SEC_SUPV_WRITE_MASK | SCICLIENT_APP_SEC_SUPV_READ_MASK |
                SCICLIENT_APP_SEC_SUPV_CACHEABLE_MASK | SCICLIENT_APP_SEC_SUPV_DEBUG_MASK |
                SCICLIENT_APP_SEC_USER_WRITE_MASK | SCICLIENT_APP_SEC_USER_READ_MASK |
                SCICLIENT_APP_SEC_USER_CACHEABLE_MASK | SCICLIENT_APP_SEC_USER_DEBUG_MASK |
                SCICLIENT_APP_NONSEC_SUPV_WRITE_MASK | SCICLIENT_APP_NONSEC_SUPV_READ_MASK |
                SCICLIENT_APP_NONSEC_SUPV_CACHEABLE_MASK | SCICLIENT_APP_NONSEC_SUPV_DEBUG_MASK |
                SCICLIENT_APP_NONSEC_USER_WRITE_MASK | SCICLIENT_APP_NONSEC_USER_READ_MASK |
                SCICLIENT_APP_NONSEC_USER_CACHEABLE_MASK | SCICLIENT_APP_NONSEC_USER_DEBUG_MASK;
    
        struct tisci_msg_fwl_change_owner_info_req req = {
          .fwl_id      = (uint16_t) APP_FWL_ID,
          .region      = (uint16_t) 0,
          .owner_index = (uint8_t) APP_R5F_HOST_ID
          };
    
        struct tisci_msg_fwl_set_firewall_region_req req_fw_set_background = {
            .fwl_id            = (uint16_t) APP_FWL_ID,
            .region            = (uint16_t) 0,
            .n_permission_regs = (uint32_t) 3,
            .control           = (uint32_t) 0x10A,
            .permissions[0]    = (uint32_t) 197 << 16 | permForAccess,
            .permissions[1]    = (uint32_t) 0,
            .permissions[2]    = (uint32_t) 0,
            .start_address     = APP_ADDRESS_START,
            .end_address       = APP_ADDRESS_END
        };  
     
        struct tisci_msg_fwl_set_firewall_region_req req_fw_block_access = {
          .fwl_id            = (uint16_t) APP_FWL_ID,
          .region            = (uint16_t) 1,
          .n_permission_regs = (uint32_t) 3,
          .control           = (uint32_t) 0xA,
          .permissions[0]    = (uint32_t) APP_PRIVID << 16 | permForNoAccess,
          .permissions[1]    = (uint32_t) 0,
          .permissions[2]    = (uint32_t) 0,
          .start_address     = APP_ADDRESS_START,
          .end_address       = APP_ADDRESS_START + (APP_SIZE - 1) * 4
        };
    
        struct tisci_msg_fwl_change_owner_info_resp resp = {0};
        struct tisci_msg_fwl_set_firewall_region_resp resp_fw_block_access = {0};
        struct tisci_msg_fwl_set_firewall_region_resp resp_fw_set_background = {0};
        
        uint32_t timeout = 0xFFFFFFFFU;
        int32_t ret = CSL_PASS;
    
        PRINT_LOG("init firewall\n");
    
        /* Register exception handler */
        /* This is needed for data abort which should occur during writing to firewalled region */
        printf("setting firewall handler\n");
        CSL_R5ExptnHandlers sciclientR5ExptnHandlers;
        Intc_InitExptnHandlers(&sciclientR5ExptnHandlers);
        sciclientR5ExptnHandlers.dabtExptnHandler = &Sciclient_fw_abort_C_handler;
        Intc_RegisterExptnHandlers(&sciclientR5ExptnHandlers);
    
        ret = Sciclient_firewallChangeOwnerInfo(&req, &resp, timeout);
        if (ret != CSL_PASS)
        {
          PRINT_LOG("failed change owner region 0\n");
        }
    
        req.region = 1;
        ret = Sciclient_firewallChangeOwnerInfo(&req, &resp, timeout);
        if (ret != CSL_PASS)
        {
          PRINT_LOG("failed change owner region 1\n");
        }
    
        if (ret == CSL_PASS)
        {
            /* Set background region */
            ret = Sciclient_firewallSetRegion(&req_fw_set_background, &resp_fw_set_background, timeout);
            if (ret != CSL_PASS)
            {
              PRINT_LOG("failed setting firewall background region\n");
            }
            ret = Sciclient_firewallSetRegion(&req_fw_block_access, &resp_fw_block_access, timeout);
            if (ret != CSL_PASS)
            {
              PRINT_LOG("failed setting firewall region\n");
            }
        }
    
        PRINT_LOG("init done !!\n");
    }
    
    /**
     * \brief   This Task test safety firewall r5f BTCM memory
     *
     * \param   
     *
     * \retval  
     */
    void vTaskTestSafety(void *pvParameters)
    {   
        bool run = true;
        uint32_t data_index = 0;
        volatile uint32_t* addr = NULL;
    
        PRINT_LOG("\r\n********************************************\r\n");
        PRINT_LOG("\r\n[FreeRTOS] SAFETY tests ... start !!!\r\n");
        PRINT_LOG("\r\n********************************************\r\n");
    
        firewall_init();
    
        /* read and write data */
        addr = (uint32_t*) APP_ADDRESS_START + 0x40; /* add offset (rsvd in linker) */
        for (data_index = 0; data_index < APP_SIZE; data_index++)
        {
            addr[data_index] = data_index;
        }
    
        CacheP_wbInv((const void*)addr, APP_SIZE * sizeof(uint32_t));
    
        for (data_index = 0; data_index < 20; data_index++)
        {
            PRINT_LOG("@0x%x = 0x%x\n", (uint32_t) &addr[data_index], addr[data_index]);
        }
    
        printf( "%d/%d error received\n", gAbortRecieved, APP_SIZE + 20);
    
        while(run)
        {
            BOARD_delay(10000);
        }
        
        vTaskDelete( NULL );
    }

  • Hi Charles,

    I setup region 0 as background region over all BTCM memory and enable every access.

    It doesn't seem to be the case in the background region, you are blocking access for every one.

    197 is PRIV ID for block everyone.PRIV ID for allowing everyone is 195.

    One more issue with the background firewall configuration. Firewall ID 2768 protect other region as well apart from BTCM.

    CORE0_ATCM 0x05C00000 0x05C0FFFF
    CORE0_BTCM 0x05C10000 0x05C1FFFF
    CORE0_ICACHE 0x4E00000000 0x4E007FFFFF
    CORE0_DCACHE 0x4E00800000 0x4E00FFFFFF

    Currently, the application only configures access for BTCM. Since these firewalls operate on a whitelist basis, this inadvertently blocks access to the other memory regions (ATCM, ICACHE, and DCACHE). So we need to configure the full address range which it is protecting in the background region.

    Regards
    Diwakar

  • Hi ,

    I changed the priv ID of the background region from 197 to 195

    The firwall has 4 regions. Is it possible to set 1 background region that would include every memory (ATCM, BTCM, ICACHE, and DCACHE), then which value for start and end addrress ?

    Because if I set 1 background region for each memory individually, there won't be any region left to setup foreground region for filtering

    Thanks

    Charles

  • Hi Charls,

    The firwall has 4 regions. Is it possible to set 1 background region that would include every memory (ATCM, BTCM, ICACHE, and DCACHE), then which value for start and end addrress ?

    Yes that is possible, set address range in the background region like this 0x00000000 - 0xFFFFFFFFFF.

    Regards
    Diwakar

  • Hi Diwakar Dhyani,

    I have setup the background region 0x00000000 - 0xFFFFFFFFFF

    and then forbid access to BTCM memory from every one

    When I try to access the memory from R5F and C7X, the core crash. Is it the normal behavior ?

    Thanks

    Charles

  • Hi Charles,

    This behaviour is normal. Since we've configured the firewall to block all access to that memory region, any attempt by the R5F or C7X processors to access it will intentionally generate a bus error.

    Regards
    Diwakar

  • Hi Diwakar Dhyani,

    Sorry but I am confused with firewall ID. I found 2 different list of firewall ID

    • In pdk : csl_soc_firewalls.h which define firewall ID for the SOC --> where I found BTCM firewall ID
    • In pdk inside sciclient documentation list the firewall ID and list of priv-IDs --> /sciclient/soc/sysfw/binaries/system-firmware-public-documentation/5_soc_doc/j784s4/firewalls.html
      • Sciclient firewall example use this list

    Thanks 

    Charles

  • Hi Charles,

    • In pdk : csl_soc_firewalls.h which define firewall ID for the SOC --> where I found BTCM firewall ID

    This header file is used internally by the PDK, while the j784s4/firewalls.html file serves as public-facing documentation.

    The RTOS SDK includes public documentation alongside other components. You can access this same public documentation here

    The table outlines the default firewall configuration that's applied by TIFS during its initialization process. TIFS automatically configures these firewalls with these settings when it starts up. Though, it does not touch all the firewall configuration.

    Regards
    Diwakar

  • Hi Diwakar Dhyani,

    The last thing is that I can't reach my Data Abort exception handler

    I am running my code on mcu2_0.
    I fall into infinite loop inside "HwiP_data_abort_handler_c"
    --> It means the pointer to the handler is null

    I have found an other functions that do the same : "dataAbortExptnHandler_c"

    But both  "HwiP_data_abort_handler_c" and  "dataAbortExptnHandler_c" use the same global var "gExptnHandlers"

    And when I call directly these functions, I reach my handler.

    This is how I setup my handler :

    CSL_R5ExptnHandlers sciclientR5ExptnHandlers;
    Intc_InitExptnHandlers(&sciclientR5ExptnHandlers);
    sciclientR5ExptnHandlers.dabtExptnHandler = &Sciclient_fw_abort_C_handler;
    Intc_RegisterExptnHandlers(&sciclientR5ExptnHandlers);

    Thanks

    Charles

  • Hi Charles,

    Can you elaborate your use case do you want to handle data abort in case of firewall exception or what ?

    Regards
    Diwakar

  • Hi Diwakar Dhyani,

    The problem disappeared by itself.

    Thanks for your help

    I am closing this post

    Charles