mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
ppc/vof: Make nextprop behave more like Open Firmware
The FDT does not normally store name properties but reconstructs it from path but Open Firmware specification says each node should at least have this property. This is correctly handled in getprop but nextprop should also return it even if not present as a property. Explicit name properties are still allowed because they are needed e.g. on the root node that guests expect to have specific names as seen on real machines instead of being empty so sometimes the node name may need to be overriden. For example on pegasos MorphOS checks the name of "/" and expects to find bplan,Pegasos2 which is how it identifies the machine. Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Link: https://lore.kernel.org/qemu-devel/366f14ce852415cc079727c54ac21a2aa6ff3917.1761176219.git.balaton@eik.bme.hu Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
This commit is contained in:
+33
-17
@@ -353,34 +353,50 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle,
|
||||
{
|
||||
int offset, nodeoff = fdt_node_offset_by_phandle(fdt, phandle);
|
||||
char prev[OF_PROPNAME_LEN_MAX + 1];
|
||||
const char *tmp;
|
||||
const char *tmp = NULL;
|
||||
bool match = false;
|
||||
|
||||
if (readstr(prevaddr, prev, sizeof(prev))) {
|
||||
return PROM_ERROR;
|
||||
}
|
||||
|
||||
fdt_for_each_property_offset(offset, fdt, nodeoff) {
|
||||
if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
|
||||
return 0;
|
||||
/*
|
||||
* "name" may or may not be present in fdt but we should still return it.
|
||||
* Do that first and then skip it if seen later.
|
||||
*/
|
||||
if (prev[0] == '\0') {
|
||||
tmp = "name";
|
||||
} else {
|
||||
if (strcmp(prev, "name") == 0) {
|
||||
prev[0] = '\0';
|
||||
}
|
||||
if (prev[0] == '\0' || strcmp(prev, tmp) == 0) {
|
||||
if (prev[0] != '\0') {
|
||||
offset = fdt_next_property_offset(fdt, offset);
|
||||
if (offset < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fdt_for_each_property_offset(offset, fdt, nodeoff) {
|
||||
if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
|
||||
return PROM_ERROR;
|
||||
if (strcmp(tmp, "name") == 0) {
|
||||
continue;
|
||||
}
|
||||
return 1;
|
||||
if (match) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(prev, tmp) == 0) {
|
||||
match = true;
|
||||
continue;
|
||||
}
|
||||
if (prev[0] == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (offset < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp) {
|
||||
if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
|
||||
return PROM_ERROR;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user