Skip to content

Commit fd3e12d

Browse files
committed
lk2nd: dev_tree: Mark as best dtb node if compatible matches with lk2nd dtb
Makes sure we load the correct dtb node based on lk2nd's device selection logic when boot.img contains multiple dtbs with same ids. For example, on msm8953-xiaomi-common.dts, we see 3 devices sharing the same msm-id and board-id. If a given boot.img contains dtbs for all these devices, without this logic lk2nd will always load the first of these dtbs, regardless of the device it's being run on. Try using compatible string from `dtb_compatible` property first, because there's some devices supposed to use some other devices' dtb in mainline kernel (e.g. xiaomi-sakura uses xiaomi-daisy dtb). This shouldn't affect booting downstream kernels, since they normally don't define `<vendor>,<device>` on their dts compatible. Change-Id: Ib7ed0908038f178d34eaa6b4952691c17055c22b
1 parent dc07936 commit fd3e12d

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

lk2nd/device/device.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ const char *const *lk2nd_device_get_dtb_hints(void)
2424
return lk2nd_dev.dtbfiles;
2525
}
2626

27+
/**
28+
* lk2nd_device_get_dtb_compatible() - Get a compatible string for matching kernel dtb.
29+
*/
30+
const char *lk2nd_device_get_dtb_compatible(void)
31+
{
32+
return lk2nd_dev.dtb_compatible ? lk2nd_dev.dtb_compatible : lk2nd_dev.compatible;
33+
}
34+
2735
static int find_device_node(const void *dtb)
2836
{
2937
int lk2nd_node, node, ret;
@@ -112,6 +120,12 @@ static void parse_dtb(const void *dtb)
112120
else
113121
dprintf(CRITICAL, "Failed to read 'compatible': %d\n", len);
114122

123+
val = fdt_getprop(dtb, node, "dtb_compatible", &len);
124+
if (val && len > 0)
125+
lk2nd_dev.dtb_compatible = strndup(val, len);
126+
else
127+
dprintf(CRITICAL, "Failed to read 'dtb_compatible': %d\n", len);
128+
115129
val = fdt_getprop(dtb, node, "model", &len);
116130
if (val && len > 0)
117131
lk2nd_dev.model = strndup(val, len);

lk2nd/device/device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct lk2nd_device {
2929
const char *model;
3030
const char *battery;
3131

32+
const char *dtb_compatible;
3233
const char *const *dtbfiles;
3334
bool single_key;
3435
struct lk2nd_menu_keys menu_keys;

lk2nd/include/lk2nd/device.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ void lk2nd_device2nd_copy_atags(void *tags, const char *cmdline,
1212

1313
#if WITH_LK2ND_DEVICE
1414
const char *const *lk2nd_device_get_dtb_hints(void);
15+
const char *lk2nd_device_get_dtb_compatible(void);
1516
#else
1617
static inline const char *const *lk2nd_device_get_dtb_hints(void) { return NULL; };
18+
static inline const char *lk2nd_device_get_dtb_compatible(void) { return NULL; };
1719
#endif
1820

1921
#endif /* LK2ND_DEVICE_H */

platform/msm_shared/dev_tree.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
#endif
5151
#include <boot_stats.h>
5252
#include <verifiedboot.h>
53+
#if WITH_LK2ND_DEVICE
54+
#include <lk2nd/device.h>
55+
#endif
5356

5457
#define NODE_PROPERTY_MAX_LEN 64
5558
#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
@@ -401,6 +404,15 @@ static boolean dtb_read_find_match(dt_info *current_dtb_info, dt_info *best_dtb_
401404
return false;
402405
}
403406

407+
#if WITH_LK2ND_DEVICE
408+
if (fdt_node_check_compatible(dtb, root_offset, lk2nd_device_get_dtb_compatible()) == 0) {
409+
dprintf(INFO, "Compatible %s matches, mark as best dtb node\n", lk2nd_device_get_dtb_compatible());
410+
current_dtb_info->dt_match_val = UINT_MAX;
411+
current_dtb_info->dt_match_val &= ~exact_match;
412+
goto cleanup;
413+
}
414+
#endif
415+
404416
/* Get the msm-id prop from DTB and find best match */
405417
platform_prop = (const char *)fdt_getprop(dtb, root_offset, "qcom,msm-id", &platform_id_len);
406418
if (platform_prop && (platform_id_len > 0) && (!(platform_id_len % PLAT_ID_SIZE))) {
@@ -823,6 +835,7 @@ static int dev_tree_compatible(const void *dtb, const void *real_dtb, uint32_t d
823835
uint32_t board_data_count;
824836
uint32_t pmic_data_count;
825837
uint32_t dtb_count = 0;;
838+
bool set_dt_entry_is_best = false;
826839

827840
if (!root_offset)
828841
root_offset = fdt_path_offset(dtb, "/");
@@ -840,6 +853,13 @@ if (DEBUGLEVEL >= SPEW) {
840853
}
841854
}
842855

856+
#if WITH_LK2ND_DEVICE
857+
if (fdt_node_check_compatible(dtb, root_offset, lk2nd_device_get_dtb_compatible()) == 0) {
858+
dprintf(INFO, "Compatible %s matches, mark as best dtb node\n", lk2nd_device_get_dtb_compatible());
859+
set_dt_entry_is_best = true;
860+
}
861+
#endif
862+
843863
/* Find the pmic-id prop from DTB , if pmic-id is present then
844864
* the DTB is version 3, otherwise find the board-id prop from DTB ,
845865
* if board-id is present then the DTB is version 2 */
@@ -921,6 +941,7 @@ if (DEBUGLEVEL >= SPEW) {
921941
cur_dt_entry->pmic_rev[3] = board_pmic_target(3);
922942
cur_dt_entry->offset = (uint32_t)real_dtb;
923943
cur_dt_entry->size = dtb_size;
944+
cur_dt_entry->is_best = set_dt_entry_is_best;
924945

925946
if (min_plat_id_len == DT_ENTRY_LGE8974_SIZE)
926947
cur_dt_entry->board_hw_subtype = fdt32_to_cpu(((const struct dt_entry_v1 *)plat_prop)->offset);
@@ -1076,6 +1097,7 @@ if (DEBUGLEVEL >= SPEW) {
10761097
dt_entry_array[k].pmic_rev[3]= pmic_data[n].pmic_version[3];
10771098
dt_entry_array[k].offset = (uint32_t)real_dtb;
10781099
dt_entry_array[k].size = dtb_size;
1100+
dt_entry_array[k].is_best = set_dt_entry_is_best;
10791101
k++;
10801102
}
10811103

@@ -1090,6 +1112,7 @@ if (DEBUGLEVEL >= SPEW) {
10901112
dt_entry_array[k].pmic_rev[3]= board_pmic_target(3);
10911113
dt_entry_array[k].offset = (uint32_t)real_dtb;
10921114
dt_entry_array[k].size = dtb_size;
1115+
dt_entry_array[k].is_best = set_dt_entry_is_best;
10931116
k++;
10941117
}
10951118
}
@@ -1829,6 +1852,20 @@ static struct dt_entry *platform_dt_match_best(struct dt_entry_node *dt_list)
18291852
if (!update_dtb_entry_node(dt_list, DTB_PMIC3))
18301853
return NULL;
18311854

1855+
#if WITH_LK2ND_DEVICE
1856+
list_for_every_entry(&dt_list->node, dt_node_tmp1, dt_node, node) {
1857+
if (!dt_node_tmp1)
1858+
break;
1859+
1860+
if (!dt_node_tmp1->dt_entry_m)
1861+
continue;
1862+
1863+
if (dt_node_tmp1->dt_entry_m->is_best) {
1864+
return dt_node_tmp1->dt_entry_m;
1865+
}
1866+
}
1867+
#endif
1868+
18321869
list_for_every_entry(&dt_list->node, dt_node_tmp1, dt_node, node) {
18331870
if (!dt_node_tmp1) {
18341871
dprintf(CRITICAL, "ERROR: Couldn't find the suitable DTB!\n");

platform/msm_shared/include/dev_tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ struct dt_entry
169169
uint32_t offset;
170170
uint32_t size;
171171
uint32_t idx;
172+
bool is_best;
172173
};
173174

174175
struct dt_table

0 commit comments

Comments
 (0)