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
* "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:
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:
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"
93
FPGA_AN521,
94
FPGA_AN524,
95
FPGA_AN547,
96
+ FPGA_AN555,
97
} MPS2TZFPGAType;
98
99
/*
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];
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
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,
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 },
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 },
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:
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
}
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) {
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,
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);
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);