Hi, TI experts,
I want to isolate a certain size of DDR region for optee-os with TI Firewall during the board boot process.
u-boot-spl
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.
-
About option b, I haven't found J721E firewall ID 4762 in the TRM, and . Is there more information about option b? Can I use this option with J7200?
-
I try to modify
u-boot-splwith 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)); ... #endifBeacuse 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); #endifHere 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, ®ion); 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, ®ion); 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); } } }set_fwl_region, more specifically, it is stuck inti_sci_do_xferwhenti_sci_cmd_set_fwl_region. However, if I configure all the registers exceptstart_addressandend_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!