All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Cain <brian.cain@oss.qualcomm.com>
To: qemu-devel@nongnu.org
Cc: "Laurent Vivier" <lvivier@redhat.com>,
	"Helge Deller" <deller@gmx.de>,
	"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
	"Fabiano Rosas" <farosas@suse.de>,
	"Anton Johansson" <anjo@rev.ng>,
	"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
	"Alessandro Di Federico" <ale@rev.ng>,
	"Brian Cain" <brian.cain@oss.qualcomm.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Laurent Vivier" <laurent@vivier.eu>
Subject: [PATCH 03/14] hw/hexagon: introduce hex-board abstraction
Date: Sun, 18 Oct 2026 22:52:34 -0700	[thread overview]
Message-ID: <20261019055245.1457795-4-brian.cain@oss.qualcomm.com> (raw)
In-Reply-To: <20261019055245.1457795-1-brian.cain@oss.qualcomm.com>

Move what virt.c does to build a board out of it into helpers in a new
hex-board.c, so that other Hexagon machines that describe themselves
with a generated device tree can reuse it.

This will be used by future commits.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 MAINTAINERS                    |   2 +
 include/hw/hexagon/hex-board.h |  65 ++++++++
 hw/hexagon/hex-board.c         | 265 +++++++++++++++++++++++++++++++++
 hw/hexagon/Kconfig             |   9 +-
 hw/hexagon/meson.build         |   1 +
 5 files changed, 340 insertions(+), 2 deletions(-)
 create mode 100644 include/hw/hexagon/hex-board.h
 create mode 100644 hw/hexagon/hex-board.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 22caaee9671..4c9eb1892c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -256,6 +256,8 @@ F: tests/qtest/l2vic-test.c
 F: hw/timer/qct-qtimer.c
 F: include/hw/timer/qct-qtimer.h
 F: tests/qtest/qct-qtimer-test.c
+F: hw/hexagon/hex-board.c
+F: include/hw/hexagon/hex-board.h
 X: target/hexagon/idef-parser/
 X: target/hexagon/gen_idef_parser_funcs.py
 F: linux-user/hexagon/
diff --git a/include/hw/hexagon/hex-board.h b/include/hw/hexagon/hex-board.h
new file mode 100644
index 00000000000..93a31cb2ecc
--- /dev/null
+++ b/include/hw/hexagon/hex-board.h
@@ -0,0 +1,65 @@
+/*
+ * Board-construction helpers shared by the Hexagon machines.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_HEXAGON_HEX_BOARD_H
+#define HW_HEXAGON_HEX_BOARD_H
+
+#include "hw/hexagon/hexagon.h"
+
+/* The L2VIC interrupt specifiers of the 32 per-cpu lines precede its lines. */
+#define HEX_BOARD_L2VIC_SPI_BASE 32
+
+/*
+ * Create the device tree with its root, /soc and /chosen (including an
+ * rng-seed) nodes.  Returns its size in @fdt_size.
+ */
+void hex_board_create_fdt(MachineState *ms, const char *model,
+                          const char *compatible, int *fdt_size);
+
+/* Add the L2VIC node and make it the interrupt parent of /soc. */
+int32_t hex_board_fdt_add_l2vic(MachineState *ms,
+                                const struct hexagon_machine_config *cfg);
+
+/* Add the /soc/vtcm and /soc/hvx nodes, for what the config provides. */
+void hex_board_fdt_add_hvx(MachineState *ms,
+                           const struct hexagon_machine_config *cfg);
+
+/* Add one /cpus/cpu@N node per CPU of the machine. */
+void hex_board_fdt_add_cpus(MachineState *ms);
+
+/* Create the L2 TCM RAM, if the config has any. */
+void hex_board_create_tcm(const struct hexagon_machine_config *cfg,
+                          MemoryRegion *tcm);
+
+/* Create the PL011 console and its fixed clock, and describe them. */
+void hex_board_create_uart(MachineState *ms, hwaddr base, hwaddr size,
+                           int irq, int32_t l2vic_phandle);
+
+/* Create @count virtio-mmio transports on consecutive lines and slots. */
+void hex_board_create_virtio(MachineState *ms, hwaddr base, hwaddr size,
+                             int irq_base, int count,
+                             int32_t l2vic_phandle);
+
+/*
+ * Load an ELF for the guest and return its entry point.  If @translate is
+ * given it maps the ELF's addresses.  The highest address used is returned
+ * in @high, if non-NULL.  Exits on failure.
+ */
+uint64_t hex_board_load_elf(const char *filename,
+                            uint64_t (*translate)(void *opaque, uint64_t addr),
+                            void *opaque, uint64_t *high);
+
+/* Copy the device tree to @addr and refresh its rng-seed on reset. */
+void hex_board_load_fdt(MachineState *ms, int fdt_size, hwaddr addr);
+
+/*
+ * Create the machine's CPUs, with CPU 0 starting at @start if @have_start,
+ * and realize the cluster.
+ */
+void hex_board_create_cpus(MachineState *ms, bool have_start, uint64_t start);
+
+#endif /* HW_HEXAGON_HEX_BOARD_H */
diff --git a/hw/hexagon/hex-board.c b/hw/hexagon/hex-board.c
new file mode 100644
index 00000000000..3bf09e4e7c7
--- /dev/null
+++ b/hw/hexagon/hex-board.c
@@ -0,0 +1,265 @@
+/*
+ * Board-construction helpers shared by the Hexagon machines that describe
+ * themselves to the guest with a generated device tree.
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "elf.h"
+#include "hw/char/pl011.h"
+#include "hw/core/boards.h"
+#include "hw/core/clock.h"
+#include "hw/core/loader.h"
+#include "hw/core/qdev-clock.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/sysbus.h"
+#include "hw/hexagon/hex-board.h"
+#include "hw/hexagon/hex-subsys.h"
+#include "qemu/error-report.h"
+#include "qemu/guest-random.h"
+#include "system/address-spaces.h"
+#include "system/device_tree.h"
+#include "system/reset.h"
+#include "system/system.h"
+#include "target/hexagon/cpu.h"
+
+#define APB_CLK_HZ 24000000
+
+void hex_board_create_fdt(MachineState *ms, const char *model,
+                          const char *compatible, int *fdt_size)
+{
+    void *fdt = create_device_tree(fdt_size);
+    uint8_t rng_seed[32];
+
+    if (!fdt) {
+        error_report("create_device_tree() failed");
+        exit(1);
+    }
+
+    ms->fdt = fdt;
+
+    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x1);
+    qemu_fdt_setprop_string(fdt, "/", "model", model);
+    qemu_fdt_setprop_string(fdt, "/", "compatible", compatible);
+
+    qemu_fdt_add_subnode(fdt, "/soc");
+    qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
+    qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x1);
+    qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
+
+    qemu_fdt_add_subnode(fdt, "/chosen");
+    qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
+    qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
+}
+
+static void fdt_set_irq(MachineState *ms, const char *nodename, int irq)
+{
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
+                           HEX_BOARD_L2VIC_SPI_BASE + irq, 0);
+}
+
+int32_t hex_board_fdt_add_l2vic(MachineState *ms,
+                                const struct hexagon_machine_config *cfg)
+{
+    int32_t l2vic_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+    g_autofree char *nodename = g_strdup_printf("/soc/interrupt-controller@%x",
+                                                cfg->l2vic_base);
+    static const char compat[] = "qcom,h2-pic\0hvm-pic";
+
+    qemu_fdt_setprop_cell(ms->fdt, "/soc", "interrupt-parent", l2vic_phandle);
+
+    qemu_fdt_add_subnode(ms->fdt, nodename);
+    qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x0);
+    qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 2);
+    qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat));
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, cfg->l2vic_base,
+                           cfg->l2vic_size);
+    qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
+    qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", l2vic_phandle);
+
+    return l2vic_phandle;
+}
+
+void hex_board_fdt_add_hvx(MachineState *ms,
+                           const struct hexagon_machine_config *cfg)
+{
+    const union hexagon_config_table *t = &cfg->cfgtable;
+
+    if (t->vtcm_size_kb > 0) {
+        qemu_fdt_add_subnode(ms->fdt, "/soc/vtcm");
+        qemu_fdt_setprop_string(ms->fdt, "/soc/vtcm", "compatible",
+                                "qcom,hexagon_vtcm");
+        qemu_fdt_setprop_cells(ms->fdt, "/soc/vtcm", "reg", 0,
+                               t->vtcm_base << 16, t->vtcm_size_kb * 1024);
+    }
+
+    if (t->ext_contexts > 0) {
+        qemu_fdt_add_subnode(ms->fdt, "/soc/hvx");
+        qemu_fdt_setprop_string(ms->fdt, "/soc/hvx", "compatible",
+                                "qcom,hexagon-hvx");
+        qemu_fdt_setprop_cells(ms->fdt, "/soc/hvx", "qcom,hvx-max-ctxts",
+                               t->ext_contexts);
+        qemu_fdt_setprop_cells(ms->fdt, "/soc/hvx", "qcom,hvx-vlength",
+                               t->hvx_vec_log_length);
+    }
+}
+
+void hex_board_fdt_add_cpus(MachineState *ms)
+{
+    qemu_fdt_add_subnode(ms->fdt, "/cpus");
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
+    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
+
+    for (int num = ms->smp.cpus - 1; num >= 0; num--) {
+        g_autofree char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
+
+        qemu_fdt_add_subnode(ms->fdt, nodename);
+        qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
+                              qemu_fdt_alloc_phandle(ms->fdt));
+    }
+}
+
+void hex_board_create_tcm(const struct hexagon_machine_config *cfg,
+                          MemoryRegion *tcm)
+{
+    if (cfg->l2tcm_size) {
+        memory_region_init_ram(tcm, NULL, "tcm.ram", cfg->l2tcm_size,
+                               &error_fatal);
+        memory_region_add_subregion(get_system_memory(),
+                                    (hwaddr)cfg->cfgtable.l2tcm_base << 16,
+                                    tcm);
+    }
+}
+
+void hex_board_create_uart(MachineState *ms, hwaddr base, hwaddr size,
+                           int irq, int32_t l2vic_phandle)
+{
+    static const char compat[] = "arm,pl011\0arm,primecell";
+    static const char clocknames[] = "uartclk\0apb_pclk";
+    HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(ms);
+    int32_t clk_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+    g_autofree char *nodename = g_strdup_printf("/pl011@%" PRIx64, base);
+    Clock *apb_clk = clock_new(OBJECT(ms), "apb-pclk");
+    DeviceState *dev = qdev_new(TYPE_PL011);
+    SysBusDevice *s = SYS_BUS_DEVICE(dev);
+
+    clock_set_hz(apb_clk, APB_CLK_HZ);
+
+    qdev_prop_set_chr(dev, "chardev", serial_hd(0));
+    qdev_connect_clock_in(dev, "clk", apb_clk);
+    sysbus_realize_and_unref(s, &error_fatal);
+    sysbus_mmio_map(s, 0, base);
+    sysbus_connect_irq(s, 0, qdev_get_gpio_in(hms->l2vic, irq));
+
+    qemu_fdt_add_subnode(ms->fdt, "/apb-pclk");
+    qemu_fdt_setprop_string(ms->fdt, "/apb-pclk", "compatible", "fixed-clock");
+    qemu_fdt_setprop_cell(ms->fdt, "/apb-pclk", "#clock-cells", 0x0);
+    qemu_fdt_setprop_cell(ms->fdt, "/apb-pclk", "clock-frequency", APB_CLK_HZ);
+    qemu_fdt_setprop_string(ms->fdt, "/apb-pclk", "clock-output-names",
+                            "clk24mhz");
+    qemu_fdt_setprop_cell(ms->fdt, "/apb-pclk", "phandle", clk_phandle);
+
+    qemu_fdt_add_subnode(ms->fdt, nodename);
+    /* Can't use setprop_string because of the embedded NUL */
+    qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat));
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, base, size);
+    fdt_set_irq(ms, nodename, irq);
+    qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+                          l2vic_phandle);
+    qemu_fdt_setprop_cells(ms->fdt, nodename, "clocks", clk_phandle,
+                           clk_phandle);
+    qemu_fdt_setprop(ms->fdt, nodename, "clock-names", clocknames,
+                     sizeof(clocknames));
+
+    qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
+    qemu_fdt_add_subnode(ms->fdt, "/aliases");
+    qemu_fdt_setprop_string(ms->fdt, "/aliases", "serial0", nodename);
+}
+
+void hex_board_create_virtio(MachineState *ms, hwaddr base, hwaddr size,
+                             int irq_base, int count,
+                             int32_t l2vic_phandle)
+{
+    HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(ms);
+
+    for (int i = 0; i < count; i++) {
+        int irq = irq_base + i;
+        hwaddr slot = base + i * size;
+        g_autofree char *nodename = g_strdup_printf("/soc/virtio_mmio@%" PRIx64,
+                                                    slot);
+        DeviceState *dev = qdev_new("virtio-mmio");
+        SysBusDevice *s = SYS_BUS_DEVICE(dev);
+
+        object_property_add_child(OBJECT(ms), "virtio-mmio[*]", OBJECT(dev));
+        sysbus_realize_and_unref(s, &error_fatal);
+        sysbus_mmio_map(s, 0, slot);
+        sysbus_connect_irq(s, 0, qdev_get_gpio_in(hms->l2vic, irq));
+
+        qemu_fdt_add_subnode(ms->fdt, nodename);
+        qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+                                "virtio,mmio");
+        qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, slot, size);
+        fdt_set_irq(ms, nodename, irq);
+        qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+                              l2vic_phandle);
+    }
+}
+
+uint64_t hex_board_load_elf(const char *filename,
+                            uint64_t (*translate)(void *opaque, uint64_t addr),
+                            void *opaque, uint64_t *high)
+{
+    uint64_t entry = 0;
+
+    if (load_elf_ram_sym(filename, NULL, translate, opaque, &entry, NULL,
+                         high, NULL, 0, EM_HEXAGON, 0, 0,
+                         &address_space_memory, false, NULL) <= 0) {
+        error_report("error loading '%s'", filename);
+        exit(1);
+    }
+    return entry;
+}
+
+void hex_board_load_fdt(MachineState *ms, int fdt_size, hwaddr addr)
+{
+    rom_add_blob_fixed_as("fdt", ms->fdt, fdt_size, addr,
+                          &address_space_memory);
+    qemu_register_reset_nosnapshotload(
+        qemu_fdt_randomize_seeds,
+        rom_ptr_for_as(&address_space_memory, addr, fdt_size));
+}
+
+static void hex_board_cpu_reset(void *opaque)
+{
+    cpu_reset(CPU(opaque));
+}
+
+void hex_board_create_cpus(MachineState *ms, bool have_start, uint64_t start)
+{
+    HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(ms);
+    g_autofree HexagonCPU **cpus = g_new(HexagonCPU *, ms->smp.cpus);
+
+    for (int i = 0; i < ms->smp.cpus; i++) {
+        HexagonCPU *cpu = HEXAGON_CPU(object_new(ms->cpu_type));
+
+        qemu_register_reset(hex_board_cpu_reset, cpu);
+        if (i == 0 && have_start) {
+            qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", start);
+        }
+        qdev_prop_set_uint32(DEVICE(cpu), "htid", i);
+        qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", i != 0);
+        hex_subsys_add_cpu(hms, DEVICE(cpu));
+        cpus[i] = cpu;
+    }
+
+    hex_subsys_realize_cluster(hms);
+    for (int i = 0; i < ms->smp.cpus; i++) {
+        hex_subsys_realize_cpu(hms, DEVICE(cpus[i]), i == 0);
+    }
+}
diff --git a/hw/hexagon/Kconfig b/hw/hexagon/Kconfig
index bb8a254fd26..63ee8836aca 100644
--- a/hw/hexagon/Kconfig
+++ b/hw/hexagon/Kconfig
@@ -7,12 +7,17 @@ config HEX_DSP
     select HEX_QTIMER
     select ARM_COMPATIBLE_SEMIHOSTING
 
-config HEX_VIRT
+config HEX_BOARD
     bool
-    default y
     depends on HEX_DSP && FDT
     select DEVICE_TREE
     select VIRTIO_MMIO
     select PL011
+
+config HEX_VIRT
+    bool
+    default y
+    depends on HEX_DSP && FDT
+    select HEX_BOARD
     select VIRTIO_BLK
     select VIRTIO_SCSI
diff --git a/hw/hexagon/meson.build b/hw/hexagon/meson.build
index c4b257dfa28..57bff31ad00 100644
--- a/hw/hexagon/meson.build
+++ b/hw/hexagon/meson.build
@@ -4,6 +4,7 @@ hexagon_ss.add(files('hexagon_globalreg.c'))
 hexagon_ss.add(files('hexagon_hvx_context.c'))
 hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hex-subsys.c'))
 hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hexagon_dsp.c'))
+hexagon_ss.add(when: 'CONFIG_HEX_BOARD', if_true: files('hex-board.c'))
 hexagon_ss.add(when: 'CONFIG_HEX_VIRT', if_true: files('virt.c'))
 
 hw_arch += {'hexagon': hexagon_ss}
-- 
2.34.1


  parent reply	other threads:[~2026-10-19  5:55 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19  5:52 [PATCH 00/14] Hexagon: Add real SoC-style machines Brian Cain
2026-10-19  5:52 ` [PATCH 01/14] Hexagon: add v85 CPU model Brian Cain
2026-10-19 22:32   ` Anton Johansson via qemu development
2026-10-19 23:58     ` Brian Cain
2026-10-19  5:52 ` [PATCH 02/14] hw/hexagon: let a machine place its DDR Brian Cain
2026-10-19 21:40   ` Pierrick Bouvier
2026-10-19  5:52 ` Brian Cain [this message]
2026-10-19 21:42   ` [PATCH 03/14] hw/hexagon: introduce hex-board abstraction Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 04/14] hw/hexagon: convert virt board to hex-board Brian Cain
2026-10-19 21:40   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 05/14] hw/misc: add the QDSP6SS PLL, RCG Brian Cain
2026-10-19 21:51   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 06/14] hw/hexagon: add the QCS6490 CDSP machine Brian Cain
2026-10-19 22:15   ` Pierrick Bouvier
2026-10-20 11:28   ` Anton Johansson via qemu development
2026-10-19  5:52 ` [PATCH 07/14] hw/hexagon: add the SA8775P " Brian Cain
2026-10-19 22:15   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 08/14] hw/hexagon: add the SC8480XP NSP0 machine Brian Cain
2026-10-19 22:15   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 09/14] hw/hexagon: add the SA8797P " Brian Cain
2026-10-19 22:15   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 10/14] hw/hexagon: add the SM8975 NSP machine Brian Cain
2026-10-19 22:15   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 11/14] hw/hexagon: add v79NA1 machine Brian Cain
2026-10-19 22:16   ` Pierrick Bouvier
2026-10-19  5:52 ` [PATCH 12/14] hw/hexagon: add subsystem-base property Brian Cain
2026-10-19 22:16   ` Pierrick Bouvier
2026-10-20 14:53   ` Anton Johansson via qemu development
2026-10-19  5:52 ` [PATCH 13/14] target/hexagon: fix the allocframe framekey Brian Cain
2026-10-19  5:52 ` [PATCH 14/14] tests/functional/hexagon: boot DSP firmware Brian Cain
2026-10-19 13:47   ` Philippe Mathieu-Daudé
2026-10-19 13:51     ` Brian Cain
2026-10-19 15:22       ` Brian Cain
2026-10-27  4:29         ` Philippe Mathieu-Daudé
2026-10-19 21:50     ` Pierrick Bouvier
2026-10-19 22:03       ` Brian Cain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261019055245.1457795-4-brian.cain@oss.qualcomm.com \
    --to=brian.cain@oss.qualcomm.com \
    --cc=ale@rev.ng \
    --cc=anjo@rev.ng \
    --cc=deller@gmx.de \
    --cc=farosas@suse.de \
    --cc=laurent@vivier.eu \
    --cc=lvivier@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@oss.qualcomm.com \
    --cc=pierrick.bouvier@oss.qualcomm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.