mirror of https://github.com/xemu-project/xemu.git
Introduce cpu topology support
Generate DBG2 table Switch to ssize_t for elf loader return type Fixed sbsa cpu type error message typo Only initialize required submodules for edk2 Dont create device-tree node for empty NUMA node -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmFxhbgdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/Z6gf/Wt/iI+cwM8+eNYgV fFrvkN2YUBS4B7QBVs7axbUmHs+/B8PIyBjo9WLmkMTdgnj13JiXmvE879PZwryr zlh/2KqKBq+87L5CMOfPXtePizlZI/TuxJL0koIMW/L85ABEYOMyaDp0bDqhJHHb UNBxvlxHgBmZUpBkmJKWoOKxQ9Jz8M5jpoUjKFCxhMHqbzAQOjS0B0IR6E4n8R4o pKiWStc2TB7aGtVRY/Jm4EaSy9n3g77K40Yxkn6txN8Eqm/QxCLq9uwEZM2YMR5h IJUxdUVNT31mCd2EhSAlHqpCrKuFaGCb+t8fQxLkd73AT5Unm5jJl5alfsO8khgV TgipUA== =boXv -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-arm-20211021' into staging Introduce cpu topology support Generate DBG2 table Switch to ssize_t for elf loader return type Fixed sbsa cpu type error message typo Only initialize required submodules for edk2 Dont create device-tree node for empty NUMA node # gpg: Signature made Thu 21 Oct 2021 08:22:32 AM PDT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * remotes/rth/tags/pull-arm-20211021: tests/data/acpi/virt: Update the empty expected file for PPTT hw/arm/virt-acpi-build: Generate PPTT table tests/data/acpi/virt: Add an empty expected file for PPTT hw/acpi/aml-build: Add PPTT table hw/acpi/aml-build: Add Processor hierarchy node structure hw/arm/virt: Add cpu-map to device tree device_tree: Add qemu_fdt_add_path hw/arm/virt: Only describe cpu topology since virt-6.2 bios-tables-test: Generate reference table for virt/DBG2 hw/arm/virt_acpi_build: Generate DBG2 table tests/acpi: Add void table for virt/DBG2 bios-tables-test hw/elf_ops.h: switch to ssize_t for elf loader return type hw/arm/sbsa-ref: Fixed cpu type error message typo. roms/edk2: Only initialize required submodules roms/edk2: Only init brotli submodule to build BaseTools hw/arm/virt: Don't create device-tree node for empty NUMA node tests/acpi: Generate reference blob for IORT rev E.b hw/arm/virt-acpi-build: IORT upgrade up to revision E.b tests/acpi: Get prepared for IORT E.b revision upgrade Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
4c127fdbe8
|
@ -50,7 +50,11 @@ build-edk2:
|
|||
GIT_DEPTH: 3
|
||||
script: # Clone the required submodules and build EDK2
|
||||
- git submodule update --init roms/edk2
|
||||
- git -C roms/edk2 submodule update --init
|
||||
- git -C roms/edk2 submodule update --init --
|
||||
ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3
|
||||
BaseTools/Source/C/BrotliCompress/brotli
|
||||
CryptoPkg/Library/OpensslLib/openssl
|
||||
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli
|
||||
- export JOBS=$(($(getconf _NPROCESSORS_ONLN) + 1))
|
||||
- echo "=== Using ${JOBS} simultaneous jobs ==="
|
||||
- make -j${JOBS} -C roms efi 2>&1 1>edk2-stdout.log | tee -a edk2-stderr.log >&2
|
||||
|
|
|
@ -1964,6 +1964,95 @@ void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
|||
acpi_table_end(linker, &table);
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI spec, Revision 6.3
|
||||
* 5.2.29.1 Processor hierarchy node structure (Type 0)
|
||||
*/
|
||||
static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
|
||||
uint32_t parent, uint32_t id,
|
||||
uint32_t *priv_rsrc,
|
||||
uint32_t priv_num)
|
||||
{
|
||||
int i;
|
||||
|
||||
build_append_byte(tbl, 0); /* Type 0 - processor */
|
||||
build_append_byte(tbl, 20 + priv_num * 4); /* Length */
|
||||
build_append_int_noprefix(tbl, 0, 2); /* Reserved */
|
||||
build_append_int_noprefix(tbl, flags, 4); /* Flags */
|
||||
build_append_int_noprefix(tbl, parent, 4); /* Parent */
|
||||
build_append_int_noprefix(tbl, id, 4); /* ACPI Processor ID */
|
||||
|
||||
/* Number of private resources */
|
||||
build_append_int_noprefix(tbl, priv_num, 4);
|
||||
|
||||
/* Private resources[N] */
|
||||
if (priv_num > 0) {
|
||||
assert(priv_rsrc);
|
||||
for (i = 0; i < priv_num; i++) {
|
||||
build_append_int_noprefix(tbl, priv_rsrc[i], 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ACPI spec, Revision 6.3
|
||||
* 5.2.29 Processor Properties Topology Table (PPTT)
|
||||
*/
|
||||
void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
{
|
||||
int pptt_start = table_data->len;
|
||||
int uid = 0;
|
||||
int socket;
|
||||
AcpiTable table = { .sig = "PPTT", .rev = 2,
|
||||
.oem_id = oem_id, .oem_table_id = oem_table_id };
|
||||
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
||||
for (socket = 0; socket < ms->smp.sockets; socket++) {
|
||||
uint32_t socket_offset = table_data->len - pptt_start;
|
||||
int core;
|
||||
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
/*
|
||||
* Physical package - represents the boundary
|
||||
* of a physical package
|
||||
*/
|
||||
(1 << 0),
|
||||
0, socket, NULL, 0);
|
||||
|
||||
for (core = 0; core < ms->smp.cores; core++) {
|
||||
uint32_t core_offset = table_data->len - pptt_start;
|
||||
int thread;
|
||||
|
||||
if (ms->smp.threads > 1) {
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
(0 << 0), /* not a physical package */
|
||||
socket_offset, core, NULL, 0);
|
||||
|
||||
for (thread = 0; thread < ms->smp.threads; thread++) {
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
(1 << 1) | /* ACPI Processor ID valid */
|
||||
(1 << 2) | /* Processor is a Thread */
|
||||
(1 << 3), /* Node is a Leaf */
|
||||
core_offset, uid++, NULL, 0);
|
||||
}
|
||||
} else {
|
||||
build_processor_hierarchy_node(
|
||||
table_data,
|
||||
(1 << 1) | /* ACPI Processor ID valid */
|
||||
(1 << 3), /* Node is a Leaf */
|
||||
socket_offset, uid++, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acpi_table_end(linker, &table);
|
||||
}
|
||||
|
||||
/* build rev1/rev3/rev5.1 FADT */
|
||||
void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
|
||||
const char *oem_id, const char *oem_table_id)
|
||||
|
|
|
@ -599,10 +599,23 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
|
|||
}
|
||||
g_strfreev(node_path);
|
||||
|
||||
/*
|
||||
* We drop all the memory nodes which correspond to empty NUMA nodes
|
||||
* from the device tree, because the Linux NUMA binding document
|
||||
* states they should not be generated. Linux will get the NUMA node
|
||||
* IDs of the empty NUMA nodes from the distance map if they are needed.
|
||||
* This means QEMU users may be obliged to provide command lines which
|
||||
* configure distance maps when the empty NUMA node IDs are needed and
|
||||
* Linux's default distance map isn't sufficient.
|
||||
*/
|
||||
if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
|
||||
mem_base = binfo->loader_start;
|
||||
for (i = 0; i < ms->numa_state->num_nodes; i++) {
|
||||
mem_len = ms->numa_state->nodes[i].node_mem;
|
||||
if (!mem_len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = fdt_add_memory_node(fdt, acells, mem_base,
|
||||
scells, mem_len, i);
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -670,7 +670,7 @@ static void sbsa_ref_init(MachineState *machine)
|
|||
int n, sbsa_max_cpus;
|
||||
|
||||
if (!cpu_type_valid(machine->cpu_type)) {
|
||||
error_report("mach-virt: CPU type %s not supported", machine->cpu_type);
|
||||
error_report("sbsa-ref: CPU type %s not supported", machine->cpu_type);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -241,19 +241,20 @@ static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineState *vms)
|
|||
#endif
|
||||
|
||||
#define ID_MAPPING_ENTRY_SIZE 20
|
||||
#define SMMU_V3_ENTRY_SIZE 60
|
||||
#define ROOT_COMPLEX_ENTRY_SIZE 32
|
||||
#define SMMU_V3_ENTRY_SIZE 68
|
||||
#define ROOT_COMPLEX_ENTRY_SIZE 36
|
||||
#define IORT_NODE_OFFSET 48
|
||||
|
||||
static void build_iort_id_mapping(GArray *table_data, uint32_t input_base,
|
||||
uint32_t id_count, uint32_t out_ref)
|
||||
{
|
||||
/* Identity RID mapping covering the whole input RID range */
|
||||
/* Table 4 ID mapping format */
|
||||
build_append_int_noprefix(table_data, input_base, 4); /* Input base */
|
||||
build_append_int_noprefix(table_data, id_count, 4); /* Number of IDs */
|
||||
build_append_int_noprefix(table_data, input_base, 4); /* Output base */
|
||||
build_append_int_noprefix(table_data, out_ref, 4); /* Output Reference */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Flags */
|
||||
/* Flags */
|
||||
build_append_int_noprefix(table_data, 0 /* Single mapping (disabled) */, 4);
|
||||
}
|
||||
|
||||
struct AcpiIortIdMapping {
|
||||
|
@ -298,7 +299,7 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b)
|
|||
/*
|
||||
* Input Output Remapping Table (IORT)
|
||||
* Conforms to "IO Remapping Table System Software on ARM Platforms",
|
||||
* Document number: ARM DEN 0049B, October 2015
|
||||
* Document number: ARM DEN 0049E.b, Feb 2021
|
||||
*/
|
||||
static void
|
||||
build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
|
@ -307,10 +308,11 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
const uint32_t iort_node_offset = IORT_NODE_OFFSET;
|
||||
size_t node_size, smmu_offset = 0;
|
||||
AcpiIortIdMapping *idmap;
|
||||
uint32_t id = 0;
|
||||
GArray *smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
|
||||
GArray *its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
|
||||
|
||||
AcpiTable table = { .sig = "IORT", .rev = 0, .oem_id = vms->oem_id,
|
||||
AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id,
|
||||
.oem_table_id = vms->oem_table_id };
|
||||
/* Table 2 The IORT */
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
@ -358,12 +360,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
build_append_int_noprefix(table_data, IORT_NODE_OFFSET, 4);
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
|
||||
/* 3.1.1.3 ITS group node */
|
||||
/* Table 12 ITS Group Format */
|
||||
build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */
|
||||
node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */;
|
||||
build_append_int_noprefix(table_data, node_size, 2); /* Length */
|
||||
build_append_int_noprefix(table_data, 0, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
build_append_int_noprefix(table_data, 1, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, id++, 4); /* Identifier */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */
|
||||
build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */
|
||||
|
@ -374,19 +376,19 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
int irq = vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
|
||||
|
||||
smmu_offset = table_data->len - table.table_offset;
|
||||
/* 3.1.1.2 SMMUv3 */
|
||||
/* Table 9 SMMUv3 Format */
|
||||
build_append_int_noprefix(table_data, 4 /* SMMUv3 */, 1); /* Type */
|
||||
node_size = SMMU_V3_ENTRY_SIZE + ID_MAPPING_ENTRY_SIZE;
|
||||
build_append_int_noprefix(table_data, node_size, 2); /* Length */
|
||||
build_append_int_noprefix(table_data, 0, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
build_append_int_noprefix(table_data, 4, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, id++, 4); /* Identifier */
|
||||
build_append_int_noprefix(table_data, 1, 4); /* Number of ID mappings */
|
||||
/* Reference to ID Array */
|
||||
build_append_int_noprefix(table_data, SMMU_V3_ENTRY_SIZE, 4);
|
||||
/* Base address */
|
||||
build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8);
|
||||
/* Flags */
|
||||
build_append_int_noprefix(table_data, 1 /* COHACC OverrideNote */, 4);
|
||||
build_append_int_noprefix(table_data, 1 /* COHACC Override */, 4);
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
build_append_int_noprefix(table_data, 0, 8); /* VATOS address */
|
||||
/* Model */
|
||||
|
@ -395,35 +397,43 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
build_append_int_noprefix(table_data, irq + 1, 4); /* PRI */
|
||||
build_append_int_noprefix(table_data, irq + 3, 4); /* GERR */
|
||||
build_append_int_noprefix(table_data, irq + 2, 4); /* Sync */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Proximity domain */
|
||||
/* DeviceID mapping index (ignored since interrupts are GSIV based) */
|
||||
build_append_int_noprefix(table_data, 0, 4);
|
||||
|
||||
/* output IORT node is the ITS group node (the first node) */
|
||||
build_iort_id_mapping(table_data, 0, 0xFFFF, IORT_NODE_OFFSET);
|
||||
}
|
||||
|
||||
/* Table 16 Root Complex Node */
|
||||
/* Table 17 Root Complex Node */
|
||||
build_append_int_noprefix(table_data, 2 /* Root complex */, 1); /* Type */
|
||||
node_size = ROOT_COMPLEX_ENTRY_SIZE +
|
||||
ID_MAPPING_ENTRY_SIZE * rc_mapping_count;
|
||||
build_append_int_noprefix(table_data, node_size, 2); /* Length */
|
||||
build_append_int_noprefix(table_data, 0, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
build_append_int_noprefix(table_data, 3, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, id++, 4); /* Identifier */
|
||||
/* Number of ID mappings */
|
||||
build_append_int_noprefix(table_data, rc_mapping_count, 4);
|
||||
/* Reference to ID Array */
|
||||
build_append_int_noprefix(table_data, ROOT_COMPLEX_ENTRY_SIZE, 4);
|
||||
|
||||
/* Table 13 Memory access properties */
|
||||
/* Table 14 Memory access properties */
|
||||
/* CCA: Cache Coherent Attribute */
|
||||
build_append_int_noprefix(table_data, 1 /* fully coherent */, 4);
|
||||
build_append_int_noprefix(table_data, 0, 1); /* AH: Note Allocation Hints */
|
||||
build_append_int_noprefix(table_data, 0, 2); /* Reserved */
|
||||
/* MAF: Note Memory Access Flags */
|
||||
build_append_int_noprefix(table_data, 0x3 /* CCA = CPM = DCAS = 1 */, 1);
|
||||
/* Table 15 Memory Access Flags */
|
||||
build_append_int_noprefix(table_data, 0x3 /* CCA = CPM = DACS = 1 */, 1);
|
||||
|
||||
build_append_int_noprefix(table_data, 0, 4); /* ATS Attribute */
|
||||
/* MCFG pci_segment */
|
||||
build_append_int_noprefix(table_data, 0, 4); /* PCI Segment number */
|
||||
|
||||
/* Memory address size limit */
|
||||
build_append_int_noprefix(table_data, 64, 1);
|
||||
|
||||
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
|
||||
|
||||
/* Output Reference */
|
||||
if (vms->iommu == VIRT_IOMMU_SMMUV3) {
|
||||
AcpiIortIdMapping *range;
|
||||
|
@ -616,6 +626,64 @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
acpi_table_end(linker, &table);
|
||||
}
|
||||
|
||||
/* Debug Port Table 2 (DBG2) */
|
||||
static void
|
||||
build_dbg2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
{
|
||||
AcpiTable table = { .sig = "DBG2", .rev = 0, .oem_id = vms->oem_id,
|
||||
.oem_table_id = vms->oem_table_id };
|
||||
int dbg2devicelength;
|
||||
const char name[] = "COM0";
|
||||
const int namespace_length = sizeof(name);
|
||||
|
||||
acpi_table_begin(&table, table_data);
|
||||
|
||||
dbg2devicelength = 22 + /* BaseAddressRegister[] offset */
|
||||
12 + /* BaseAddressRegister[] */
|
||||
4 + /* AddressSize[] */
|
||||
namespace_length /* NamespaceString[] */;
|
||||
|
||||
/* OffsetDbgDeviceInfo */
|
||||
build_append_int_noprefix(table_data, 44, 4);
|
||||
/* NumberDbgDeviceInfo */
|
||||
build_append_int_noprefix(table_data, 1, 4);
|
||||
|
||||
/* Table 2. Debug Device Information structure format */
|
||||
build_append_int_noprefix(table_data, 0, 1); /* Revision */
|
||||
build_append_int_noprefix(table_data, dbg2devicelength, 2); /* Length */
|
||||
/* NumberofGenericAddressRegisters */
|
||||
build_append_int_noprefix(table_data, 1, 1);
|
||||
/* NameSpaceStringLength */
|
||||
build_append_int_noprefix(table_data, namespace_length, 2);
|
||||
build_append_int_noprefix(table_data, 38, 2); /* NameSpaceStringOffset */
|
||||
build_append_int_noprefix(table_data, 0, 2); /* OemDataLength */
|
||||
/* OemDataOffset (0 means no OEM data) */
|
||||
build_append_int_noprefix(table_data, 0, 2);
|
||||
|
||||
/* Port Type */
|
||||
build_append_int_noprefix(table_data, 0x8000 /* Serial */, 2);
|
||||
/* Port Subtype */
|
||||
build_append_int_noprefix(table_data, 0x3 /* ARM PL011 UART */, 2);
|
||||
build_append_int_noprefix(table_data, 0, 2); /* Reserved */
|
||||
/* BaseAddressRegisterOffset */
|
||||
build_append_int_noprefix(table_data, 22, 2);
|
||||
/* AddressSizeOffset */
|
||||
build_append_int_noprefix(table_data, 34, 2);
|
||||
|
||||
/* BaseAddressRegister[] */
|
||||
build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1,
|
||||
vms->memmap[VIRT_UART].base);
|
||||
|
||||
/* AddressSize[] */
|
||||
build_append_int_noprefix(table_data,
|
||||
vms->memmap[VIRT_UART].size, 4);
|
||||
|
||||
/* NamespaceString[] */
|
||||
g_array_append_vals(table_data, name, namespace_length);
|
||||
|
||||
acpi_table_end(linker, &table);
|
||||
};
|
||||
|
||||
/*
|
||||
* ACPI spec, Revision 5.1 Errata A
|
||||
* 5.2.12 Multiple APIC Description Table (MADT)
|
||||
|
@ -875,13 +943,19 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
|||
dsdt = tables_blob->len;
|
||||
build_dsdt(tables_blob, tables->linker, vms);
|
||||
|
||||
/* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
|
||||
/* FADT MADT PPTT GTDT MCFG SPCR DBG2 pointed to by RSDT */
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_fadt_rev5(tables_blob, tables->linker, vms, dsdt);
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_madt(tables_blob, tables->linker, vms);
|
||||
|
||||
if (!vmc->no_cpu_topology) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_pptt(tables_blob, tables->linker, ms,
|
||||
vms->oem_id, vms->oem_table_id);
|
||||
}
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_gtdt(tables_blob, tables->linker, vms);
|
||||
|
||||
|
@ -898,6 +972,9 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
|||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_spcr(tables_blob, tables->linker, vms);
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_dbg2(tables_blob, tables->linker, vms);
|
||||
|
||||
if (vms->ras) {
|
||||
build_ghes_error_table(tables->hardware_errors, tables->linker);
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
|
|
|
@ -351,20 +351,21 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
|||
int cpu;
|
||||
int addr_cells = 1;
|
||||
const MachineState *ms = MACHINE(vms);
|
||||
const VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
|
||||
int smp_cpus = ms->smp.cpus;
|
||||
|
||||
/*
|
||||
* From Documentation/devicetree/bindings/arm/cpus.txt
|
||||
* On ARM v8 64-bit systems value should be set to 2,
|
||||
* that corresponds to the MPIDR_EL1 register size.
|
||||
* If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
|
||||
* in the system, #address-cells can be set to 1, since
|
||||
* MPIDR_EL1[63:32] bits are not used for CPUs
|
||||
* identification.
|
||||
* See Linux Documentation/devicetree/bindings/arm/cpus.yaml
|
||||
* On ARM v8 64-bit systems value should be set to 2,
|
||||
* that corresponds to the MPIDR_EL1 register size.
|
||||
* If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
|
||||
* in the system, #address-cells can be set to 1, since
|
||||
* MPIDR_EL1[63:32] bits are not used for CPUs
|
||||
* identification.
|
||||
*
|
||||
* Here we actually don't know whether our system is 32- or 64-bit one.
|
||||
* The simplest way to go is to examine affinity IDs of all our CPUs. If
|
||||
* at least one of them has Aff3 populated, we set #address-cells to 2.
|
||||
* Here we actually don't know whether our system is 32- or 64-bit one.
|
||||
* The simplest way to go is to examine affinity IDs of all our CPUs. If
|
||||
* at least one of them has Aff3 populated, we set #address-cells to 2.
|
||||
*/
|
||||
for (cpu = 0; cpu < smp_cpus; cpu++) {
|
||||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
|
||||
|
@ -407,8 +408,57 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
|||
ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
|
||||
}
|
||||
|
||||
if (!vmc->no_cpu_topology) {
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
||||
qemu_fdt_alloc_phandle(ms->fdt));
|
||||
}
|
||||
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
if (!vmc->no_cpu_topology) {
|
||||
/*
|
||||
* Add vCPU topology description through fdt node cpu-map.
|
||||
*
|
||||
* See Linux Documentation/devicetree/bindings/cpu/cpu-topology.txt
|
||||
* In a SMP system, the hierarchy of CPUs can be defined through
|
||||
* four entities that are used to describe the layout of CPUs in
|
||||
* the system: socket/cluster/core/thread.
|
||||
*
|
||||
* A socket node represents the boundary of system physical package
|
||||
* and its child nodes must be one or more cluster nodes. A system
|
||||
* can contain several layers of clustering within a single physical
|
||||
* package and cluster nodes can be contained in parent cluster nodes.
|
||||
*
|
||||
* Given that cluster is not yet supported in the vCPU topology,
|
||||
* we currently generate one cluster node within each socket node
|
||||
* by default.
|
||||
*/
|
||||
qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
|
||||
|
||||
for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
|
||||
char *cpu_path = g_strdup_printf("/cpus/cpu@%d", cpu);
|
||||
char *map_path;
|
||||
|
||||
if (ms->smp.threads > 1) {
|
||||
map_path = g_strdup_printf(
|
||||
"/cpus/cpu-map/socket%d/cluster0/core%d/thread%d",
|
||||
cpu / (ms->smp.cores * ms->smp.threads),
|
||||
(cpu / ms->smp.threads) % ms->smp.cores,
|
||||
cpu % ms->smp.threads);
|
||||
} else {
|
||||
map_path = g_strdup_printf(
|
||||
"/cpus/cpu-map/socket%d/cluster0/core%d",
|
||||
cpu / ms->smp.cores,
|
||||
cpu % ms->smp.cores);
|
||||
}
|
||||
qemu_fdt_add_path(ms->fdt, map_path);
|
||||
qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path);
|
||||
|
||||
g_free(map_path);
|
||||
g_free(cpu_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fdt_add_its_gic_node(VirtMachineState *vms)
|
||||
|
@ -2816,6 +2866,7 @@ static void virt_machine_6_1_options(MachineClass *mc)
|
|||
virt_machine_6_2_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
|
||||
mc->smp_props.prefer_sockets = true;
|
||||
vmc->no_cpu_topology = true;
|
||||
|
||||
/* qemu ITS was introduced with 6.2 */
|
||||
vmc->no_tcg_its = true;
|
||||
|
|
|
@ -326,7 +326,7 @@ static void *load_at(int fd, off_t offset, size_t size)
|
|||
#define SZ 64
|
||||
#include "hw/elf_ops.h"
|
||||
|
||||
const char *load_elf_strerror(int error)
|
||||
const char *load_elf_strerror(ssize_t error)
|
||||
{
|
||||
switch (error) {
|
||||
case 0:
|
||||
|
@ -402,12 +402,12 @@ fail:
|
|||
}
|
||||
|
||||
/* return < 0 if error, otherwise the number of bytes loaded in memory */
|
||||
int load_elf(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab)
|
||||
ssize_t load_elf(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab)
|
||||
{
|
||||
return load_elf_as(filename, elf_note_fn, translate_fn, translate_opaque,
|
||||
pentry, lowaddr, highaddr, pflags, big_endian,
|
||||
|
@ -415,12 +415,13 @@ int load_elf(const char *filename,
|
|||
}
|
||||
|
||||
/* return < 0 if error, otherwise the number of bytes loaded in memory */
|
||||
int load_elf_as(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab, AddressSpace *as)
|
||||
ssize_t load_elf_as(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab,
|
||||
AddressSpace *as)
|
||||
{
|
||||
return load_elf_ram(filename, elf_note_fn, translate_fn, translate_opaque,
|
||||
pentry, lowaddr, highaddr, pflags, big_endian,
|
||||
|
@ -428,13 +429,13 @@ int load_elf_as(const char *filename,
|
|||
}
|
||||
|
||||
/* return < 0 if error, otherwise the number of bytes loaded in memory */
|
||||
int load_elf_ram(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom)
|
||||
ssize_t load_elf_ram(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
|
||||
int big_endian, int elf_machine, int clear_lsb,
|
||||
int data_swab, AddressSpace *as, bool load_rom)
|
||||
{
|
||||
return load_elf_ram_sym(filename, elf_note_fn,
|
||||
translate_fn, translate_opaque,
|
||||
|
@ -444,16 +445,17 @@ int load_elf_ram(const char *filename,
|
|||
}
|
||||
|
||||
/* return < 0 if error, otherwise the number of bytes loaded in memory */
|
||||
int load_elf_ram_sym(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
|
||||
int big_endian, int elf_machine,
|
||||
int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom, symbol_fn_t sym_cb)
|
||||
ssize_t load_elf_ram_sym(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr,
|
||||
uint32_t *pflags, int big_endian, int elf_machine,
|
||||
int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom, symbol_fn_t sym_cb)
|
||||
{
|
||||
int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED;
|
||||
int fd, data_order, target_data_order, must_swab;
|
||||
ssize_t ret = ELF_LOAD_FAILED;
|
||||
uint8_t e_ident[EI_NIDENT];
|
||||
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
|
|
|
@ -489,6 +489,9 @@ void build_srat_memory(GArray *table_data, uint64_t base,
|
|||
void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
|
||||
|
|
|
@ -125,11 +125,13 @@ struct VirtMachineClass {
|
|||
bool claim_edge_triggered_timers;
|
||||
bool smbios_old_sys_ver;
|
||||
bool no_highmem_ecam;
|
||||
bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
|
||||
bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */
|
||||
bool kvm_no_adjvtime;
|
||||
bool no_kvm_steal_time;
|
||||
bool acpi_expose_flash;
|
||||
bool no_secure_gpio;
|
||||
/* Machines < 6.2 have no support for describing cpu topology to guest */
|
||||
bool no_cpu_topology;
|
||||
};
|
||||
|
||||
struct VirtMachineState {
|
||||
|
|
|
@ -312,25 +312,26 @@ static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr,
|
|||
return nhdr;
|
||||
}
|
||||
|
||||
static int glue(load_elf, SZ)(const char *name, int fd,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque,
|
||||
int must_swab, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr,
|
||||
uint32_t *pflags, int elf_machine,
|
||||
int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom,
|
||||
symbol_fn_t sym_cb)
|
||||
static ssize_t glue(load_elf, SZ)(const char *name, int fd,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque,
|
||||
int must_swab, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr,
|
||||
uint32_t *pflags, int elf_machine,
|
||||
int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom,
|
||||
symbol_fn_t sym_cb)
|
||||
{
|
||||
struct elfhdr ehdr;
|
||||
struct elf_phdr *phdr = NULL, *ph;
|
||||
int size, i, total_size;
|
||||
int size, i;
|
||||
ssize_t total_size;
|
||||
elf_word mem_size, file_size, data_offset;
|
||||
uint64_t addr, low = (uint64_t)-1, high = 0;
|
||||
GMappedFile *mapped_file = NULL;
|
||||
uint8_t *data = NULL;
|
||||
int ret = ELF_LOAD_FAILED;
|
||||
ssize_t ret = ELF_LOAD_FAILED;
|
||||
|
||||
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
|
||||
goto fail;
|
||||
|
@ -482,7 +483,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
|
|||
}
|
||||
}
|
||||
|
||||
if (mem_size > INT_MAX - total_size) {
|
||||
if (mem_size > SSIZE_MAX - total_size) {
|
||||
ret = ELF_LOAD_TOO_BIG;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ int load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz);
|
|||
#define ELF_LOAD_WRONG_ARCH -3
|
||||
#define ELF_LOAD_WRONG_ENDIAN -4
|
||||
#define ELF_LOAD_TOO_BIG -5
|
||||
const char *load_elf_strerror(int error);
|
||||
const char *load_elf_strerror(ssize_t error);
|
||||
|
||||
/** load_elf_ram_sym:
|
||||
* @filename: Path of ELF file
|
||||
|
@ -128,48 +128,48 @@ const char *load_elf_strerror(int error);
|
|||
typedef void (*symbol_fn_t)(const char *st_name, int st_info,
|
||||
uint64_t st_value, uint64_t st_size);
|
||||
|
||||
int load_elf_ram_sym(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
|
||||
int big_endian, int elf_machine,
|
||||
int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom, symbol_fn_t sym_cb);
|
||||
ssize_t load_elf_ram_sym(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr,
|
||||
uint32_t *pflags, int big_endian, int elf_machine,
|
||||
int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom, symbol_fn_t sym_cb);
|
||||
|
||||
/** load_elf_ram:
|
||||
* Same as load_elf_ram_sym(), but doesn't allow the caller to specify a
|
||||
* symbol callback function
|
||||
*/
|
||||
int load_elf_ram(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab,
|
||||
AddressSpace *as, bool load_rom);
|
||||
ssize_t load_elf_ram(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry,
|
||||
uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags,
|
||||
int big_endian, int elf_machine, int clear_lsb,
|
||||
int data_swab, AddressSpace *as, bool load_rom);
|
||||
|
||||
/** load_elf_as:
|
||||
* Same as load_elf_ram(), but always loads the elf as ROM
|
||||
*/
|
||||
int load_elf_as(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab,
|
||||
AddressSpace *as);
|
||||
ssize_t load_elf_as(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab,
|
||||
AddressSpace *as);
|
||||
|
||||
/** load_elf:
|
||||
* Same as load_elf_as(), but doesn't allow the caller to specify an
|
||||
* AddressSpace.
|
||||
*/
|
||||
int load_elf(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab);
|
||||
ssize_t load_elf(const char *filename,
|
||||
uint64_t (*elf_note_fn)(void *, void *, bool),
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, uint32_t *pflags, int big_endian,
|
||||
int elf_machine, int clear_lsb, int data_swab);
|
||||
|
||||
/** load_elf_hdr:
|
||||
* @filename: Path of ELF file
|
||||
|
|
|
@ -121,6 +121,7 @@ uint32_t qemu_fdt_get_phandle(void *fdt, const char *path);
|
|||
uint32_t qemu_fdt_alloc_phandle(void *fdt);
|
||||
int qemu_fdt_nop_node(void *fdt, const char *node_path);
|
||||
int qemu_fdt_add_subnode(void *fdt, const char *name);
|
||||
int qemu_fdt_add_path(void *fdt, const char *path);
|
||||
|
||||
#define qemu_fdt_setprop_cells(fdt, node_path, property, ...) \
|
||||
do { \
|
||||
|
|
|
@ -143,7 +143,8 @@ build-efi-roms: build-pxe-roms
|
|||
# efirom
|
||||
#
|
||||
edk2-basetools:
|
||||
cd edk2/BaseTools && git submodule update --init --force
|
||||
cd edk2/BaseTools && git submodule update --init --force \
|
||||
Source/C/BrotliCompress/brotli
|
||||
$(MAKE) -C edk2/BaseTools \
|
||||
PYTHON_COMMAND=$${EDK2_PYTHON_COMMAND:-python3} \
|
||||
EXTRA_OPTFLAGS='$(EDK2_BASETOOLS_OPTFLAGS)' \
|
||||
|
|
|
@ -51,7 +51,12 @@ all: $(foreach flashdev,$(flashdevs),../pc-bios/edk2-$(flashdev).fd.bz2) \
|
|||
# make-release/tarball scripts.
|
||||
submodules:
|
||||
if test -d edk2/.git; then \
|
||||
cd edk2 && git submodule update --init --force; \
|
||||
cd edk2 && git submodule update --init --force -- \
|
||||
ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 \
|
||||
BaseTools/Source/C/BrotliCompress/brotli \
|
||||
CryptoPkg/Library/OpensslLib/openssl \
|
||||
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli \
|
||||
; \
|
||||
fi
|
||||
|
||||
# See notes on the ".NOTPARALLEL" target and the "+" indicator in
|
||||
|
|
|
@ -27,7 +27,12 @@ git submodule update --init
|
|||
# don't necessarily have much control over how a submodule handles its
|
||||
# submodule dependencies, so we continue to handle these on a case-by-case
|
||||
# basis for now.
|
||||
(cd roms/edk2 && git submodule update --init)
|
||||
(cd roms/edk2 && \
|
||||
git submodule update --init -- \
|
||||
ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 \
|
||||
BaseTools/Source/C/BrotliCompress/brotli \
|
||||
CryptoPkg/Library/OpensslLib/openssl \
|
||||
MdeModulePkg/Library/BrotliCustomDecompressLib/brotli)
|
||||
popd
|
||||
tar --exclude=.git -cjf ${destination}.tar.bz2 ${destination}
|
||||
rm -rf ${destination}
|
||||
|
|
|
@ -540,8 +540,8 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
|
|||
|
||||
retval = fdt_add_subnode(fdt, parent, basename);
|
||||
if (retval < 0) {
|
||||
error_report("FDT: Failed to create subnode %s: %s", name,
|
||||
fdt_strerror(retval));
|
||||
error_report("%s: Failed to create subnode %s: %s",
|
||||
__func__, name, fdt_strerror(retval));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -549,6 +549,46 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* qemu_fdt_add_path: Like qemu_fdt_add_subnode(), but will add
|
||||
* all missing subnodes from the given path.
|
||||
*/
|
||||
int qemu_fdt_add_path(void *fdt, const char *path)
|
||||
{
|
||||
const char *name;
|
||||
const char *p = path;
|
||||
int namelen, retval;
|
||||
int parent = 0;
|
||||
|
||||
if (path[0] != '/') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (p) {
|
||||
name = p + 1;
|
||||
p = strchr(name, '/');
|
||||
namelen = p != NULL ? p - name : strlen(name);
|
||||
|
||||
retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen);
|
||||
if (retval < 0 && retval != -FDT_ERR_NOTFOUND) {
|
||||
error_report("%s: Unexpected error in finding subnode %.*s: %s",
|
||||
__func__, namelen, name, fdt_strerror(retval));
|
||||
exit(1);
|
||||
} else if (retval == -FDT_ERR_NOTFOUND) {
|
||||
retval = fdt_add_subnode_namelen(fdt, parent, name, namelen);
|
||||
if (retval < 0) {
|
||||
error_report("%s: Failed to create subnode %.*s: %s",
|
||||
__func__, namelen, name, fdt_strerror(retval));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
parent = retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void qemu_fdt_dumpdtb(void *fdt, int size)
|
||||
{
|
||||
const char *dumpdtb = current_machine->dumpdtb;
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue