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