hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/of/fdt.c
....@@ -11,7 +11,6 @@
1111 #include <linux/crc32.h>
1212 #include <linux/kernel.h>
1313 #include <linux/initrd.h>
14
-#include <linux/bootmem.h>
1514 #include <linux/memblock.h>
1615 #include <linux/mutex.h>
1716 #include <linux/of.h>
....@@ -40,7 +39,7 @@
4039 * memory entries in the /memory node. This function may be called
4140 * any time after initial_boot_param is set.
4241 */
43
-void of_fdt_limit_memory(int limit)
42
+void __init of_fdt_limit_memory(int limit)
4443 {
4544 int memory;
4645 int len;
....@@ -80,149 +79,6 @@
8079 }
8180 }
8281
83
-/**
84
- * of_fdt_get_ddrhbb - Return the highest bank bit of ddr on the current device
85
- *
86
- * On match, returns a non-zero positive value which matches the highest bank
87
- * bit.
88
- * Otherwise returns -ENOENT.
89
- */
90
-int of_fdt_get_ddrhbb(int channel, int rank)
91
-{
92
- int memory;
93
- int len;
94
- int ret;
95
- /* Single spaces reserved for channel(0-9), rank(0-9) */
96
- char pname[] = "ddr_device_hbb_ch _rank ";
97
- fdt32_t *prop = NULL;
98
-
99
- memory = fdt_path_offset(initial_boot_params, "/memory");
100
- if (memory > 0) {
101
- snprintf(pname, sizeof(pname),
102
- "ddr_device_hbb_ch%d_rank%d", channel, rank);
103
- prop = fdt_getprop_w(initial_boot_params, memory,
104
- pname, &len);
105
- }
106
-
107
- if (!prop || len != sizeof(u32))
108
- return -ENOENT;
109
-
110
- ret = fdt32_to_cpu(*prop);
111
-
112
- return ret;
113
-}
114
-EXPORT_SYMBOL_GPL(of_fdt_get_ddrhbb);
115
-
116
-/**
117
- * of_fdt_get_ddrrank - Return the rank of ddr on the current device
118
- *
119
- * On match, returns a non-zero positive value which matches the ddr rank.
120
- * Otherwise returns -ENOENT.
121
- */
122
-int of_fdt_get_ddrrank(int channel)
123
-{
124
- int memory;
125
- int len;
126
- int ret;
127
- /* Single space reserved for channel(0-9) */
128
- char pname[] = "ddr_device_rank_ch ";
129
- fdt32_t *prop = NULL;
130
-
131
- memory = fdt_path_offset(initial_boot_params, "/memory");
132
- if (memory > 0) {
133
- snprintf(pname, sizeof(pname),
134
- "ddr_device_rank_ch%d", channel);
135
- prop = fdt_getprop_w(initial_boot_params, memory,
136
- pname, &len);
137
- }
138
-
139
- if (!prop || len != sizeof(u32))
140
- return -ENOENT;
141
-
142
- ret = fdt32_to_cpu(*prop);
143
-
144
- return ret;
145
-}
146
-EXPORT_SYMBOL_GPL(of_fdt_get_ddrrank);
147
-
148
-/**
149
- * of_fdt_get_ddrtype - Return the type of ddr (4/5) on the current device
150
- *
151
- * On match, returns a non-zero positive value which matches the ddr type.
152
- * Otherwise returns -ENOENT.
153
- */
154
-int of_fdt_get_ddrtype(void)
155
-{
156
- int memory;
157
- int len;
158
- int ret;
159
- fdt32_t *prop = NULL;
160
-
161
- memory = fdt_path_offset(initial_boot_params, "/memory");
162
- if (memory > 0)
163
- prop = fdt_getprop_w(initial_boot_params, memory,
164
- "ddr_device_type", &len);
165
-
166
- if (!prop || len != sizeof(u32))
167
- return -ENOENT;
168
-
169
- ret = fdt32_to_cpu(*prop);
170
-
171
- return ret;
172
-}
173
-EXPORT_SYMBOL_GPL(of_fdt_get_ddrtype);
174
-
175
-/**
176
- * of_fdt_is_compatible - Return true if given node from the given blob has
177
- * compat in its compatible list
178
- * @blob: A device tree blob
179
- * @node: node to test
180
- * @compat: compatible string to compare with compatible list.
181
- *
182
- * On match, returns a non-zero value with smaller values returned for more
183
- * specific compatible values.
184
- */
185
-static int of_fdt_is_compatible(const void *blob,
186
- unsigned long node, const char *compat)
187
-{
188
- const char *cp;
189
- int cplen;
190
- unsigned long l, score = 0;
191
-
192
- cp = fdt_getprop(blob, node, "compatible", &cplen);
193
- if (cp == NULL)
194
- return 0;
195
- while (cplen > 0) {
196
- score++;
197
- if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
198
- return score;
199
- l = strlen(cp) + 1;
200
- cp += l;
201
- cplen -= l;
202
- }
203
-
204
- return 0;
205
-}
206
-
207
-/**
208
- * of_fdt_is_big_endian - Return true if given node needs BE MMIO accesses
209
- * @blob: A device tree blob
210
- * @node: node to test
211
- *
212
- * Returns true if the node has a "big-endian" property, or if the kernel
213
- * was compiled for BE *and* the node has a "native-endian" property.
214
- * Returns false otherwise.
215
- */
216
-bool of_fdt_is_big_endian(const void *blob, unsigned long node)
217
-{
218
- if (fdt_getprop(blob, node, "big-endian", NULL))
219
- return true;
220
- if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) &&
221
- fdt_getprop(blob, node, "native-endian", NULL))
222
- return true;
223
- return false;
224
-}
225
-
22682 static bool of_fdt_device_is_available(const void *blob, unsigned long node)
22783 {
22884 const char *status = fdt_getprop(blob, node, "status", NULL);
....@@ -234,27 +90,6 @@
23490 return true;
23591
23692 return false;
237
-}
238
-
239
-/**
240
- * of_fdt_match - Return true if node matches a list of compatible values
241
- */
242
-int of_fdt_match(const void *blob, unsigned long node,
243
- const char *const *compat)
244
-{
245
- unsigned int tmp, score = 0;
246
-
247
- if (!compat)
248
- return 0;
249
-
250
- while (*compat) {
251
- tmp = of_fdt_is_compatible(blob, node, *compat);
252
- if (tmp && (score == 0 || (tmp < score)))
253
- score = tmp;
254
- compat++;
255
- }
256
-
257
- return score;
25893 }
25994
26095 static void *unflatten_dt_alloc(void **mem, unsigned long size,
....@@ -408,12 +243,8 @@
408243 populate_properties(blob, offset, mem, np, pathp, dryrun);
409244 if (!dryrun) {
410245 np->name = of_get_property(np, "name", NULL);
411
- np->type = of_get_property(np, "device_type", NULL);
412
-
413246 if (!np->name)
414247 np->name = "<NULL>";
415
- if (!np->type)
416
- np->type = "<NULL>";
417248 }
418249
419250 *pnp = np;
....@@ -484,7 +315,7 @@
484315 for (offset = 0;
485316 offset >= 0 && depth >= initial_depth;
486317 offset = fdt_next_node(blob, offset, &depth)) {
487
- if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH))
318
+ if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH - 1))
488319 continue;
489320
490321 if (!IS_ENABLED(CONFIG_OF_KOBJ) &&
....@@ -581,8 +412,8 @@
581412 /* Second pass, do actual unflattening */
582413 unflatten_dt_nodes(blob, mem, dad, mynodes);
583414 if (be32_to_cpup(mem + size) != 0xdeadbeef)
584
- pr_warning("End of tree marker overwritten: %08x\n",
585
- be32_to_cpup(mem + size));
415
+ pr_warn("End of tree marker overwritten: %08x\n",
416
+ be32_to_cpup(mem + size));
586417
587418 if (detached && mynodes) {
588419 of_node_set_flag(*mynodes, OF_DETACHED);
....@@ -633,14 +464,14 @@
633464 int __initdata dt_root_addr_cells;
634465 int __initdata dt_root_size_cells;
635466
636
-void *initial_boot_params;
467
+void *initial_boot_params __ro_after_init;
637468
638469 #ifdef CONFIG_OF_EARLY_FLATTREE
639470
640471 static u32 of_fdt_crc32;
641472
642473 /**
643
- * res_mem_reserve_reg() - reserve all memory described in 'reg' property
474
+ * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
644475 */
645476 static int __init __reserved_mem_reserve_reg(unsigned long node,
646477 const char *uname)
....@@ -649,7 +480,8 @@
649480 phys_addr_t base, size;
650481 int len;
651482 const __be32 *prop;
652
- int nomap, first = 1;
483
+ int first = 1;
484
+ bool nomap;
653485
654486 prop = of_get_flat_dt_prop(node, "reg", &len);
655487 if (!prop)
....@@ -764,7 +596,7 @@
764596 fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
765597 if (!size)
766598 break;
767
- early_init_dt_reserve_memory_arch(base, size, 0);
599
+ early_init_dt_reserve_memory_arch(base, size, false);
768600 }
769601
770602 of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
....@@ -782,7 +614,7 @@
782614 /* Reserve the dtb region */
783615 early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
784616 fdt_totalsize(initial_boot_params),
785
- 0);
617
+ false);
786618 }
787619
788620 /**
....@@ -811,8 +643,6 @@
811643 offset = fdt_next_node(blob, offset, &depth)) {
812644
813645 pathp = fdt_get_name(blob, offset, NULL);
814
- if (*pathp == '/')
815
- pathp = kbasename(pathp);
816646 rc = it(offset, pathp, depth, data);
817647 }
818648 return rc;
....@@ -839,8 +669,6 @@
839669 int rc;
840670
841671 pathp = fdt_get_name(blob, node, NULL);
842
- if (*pathp == '/')
843
- pathp = kbasename(pathp);
844672 rc = it(node, pathp, data);
845673 if (rc)
846674 return rc;
....@@ -856,7 +684,7 @@
856684 * @return offset of the subnode, or -FDT_ERR_NOTFOUND if there is none
857685 */
858686
859
-int of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
687
+int __init of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
860688 {
861689 return fdt_subnode_offset(initial_boot_params, node, uname);
862690 }
....@@ -867,14 +695,6 @@
867695 unsigned long __init of_get_flat_dt_root(void)
868696 {
869697 return 0;
870
-}
871
-
872
-/**
873
- * of_get_flat_dt_size - Return the total size of the FDT
874
- */
875
-int __init of_get_flat_dt_size(void)
876
-{
877
- return fdt_totalsize(initial_boot_params);
878698 }
879699
880700 /**
....@@ -890,6 +710,38 @@
890710 }
891711
892712 /**
713
+ * of_fdt_is_compatible - Return true if given node from the given blob has
714
+ * compat in its compatible list
715
+ * @blob: A device tree blob
716
+ * @node: node to test
717
+ * @compat: compatible string to compare with compatible list.
718
+ *
719
+ * On match, returns a non-zero value with smaller values returned for more
720
+ * specific compatible values.
721
+ */
722
+static int of_fdt_is_compatible(const void *blob,
723
+ unsigned long node, const char *compat)
724
+{
725
+ const char *cp;
726
+ int cplen;
727
+ unsigned long l, score = 0;
728
+
729
+ cp = fdt_getprop(blob, node, "compatible", &cplen);
730
+ if (cp == NULL)
731
+ return 0;
732
+ while (cplen > 0) {
733
+ score++;
734
+ if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
735
+ return score;
736
+ l = strlen(cp) + 1;
737
+ cp += l;
738
+ cplen -= l;
739
+ }
740
+
741
+ return 0;
742
+}
743
+
744
+/**
893745 * of_flat_dt_is_compatible - Return true if given node has compat in compatible list
894746 * @node: node to test
895747 * @compat: compatible string to compare with compatible list.
....@@ -902,9 +754,21 @@
902754 /**
903755 * of_flat_dt_match - Return true if node matches a list of compatible values
904756 */
905
-int __init of_flat_dt_match(unsigned long node, const char *const *compat)
757
+static int __init of_flat_dt_match(unsigned long node, const char *const *compat)
906758 {
907
- return of_fdt_match(initial_boot_params, node, compat);
759
+ unsigned int tmp, score = 0;
760
+
761
+ if (!compat)
762
+ return 0;
763
+
764
+ while (*compat) {
765
+ tmp = of_fdt_is_compatible(initial_boot_params, node, *compat);
766
+ if (tmp && (score == 0 || (tmp < score)))
767
+ score = tmp;
768
+ compat++;
769
+ }
770
+
771
+ return score;
908772 }
909773
910774 /**
....@@ -985,15 +849,20 @@
985849 }
986850
987851 #ifdef CONFIG_BLK_DEV_INITRD
988
-#ifndef __early_init_dt_declare_initrd
989852 static void __early_init_dt_declare_initrd(unsigned long start,
990853 unsigned long end)
991854 {
992
- initrd_start = (unsigned long)__va(start);
993
- initrd_end = (unsigned long)__va(end);
994
- initrd_below_start_ok = 1;
855
+ /* ARM64 would cause a BUG to occur here when CONFIG_DEBUG_VM is
856
+ * enabled since __va() is called too early. ARM64 does make use
857
+ * of phys_initrd_start/phys_initrd_size so we can skip this
858
+ * conversion.
859
+ */
860
+ if (!IS_ENABLED(CONFIG_ARM64)) {
861
+ initrd_start = (unsigned long)__va(start);
862
+ initrd_end = (unsigned long)__va(end);
863
+ initrd_below_start_ok = 1;
864
+ }
995865 }
996
-#endif
997866
998867 /**
999868 * early_init_dt_check_for_initrd - Decode initrd location from flat tree
....@@ -1018,6 +887,8 @@
1018887 end = of_read_number(prop, len/4);
1019888
1020889 __early_init_dt_declare_initrd(start, end);
890
+ phys_initrd_start = start;
891
+ phys_initrd_size = end - start;
1021892
1022893 pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n",
1023894 (unsigned long long)start, (unsigned long long)end);
....@@ -1072,8 +943,8 @@
1072943 if (fdt_node_check_compatible(fdt, offset, match->compatible))
1073944 continue;
1074945
1075
- of_setup_earlycon(match, offset, options);
1076
- return 0;
946
+ if (of_setup_earlycon(match, offset, options) == 0)
947
+ return 0;
1077948 }
1078949 return -ENODEV;
1079950 }
....@@ -1193,8 +1064,8 @@
11931064 {
11941065 int l = 0;
11951066 const char *p = NULL;
1196
- char *cmdline = data;
11971067 const void *rng_seed;
1068
+ char *cmdline = data;
11981069
11991070 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
12001071
....@@ -1223,11 +1094,11 @@
12231094 strncpy(cmdline + cmdline_len, p, copy_len);
12241095 cmdline[cmdline_len + copy_len] = '\0';
12251096 } else {
1226
- strlcpy(cmdline, p, min((int)l, COMMAND_LINE_SIZE));
1097
+ strlcpy(cmdline, p, min(l, COMMAND_LINE_SIZE));
12271098 }
12281099 }
12291100
1230
- pr_debug("Command line is: %s\n", (char*)data);
1101
+ pr_debug("Command line is: %s\n", (char *)data);
12311102
12321103 rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
12331104 if (rng_seed && l > 0) {
....@@ -1245,7 +1116,6 @@
12451116 return 1;
12461117 }
12471118
1248
-#ifdef CONFIG_HAVE_MEMBLOCK
12491119 #ifndef MIN_MEMBLOCK_ADDR
12501120 #define MIN_MEMBLOCK_ADDR __pa(PAGE_OFFSET)
12511121 #endif
....@@ -1257,37 +1127,38 @@
12571127 {
12581128 const u64 phys_offset = MIN_MEMBLOCK_ADDR;
12591129
1130
+ if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
1131
+ pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1132
+ base, base + size);
1133
+ return;
1134
+ }
1135
+
12601136 if (!PAGE_ALIGNED(base)) {
1261
- if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
1262
- pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1263
- base, base + size);
1264
- return;
1265
- }
12661137 size -= PAGE_SIZE - (base & ~PAGE_MASK);
12671138 base = PAGE_ALIGN(base);
12681139 }
12691140 size &= PAGE_MASK;
12701141
12711142 if (base > MAX_MEMBLOCK_ADDR) {
1272
- pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
1273
- base, base + size);
1143
+ pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1144
+ base, base + size);
12741145 return;
12751146 }
12761147
12771148 if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
1278
- pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
1279
- ((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
1149
+ pr_warn("Ignoring memory range 0x%llx - 0x%llx\n",
1150
+ ((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
12801151 size = MAX_MEMBLOCK_ADDR - base + 1;
12811152 }
12821153
12831154 if (base + size < phys_offset) {
1284
- pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
1285
- base, base + size);
1155
+ pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
1156
+ base, base + size);
12861157 return;
12871158 }
12881159 if (base < phys_offset) {
1289
- pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
1290
- base, phys_offset);
1160
+ pr_warn("Ignoring memory range 0x%llx - 0x%llx\n",
1161
+ base, phys_offset);
12911162 size -= phys_offset - base;
12921163 base = phys_offset;
12931164 }
....@@ -1302,34 +1173,31 @@
13021173 int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
13031174 phys_addr_t size, bool nomap)
13041175 {
1305
- if (nomap)
1306
- return memblock_remove(base, size);
1176
+ if (nomap) {
1177
+ /*
1178
+ * If the memory is already reserved (by another region), we
1179
+ * should not allow it to be marked nomap.
1180
+ */
1181
+ if (memblock_is_region_reserved(base, size))
1182
+ return -EBUSY;
1183
+
1184
+ if (memblock_is_nomap_remove())
1185
+ return memblock_remove(base, size);
1186
+
1187
+ return memblock_mark_nomap(base, size);
1188
+ }
13071189 return memblock_reserve(base, size);
13081190 }
13091191
1310
-#else
1311
-void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
1312
-{
1313
- WARN_ON(1);
1314
-}
1315
-
1316
-int __init __weak early_init_dt_mark_hotplug_memory_arch(u64 base, u64 size)
1317
-{
1318
- return -ENOSYS;
1319
-}
1320
-
1321
-int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
1322
- phys_addr_t size, bool nomap)
1323
-{
1324
- pr_err("Reserved memory not supported, ignoring range %pa - %pa%s\n",
1325
- &base, &size, nomap ? " (nomap)" : "");
1326
- return -ENOSYS;
1327
-}
1328
-#endif
1329
-
13301192 static void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
13311193 {
1332
- return memblock_virt_alloc(size, align);
1194
+ void *ptr = memblock_alloc(size, align);
1195
+
1196
+ if (!ptr)
1197
+ panic("%s: Failed to allocate %llu bytes align=0x%llx\n",
1198
+ __func__, size, align);
1199
+
1200
+ return ptr;
13331201 }
13341202
13351203 bool __init early_init_dt_verify(void *params)
....@@ -1351,8 +1219,12 @@
13511219
13521220 void __init early_init_dt_scan_nodes(void)
13531221 {
1222
+ int rc = 0;
1223
+
13541224 /* Retrieve various information from the /chosen node */
1355
- of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
1225
+ rc = of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
1226
+ if (!rc)
1227
+ pr_warn("No chosen node found, continuing without\n");
13561228
13571229 /* Initialize {size,address}-cells info */
13581230 of_scan_flat_dt(early_init_dt_scan_root, NULL);