@@ -1224,6 +1224,138 @@ int rt_ofw_get_alias_last_id(const char *tag)
1224
1224
return id ;
1225
1225
}
1226
1226
1227
+ static rt_err_t ofw_map_id (struct rt_ofw_node * np , rt_uint32_t id , const char * map_name , const char * map_mask_name ,
1228
+ const fdt32_t * map , rt_ssize_t map_len , struct rt_ofw_node * * ref_np , rt_uint32_t * out_id )
1229
+ {
1230
+ rt_err_t err = RT_EOK ;
1231
+ rt_uint32_t masked_id , map_mask ;
1232
+
1233
+ /* Select all bits default */
1234
+ map_mask = 0xffffffff ;
1235
+
1236
+ if (map_mask_name )
1237
+ {
1238
+ rt_ofw_prop_read_u32 (np , map_mask_name , & map_mask );
1239
+ }
1240
+
1241
+ masked_id = map_mask & id ;
1242
+
1243
+ for (; map_len > 0 ; map_len -= 4 * sizeof (* map ), map += 4 )
1244
+ {
1245
+ struct rt_ofw_node * phandle_node ;
1246
+ rt_uint32_t id_base = fdt32_to_cpu (* (map + 0 ));
1247
+ rt_uint32_t phandle = fdt32_to_cpu (* (map + 1 ));
1248
+ rt_uint32_t out_base = fdt32_to_cpu (* (map + 2 ));
1249
+ rt_uint32_t id_len = fdt32_to_cpu (* (map + 3 ));
1250
+
1251
+ if (id_base & ~map_mask )
1252
+ {
1253
+ LOG_E ("%s: Invalid %s translation - %s(0x%x) for id-base = 0x%x" ,
1254
+ np -> full_name , map_name , map_mask_name , map_mask , id_base );
1255
+
1256
+ err = - RT_ERROR ;
1257
+ break ;
1258
+ }
1259
+
1260
+ if (masked_id < id_base || masked_id >= id_base + id_len )
1261
+ {
1262
+ continue ;
1263
+ }
1264
+
1265
+ phandle_node = rt_ofw_find_node_by_phandle ((rt_phandle )phandle );
1266
+
1267
+ if (!phandle_node )
1268
+ {
1269
+ err = - RT_EEMPTY ;
1270
+ break ;
1271
+ }
1272
+
1273
+ if (ref_np )
1274
+ {
1275
+ if (* ref_np )
1276
+ {
1277
+ rt_ofw_node_put (phandle_node );
1278
+ }
1279
+ else
1280
+ {
1281
+ * ref_np = phandle_node ;
1282
+ }
1283
+
1284
+ if (* ref_np != phandle_node )
1285
+ {
1286
+ continue ;
1287
+ }
1288
+ }
1289
+
1290
+ if (out_id )
1291
+ {
1292
+ * out_id = masked_id - id_base + out_base ;
1293
+ }
1294
+
1295
+ LOG_D ("%s: Get %s translation - %s(0x%x) for id-base = 0x%x, out-base = 0x%x, length = %d, id: 0x%x -> 0x%x" ,
1296
+ np -> full_name , map_name , map_mask_name , map_mask ,
1297
+ id_base , out_base , id_len , id , masked_id - id_base + out_base );
1298
+
1299
+ break ;
1300
+ }
1301
+
1302
+ if (map_len <= 0 )
1303
+ {
1304
+ LOG_I ("%s: No %s translation for id(0x%x) on %s" , np -> full_name , map_name ,
1305
+ id , ref_np && * ref_np ? * ref_np : RT_NULL );
1306
+
1307
+ /* Bypasses translation */
1308
+ if (out_id )
1309
+ {
1310
+ * out_id = id ;
1311
+ }
1312
+ }
1313
+
1314
+ return err ;
1315
+ }
1316
+
1317
+ rt_err_t rt_ofw_map_id (struct rt_ofw_node * np , rt_uint32_t id , const char * map_name , const char * map_mask_name ,
1318
+ struct rt_ofw_node * * ref_np , rt_uint32_t * out_id )
1319
+ {
1320
+ rt_err_t err ;
1321
+
1322
+ if (np && map_name && (ref_np || out_id ))
1323
+ {
1324
+ rt_ssize_t map_len ;
1325
+ const fdt32_t * map = rt_ofw_prop_read_raw (np , map_name , & map_len );
1326
+
1327
+ if (!map )
1328
+ {
1329
+ if (ref_np )
1330
+ {
1331
+ err = - RT_EEMPTY ;
1332
+ }
1333
+ else
1334
+ {
1335
+ * out_id = id ;
1336
+ }
1337
+
1338
+ err = RT_EOK ;
1339
+ }
1340
+ else if (!map_len || map_len % (4 * sizeof (* map )))
1341
+ {
1342
+ LOG_E ("%s: Invalid %s length = %u" , np -> full_name , map_name , map_len );
1343
+
1344
+ err = - RT_EINVAL ;
1345
+ }
1346
+ else
1347
+ {
1348
+ err = ofw_map_id (np , id , map_name , map_mask_name , map , map_len , ref_np , out_id );
1349
+ }
1350
+ }
1351
+ else
1352
+ {
1353
+ err = - RT_EINVAL ;
1354
+ }
1355
+
1356
+ return err ;
1357
+ }
1358
+
1227
1359
struct rt_ofw_node * rt_ofw_append_child (struct rt_ofw_node * parent , const char * full_name )
1228
1360
{
1229
1361
rt_phandle phandle ;
0 commit comments