@samitouri / QOSamiQemu / commits / 6d0f9427f4

hw/hexagon: Add machine configs for sysemu

Some header includes are modified here: these are uniquely required for basic system emulation functionality and had not been required for linux-user. Acked-by: Markus Armbruster <armbru@redhat.com> Co-authored-by: Mike Lambert <mlambert@quicinc.com> Co-authored-by: Sid Manning <sidneym@quicinc.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

Brian Cain committed Jun 22, 2026 at 15:28 UTC 6d0f9427f4e59757f6e680c0bb92d96ee1b89f21
10 files changed +472 -1
MAINTAINERS
+12
@@ -1344,6 +1344,18 @@ F: pc-bios/hppa-firmware.img
1344 F: roms/seabios-hppa/
1345 F: tests/functional/hppa/
1346
1347 +Hexagon Machines
1348 +----------------
1349 +V66G_1024, V68N_1024, sa8775-cdsp0
1350 +M: Brian Cain <brian.cain@oss.qualcomm.com>
1351 +R: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
1352 +S: Supported
1353 +F: hw/hexagon/
1354 +F: include/hw/hexagon/
1355 +F: configs/devices/hexagon-softmmu/default.mak
1356 +F: docs/system/hexagon/
1357 +F: docs/devel/hexagon-sys.rst
1358 +
1359 LoongArch Machines
1360 ------------------
1361 Virt
hw/Kconfig
+1
@@ -53,6 +53,7 @@ source arm/Kconfig
53 source cpu/Kconfig
54 source alpha/Kconfig
55 source avr/Kconfig
56 +source hexagon/Kconfig
57 source hppa/Kconfig
58 source i386/Kconfig
59 source loongarch/Kconfig
hw/hexagon/Kconfig new
+4
@@ -0,0 +1,4 @@
1 +config HEX_DSP
2 + bool
3 + default y
4 + depends on HEXAGON
hw/hexagon/hexagon_dsp.c new
+221
@@ -0,0 +1,221 @@
1 +/*
2 + * Hexagon DSP Subsystem emulation. This represents a generic DSP
3 + * subsystem with few peripherals, like the Compute DSP.
4 + *
5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6 + *
7 + * SPDX-License-Identifier: GPL-2.0-or-later
8 + */
9 +
10 +
11 +#include "qemu/osdep.h"
12 +#include "qemu/units.h"
13 +#include "system/address-spaces.h"
14 +#include "hw/core/boards.h"
15 +#include "hw/core/qdev-properties.h"
16 +#include "hw/hexagon/hexagon.h"
17 +#include "hw/hexagon/hexagon_globalreg.h"
18 +#include "hw/hexagon/hexagon_tlb.h"
19 +#include "hw/core/loader.h"
20 +#include "qapi/error.h"
21 +#include "qemu/error-report.h"
22 +#include "qemu/log.h"
23 +#include "elf.h"
24 +#include "cpu.h"
25 +#include "migration/cpu.h"
26 +#include "system/system.h"
27 +#include "target/hexagon/internal.h"
28 +#include "system/physmem.h"
29 +#include "system/reset.h"
30 +
31 +#include "machine_cfg_v66g_1024.h.inc"
32 +
33 +#define TYPE_HEXAGON_DSP_MACHINE "hexagon-dsp-machine"
34 +OBJECT_DECLARE_SIMPLE_TYPE(HexagonDspMachineState, HEXAGON_DSP_MACHINE)
35 +
36 +struct HexagonDspMachineState {
37 + HexagonCommonMachineState parent_obj;
38 +
39 + hwaddr isdb_secure_flag;
40 + hwaddr isdb_trusted_flag;
41 +};
42 +
43 +static HexagonDspMachineState *current_dms;
44 +
45 +static void hex_symbol_callback(const char *st_name, int st_info,
46 + uint64_t st_value, uint64_t st_size)
47 +{
48 + if (!g_strcmp0("isdb_secure_flag", st_name)) {
49 + current_dms->isdb_secure_flag = st_value;
50 + }
51 + if (!g_strcmp0("isdb_trusted_flag", st_name)) {
52 + current_dms->isdb_trusted_flag = st_value;
53 + }
54 +}
55 +
56 +/* Board init. */
57 +static struct hexagon_board_boot_info hexagon_binfo;
58 +
59 +static void hexagon_load_kernel(HexagonDspMachineState *dms, HexagonCPU *cpu)
60 +{
61 + uint64_t pentry;
62 + long kernel_size;
63 +
64 + current_dms = dms;
65 + kernel_size = load_elf_ram_sym(hexagon_binfo.kernel_filename, NULL, NULL,
66 + NULL, &pentry, NULL, NULL,
67 + &hexagon_binfo.kernel_elf_flags, 0, EM_HEXAGON, 0, 0,
68 + &address_space_memory, false, hex_symbol_callback);
69 + current_dms = NULL;
70 +
71 + if (kernel_size <= 0) {
72 + error_report("no kernel file '%s'",
73 + hexagon_binfo.kernel_filename);
74 + exit(1);
75 + }
76 +
77 + qdev_prop_set_uint32(DEVICE(cpu), "exec-start-addr", pentry);
78 +}
79 +
80 +static void hexagon_init_bootstrap(HexagonDspMachineState *dms, HexagonCPU *cpu)
81 +{
82 + MachineState *machine = MACHINE(dms);
83 +
84 + if (machine->kernel_filename) {
85 + uint32_t mem = 1;
86 +
87 + hexagon_load_kernel(dms, cpu);
88 + if (dms->isdb_secure_flag) {
89 + physical_memory_write(dms->isdb_secure_flag,
90 + &mem, sizeof(mem));
91 + }
92 + if (dms->isdb_trusted_flag) {
93 + physical_memory_write(dms->isdb_trusted_flag,
94 + &mem, sizeof(mem));
95 + }
96 + }
97 +}
98 +
99 +static void do_cpu_reset(void *opaque)
100 +{
101 + HexagonCPU *cpu = opaque;
102 + CPUState *cs = CPU(cpu);
103 + cpu_reset(cs);
104 +}
105 +
106 +static void hexagon_common_init(MachineState *machine, Rev_t rev,
107 + const struct hexagon_machine_config *m_cfg)
108 +{
109 + HexagonCommonMachineState *hms = HEXAGON_COMMON_MACHINE(machine);
110 + HexagonDspMachineState *dms = HEXAGON_DSP_MACHINE(machine);
111 + MemoryRegion *address_space;
112 + DeviceState *glob_regs_dev;
113 + DeviceState *tlb_dev;
114 +
115 + memset(&hexagon_binfo, 0, sizeof(hexagon_binfo));
116 + if (machine->kernel_filename) {
117 + hexagon_binfo.ram_size = machine->ram_size;
118 + hexagon_binfo.kernel_filename = machine->kernel_filename;
119 + }
120 +
121 + machine->enable_graphics = 0;
122 +
123 + address_space = get_system_memory();
124 +
125 + memory_region_init_rom(&hms->cfgtable_rom, NULL, "config_table.rom",
126 + sizeof(m_cfg->cfgtable), &error_fatal);
127 + memory_region_add_subregion(address_space, m_cfg->cfgbase,
128 + &hms->cfgtable_rom);
129 +
130 + memory_region_init_ram(&hms->ram, NULL, "ddr.ram",
131 + machine->ram_size, &error_fatal);
132 + memory_region_add_subregion(address_space, 0x0, &hms->ram);
133 +
134 + glob_regs_dev = qdev_new(TYPE_HEXAGON_GLOBALREG);
135 + object_property_add_child(OBJECT(machine), "global-regs",
136 + OBJECT(glob_regs_dev));
137 + qdev_prop_set_uint64(glob_regs_dev, "config-table-addr", m_cfg->cfgbase);
138 + qdev_prop_set_uint32(glob_regs_dev, "dsp-rev", rev);
139 + sysbus_realize_and_unref(SYS_BUS_DEVICE(glob_regs_dev), &error_fatal);
140 +
141 + tlb_dev = qdev_new(TYPE_HEXAGON_TLB);
142 + object_property_add_child(OBJECT(machine), "tlb", OBJECT(tlb_dev));
143 + qdev_prop_set_uint32(tlb_dev, "num-entries",
144 + m_cfg->cfgtable.jtlb_size_entries);
145 + sysbus_realize_and_unref(SYS_BUS_DEVICE(tlb_dev), &error_fatal);
146 +
147 + for (int i = 0; i < machine->smp.cpus; i++) {
148 + HexagonCPU *cpu = HEXAGON_CPU(object_new(machine->cpu_type));
149 + qemu_register_reset(do_cpu_reset, cpu);
150 +
151 + /*
152 + * CPU #0 is the only CPU running at boot, others must be
153 + * explicitly enabled via start instruction.
154 + */
155 + qdev_prop_set_bit(DEVICE(cpu), "start-powered-off", (i != 0));
156 + if (i == 0) {
157 + hexagon_init_bootstrap(dms, cpu);
158 + }
159 + object_property_set_link(OBJECT(cpu), "global-regs",
160 + OBJECT(glob_regs_dev), &error_fatal);
161 + object_property_set_link(OBJECT(cpu), "tlb",
162 + OBJECT(tlb_dev), &error_fatal);
163 + qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
164 + }
165 +}
166 +
167 +static void init_mc(MachineClass *mc)
168 +{
169 + mc->block_default_type = IF_SD;
170 + mc->default_ram_size = 4 * GiB;
171 + mc->no_parallel = 1;
172 + mc->no_floppy = 1;
173 + mc->no_cdrom = 1;
174 + mc->no_serial = 1;
175 + mc->is_default = false;
176 + mc->max_cpus = 8;
177 +}
178 +
179 +/* ----------------------------------------------------------------- */
180 +/* Core-specific configuration settings are defined below this line. */
181 +/* Config table values defined in machine_configs.h.inc */
182 +/* ----------------------------------------------------------------- */
183 +
184 +static void v66g_1024_config_init(MachineState *machine)
185 +{
186 + hexagon_common_init(machine, v66_rev, &v66g_1024);
187 +}
188 +
189 +static void v66g_1024_init(ObjectClass *oc, const void *data)
190 +{
191 + MachineClass *mc = MACHINE_CLASS(oc);
192 +
193 + mc->desc = "Hexagon V66G_1024";
194 + mc->init = v66g_1024_config_init;
195 + init_mc(mc);
196 + mc->is_default = true;
197 + mc->default_cpu_type = TYPE_HEXAGON_CPU_V66;
198 + mc->default_cpus = 4;
199 +}
200 +
201 +static const TypeInfo hexagon_machine_types[] = {
202 + {
203 + .name = TYPE_HEXAGON_COMMON_MACHINE,
204 + .parent = TYPE_MACHINE,
205 + .instance_size = sizeof(HexagonCommonMachineState),
206 + .abstract = true,
207 + },
208 + {
209 + .name = TYPE_HEXAGON_DSP_MACHINE,
210 + .parent = TYPE_HEXAGON_COMMON_MACHINE,
211 + .instance_size = sizeof(HexagonDspMachineState),
212 + .abstract = true,
213 + },
214 + {
215 + .name = MACHINE_TYPE_NAME("V66G_1024"),
216 + .parent = TYPE_HEXAGON_DSP_MACHINE,
217 + .class_init = v66g_1024_init,
218 + },
219 +};
220 +
221 +DEFINE_TYPES(hexagon_machine_types)
hw/hexagon/machine_cfg_v66g_1024.h.inc new
+64
@@ -0,0 +1,64 @@
1 +/* SPDX-License-Identifier: GPL-2.0-or-later */
2 +
3 +static const struct hexagon_machine_config v66g_1024 = {
4 + .cfgbase = 0xd8180000,
5 + .l2tcm_size = 0x00000000,
6 + .l2vic_base = 0xfc910000,
7 + .l2vic_size = 0x00001000,
8 + .csr_base = 0xfc900000,
9 + .qtmr_region = 0xfc921000,
10 + .cfgtable = {
11 + .l2tcm_base = 0x0000d800,
12 + .reserved0 = 0x0000d400,
13 + .subsystem_base = 0x0000fc90,
14 + .etm_base = 0x0000d805,
15 + .l2cfg_base = 0x0000d81a,
16 + .reserved1 = 0x00000000,
17 + .l1s0_base = 0x0000d820,
18 + .axi2_lowaddr = 0x00003000,
19 + .streamer_base = 0x00000000,
20 + .reserved2 = 0x0000d819,
21 + .fastl2vic_base = 0x0000d81e,
22 + .jtlb_size_entries = 0x00000080,
23 + .coproc_present = 0x00000001,
24 + .ext_contexts = 0x00000004,
25 + .vtcm_base = 0x0000d820,
26 + .vtcm_size_kb = 0x00000100,
27 + .l2tag_size = 0x00000400,
28 + .l2ecomem_size = 0x00000400,
29 + .thread_enable_mask = 0x0000000f,
30 + .eccreg_base = 0x0000d81f,
31 + .l2line_size = 0x00000080,
32 + .tiny_core = 0x00000000,
33 + .l2itcm_size = 0x00000000,
34 + .l2itcm_base = 0x0000d820,
35 + .reserved3 = 0x00000000,
36 + .dtm_present = 0x00000000,
37 + .dma_version = 0x00000000,
38 + .hvx_vec_log_length = 0x00000080,
39 + .core_id = 0x00000000,
40 + .core_count = 0x00000000,
41 + .coproc2_reg0 = 0x00000000,
42 + .coproc2_reg1 = 0x00000000,
43 + .v2x_mode = 0x00000000,
44 + .coproc2_reg2 = 0x00000000,
45 + .coproc2_reg3 = 0x00000000,
46 + .coproc2_reg4 = 0x00000000,
47 + .coproc2_reg5 = 0x00000000,
48 + .coproc2_reg6 = 0x00000000,
49 + .coproc2_reg7 = 0x00000000,
50 + .acd_preset = 0x00000000,
51 + .mnd_preset = 0x00000000,
52 + .l1d_size_kb = 0x00000000,
53 + .l1i_size_kb = 0x00000000,
54 + .l1d_write_policy = 0x00000000,
55 + .vtcm_bank_width = 0x00000000,
56 + .reserved4 = 0x00000000,
57 + .reserved5 = 0x00000000,
58 + .reserved6 = 0x00000000,
59 + .coproc2_cvt_mpy_size = 0x00000000,
60 + .consistency_domain = 0x00000000,
61 + .capacity_domain = 0x00000000,
62 + .axi3_lowaddr = 0x00000000,
63 + },
64 +};
hw/hexagon/meson.build new
+6
@@ -0,0 +1,6 @@
1 +hexagon_ss = ss.source_set()
2 +hexagon_ss.add(files('hexagon_tlb.c'))
3 +hexagon_ss.add(files('hexagon_globalreg.c'))
4 +hexagon_ss.add(when: 'CONFIG_HEX_DSP', if_true: files('hexagon_dsp.c'))
5 +
6 +hw_arch += {'hexagon': hexagon_ss}
hw/meson.build
+1
@@ -3,6 +3,7 @@ subdir('alpha')
3 subdir('arm')
4 subdir('avr')
5 subdir('hppa')
6 +subdir('hexagon')
7 subdir('xenpv') # i386 uses it
8 subdir('i386')
9 subdir('loongarch')
include/hw/hexagon/hexagon.h new
+161
@@ -0,0 +1,161 @@
1 +/*
2 + * Hexagon Baseboard System emulation.
3 + *
4 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5 + * SPDX-License-Identifier: GPL-2.0-or-later
6 + */
7 +
8 +
9 +#ifndef HW_HEXAGON_H
10 +#define HW_HEXAGON_H
11 +
12 +#include "system/memory.h"
13 +#include "hw/core/boards.h"
14 +
15 +struct hexagon_board_boot_info {
16 + uint64_t ram_size;
17 + const char *kernel_filename;
18 + uint32_t kernel_elf_flags;
19 +};
20 +
21 +typedef enum {
22 + unknown_rev = 0,
23 + v66_rev = 0xa666,
24 + v67_rev = 0x2667,
25 + v68_rev = 0x8d68,
26 + v69_rev = 0x8c69,
27 + v71_rev = 0x8c71,
28 + v73_rev = 0x8c73,
29 + v73m_rev = 0xcc73,
30 +} Rev_t;
31 +#define HEXAGON_LATEST_REV v73
32 +#define HEXAGON_LATEST_REV_UPPER V73
33 +
34 +/*
35 + * Config table address bases represent bits [35:16].
36 + */
37 +#define HEXAGON_CFG_ADDR_BASE(addr) (((addr) >> 16) & 0x0fffff)
38 +
39 +#define HEXAGON_CFGSPACE_ENTRIES (128)
40 +
41 +union hexagon_config_table {
42 + struct {
43 + /* Base address of L2TCM space */
44 + uint32_t l2tcm_base;
45 + uint32_t reserved0;
46 + /* Base address of subsystem space */
47 + uint32_t subsystem_base;
48 + /* Base address of ETM space */
49 + uint32_t etm_base;
50 + /* Base address of L2 configuration space */
51 + uint32_t l2cfg_base;
52 + uint32_t reserved1;
53 + /* Base address of L1S */
54 + uint32_t l1s0_base;
55 + /* Base address of AXI2 */
56 + uint32_t axi2_lowaddr;
57 + /* Base address of streamer base */
58 + uint32_t streamer_base;
59 + uint32_t reserved2;
60 + /* Base address of fast L2VIC */
61 + uint32_t fastl2vic_base;
62 + /* Number of entries in JTLB */
63 + uint32_t jtlb_size_entries;
64 + /* Coprocessor type */
65 + uint32_t coproc_present;
66 + /* Number of extension execution contexts available */
67 + uint32_t ext_contexts;
68 + /* Base address of Hexagon Vector Tightly Coupled Memory (VTCM) */
69 + uint32_t vtcm_base;
70 + /* Size of VTCM (in KB) */
71 + uint32_t vtcm_size_kb;
72 + /* L2 tag size */
73 + uint32_t l2tag_size;
74 + /* Amount of physical L2 memory in released version */
75 + uint32_t l2ecomem_size;
76 + /* Hardware threads available on the core */
77 + uint32_t thread_enable_mask;
78 + /* Base address of the ECC registers */
79 + uint32_t eccreg_base;
80 + /* L2 line size */
81 + uint32_t l2line_size;
82 + /* Small Core processor (also implies audio extension) */
83 + uint32_t tiny_core;
84 + /* Size of L2TCM */
85 + uint32_t l2itcm_size;
86 + /* Base address of L2-ITCM */
87 + uint32_t l2itcm_base;
88 + uint32_t reserved3;
89 + /* DTM is present */
90 + uint32_t dtm_present;
91 + /* Version of the DMA */
92 + uint32_t dma_version;
93 + /* Native HVX vector length in log of bytes */
94 + uint32_t hvx_vec_log_length;
95 + /* Core ID of the multi-core */
96 + uint32_t core_id;
97 + /* Number of multi-core cores */
98 + uint32_t core_count;
99 + uint32_t coproc2_reg0;
100 + uint32_t coproc2_reg1;
101 + /* Supported HVX vector length */
102 + uint32_t v2x_mode;
103 + uint32_t coproc2_reg2;
104 + uint32_t coproc2_reg3;
105 + uint32_t coproc2_reg4;
106 + uint32_t coproc2_reg5;
107 + uint32_t coproc2_reg6;
108 + uint32_t coproc2_reg7;
109 + /* Voltage droop mitigation technique parameter */
110 + uint32_t acd_preset;
111 + /* Voltage droop mitigation technique parameter */
112 + uint32_t mnd_preset;
113 + /* L1 data cache size (in KB) */
114 + uint32_t l1d_size_kb;
115 + /* L1 instruction cache size in (KB) */
116 + uint32_t l1i_size_kb;
117 + /* L1 data cache write policy: see HexagonL1WritePolicy */
118 + uint32_t l1d_write_policy;
119 + /* VTCM bank width */
120 + uint32_t vtcm_bank_width;
121 + uint32_t reserved4;
122 + uint32_t reserved5;
123 + uint32_t reserved6;
124 + uint32_t coproc2_cvt_mpy_size;
125 + uint32_t consistency_domain;
126 + uint32_t capacity_domain;
127 + uint32_t axi3_lowaddr;
128 + uint32_t coproc2_int8_subcolumns;
129 + uint32_t corecfg_present;
130 + uint32_t coproc2_fp16_acc_exp;
131 + uint32_t AXIM2_secondary_base;
132 + };
133 + uint32_t raw[HEXAGON_CFGSPACE_ENTRIES];
134 +};
135 +
136 +struct hexagon_machine_config {
137 + /* Base address of config table */
138 + uint32_t cfgbase;
139 + /* Size of L2 TCM */
140 + uint32_t l2tcm_size;
141 + /* Base address of L2VIC */
142 + uint32_t l2vic_base;
143 + /* Size of L2VIC region */
144 + uint32_t l2vic_size;
145 + /* QTimer csr base */
146 + uint32_t csr_base;
147 + uint32_t qtmr_region;
148 + union hexagon_config_table cfgtable;
149 +};
150 +
151 +#define TYPE_HEXAGON_COMMON_MACHINE "hexagon-common-machine"
152 +OBJECT_DECLARE_SIMPLE_TYPE(HexagonCommonMachineState, HEXAGON_COMMON_MACHINE)
153 +
154 +struct HexagonCommonMachineState {
155 + MachineState parent_obj;
156 +
157 + MemoryRegion ram;
158 + MemoryRegion cfgtable_rom;
159 +};
160 +
161 +#endif
system/qdev-monitor.c
+1 -1
@@ -71,7 +71,7 @@ typedef struct QDevAlias
71 QEMU_ARCH_SPARC | \
72 QEMU_ARCH_XTENSA)
73 #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
74 -#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
74 +#define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K | QEMU_ARCH_HEXAGON)
75
76 /* Please keep this table sorted by typename. */
77 static const QDevAlias qdev_alias_table[] = {
target/hexagon/translate.c
+1
@@ -32,6 +32,7 @@
32 #include "translate.h"
33 #include "genptr.h"
34 #include "printinsn.h"
35 +#include "exec/target_page.h"
36
37 #define HELPER_H "helper.h"
38 #include "exec/helper-info.c.inc"