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-J7200: How can I firewall DDR?

Part Number: PROCESSOR-SDK-J7200


Hi, TI experts,

I want to isolate a certain size of DDR region for optee-os with TI Firewall during the board boot process.

At which stage(on which core) of boot process should the firewall registers be configured? Is u-boot-spl appropriate?

Here is what I have done so far.

I found an example related to firewall registers configuration at ti-processor-sdk-rtos-j7200-evm/pdk_j7200_08_00_00_37/packages/ti/drv/sciclient/examples/sciclient_fw_testapp, which is running on the mcu1_0. This example proposes two types of firewalls for isolating DDR, but only "option a" is achieved.

From MCU domain or UDMA coming from MCU domain –

There are two options.

a.Interdomain firewall from MCU to DDR can be configured to filter accesses. – J721E ID DRAM_FWL_ID | AM65xx DRAM_FWL_ID

b.Northbridge firewall between NAVSS and Compute cluster can be configured. – J721E ID 4762, 4763 | AM65xx 4450

The below example shows option a.

  1. About option b, I haven't found J721E firewall ID 4762 in the TRM, and J721E Firewall Descriptions — TISCI User Guide. Is there more information about option b? Can I use this option with J7200?

  2. I try to modify u-boot-spl with option a.

    I added the firewall configuration code at board-support/u-boot-2021.01/arch/arm/mach-k3/j721e_init.c:267, as shown below.

    #ifdef CONFIG_TI_SECURE_DEVICE
        sdram_fwl_configs(navss0_ddr0_mem_fwls, ARRAY_SIZE(navss0_ddr0_mem_fwls));
        remove_fwl_configs(cbass_hc_cfg0_fwls, ARRAY_SIZE(cbass_hc_cfg0_fwls));
    ...
    #endif

    Beacuse I haven't got the TI development package(Secure development package (SECDEV)), so I skipped the Image signature authentication at board-support/u-boot-2021.01/arch/arm/mach-k3/common.c:310

    #ifdef CONFIG_TI_SECURE_DEVICE
        //ti_secure_image_post_process(p_image, p_size);
    #endif

    Here is more detailed code.

    struct fwl_data nvss0_ddr0_mem_fwls[] = {
        { "DRAM", 1280, 1},
    };
    
    #define MCU_1_0_PRIVID (96)
    
    /** MCU_0_R5_0(Non Secure): Cortex R5 context 0 on MCU island */
    #define TISCI_HOST_ID_MCU_0_R5_0 (3U)
    /** MCU_0_R5_1(Secure): Cortex R5 context 1 on MCU island(Boot) */
    #define TISCI_HOST_ID_MCU_0_R5_1 (4U)
    
    void sdram_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size)
    {
        struct ti_sci_msg_fwl_region region;
        struct ti_sci_msg_fwl_owner owner;
        struct ti_sci_fwl_ops *fwl_ops;
        struct ti_sci_handle *ti_sci;
        size_t i, j;
        int ret = 0;
        const u32 perm_for_access =
             SEC_SUPV_WRITE_MASK | SEC_SUPV_READ_MASK | 
             SEC_SUPV_CACHEABLE_MASK | SEC_SUPV_DEBUG_MASK |
             SEC_USER_WRITE_MASK | SEC_USER_READ_MASK | 
             SEC_USER_CACHEABLE_MASK | SEC_USER_DEBUG_MASK |
             NONSEC_SUPV_WRITE_MASK | NONSEC_SUPV_READ_MASK | 
             NONSEC_SUPV_CACHEABLE_MASK | NONSEC_SUPV_DEBUG_MASK |
             NONSEC_USER_WRITE_MASK | NONSEC_USER_READ_MASK | 
             NONSEC_USER_CACHEABLE_MASK | NONSEC_USER_DEBUG_MASK;
        
        ti_sci = get_ti_sci_handle();
        fwl_ops = &ti_sci->ops.fwl_ops;
       
        for (i = 0; i < fwl_data_size; i++) {
            for (j = 0; j < fwl_data[i].regions; j++) {
    //change fwl owner
                owner.fwl_id = fwl_data[i].fwl_id;
                owner.region = 1;
                owner.owner_index = (u8)TISCI_HOST_ID_MCU_0_R5_1; 
                owner.owner_privid = (u8)MCU_1_0_PRIVID;
                owner.owner_permission_bits = (u16)perm_for_access;
                if (fwl_ops->change_fwl_owner(ti_sci, &owner)){
                    printf("Could not change (%s) firewall owner\n", fwl_data[i].name);
                }
    //set fwl region
                region.fwl_id = fwl_data[i].fwl_id;
                region.region = j; 
                region.n_permission_regs = 1;  
                region.control = (u32)0xA;
                region.permissions[0] = (u32)(MCU_1_0_PRIVID << 16) | perm_for_access;
                printf("region.permissions is going to be set as %x\n", region.permissions[0]);
                region.start_address = (u64) 0x9E800000;
                region.end_address =  (u64)(0x9E800000 + 4 * 1024 - 1);
             
                ret = fwl_ops->set_fwl_region(ti_sci, &region);
                if (ret){
                    printf("Could not set firewall (%s)\n", fwl_data[i].name);
                    printf("ret is %d\n", ret);
                }
        //check if fwl region is set or not
                ret = fwl_ops->get_fwl_region(ti_sci, &region);
                if (ret){
                    printf("Could not get firewall (%s)\n", fwl_data[i].name);
                    printf("ret is %d\n", ret);
                }
                printf("Fwl name is %s\n", fwl_data[i].name);
                printf("Check region.fwl_id is %d\n", region.fwl_id);
                printf("Check region.region is %d\n", region.region);
                printf("Check region.n_permission_regs is %d\n", region.n_permission_regs);
                printf("Check region.permissions[0] is %x\n", region.permissions[0]);
                printf("Check region.start_address is %x\n", region.start_address);
                printf("Check region.end_address is %x\n", region.end_address);
                printf("Check region.control is %x\n", region.control);
            }
        }
    }

    But the code will be stuck when set_fwl_region, more specifically, it is stuck in ti_sci_do_xfer when ti_sci_cmd_set_fwl_region. However, if I configure all the registers except start_address and end_address, the code runs through.

    This is configured at uboot board_init_f, the DDR hasn't been initialized, but in my opinion, this operation is only related to the firewall registers configration, ans has nothing to do with DDR.  Why doesn't this work, did I miss or misunderstand something?

Thanks!