{"id":2198217,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2198217/?format=json","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/1.0/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260219144901.3317747-2-ruslichenko.r@gmail.com>","date":"2026-02-19T14:48:48","name":"[v2,20/33] hw/arm: add generic ARM machine initialized by FDT","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"aaa95a71b7699455b8f42e95320ad67aae00eb07","submitter":{"id":92275,"url":"http://patchwork.ozlabs.org/api/1.0/people/92275/?format=json","name":"Ruslan Ruslichenko","email":"ruslichenko.r@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/20260219144901.3317747-2-ruslichenko.r@gmail.com/mbox/","series":[{"id":492690,"url":"http://patchwork.ozlabs.org/api/1.0/series/492690/?format=json","date":"2026-02-19T14:33:04","name":"hw/arm: Introduce generic FDT-driven machine","version":2,"mbox":"http://patchwork.ozlabs.org/series/492690/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2198217/checks/","tags":{},"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=kKY2nR8Y;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fGxCg3BSGz1xpl\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 20 Feb 2026 01:51:27 +1100 (AEDT)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vt5MH-0003zd-8n; Thu, 19 Feb 2026 09:50:25 -0500","from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <ruslichenko.r@gmail.com>)\n id 1vt5Lp-0003k3-LV\n for qemu-devel@nongnu.org; Thu, 19 Feb 2026 09:50:06 -0500","from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <ruslichenko.r@gmail.com>)\n id 1vt5Lc-00082t-Go\n for qemu-devel@nongnu.org; Thu, 19 Feb 2026 09:49:53 -0500","by mail-wr1-x42a.google.com with SMTP id\n ffacd0b85a97d-4362d4050c1so1024335f8f.2\n for <qemu-devel@nongnu.org>; Thu, 19 Feb 2026 06:49:42 -0800 (PST)","from thinkpad-t470s.. (93-143-129-182.adsl.net.t-com.hr.\n [93.143.129.182]) by smtp.googlemail.com with ESMTPSA id\n ffacd0b85a97d-43796ac8d82sm50163087f8f.31.2026.02.19.06.49.39\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 19 Feb 2026 06:49:40 -0800 (PST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20230601; t=1771512581; x=1772117381; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=6UYWT62sEHBxv5crU/HblRe1sAfAFjgx1BptkDY9LkA=;\n b=kKY2nR8Y4mK8gMzjWDzMU9lw3EYjBIMjS1wqtdzTtwYqYMfnYJGW1CitJUI5rv+o0o\n mRVn9SqbCulUD9y1F/boYfwPJP7fmFRXRUXguPKA3XRxkQQTzB0YaBBUc6HblGzqwvzU\n y5/5JOWd7fHtlVsW7JqySNpeAOGE7/rMR6CwgCUtm8jJX4O3jj2UwXOb+yELpwIjOSv6\n fM0MMXPVHWvJf+DSGsEX6FN5SsQYQvGrqb86S7eRVC5z9JmQnQC3+ZyFBBY621F6bPh6\n 8Txu/5hIR4vR9+TxDR5bjRZqaebBS+NVsFTBjIbxdTPjFV/pcACsnHxniuHFdJGuqXKd\n 6mZA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1771512581; x=1772117381;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=6UYWT62sEHBxv5crU/HblRe1sAfAFjgx1BptkDY9LkA=;\n b=mFn3jY2E1Uk7yo/0nbb4R2MiudVmHNeTC+rMZrbwNv6Lk3nfGiBhPL8FXECtO6Jce3\n vuks/fhK+ApTm0aautBM7rFCkmgrwPQxlg3RIYSF1sAHzFdB9EkLatRRr27+KUKmeKEa\n J5MMaWF6511o6NaT0GL66aQWeeLz0zi2f02OWObt9iOwjTyZbnLQz5C06qZfNJlYeRQZ\n gFzP+EHqGXdNxisMZvjyH+Q//OUgT7nwiiuHpDU24pKxqRAgmb6HQFAzWx41P8HjHspz\n DMdSti2G6vf89s8zP2C4hT5UcGNs8S7BEG3NGlgaGxchBu5X3S8QvfSEOi97TNNQ3/yB\n S9iw==","X-Gm-Message-State":"AOJu0Yw3aCwGI8ZNX9woSAdI9CpGqxae2XE8wAEixg0M5qZs5lmAzolH\n qZz93/gV9FO44N2jowdgdF6rnWBm6lNVm82fL9NKP8LApoi/TjweDFuq5mthfnxQ","X-Gm-Gg":"AZuq6aLFbPDrWEZfbpOUf3vwhj0bsRMsfWlmbcg+AhGAvca3yjmdxGwcLvrpys5DI9n\n kSoYOAeO96t50RU6cqhbg3CZLDA4/IVRlLtGiCeRqWU0kFuAnmGgRCPoiibMlamjEd5lrW6WG8X\n Xh4CzFmwpAkPvML/cbC4vFqFRzD5hMUZuwUPs7GPvPHQe4ZKdBQr8lgCoZmAB36lnF5PM4BGM5j\n wwRsqo5ucOXnUsbVdVbA1U8ozP0g3iWqXLTiVrH0exy9Ywe/wZeSFX1k5UT3WBn6Udxzs6oQAMk\n H7HxV1g7touTbHbUa97iSE3gIxir5lg+cn3Iccgq65JFT9LH2YGFrihpWobbZiwpRG71Jt3CzIp\n nh77HoabZRUoSdUGEiIihm7op7F6KV7lfcQDp1HdFs46mCYuPssU2e2awRu1x9/LD6/vhH3t/Fr\n an74HCTYMgtwhdcCw7vCcaFWFfGvvHw+8HylZMK7nbGg/Cwr2egtox+YHuEqz8nm6yypbYdSPES\n ahw0kA=","X-Received":"by 2002:a05:6000:402b:b0:437:95d4:fcb3 with SMTP id\n ffacd0b85a97d-43797913ce2mr37609847f8f.36.1771512581176;\n Thu, 19 Feb 2026 06:49:41 -0800 (PST)","From":"Ruslan Ruslichenko <ruslichenko.r@gmail.com>","To":"qemu-devel@nongnu.org","Cc":"qemu-arm@nongnu.org, alex.bennee@linaro.org, peter.maydell@linaro.org,\n artem_mygaiev@epam.com, volodymyr_babchuk@epam.com,\n takahiro.nakata.wr@renesas.com,\n \"Edgar E . Iglesias\" <edgar.iglesias@gmail.com>,\n Ruslan_Ruslichenko@epam.com, balaton@eik.bme.hu","Subject":"[PATCH v2 20/33] hw/arm: add generic ARM machine initialized by FDT","Date":"Thu, 19 Feb 2026 15:48:48 +0100","Message-ID":"<20260219144901.3317747-2-ruslichenko.r@gmail.com>","X-Mailer":"git-send-email 2.43.0","In-Reply-To":"<20260219144901.3317747-1-ruslichenko.r@gmail.com>","References":"<20260219143332.3316679-1-ruslichenko.r@gmail.com>\n <20260219144901.3317747-1-ruslichenko.r@gmail.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Received-SPF":"pass client-ip=2a00:1450:4864:20::42a;\n envelope-from=ruslichenko.r@gmail.com; helo=mail-wr1-x42a.google.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,\n RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"qemu development <qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>\n\nThis patch introduces new ARM machine model, which is\nfully instantiated from a Device Tree description.\n\nThis model uses fdt_generic framework to dynamically\nconstruct system topology based on provided DTB, instead\nof standard machines which rely on hardcoded models in\nC files.\n\nThis allows to contruct machines with custom memory maps,\ndevice structures without the need to modify and re-build\nQEMU sources each time.\n\nSigned-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>\n---\n hw/arm/arm_generic_fdt.c | 180 +++++++++++++++++++++++++++++++++++++++\n hw/arm/meson.build       |   2 +\n 2 files changed, 182 insertions(+)\n create mode 100644 hw/arm/arm_generic_fdt.c","diff":"diff --git a/hw/arm/arm_generic_fdt.c b/hw/arm/arm_generic_fdt.c\nnew file mode 100644\nindex 0000000000..49206269aa\n--- /dev/null\n+++ b/hw/arm/arm_generic_fdt.c\n@@ -0,0 +1,180 @@\n+// SPDX-License-Identifier: GPL-2.0-or-later\n+/*\n+ * Copyright (c) 2012 Xilinx. Inc\n+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@xilinx.com)\n+ *\n+ * This program is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU General Public License\n+ * as published by the Free Software Foundation; either version\n+ * 2 of the License, or (at your option) any later version.\n+ *\n+ * You should have received a copy of the GNU General Public License along\n+ * with this program; if not, see <http://www.gnu.org/licenses/>.\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"cpu.h\"\n+#include \"hw/core/boards.h\"\n+#include \"hw/core/loader.h\"\n+#include \"hw/core/hw-error.h\"\n+#include \"qapi/error.h\"\n+#include \"hw/block/flash.h\"\n+#include \"qemu/error-report.h\"\n+#include \"qemu/log.h\"\n+#include \"qemu/config-file.h\"\n+#include \"qemu/option.h\"\n+#include \"system/system.h\"\n+#include \"system/qtest.h\"\n+#include \"hw/arm/boot.h\"\n+#include \"hw/arm/machines-qom.h\"\n+\n+#include <libfdt.h>\n+#include \"hw/core/fdt_generic_util.h\"\n+\n+#define GENERAL_MACHINE_NAME \"arm-generic-fdt\"\n+\n+#define QTEST_RUNNING (qtest_enabled() && qtest_driver())\n+\n+#define SMP_BOOT_ADDR 0xfffffff0\n+/* Meaningless, but keeps arm boot happy */\n+#define SMP_BOOTREG_ADDR 0xfffffffc\n+\n+static struct arm_boot_info arm_generic_fdt_binfo = {};\n+\n+typedef struct {\n+    ram_addr_t ram_kernel_base;\n+    ram_addr_t ram_kernel_size;\n+} memory_info;\n+\n+typedef struct {\n+    int fdt_size;\n+    char *dtb;\n+} FdtBlob;\n+\n+FdtBlob sw_fdt;\n+\n+static memory_info init_memory(void *fdt, ram_addr_t ram_size)\n+{\n+    FDTMachineInfo *fdti;\n+    MemoryRegion *mem_area;\n+    memory_info kernel_info;\n+    Error *errp = NULL;\n+    char **node_path;\n+\n+    /* Find a memory node or add new one if needed */\n+    node_path = qemu_fdt_node_unit_path(fdt, \"memory\", &errp);\n+    if (errp) {\n+        error_report_err(errp);\n+        exit(1);\n+    }\n+    if (!g_str_has_prefix(node_path[0], \"/memory\")) {\n+        error_report(\"Failed to find /memory node\");\n+        exit(1);\n+    }\n+\n+    /* Instantiate peripherals from the FDT.  */\n+    fdti = fdt_generic_create_machine(fdt, NULL);\n+\n+    mem_area = MEMORY_REGION(object_resolve_path(node_path[0], NULL));\n+\n+    kernel_info.ram_kernel_base = object_property_get_int(OBJECT(mem_area),\n+                                                            \"addr\", NULL);\n+\n+    kernel_info.ram_kernel_size = object_property_get_int(OBJECT(mem_area),\n+                                                          \"size\", NULL);\n+\n+    if (kernel_info.ram_kernel_size == -1) {\n+        kernel_info.ram_kernel_size = ram_size;\n+    }\n+\n+    fdt_init_destroy_fdti(fdti);\n+    g_strfreev(node_path);\n+\n+    return kernel_info;\n+}\n+\n+static void *get_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)\n+{\n+    *fdt_size = sw_fdt.fdt_size;\n+    return sw_fdt.dtb;\n+}\n+\n+static void arm_generic_fdt_init(MachineState *machine)\n+{\n+    void *fdt = NULL;\n+    int fdt_size;\n+    const char *hw_dtb_arg, *dtb_arg;\n+    memory_info kernel_info;\n+\n+    dtb_arg = machine->dtb;\n+    hw_dtb_arg = machine->hw_dtb;\n+    if (!dtb_arg && !hw_dtb_arg) {\n+        if (!QTEST_RUNNING) {\n+            /*\n+             * Just return without error if running qtest, as we never have a\n+             * device tree\n+             */\n+            hw_error(\"DTB must be specified for %s machine model\\n\",\n+                     MACHINE_GET_CLASS(machine)->name);\n+        }\n+        return;\n+    }\n+\n+    /* Software dtb is always the -dtb arg */\n+    if (dtb_arg) {\n+        sw_fdt.dtb = load_device_tree(dtb_arg, &sw_fdt.fdt_size);\n+        if (!sw_fdt.dtb) {\n+            error_report(\"Error: Unable to load Device Tree %s\", dtb_arg);\n+            exit(1);\n+        }\n+    }\n+\n+    /* If the user provided a -hw-dtb, use it as the hw description.  */\n+    if (hw_dtb_arg) {\n+        fdt = load_device_tree(hw_dtb_arg, &fdt_size);\n+        if (!fdt) {\n+            error_report(\"Error: Unable to load Device Tree %s\", hw_dtb_arg);\n+            exit(1);\n+        }\n+    } else if (sw_fdt.dtb) {\n+        fdt = sw_fdt.dtb;\n+        fdt_size = sw_fdt.fdt_size;\n+    }\n+\n+    kernel_info = init_memory(fdt, machine->ram_size);\n+\n+    arm_generic_fdt_binfo.get_dtb = get_ref_dtb;\n+    arm_generic_fdt_binfo.ram_size = kernel_info.ram_kernel_size;\n+    arm_generic_fdt_binfo.kernel_filename = machine->kernel_filename;\n+    arm_generic_fdt_binfo.kernel_cmdline = machine->kernel_cmdline;\n+    arm_generic_fdt_binfo.initrd_filename = machine->initrd_filename;\n+    arm_generic_fdt_binfo.smp_loader_start = SMP_BOOT_ADDR;\n+    arm_generic_fdt_binfo.smp_bootreg_addr = SMP_BOOTREG_ADDR;\n+    arm_generic_fdt_binfo.board_id = 0xd32;\n+    arm_generic_fdt_binfo.loader_start = kernel_info.ram_kernel_base;\n+    arm_generic_fdt_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;\n+\n+    if (!machine->kernel_filename) {\n+        arm_generic_fdt_binfo.firmware_loaded = true;\n+        arm_generic_fdt_binfo.psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;\n+    }\n+\n+    arm_load_kernel(ARM_CPU(first_cpu), machine, &arm_generic_fdt_binfo);\n+\n+    return;\n+}\n+\n+static void arm_generic_fdt_machine_init(MachineClass *mc)\n+{\n+    mc->desc = \"ARM device tree driven machine model\";\n+    mc->init = arm_generic_fdt_init;\n+    mc->max_cpus = 64;\n+    mc->default_cpus = 4;\n+\n+    mc->pci_allow_0_address = true;\n+    mc->minimum_page_bits = 12;\n+    mc->smp_props.clusters_supported = true;\n+\n+}\n+\n+DEFINE_MACHINE_ARM(\"arm-generic-fdt\", arm_generic_fdt_machine_init)\ndiff --git a/hw/arm/meson.build b/hw/arm/meson.build\nindex 47cdc51d13..1ef0b8c2c1 100644\n--- a/hw/arm/meson.build\n+++ b/hw/arm/meson.build\n@@ -1,4 +1,6 @@\n arm_ss = ss.source_set()\n+arm_ss.add(files('arm_generic_fdt.c'))\n+\n arm_common_ss = ss.source_set()\n arm_common_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c'))\n arm_common_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))\n","prefixes":["v2","20/33"]}