arm: mach-k3: common: reorder removal of firewalls
authorManorit Chawdhry <m-chawdhry@ti.com>
Fri, 5 May 2023 10:24:00 +0000 (15:54 +0530)
committerTom Rini <trini@konsulko.com>
Thu, 1 Jun 2023 16:32:03 +0000 (12:32 -0400)
K3 devices have some firewalls set up by ROM that we usually remove so
that the development is easy in HS devices.

While removing the firewalls disabling a background region before
disabling the foreground regions keeps the firewall in a state where all
the transactions will be blacklisted until all the regions are disabled.
This causes a race for some other entity trying to access that memory
region before all the firewalls are disabled and causes an exception.

Since there is no guarantee on where the background regions lie based on
ROM configurations or no guarantee if the background regions will allow
all transactions across the memory spaces, iterate the loop twice removing
the foregrounds first and then backgrounds.

Signed-off-by: Manorit Chawdhry <m-chawdhry@ti.com>
arch/arm/mach-k3/common.c
arch/arm/mach-k3/common.h

index b40e930..0e04591 100644 (file)
@@ -563,36 +563,51 @@ void disable_linefill_optimization(void)
 }
 #endif
 
-void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size)
+static void remove_fwl_regions(struct fwl_data fwl_data, size_t num_regions,
+                              enum k3_firewall_region_type fwl_type)
 {
-       struct ti_sci_msg_fwl_region region;
        struct ti_sci_fwl_ops *fwl_ops;
        struct ti_sci_handle *ti_sci;
-       size_t i, j;
+       struct ti_sci_msg_fwl_region region;
+       size_t j;
 
        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++) {
-                       region.fwl_id = fwl_data[i].fwl_id;
-                       region.region = j;
-                       region.n_permission_regs = 3;
-
-                       fwl_ops->get_fwl_region(ti_sci, &region);
-
-                       if (region.control != 0) {
-                               pr_debug("Attempting to disable firewall %5d (%25s)\n",
-                                        region.fwl_id, fwl_data[i].name);
-                               region.control = 0;
-
-                               if (fwl_ops->set_fwl_region(ti_sci, &region))
-                                       pr_err("Could not disable firewall %5d (%25s)\n",
-                                              region.fwl_id, fwl_data[i].name);
-                       }
+
+       for (j = 0; j < fwl_data.regions; j++) {
+               region.fwl_id = fwl_data.fwl_id;
+               region.region = j;
+               region.n_permission_regs = 3;
+
+               fwl_ops->get_fwl_region(ti_sci, &region);
+
+               /* Don't disable the background regions */
+               if (region.control != 0 &&
+                   ((region.control & K3_FIREWALL_BACKGROUND_BIT) ==
+                    fwl_type)) {
+                       pr_debug("Attempting to disable firewall %5d (%25s)\n",
+                                region.fwl_id, fwl_data.name);
+                       region.control = 0;
+
+                       if (fwl_ops->set_fwl_region(ti_sci, &region))
+                               pr_err("Could not disable firewall %5d (%25s)\n",
+                                      region.fwl_id, fwl_data.name);
                }
        }
 }
 
+void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size)
+{
+       size_t i;
+
+       for (i = 0; i < fwl_data_size; i++) {
+               remove_fwl_regions(fwl_data[i], fwl_data[i].regions,
+                                  K3_FIREWALL_REGION_FOREGROUND);
+               remove_fwl_regions(fwl_data[i], fwl_data[i].regions,
+                                  K3_FIREWALL_REGION_BACKGROUND);
+       }
+}
+
 void spl_enable_dcache(void)
 {
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
index 130f502..a994c3d 100644 (file)
@@ -9,12 +9,19 @@
 #include <asm/armv7_mpu.h>
 #include <asm/hardware.h>
 
+#define K3_FIREWALL_BACKGROUND_BIT BIT(8)
+
 struct fwl_data {
        const char *name;
        u16 fwl_id;
        u16 regions;
 };
 
+enum k3_firewall_region_type {
+       K3_FIREWALL_REGION_FOREGROUND,
+       K3_FIREWALL_REGION_BACKGROUND
+};
+
 enum k3_device_type {
        K3_DEVICE_TYPE_BAD,
        K3_DEVICE_TYPE_GP,