Skip to content

Commit f035188

Browse files
authored
[OFW] Support ID map interface (#8994)
The OFW map id is always use in DMA, PCI, IOMMU bus system to find the device identity. this is a access interface. Signed-off-by: GuEe-GUI <[email protected]>
1 parent 8c6c920 commit f035188

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

components/drivers/include/drivers/ofw.h

+3
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ struct rt_ofw_node *rt_ofw_get_alias_node(const char *tag, int id);
205205
int rt_ofw_get_alias_id(struct rt_ofw_node *np, const char *tag);
206206
int rt_ofw_get_alias_last_id(const char *tag);
207207

208+
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,
209+
struct rt_ofw_node **ref_np, rt_uint32_t *out_id);
210+
208211
struct rt_ofw_node *rt_ofw_append_child(struct rt_ofw_node *parent, const char *full_name);
209212
rt_err_t rt_ofw_append_prop(struct rt_ofw_node *np, const char *name, int length, void *value);
210213

components/drivers/ofw/base.c

+132
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,138 @@ int rt_ofw_get_alias_last_id(const char *tag)
12241224
return id;
12251225
}
12261226

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+
12271359
struct rt_ofw_node *rt_ofw_append_child(struct rt_ofw_node *parent, const char *full_name)
12281360
{
12291361
rt_phandle phandle;

0 commit comments

Comments
 (0)