Browse Source

[drivers][ofw] Fixed fdt_scan_memory() memory adjustment bug (#8853)

* Fixed fdt memory adjustment bug

* Modify the memory adjustment logic
liYangYang 1 year ago
parent
commit
d30c8b340e
1 changed files with 45 additions and 39 deletions
  1. 45 39
      components/drivers/ofw/fdt.c

+ 45 - 39
components/drivers/ofw/fdt.c

@@ -475,6 +475,19 @@ static rt_err_t fdt_scan_memory(void)
                 break;
             }
 
+            /*
+             *  +--------+                                    +--------+
+             *  | memory |                                    | memory |
+             *  +--------+  +----------+        +----------+  +--------+
+             *              | reserved |        | reserved |
+             *              +----------+        +----------+
+             */
+            if (res_region->start >= region->end || res_region->end <= region->start)
+            {
+                /* No adjustments needed */
+                continue;
+            }
+
             /*
              * case 0:                      case 1:
              *  +------------------+             +----------+
@@ -490,56 +503,49 @@ static rt_err_t fdt_scan_memory(void)
              *                 | reserved |  | reserved |
              *                 +----------+  +----------+
              */
-
-            /* case 0 */
-            if (res_region->start >= region->start && res_region->end <= region->end)
+            if (res_region->start > region->start)
             {
-                rt_size_t new_size = region->end - res_region->end;
+                if (res_region->end < region->end)
+                {
+                    /* case 0 */
+                    rt_size_t new_size = region->end - res_region->end;
 
-                region->end = res_region->start;
+                    region->end = res_region->start;
 
-                /* Commit part next block */
-                if (new_size)
-                {
+                    /* Commit part next block */
                     err = commit_memregion(region->name, res_region->end, new_size, RT_FALSE);
-                }
 
-                if (!err)
-                {
-                    ++no;
+                    if (!err)
+                    {
+                        ++no;
 
-                    /* Scan again */
-                    region = &_memregion[0];
-                    --region;
+                        /* Scan again */
+                        region = &_memregion[0];
+                        --region;
 
-                    break;
+                        break;
+                    }
+                }
+                else
+                {
+                    /* case 2 */
+                    region->end = res_region->start;
                 }
-
-                continue;
-            }
-
-            /* case 1 */
-            if (res_region->start <= region->start && res_region->end >= region->end)
-            {
-                region->name = RT_NULL;
-
-                break;
-            }
-
-            /* case 2 */
-            if (res_region->start <= region->end && res_region->end >= region->end)
-            {
-                region->end = res_region->start;
-
-                continue;
             }
-
-            /* case 3 */
-            if (res_region->start <= region->start && res_region->end >= region->start)
+            else
             {
-                region->start = res_region->end;
+                if (res_region->end < region->end)
+                {
+                    /* case 3 */
+                    region->start = res_region->end;
+                }
+                else
+                {
+                    /* case 1 */
+                    region->name = RT_NULL;
 
-                continue;
+                    break;
+                }
             }
         }
     }