瀏覽代碼

[OFW] io ranges use list to storage without ofw data (#8993)

[OFW] io ranges use ptr array to storage without ofw data

ofw data is private data for every ofw node that
the drivers of ofw node will use item.
replace the ranges supported to a ptr array.

the ptr array size is config by `RT_USING_OFW_BUS_RANGES_NUMBER`

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GUI 11 月之前
父節點
當前提交
b45fb59df2
共有 3 個文件被更改,包括 32 次插入3 次删除
  1. 6 0
      components/drivers/ofw/Kconfig
  2. 25 3
      components/drivers/ofw/io.c
  3. 1 0
      components/drivers/ofw/ofw_internal.h

+ 6 - 0
components/drivers/ofw/Kconfig

@@ -20,3 +20,9 @@ config RT_FDT_EARLYCON_MSG_SIZE
     int "Earlycon message buffer size (KB)"
     depends on RT_USING_OFW
     default 128
+
+config RT_USING_OFW_BUS_RANGES_NUMBER
+    int "Max bus ranges number"
+    depends on RT_USING_OFW
+    default 8 if ARCH_CPU_64BIT
+    default 4

+ 25 - 3
components/drivers/ofw/io.c

@@ -13,6 +13,7 @@
 #include <drivers/ofw.h>
 #include <drivers/ofw_io.h>
 #include <drivers/ofw_fdt.h>
+#include <drivers/misc.h>
 
 #define DBG_TAG "rtdm.ofw"
 #define DBG_LVL DBG_INFO
@@ -20,6 +21,9 @@
 
 #include "ofw_internal.h"
 
+static volatile rt_atomic_t _bus_ranges_idx = 0;
+static struct bus_ranges *_bus_ranges[RT_USING_OFW_BUS_RANGES_NUMBER] = {};
+
 static int ofw_bus_addr_cells(struct rt_ofw_node *np)
 {
     int res = OFW_ROOT_NODE_ADDR_CELLS_DEFAULT;
@@ -245,6 +249,7 @@ int rt_ofw_get_address_array(struct rt_ofw_node *np, int nr, rt_uint64_t *out_re
 
 static struct bus_ranges *ofw_bus_ranges(struct rt_ofw_node *np, struct rt_ofw_prop *prop)
 {
+    int id;
     const fdt32_t *cell;
     struct bus_ranges *ranges = RT_NULL;
     int child_address_cells, child_size_cells, parent_address_cells, groups;
@@ -322,7 +327,12 @@ static struct bus_ranges *ofw_bus_ranges(struct rt_ofw_node *np, struct rt_ofw_p
             *child_size++ = rt_fdt_next_cell(&cell, child_size_cells);
         }
 
-        rt_ofw_data(np) = ranges;
+        ranges->np = np;
+
+        id = (int)rt_atomic_add(&_bus_ranges_idx, 1);
+        RT_ASSERT(id < RT_ARRAY_SIZE(_bus_ranges));
+
+        _bus_ranges[id] = ranges;
     } while (0);
 
     return ranges;
@@ -341,7 +351,7 @@ rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_t
     {
         rt_ssize_t len;
         struct rt_ofw_prop *prop;
-        struct bus_ranges *ranges;
+        struct bus_ranges *ranges = RT_NULL;
 
         prop = rt_ofw_get_prop(np, range_type, &len);
 
@@ -350,7 +360,19 @@ rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_t
             continue;
         }
 
-        ranges = rt_ofw_data(np);
+        for (int i = 0; i < RT_ARRAY_SIZE(_bus_ranges); ++i)
+        {
+            if (!_bus_ranges[i])
+            {
+                break;
+            }
+
+            if (_bus_ranges[i]->np == np)
+            {
+                ranges = _bus_ranges[i];
+                break;
+            }
+        }
 
         if (!ranges)
         {

+ 1 - 0
components/drivers/ofw/ofw_internal.h

@@ -50,6 +50,7 @@ struct alias_info
 struct bus_ranges
 {
     rt_size_t nr;
+    struct rt_ofw_node *np;
 
     rt_uint64_t *child_addr;
     rt_uint64_t *parent_addr;