1*273a70aeSPeter Maydell /* 2*273a70aeSPeter Maydell * Arm MPS3 board emulation for Cortex-R-based FPGA images. 3*273a70aeSPeter Maydell * (For M-profile images see mps2.c and mps2tz.c.) 4*273a70aeSPeter Maydell * 5*273a70aeSPeter Maydell * Copyright (c) 2017 Linaro Limited 6*273a70aeSPeter Maydell * Written by Peter Maydell 7*273a70aeSPeter Maydell * 8*273a70aeSPeter Maydell * This program is free software; you can redistribute it and/or modify 9*273a70aeSPeter Maydell * it under the terms of the GNU General Public License version 2 or 10*273a70aeSPeter Maydell * (at your option) any later version. 11*273a70aeSPeter Maydell */ 12*273a70aeSPeter Maydell 13*273a70aeSPeter Maydell /* 14*273a70aeSPeter Maydell * The MPS3 is an FPGA based dev board. This file handles FPGA images 15*273a70aeSPeter Maydell * which use the Cortex-R CPUs. We model these separately from the 16*273a70aeSPeter Maydell * M-profile images, because on M-profile the FPGA image is based on 17*273a70aeSPeter Maydell * a "Subsystem for Embedded" which is similar to an SoC, whereas 18*273a70aeSPeter Maydell * the R-profile FPGA images don't have that abstraction layer. 19*273a70aeSPeter Maydell * 20*273a70aeSPeter Maydell * We model the following FPGA images here: 21*273a70aeSPeter Maydell * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536 22*273a70aeSPeter Maydell * 23*273a70aeSPeter Maydell * Application Note AN536: 24*273a70aeSPeter Maydell * https://developer.arm.com/documentation/dai0536/latest/ 25*273a70aeSPeter Maydell */ 26*273a70aeSPeter Maydell 27*273a70aeSPeter Maydell #include "qemu/osdep.h" 28*273a70aeSPeter Maydell #include "qemu/units.h" 29*273a70aeSPeter Maydell #include "qapi/error.h" 30*273a70aeSPeter Maydell #include "exec/address-spaces.h" 31*273a70aeSPeter Maydell #include "cpu.h" 32*273a70aeSPeter Maydell #include "hw/boards.h" 33*273a70aeSPeter Maydell #include "hw/arm/boot.h" 34*273a70aeSPeter Maydell 35*273a70aeSPeter Maydell /* Define the layout of RAM and ROM in a board */ 36*273a70aeSPeter Maydell typedef struct RAMInfo { 37*273a70aeSPeter Maydell const char *name; 38*273a70aeSPeter Maydell hwaddr base; 39*273a70aeSPeter Maydell hwaddr size; 40*273a70aeSPeter Maydell int mrindex; /* index into rams[]; -1 for the system RAM block */ 41*273a70aeSPeter Maydell int flags; 42*273a70aeSPeter Maydell } RAMInfo; 43*273a70aeSPeter Maydell 44*273a70aeSPeter Maydell /* 45*273a70aeSPeter Maydell * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit 46*273a70aeSPeter Maydell * emulation of that much guest RAM, so artificially make it smaller. 47*273a70aeSPeter Maydell */ 48*273a70aeSPeter Maydell #if HOST_LONG_BITS == 32 49*273a70aeSPeter Maydell #define MPS3_DDR_SIZE (1 * GiB) 50*273a70aeSPeter Maydell #else 51*273a70aeSPeter Maydell #define MPS3_DDR_SIZE (3 * GiB) 52*273a70aeSPeter Maydell #endif 53*273a70aeSPeter Maydell 54*273a70aeSPeter Maydell /* 55*273a70aeSPeter Maydell * Flag values: 56*273a70aeSPeter Maydell * IS_MAIN: this is the main machine RAM 57*273a70aeSPeter Maydell * IS_ROM: this area is read-only 58*273a70aeSPeter Maydell */ 59*273a70aeSPeter Maydell #define IS_MAIN 1 60*273a70aeSPeter Maydell #define IS_ROM 2 61*273a70aeSPeter Maydell 62*273a70aeSPeter Maydell #define MPS3R_RAM_MAX 9 63*273a70aeSPeter Maydell 64*273a70aeSPeter Maydell typedef enum MPS3RFPGAType { 65*273a70aeSPeter Maydell FPGA_AN536, 66*273a70aeSPeter Maydell } MPS3RFPGAType; 67*273a70aeSPeter Maydell 68*273a70aeSPeter Maydell struct MPS3RMachineClass { 69*273a70aeSPeter Maydell MachineClass parent; 70*273a70aeSPeter Maydell MPS3RFPGAType fpga_type; 71*273a70aeSPeter Maydell const RAMInfo *raminfo; 72*273a70aeSPeter Maydell }; 73*273a70aeSPeter Maydell 74*273a70aeSPeter Maydell struct MPS3RMachineState { 75*273a70aeSPeter Maydell MachineState parent; 76*273a70aeSPeter Maydell MemoryRegion ram[MPS3R_RAM_MAX]; 77*273a70aeSPeter Maydell }; 78*273a70aeSPeter Maydell 79*273a70aeSPeter Maydell #define TYPE_MPS3R_MACHINE "mps3r" 80*273a70aeSPeter Maydell #define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536") 81*273a70aeSPeter Maydell 82*273a70aeSPeter Maydell OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE) 83*273a70aeSPeter Maydell 84*273a70aeSPeter Maydell static const RAMInfo an536_raminfo[] = { 85*273a70aeSPeter Maydell { 86*273a70aeSPeter Maydell .name = "ATCM", 87*273a70aeSPeter Maydell .base = 0x00000000, 88*273a70aeSPeter Maydell .size = 0x00008000, 89*273a70aeSPeter Maydell .mrindex = 0, 90*273a70aeSPeter Maydell }, { 91*273a70aeSPeter Maydell /* We model the QSPI flash as simple ROM for now */ 92*273a70aeSPeter Maydell .name = "QSPI", 93*273a70aeSPeter Maydell .base = 0x08000000, 94*273a70aeSPeter Maydell .size = 0x00800000, 95*273a70aeSPeter Maydell .flags = IS_ROM, 96*273a70aeSPeter Maydell .mrindex = 1, 97*273a70aeSPeter Maydell }, { 98*273a70aeSPeter Maydell .name = "BRAM", 99*273a70aeSPeter Maydell .base = 0x10000000, 100*273a70aeSPeter Maydell .size = 0x00080000, 101*273a70aeSPeter Maydell .mrindex = 2, 102*273a70aeSPeter Maydell }, { 103*273a70aeSPeter Maydell .name = "DDR", 104*273a70aeSPeter Maydell .base = 0x20000000, 105*273a70aeSPeter Maydell .size = MPS3_DDR_SIZE, 106*273a70aeSPeter Maydell .mrindex = -1, 107*273a70aeSPeter Maydell }, { 108*273a70aeSPeter Maydell .name = "ATCM0", 109*273a70aeSPeter Maydell .base = 0xee000000, 110*273a70aeSPeter Maydell .size = 0x00008000, 111*273a70aeSPeter Maydell .mrindex = 3, 112*273a70aeSPeter Maydell }, { 113*273a70aeSPeter Maydell .name = "BTCM0", 114*273a70aeSPeter Maydell .base = 0xee100000, 115*273a70aeSPeter Maydell .size = 0x00008000, 116*273a70aeSPeter Maydell .mrindex = 4, 117*273a70aeSPeter Maydell }, { 118*273a70aeSPeter Maydell .name = "CTCM0", 119*273a70aeSPeter Maydell .base = 0xee200000, 120*273a70aeSPeter Maydell .size = 0x00008000, 121*273a70aeSPeter Maydell .mrindex = 5, 122*273a70aeSPeter Maydell }, { 123*273a70aeSPeter Maydell .name = "ATCM1", 124*273a70aeSPeter Maydell .base = 0xee400000, 125*273a70aeSPeter Maydell .size = 0x00008000, 126*273a70aeSPeter Maydell .mrindex = 6, 127*273a70aeSPeter Maydell }, { 128*273a70aeSPeter Maydell .name = "BTCM1", 129*273a70aeSPeter Maydell .base = 0xee500000, 130*273a70aeSPeter Maydell .size = 0x00008000, 131*273a70aeSPeter Maydell .mrindex = 7, 132*273a70aeSPeter Maydell }, { 133*273a70aeSPeter Maydell .name = "CTCM1", 134*273a70aeSPeter Maydell .base = 0xee600000, 135*273a70aeSPeter Maydell .size = 0x00008000, 136*273a70aeSPeter Maydell .mrindex = 8, 137*273a70aeSPeter Maydell }, { 138*273a70aeSPeter Maydell .name = NULL, 139*273a70aeSPeter Maydell } 140*273a70aeSPeter Maydell }; 141*273a70aeSPeter Maydell 142*273a70aeSPeter Maydell static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms, 143*273a70aeSPeter Maydell const RAMInfo *raminfo) 144*273a70aeSPeter Maydell { 145*273a70aeSPeter Maydell /* Return an initialized MemoryRegion for the RAMInfo. */ 146*273a70aeSPeter Maydell MemoryRegion *ram; 147*273a70aeSPeter Maydell 148*273a70aeSPeter Maydell if (raminfo->mrindex < 0) { 149*273a70aeSPeter Maydell /* Means this RAMInfo is for QEMU's "system memory" */ 150*273a70aeSPeter Maydell MachineState *machine = MACHINE(mms); 151*273a70aeSPeter Maydell assert(!(raminfo->flags & IS_ROM)); 152*273a70aeSPeter Maydell return machine->ram; 153*273a70aeSPeter Maydell } 154*273a70aeSPeter Maydell 155*273a70aeSPeter Maydell assert(raminfo->mrindex < MPS3R_RAM_MAX); 156*273a70aeSPeter Maydell ram = &mms->ram[raminfo->mrindex]; 157*273a70aeSPeter Maydell 158*273a70aeSPeter Maydell memory_region_init_ram(ram, NULL, raminfo->name, 159*273a70aeSPeter Maydell raminfo->size, &error_fatal); 160*273a70aeSPeter Maydell if (raminfo->flags & IS_ROM) { 161*273a70aeSPeter Maydell memory_region_set_readonly(ram, true); 162*273a70aeSPeter Maydell } 163*273a70aeSPeter Maydell return ram; 164*273a70aeSPeter Maydell } 165*273a70aeSPeter Maydell 166*273a70aeSPeter Maydell static void mps3r_common_init(MachineState *machine) 167*273a70aeSPeter Maydell { 168*273a70aeSPeter Maydell MPS3RMachineState *mms = MPS3R_MACHINE(machine); 169*273a70aeSPeter Maydell MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms); 170*273a70aeSPeter Maydell MemoryRegion *sysmem = get_system_memory(); 171*273a70aeSPeter Maydell 172*273a70aeSPeter Maydell for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) { 173*273a70aeSPeter Maydell MemoryRegion *mr = mr_for_raminfo(mms, ri); 174*273a70aeSPeter Maydell memory_region_add_subregion(sysmem, ri->base, mr); 175*273a70aeSPeter Maydell } 176*273a70aeSPeter Maydell } 177*273a70aeSPeter Maydell 178*273a70aeSPeter Maydell static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc) 179*273a70aeSPeter Maydell { 180*273a70aeSPeter Maydell /* 181*273a70aeSPeter Maydell * Set mc->default_ram_size and default_ram_id from the 182*273a70aeSPeter Maydell * information in mmc->raminfo. 183*273a70aeSPeter Maydell */ 184*273a70aeSPeter Maydell MachineClass *mc = MACHINE_CLASS(mmc); 185*273a70aeSPeter Maydell const RAMInfo *p; 186*273a70aeSPeter Maydell 187*273a70aeSPeter Maydell for (p = mmc->raminfo; p->name; p++) { 188*273a70aeSPeter Maydell if (p->mrindex < 0) { 189*273a70aeSPeter Maydell /* Found the entry for "system memory" */ 190*273a70aeSPeter Maydell mc->default_ram_size = p->size; 191*273a70aeSPeter Maydell mc->default_ram_id = p->name; 192*273a70aeSPeter Maydell return; 193*273a70aeSPeter Maydell } 194*273a70aeSPeter Maydell } 195*273a70aeSPeter Maydell g_assert_not_reached(); 196*273a70aeSPeter Maydell } 197*273a70aeSPeter Maydell 198*273a70aeSPeter Maydell static void mps3r_class_init(ObjectClass *oc, void *data) 199*273a70aeSPeter Maydell { 200*273a70aeSPeter Maydell MachineClass *mc = MACHINE_CLASS(oc); 201*273a70aeSPeter Maydell 202*273a70aeSPeter Maydell mc->init = mps3r_common_init; 203*273a70aeSPeter Maydell } 204*273a70aeSPeter Maydell 205*273a70aeSPeter Maydell static void mps3r_an536_class_init(ObjectClass *oc, void *data) 206*273a70aeSPeter Maydell { 207*273a70aeSPeter Maydell MachineClass *mc = MACHINE_CLASS(oc); 208*273a70aeSPeter Maydell MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc); 209*273a70aeSPeter Maydell static const char * const valid_cpu_types[] = { 210*273a70aeSPeter Maydell ARM_CPU_TYPE_NAME("cortex-r52"), 211*273a70aeSPeter Maydell NULL 212*273a70aeSPeter Maydell }; 213*273a70aeSPeter Maydell 214*273a70aeSPeter Maydell mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52"; 215*273a70aeSPeter Maydell mc->default_cpus = 2; 216*273a70aeSPeter Maydell mc->min_cpus = mc->default_cpus; 217*273a70aeSPeter Maydell mc->max_cpus = mc->default_cpus; 218*273a70aeSPeter Maydell mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52"); 219*273a70aeSPeter Maydell mc->valid_cpu_types = valid_cpu_types; 220*273a70aeSPeter Maydell mmc->raminfo = an536_raminfo; 221*273a70aeSPeter Maydell mps3r_set_default_ram_info(mmc); 222*273a70aeSPeter Maydell } 223*273a70aeSPeter Maydell 224*273a70aeSPeter Maydell static const TypeInfo mps3r_machine_types[] = { 225*273a70aeSPeter Maydell { 226*273a70aeSPeter Maydell .name = TYPE_MPS3R_MACHINE, 227*273a70aeSPeter Maydell .parent = TYPE_MACHINE, 228*273a70aeSPeter Maydell .abstract = true, 229*273a70aeSPeter Maydell .instance_size = sizeof(MPS3RMachineState), 230*273a70aeSPeter Maydell .class_size = sizeof(MPS3RMachineClass), 231*273a70aeSPeter Maydell .class_init = mps3r_class_init, 232*273a70aeSPeter Maydell }, { 233*273a70aeSPeter Maydell .name = TYPE_MPS3R_AN536_MACHINE, 234*273a70aeSPeter Maydell .parent = TYPE_MPS3R_MACHINE, 235*273a70aeSPeter Maydell .class_init = mps3r_an536_class_init, 236*273a70aeSPeter Maydell }, 237*273a70aeSPeter Maydell }; 238*273a70aeSPeter Maydell 239*273a70aeSPeter Maydell DEFINE_TYPES(mps3r_machine_types); 240