@samitouri / QOSamiQemu / commits / 48ed36e055

hw/arm/mps2-tz.c add Arm mps3-an555 board

Add mps3-an555 board modeled after the existing mps3-an547 board. Add UnimplementedDeivceState for timing adapters and qspi controllers in MPS2TZMachineState. Changes in AN555: Timing adapters in APB PPC EX0 instead of MPC. Additional QSPI controllers in AHB PPC EX0. Additional AHB PPC EX1 with DMA. Create standalone unimplemented devices for MPC instead of timing adapters. Set fpgaio_has_gpioalt2 to true. Include documentation for SSE-310 and mps3-an555. Arm mps3-an555 TRM: https://developer.arm.com/documentation/107642/latest/ As our M85 model doesn't yet have PACBTI, note this omission in the documentation of where we deviate from the real AN555. Reviewed-by: Owen Giles <owen.giles@hpe.com> Reviewed-by: Robert Elliott <elliott@hpe.com> Signed-off-by: Simon Xu <simonxhy0404@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20260805153005.9989-9-simonxhy0404@gmail.com> [PMM: added doc note about PACBTI] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Simon Xu committed Aug 17, 2026 at 19:26 UTC 48ed36e0555e19b290ef0f0a2f40819180ff1aae
2 files changed +157 -6
docs/system/arm/mps2.rst
+5 -2
@@ -1,5 +1,5 @@
1 -Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
2 -=========================================================================================================================================================================
1 +Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``, ``mps3-an555``)
2 +=========================================================================================================================================================================================
3
4 These board models use Arm M-profile or R-profile CPUs.
5
@@ -31,6 +31,8 @@ FPGA images using M-profile CPUs:
31 Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
32 ``mps3-an547``
33 Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
34 +``mps3-an555``
35 + Cortex-M85 on an MPS3, as documented in Arm Application Note AN555
36
37 FPGA images using R-profile CPUs:
38
@@ -66,6 +68,7 @@ Differences between QEMU and real hardware:
68 held in halt via the initial SCC CFG_REG0 register setting. You can
69 create the second CPU with ``-smp 2``; both CPUs will then start
70 execution immediately on startup.
71 +- AN555 provides a Cortex-M85 without the PACBTI extension
72
73 Note that for the AN536 the first UART is accessible only by
74 CPU0, and the second UART is accessible only by CPU1. The
hw/arm/mps2-tz.c
+152 -4
@@ -1,5 +1,5 @@
1 /*
2 - * ARM V2M MPS2 board emulation, trustzone aware FPGA images
2 + * Arm V2M MPS2 and MPS3 board emulation, trustzone aware FPGA images
3 *
4 * Copyright (c) 2017 Linaro Limited
5 * Written by Peter Maydell
@@ -18,13 +18,17 @@
18 * "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
19 * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
20 * "mps2-an547" -- Single Cortex-M55 as documented in Application Note AN547
21 + * "mps3-an555" -- Single Cortex-M85 as documented in Application Note AN555
22 *
23 * Links to the TRM for the board itself and to the various Application
24 * Notes which document the FPGA images can be found here:
25 * https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
26 *
26 - * Board TRM:
27 + * MPS2 and MPS2+ Board TRM:
28 * https://developer.arm.com/documentation/100112/latest/
29 + * MPS3 Board TRM:
30 + * https://developer.arm.com/documentation/100765/latest/
31 + *
32 * Application Note AN505:
33 * https://developer.arm.com/documentation/dai0505/latest/
34 * Application Note AN521:
@@ -33,6 +37,8 @@
37 * https://developer.arm.com/documentation/dai0524/latest/
38 * Application Note AN547:
39 * https://developer.arm.com/documentation/dai0547/latest/
40 + * Application Note AN555:
41 + * https://developer.arm.com/documentation/107642/latest/
42 *
43 * The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
44 * (ARM ECM0601256) for the details of some of the device layout:
@@ -42,6 +48,8 @@
48 * https://developer.arm.com/documentation/101104/latest/
49 * and the AN547 uses the SSE-300, whose layout is in the SSE-300 TRM:
50 * https://developer.arm.com/documentation/101773/latest/
51 + * and the AN555 uses the SSE-310, whose layout is in the SSE-310 TRM:
52 + * https://developer.arm.com/documentation/102778/latest/
53 */
54
55 #include "qemu/osdep.h"
@@ -85,6 +93,7 @@ typedef enum MPS2TZFPGAType {
93 FPGA_AN521,
94 FPGA_AN524,
95 FPGA_AN547,
96 + FPGA_AN555,
97 } MPS2TZFPGAType;
98
99 /*
@@ -154,6 +163,8 @@ struct MPS2TZMachineState {
163 UnimplementedDeviceState gfx;
164 UnimplementedDeviceState cldc;
165 UnimplementedDeviceState usb;
166 + UnimplementedDeviceState ta[3]; /* timing adatper */
167 + UnimplementedDeviceState qspi_controller[3];
168 PL031State rtc;
169 PL080State dma[4];
170 TZMSC msc[4];
@@ -174,6 +185,7 @@ struct MPS2TZMachineState {
185 #define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
186 #define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
187 #define TYPE_MPS3TZ_AN547_MACHINE MACHINE_TYPE_NAME("mps3-an547")
188 +#define TYPE_MPS3TZ_AN555_MACHINE MACHINE_TYPE_NAME("mps3-an555")
189
190 OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
191
@@ -208,6 +220,15 @@ static const uint32_t an524_oscclk[] = {
220 23750000,
221 };
222
223 +static const uint32_t an555_oscclk[] = {
224 + 24000000,
225 + 25000000,
226 + 30000000,
227 + 50000000,
228 + 24576000,
229 + 23750000,
230 +};
231 +
232 static const RAMInfo an505_raminfo[] = { {
233 .name = "ssram-0",
234 .base = 0x00000000,
@@ -1030,7 +1051,6 @@ static void mps2tz_common_init(MachineState *machine)
1051 { "uart3", make_uart, &mms->uart[3], 0x41306000, 0x1000, { 38, 39, 45 } },
1052 { "uart4", make_uart, &mms->uart[4], 0x41307000, 0x1000, { 40, 41, 46 } },
1053 { "uart5", make_uart, &mms->uart[5], 0x41308000, 0x1000, { 124, 125, 126 } },
1033 -
1054 { /* port 9 reserved */ },
1055 { "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
1056 { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
@@ -1097,7 +1117,6 @@ static void mps2tz_common_init(MachineState *machine)
1117 { "uart3", make_uart, &mms->uart[3], 0x49306000, 0x1000, { 39, 40, 46 } },
1118 { "uart4", make_uart, &mms->uart[4], 0x49307000, 0x1000, { 41, 42, 47 } },
1119 { "uart5", make_uart, &mms->uart[5], 0x49308000, 0x1000, { 125, 126, 127 } },
1100 -
1120 { /* port 9 reserved */ },
1121 { "clcd", make_unimp_dev, &mms->cldc, 0x4930a000, 0x1000 },
1122 { "rtc", make_rtc, &mms->rtc, 0x4930b000, 0x1000 },
@@ -1126,6 +1145,81 @@ static void mps2tz_common_init(MachineState *machine)
1145 },
1146 };
1147
1148 + const PPCInfo an555_ppcs[] = { {
1149 + .name = "apb_ppcexp0",
1150 + .ports = {
1151 + { "sram-timing-adapter", make_unimp_dev, &mms->ta[0], 0x41700000, 0x1000 },
1152 + { "qspi-timing-adapter", make_unimp_dev, &mms->ta[1], 0x41701000, 0x1000 },
1153 + { "ddr4-timing-adapter", make_unimp_dev, &mms->ta[2], 0x41702000, 0x1000 },
1154 + },
1155 + }, {
1156 + .name = "apb_ppcexp1",
1157 + .ports = {
1158 + { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000, {},
1159 + { .i2c_internal = true /* touchscreen */ } },
1160 + { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000, {},
1161 + { .i2c_internal = true /* audio conf */ } },
1162 + { "spi0", make_spi, &mms->spi[0], 0x49202000, 0x1000, { 53 } },
1163 + { "spi1", make_spi, &mms->spi[1], 0x49203000, 0x1000, { 54 } },
1164 + { "spi2", make_spi, &mms->spi[2], 0x49204000, 0x1000, { 55 } },
1165 + { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000, {},
1166 + { .i2c_internal = false /* shield 0 */ } },
1167 + { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000, {},
1168 + { .i2c_internal = false /* shield 1 */ } },
1169 + { /* port 7 reserved */ },
1170 + { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000, {},
1171 + { .i2c_internal = true /* DDR4 EEPROM */ } },
1172 + },
1173 + }, {
1174 + .name = "apb_ppcexp2",
1175 + .ports = {
1176 + { "scc", make_scc, &mms->scc, 0x49300000, 0x1000 },
1177 + { "i2s-audio", make_unimp_dev, &mms->i2s_audio, 0x49301000, 0x1000 },
1178 + { "fpgaio", make_fpgaio, &mms->fpgaio, 0x49302000, 0x1000 },
1179 + { "uart0", make_uart, &mms->uart[0], 0x49303000, 0x1000, { 33, 34, 43 } },
1180 + { "uart1", make_uart, &mms->uart[1], 0x49304000, 0x1000, { 35, 36, 44 } },
1181 + { "uart2", make_uart, &mms->uart[2], 0x49305000, 0x1000, { 37, 38, 45 } },
1182 + { "uart3", make_uart, &mms->uart[3], 0x49306000, 0x1000, { 39, 40, 46 } },
1183 + { "uart4", make_uart, &mms->uart[4], 0x49307000, 0x1000, { 41, 42, 47 } },
1184 + { "uart5", make_uart, &mms->uart[5], 0x49308000, 0x1000, { 125, 126, 127 } },
1185 + { /* port 9 reserved */ },
1186 + { "clcd", make_unimp_dev, &mms->cldc, 0x4930a000, 0x1000 },
1187 + { "rtc", make_rtc, &mms->rtc, 0x4930b000, 0x1000 },
1188 + },
1189 + }, {
1190 + .name = "ahb_ppcexp0",
1191 + .ports = {
1192 + { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
1193 + { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
1194 + { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
1195 + { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
1196 + { /* port 4 USER AHB interface 0 */ },
1197 + { /* port 5 USER AHB interface 1 */ },
1198 + { /* port 6 USER AHB interface 2 */ },
1199 + { /* port 7 USER AHB interface 3 */ },
1200 + { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
1201 + { /* port 9 reserved */ },
1202 + { /* port 10 reserved */ },
1203 + { /* port 11 reserved */ },
1204 + { /* port 12 reserved */ },
1205 + { "qspi-controller0", make_unimp_dev, &mms->qspi_controller[0],
1206 + 0x41800000, 0x1000 },
1207 + { "qspi-controller1", make_unimp_dev, &mms->qspi_controller[1],
1208 + 0x41801000, 0x1000 },
1209 + { "qspi-controller2", make_unimp_dev, &mms->qspi_controller[2],
1210 + 0x41802000, 0x1000 },
1211 + },
1212 + }, {
1213 + .name = "ahb_ppcexp1",
1214 + .ports = {
1215 + { "dma0", make_dma, &mms->dma[0], 0x41200000, 0x1000, { 59, 57, 58 } },
1216 + { "dma1", make_dma, &mms->dma[1], 0x41201000, 0x1000, { 62, 60, 61 } },
1217 + { "dma2", make_dma, &mms->dma[2], 0x41202000, 0x1000, { 65, 63, 64 } },
1218 + { "dma3", make_dma, &mms->dma[3], 0x41203000, 0x1000, { 68, 66, 67 } },
1219 + },
1220 + },
1221 + };
1222 +
1223 switch (mmc->fpga_type) {
1224 case FPGA_AN505:
1225 case FPGA_AN521:
@@ -1140,6 +1234,10 @@ static void mps2tz_common_init(MachineState *machine)
1234 ppcs = an547_ppcs;
1235 num_ppcs = ARRAY_SIZE(an547_ppcs);
1236 break;
1237 + case FPGA_AN555:
1238 + ppcs = an555_ppcs;
1239 + num_ppcs = ARRAY_SIZE(an555_ppcs);
1240 + break;
1241 default:
1242 g_assert_not_reached();
1243 }
@@ -1223,6 +1321,12 @@ static void mps2tz_common_init(MachineState *machine)
1321 create_unimplemented_device("U55 timing adapter 1", 0x48103000, 0x1000);
1322 }
1323
1324 + if (mmc->fpga_type == FPGA_AN555) {
1325 + create_unimplemented_device("SRAM MPC", 0x57000000, 0x1000);
1326 + create_unimplemented_device("QSPI MPC", 0x57001000, 0x1000);
1327 + create_unimplemented_device("DDR4 MPC", 0x57002000, 0x1000);
1328 + }
1329 +
1330 create_non_mpc_ram(mms);
1331
1332 if (mmc->fpga_type == FPGA_AN524) {
@@ -1474,6 +1578,42 @@ static void mps3tz_an547_class_init(ObjectClass *oc, const void *data)
1578 mps2tz_set_default_ram_info(mmc);
1579 }
1580
1581 +static void mps3tz_an555_class_init(ObjectClass *oc, const void *data)
1582 +{
1583 + MachineClass *mc = MACHINE_CLASS(oc);
1584 + MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
1585 + static const char * const valid_cpu_types[] = {
1586 + ARM_CPU_TYPE_NAME("cortex-m85"),
1587 + NULL
1588 + };
1589 +
1590 + mc->desc = "ARM MPS3 with AN555 FPGA image for Cortex-M85";
1591 + mc->default_cpus = 1;
1592 + mc->min_cpus = mc->default_cpus;
1593 + mc->max_cpus = mc->default_cpus;
1594 + mmc->fpga_type = FPGA_AN555;
1595 + mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m85");
1596 + mc->valid_cpu_types = valid_cpu_types;
1597 + mmc->scc_id = 0x41055551;
1598 + mmc->sysclk_frq = 25 * 1000 * 1000; /* 25MHz */
1599 + mmc->apb_periph_frq = 25 * 1000 * 1000; /* 25MHz */
1600 + mmc->oscclk = an555_oscclk;
1601 + mmc->len_oscclk = ARRAY_SIZE(an555_oscclk);
1602 + mmc->fpgaio_num_leds = 10;
1603 + mmc->fpgaio_has_switches = true;
1604 + mmc->fpgaio_has_dbgctrl = true;
1605 + mmc->fpgaio_has_gpioalt2 = true;
1606 + mmc->numirq = 96;
1607 + mmc->uart_overflow_irq = 48;
1608 + mmc->init_svtor = 0x00000000;
1609 + mmc->cpu0_mpu_s = mmc->cpu0_mpu_ns = 8;
1610 + mmc->sram_addr_width = 21;
1611 + mmc->raminfo = an547_raminfo; /* same as AN547*/
1612 + mmc->armsse_type = TYPE_SSE310;
1613 + mmc->boot_ram_size = 512 * KiB;
1614 + mps2tz_set_default_ram_info(mmc);
1615 +}
1616 +
1617 static const TypeInfo mps2tz_info = {
1618 .name = TYPE_MPS2TZ_MACHINE,
1619 .parent = TYPE_MACHINE,
@@ -1515,6 +1655,13 @@ static const TypeInfo mps3tz_an547_info = {
1655 .interfaces = arm_machine_interfaces,
1656 };
1657
1658 +static const TypeInfo mps3tz_an555_info = {
1659 + .name = TYPE_MPS3TZ_AN555_MACHINE,
1660 + .parent = TYPE_MPS2TZ_MACHINE,
1661 + .class_init = mps3tz_an555_class_init,
1662 + .interfaces = arm_machine_interfaces,
1663 +};
1664 +
1665 static void mps2tz_machine_init(void)
1666 {
1667 type_register_static(&mps2tz_info);
@@ -1522,6 +1669,7 @@ static void mps2tz_machine_init(void)
1669 type_register_static(&mps2tz_an521_info);
1670 type_register_static(&mps3tz_an524_info);
1671 type_register_static(&mps3tz_an547_info);
1672 + type_register_static(&mps3tz_an555_info);
1673 }
1674
1675 type_init(mps2tz_machine_init);