1*34602f99SAndreas Konopik /* 2*34602f99SAndreas Konopik * Infineon tc27x SoC System emulation. 3*34602f99SAndreas Konopik * 4*34602f99SAndreas Konopik * Copyright (c) 2020 Andreas Konopik <andreas.konopik@efs-auto.de> 5*34602f99SAndreas Konopik * Copyright (c) 2020 David Brenken <david.brenken@efs-auto.de> 6*34602f99SAndreas Konopik * 7*34602f99SAndreas Konopik * This library is free software; you can redistribute it and/or 8*34602f99SAndreas Konopik * modify it under the terms of the GNU Lesser General Public 9*34602f99SAndreas Konopik * License as published by the Free Software Foundation; either 10*34602f99SAndreas Konopik * version 2 of the License, or (at your option) any later version. 11*34602f99SAndreas Konopik * 12*34602f99SAndreas Konopik * This library is distributed in the hope that it will be useful, 13*34602f99SAndreas Konopik * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*34602f99SAndreas Konopik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*34602f99SAndreas Konopik * Lesser General Public License for more details. 16*34602f99SAndreas Konopik * 17*34602f99SAndreas Konopik * You should have received a copy of the GNU Lesser General Public 18*34602f99SAndreas Konopik * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19*34602f99SAndreas Konopik */ 20*34602f99SAndreas Konopik 21*34602f99SAndreas Konopik #include "qemu/osdep.h" 22*34602f99SAndreas Konopik #include "qapi/error.h" 23*34602f99SAndreas Konopik #include "hw/sysbus.h" 24*34602f99SAndreas Konopik #include "hw/boards.h" 25*34602f99SAndreas Konopik #include "hw/loader.h" 26*34602f99SAndreas Konopik #include "qemu/units.h" 27*34602f99SAndreas Konopik #include "hw/misc/unimp.h" 28*34602f99SAndreas Konopik #include "exec/address-spaces.h" 29*34602f99SAndreas Konopik #include "qemu/log.h" 30*34602f99SAndreas Konopik #include "cpu.h" 31*34602f99SAndreas Konopik 32*34602f99SAndreas Konopik #include "hw/tricore/tc27x_soc.h" 33*34602f99SAndreas Konopik #include "hw/tricore/triboard.h" 34*34602f99SAndreas Konopik 35*34602f99SAndreas Konopik const MemmapEntry tc27x_soc_memmap[] = { 36*34602f99SAndreas Konopik [TC27XD_DSPR2] = { 0x50000000, 120 * KiB }, 37*34602f99SAndreas Konopik [TC27XD_DCACHE2] = { 0x5001E000, 8 * KiB }, 38*34602f99SAndreas Konopik [TC27XD_DTAG2] = { 0x500C0000, 0xC00 }, 39*34602f99SAndreas Konopik [TC27XD_PSPR2] = { 0x50100000, 32 * KiB }, 40*34602f99SAndreas Konopik [TC27XD_PCACHE2] = { 0x50108000, 16 * KiB }, 41*34602f99SAndreas Konopik [TC27XD_PTAG2] = { 0x501C0000, 0x1800 }, 42*34602f99SAndreas Konopik [TC27XD_DSPR1] = { 0x60000000, 120 * KiB }, 43*34602f99SAndreas Konopik [TC27XD_DCACHE1] = { 0x6001E000, 8 * KiB }, 44*34602f99SAndreas Konopik [TC27XD_DTAG1] = { 0x600C0000, 0xC00 }, 45*34602f99SAndreas Konopik [TC27XD_PSPR1] = { 0x60100000, 32 * KiB }, 46*34602f99SAndreas Konopik [TC27XD_PCACHE1] = { 0x60108000, 16 * KiB }, 47*34602f99SAndreas Konopik [TC27XD_PTAG1] = { 0x601C0000, 0x1800 }, 48*34602f99SAndreas Konopik [TC27XD_DSPR0] = { 0x70000000, 112 * KiB }, 49*34602f99SAndreas Konopik [TC27XD_PSPR0] = { 0x70100000, 24 * KiB }, 50*34602f99SAndreas Konopik [TC27XD_PCACHE0] = { 0x70106000, 8 * KiB }, 51*34602f99SAndreas Konopik [TC27XD_PTAG0] = { 0x701C0000, 0xC00 }, 52*34602f99SAndreas Konopik [TC27XD_PFLASH0_C] = { 0x80000000, 2 * MiB }, 53*34602f99SAndreas Konopik [TC27XD_PFLASH1_C] = { 0x80200000, 2 * MiB }, 54*34602f99SAndreas Konopik [TC27XD_OLDA_C] = { 0x8FE70000, 32 * KiB }, 55*34602f99SAndreas Konopik [TC27XD_BROM_C] = { 0x8FFF8000, 32 * KiB }, 56*34602f99SAndreas Konopik [TC27XD_LMURAM_C] = { 0x90000000, 32 * KiB }, 57*34602f99SAndreas Konopik [TC27XD_EMEM_C] = { 0x9F000000, 1 * MiB }, 58*34602f99SAndreas Konopik [TC27XD_PFLASH0_U] = { 0xA0000000, 0x0 }, 59*34602f99SAndreas Konopik [TC27XD_PFLASH1_U] = { 0xA0200000, 0x0 }, 60*34602f99SAndreas Konopik [TC27XD_DFLASH0] = { 0xAF000000, 1 * MiB + 16 * KiB }, 61*34602f99SAndreas Konopik [TC27XD_DFLASH1] = { 0xAF110000, 64 * KiB }, 62*34602f99SAndreas Konopik [TC27XD_OLDA_U] = { 0xAFE70000, 0x0 }, 63*34602f99SAndreas Konopik [TC27XD_BROM_U] = { 0xAFFF8000, 0x0 }, 64*34602f99SAndreas Konopik [TC27XD_LMURAM_U] = { 0xB0000000, 0x0 }, 65*34602f99SAndreas Konopik [TC27XD_EMEM_U] = { 0xBF000000, 0x0 }, 66*34602f99SAndreas Konopik [TC27XD_PSPRX] = { 0xC0000000, 0x0 }, 67*34602f99SAndreas Konopik [TC27XD_DSPRX] = { 0xD0000000, 0x0 }, 68*34602f99SAndreas Konopik }; 69*34602f99SAndreas Konopik 70*34602f99SAndreas Konopik /* 71*34602f99SAndreas Konopik * Initialize the auxiliary ROM region @mr and map it into 72*34602f99SAndreas Konopik * the memory map at @base. 73*34602f99SAndreas Konopik */ 74*34602f99SAndreas Konopik static void make_rom(MemoryRegion *mr, const char *name, 75*34602f99SAndreas Konopik hwaddr base, hwaddr size) 76*34602f99SAndreas Konopik { 77*34602f99SAndreas Konopik memory_region_init_rom(mr, NULL, name, size, &error_fatal); 78*34602f99SAndreas Konopik memory_region_add_subregion(get_system_memory(), base, mr); 79*34602f99SAndreas Konopik } 80*34602f99SAndreas Konopik 81*34602f99SAndreas Konopik /* 82*34602f99SAndreas Konopik * Initialize the auxiliary RAM region @mr and map it into 83*34602f99SAndreas Konopik * the memory map at @base. 84*34602f99SAndreas Konopik */ 85*34602f99SAndreas Konopik static void make_ram(MemoryRegion *mr, const char *name, 86*34602f99SAndreas Konopik hwaddr base, hwaddr size) 87*34602f99SAndreas Konopik { 88*34602f99SAndreas Konopik memory_region_init_ram(mr, NULL, name, size, &error_fatal); 89*34602f99SAndreas Konopik memory_region_add_subregion(get_system_memory(), base, mr); 90*34602f99SAndreas Konopik } 91*34602f99SAndreas Konopik 92*34602f99SAndreas Konopik /* 93*34602f99SAndreas Konopik * Create an alias of an entire original MemoryRegion @orig 94*34602f99SAndreas Konopik * located at @base in the memory map. 95*34602f99SAndreas Konopik */ 96*34602f99SAndreas Konopik static void make_alias(MemoryRegion *mr, const char *name, 97*34602f99SAndreas Konopik MemoryRegion *orig, hwaddr base) 98*34602f99SAndreas Konopik { 99*34602f99SAndreas Konopik memory_region_init_alias(mr, NULL, name, orig, 0, 100*34602f99SAndreas Konopik memory_region_size(orig)); 101*34602f99SAndreas Konopik memory_region_add_subregion(get_system_memory(), base, mr); 102*34602f99SAndreas Konopik } 103*34602f99SAndreas Konopik 104*34602f99SAndreas Konopik static void tc27x_soc_init_memory_mapping(DeviceState *dev_soc) 105*34602f99SAndreas Konopik { 106*34602f99SAndreas Konopik TC27XSoCState *s = TC27X_SOC(dev_soc); 107*34602f99SAndreas Konopik TC27XSoCClass *sc = TC27X_SOC_GET_CLASS(s); 108*34602f99SAndreas Konopik 109*34602f99SAndreas Konopik make_ram(&s->cpu0mem.dspr, "CPU0.DSPR", 110*34602f99SAndreas Konopik sc->memmap[TC27XD_DSPR0].base, sc->memmap[TC27XD_DSPR0].size); 111*34602f99SAndreas Konopik make_ram(&s->cpu0mem.pspr, "CPU0.PSPR", 112*34602f99SAndreas Konopik sc->memmap[TC27XD_PSPR0].base, sc->memmap[TC27XD_PSPR0].size); 113*34602f99SAndreas Konopik make_ram(&s->cpu1mem.dspr, "CPU1.DSPR", 114*34602f99SAndreas Konopik sc->memmap[TC27XD_DSPR1].base, sc->memmap[TC27XD_DSPR1].size); 115*34602f99SAndreas Konopik make_ram(&s->cpu1mem.pspr, "CPU1.PSPR", 116*34602f99SAndreas Konopik sc->memmap[TC27XD_PSPR1].base, sc->memmap[TC27XD_PSPR1].size); 117*34602f99SAndreas Konopik make_ram(&s->cpu2mem.dspr, "CPU2.DSPR", 118*34602f99SAndreas Konopik sc->memmap[TC27XD_DSPR2].base, sc->memmap[TC27XD_DSPR2].size); 119*34602f99SAndreas Konopik make_ram(&s->cpu2mem.pspr, "CPU2.PSPR", 120*34602f99SAndreas Konopik sc->memmap[TC27XD_PSPR2].base, sc->memmap[TC27XD_PSPR2].size); 121*34602f99SAndreas Konopik 122*34602f99SAndreas Konopik /* TODO: Control Cache mapping with Memory Test Unit (MTU) */ 123*34602f99SAndreas Konopik make_ram(&s->cpu2mem.dcache, "CPU2.DCACHE", 124*34602f99SAndreas Konopik sc->memmap[TC27XD_DCACHE2].base, sc->memmap[TC27XD_DCACHE2].size); 125*34602f99SAndreas Konopik make_ram(&s->cpu2mem.dtag, "CPU2.DTAG", 126*34602f99SAndreas Konopik sc->memmap[TC27XD_DTAG2].base, sc->memmap[TC27XD_DTAG2].size); 127*34602f99SAndreas Konopik make_ram(&s->cpu2mem.pcache, "CPU2.PCACHE", 128*34602f99SAndreas Konopik sc->memmap[TC27XD_PCACHE2].base, sc->memmap[TC27XD_PCACHE2].size); 129*34602f99SAndreas Konopik make_ram(&s->cpu2mem.ptag, "CPU2.PTAG", 130*34602f99SAndreas Konopik sc->memmap[TC27XD_PTAG2].base, sc->memmap[TC27XD_PTAG2].size); 131*34602f99SAndreas Konopik 132*34602f99SAndreas Konopik make_ram(&s->cpu1mem.dcache, "CPU1.DCACHE", 133*34602f99SAndreas Konopik sc->memmap[TC27XD_DCACHE1].base, sc->memmap[TC27XD_DCACHE1].size); 134*34602f99SAndreas Konopik make_ram(&s->cpu1mem.dtag, "CPU1.DTAG", 135*34602f99SAndreas Konopik sc->memmap[TC27XD_DTAG1].base, sc->memmap[TC27XD_DTAG1].size); 136*34602f99SAndreas Konopik make_ram(&s->cpu1mem.pcache, "CPU1.PCACHE", 137*34602f99SAndreas Konopik sc->memmap[TC27XD_PCACHE1].base, sc->memmap[TC27XD_PCACHE1].size); 138*34602f99SAndreas Konopik make_ram(&s->cpu1mem.ptag, "CPU1.PTAG", 139*34602f99SAndreas Konopik sc->memmap[TC27XD_PTAG1].base, sc->memmap[TC27XD_PTAG1].size); 140*34602f99SAndreas Konopik 141*34602f99SAndreas Konopik make_ram(&s->cpu0mem.pcache, "CPU0.PCACHE", 142*34602f99SAndreas Konopik sc->memmap[TC27XD_PCACHE0].base, sc->memmap[TC27XD_PCACHE0].size); 143*34602f99SAndreas Konopik make_ram(&s->cpu0mem.ptag, "CPU0.PTAG", 144*34602f99SAndreas Konopik sc->memmap[TC27XD_PTAG0].base, sc->memmap[TC27XD_PTAG0].size); 145*34602f99SAndreas Konopik 146*34602f99SAndreas Konopik /* 147*34602f99SAndreas Konopik * TriCore QEMU executes CPU0 only, thus it is sufficient to map 148*34602f99SAndreas Konopik * LOCAL.PSPR/LOCAL.DSPR exclusively onto PSPR0/DSPR0. 149*34602f99SAndreas Konopik */ 150*34602f99SAndreas Konopik make_alias(&s->psprX, "LOCAL.PSPR", &s->cpu0mem.pspr, 151*34602f99SAndreas Konopik sc->memmap[TC27XD_PSPRX].base); 152*34602f99SAndreas Konopik make_alias(&s->dsprX, "LOCAL.DSPR", &s->cpu0mem.dspr, 153*34602f99SAndreas Konopik sc->memmap[TC27XD_DSPRX].base); 154*34602f99SAndreas Konopik 155*34602f99SAndreas Konopik make_ram(&s->flashmem.pflash0_c, "PF0", 156*34602f99SAndreas Konopik sc->memmap[TC27XD_PFLASH0_C].base, sc->memmap[TC27XD_PFLASH0_C].size); 157*34602f99SAndreas Konopik make_ram(&s->flashmem.pflash1_c, "PF1", 158*34602f99SAndreas Konopik sc->memmap[TC27XD_PFLASH1_C].base, sc->memmap[TC27XD_PFLASH1_C].size); 159*34602f99SAndreas Konopik make_ram(&s->flashmem.dflash0, "DF0", 160*34602f99SAndreas Konopik sc->memmap[TC27XD_DFLASH0].base, sc->memmap[TC27XD_DFLASH0].size); 161*34602f99SAndreas Konopik make_ram(&s->flashmem.dflash1, "DF1", 162*34602f99SAndreas Konopik sc->memmap[TC27XD_DFLASH1].base, sc->memmap[TC27XD_DFLASH1].size); 163*34602f99SAndreas Konopik make_ram(&s->flashmem.olda_c, "OLDA", 164*34602f99SAndreas Konopik sc->memmap[TC27XD_OLDA_C].base, sc->memmap[TC27XD_OLDA_C].size); 165*34602f99SAndreas Konopik make_rom(&s->flashmem.brom_c, "BROM", 166*34602f99SAndreas Konopik sc->memmap[TC27XD_BROM_C].base, sc->memmap[TC27XD_BROM_C].size); 167*34602f99SAndreas Konopik make_ram(&s->flashmem.lmuram_c, "LMURAM", 168*34602f99SAndreas Konopik sc->memmap[TC27XD_LMURAM_C].base, sc->memmap[TC27XD_LMURAM_C].size); 169*34602f99SAndreas Konopik make_ram(&s->flashmem.emem_c, "EMEM", 170*34602f99SAndreas Konopik sc->memmap[TC27XD_EMEM_C].base, sc->memmap[TC27XD_EMEM_C].size); 171*34602f99SAndreas Konopik 172*34602f99SAndreas Konopik make_alias(&s->flashmem.pflash0_u, "PF0.U", &s->flashmem.pflash0_c, 173*34602f99SAndreas Konopik sc->memmap[TC27XD_PFLASH0_U].base); 174*34602f99SAndreas Konopik make_alias(&s->flashmem.pflash1_u, "PF1.U", &s->flashmem.pflash1_c, 175*34602f99SAndreas Konopik sc->memmap[TC27XD_PFLASH1_U].base); 176*34602f99SAndreas Konopik make_alias(&s->flashmem.olda_u, "OLDA.U", &s->flashmem.olda_c, 177*34602f99SAndreas Konopik sc->memmap[TC27XD_OLDA_U].base); 178*34602f99SAndreas Konopik make_alias(&s->flashmem.brom_u, "BROM.U", &s->flashmem.brom_c, 179*34602f99SAndreas Konopik sc->memmap[TC27XD_BROM_U].base); 180*34602f99SAndreas Konopik make_alias(&s->flashmem.lmuram_u, "LMURAM.U", &s->flashmem.lmuram_c, 181*34602f99SAndreas Konopik sc->memmap[TC27XD_LMURAM_U].base); 182*34602f99SAndreas Konopik make_alias(&s->flashmem.emem_u, "EMEM.U", &s->flashmem.emem_c, 183*34602f99SAndreas Konopik sc->memmap[TC27XD_EMEM_U].base); 184*34602f99SAndreas Konopik } 185*34602f99SAndreas Konopik 186*34602f99SAndreas Konopik static void tc27x_soc_realize(DeviceState *dev_soc, Error **errp) 187*34602f99SAndreas Konopik { 188*34602f99SAndreas Konopik TC27XSoCState *s = TC27X_SOC(dev_soc); 189*34602f99SAndreas Konopik Error *err = NULL; 190*34602f99SAndreas Konopik 191*34602f99SAndreas Konopik qdev_realize(DEVICE(&s->cpu), NULL, &err); 192*34602f99SAndreas Konopik if (err) { 193*34602f99SAndreas Konopik error_propagate(errp, err); 194*34602f99SAndreas Konopik return; 195*34602f99SAndreas Konopik } 196*34602f99SAndreas Konopik 197*34602f99SAndreas Konopik tc27x_soc_init_memory_mapping(dev_soc); 198*34602f99SAndreas Konopik } 199*34602f99SAndreas Konopik 200*34602f99SAndreas Konopik static void tc27x_soc_init(Object *obj) 201*34602f99SAndreas Konopik { 202*34602f99SAndreas Konopik TC27XSoCState *s = TC27X_SOC(obj); 203*34602f99SAndreas Konopik TC27XSoCClass *sc = TC27X_SOC_GET_CLASS(s); 204*34602f99SAndreas Konopik 205*34602f99SAndreas Konopik object_initialize_child(obj, "tc27x", &s->cpu, sc->cpu_type); 206*34602f99SAndreas Konopik } 207*34602f99SAndreas Konopik 208*34602f99SAndreas Konopik static Property tc27x_soc_properties[] = { 209*34602f99SAndreas Konopik DEFINE_PROP_END_OF_LIST(), 210*34602f99SAndreas Konopik }; 211*34602f99SAndreas Konopik 212*34602f99SAndreas Konopik static void tc27x_soc_class_init(ObjectClass *klass, void *data) 213*34602f99SAndreas Konopik { 214*34602f99SAndreas Konopik DeviceClass *dc = DEVICE_CLASS(klass); 215*34602f99SAndreas Konopik 216*34602f99SAndreas Konopik dc->realize = tc27x_soc_realize; 217*34602f99SAndreas Konopik device_class_set_props(dc, tc27x_soc_properties); 218*34602f99SAndreas Konopik } 219*34602f99SAndreas Konopik 220*34602f99SAndreas Konopik static void tc277d_soc_class_init(ObjectClass *oc, void *data) 221*34602f99SAndreas Konopik { 222*34602f99SAndreas Konopik TC27XSoCClass *sc = TC27X_SOC_CLASS(oc); 223*34602f99SAndreas Konopik 224*34602f99SAndreas Konopik sc->name = "tc277d-soc"; 225*34602f99SAndreas Konopik sc->cpu_type = TRICORE_CPU_TYPE_NAME("tc27x"); 226*34602f99SAndreas Konopik sc->memmap = tc27x_soc_memmap; 227*34602f99SAndreas Konopik sc->num_cpus = 1; 228*34602f99SAndreas Konopik } 229*34602f99SAndreas Konopik 230*34602f99SAndreas Konopik static const TypeInfo tc27x_soc_types[] = { 231*34602f99SAndreas Konopik { 232*34602f99SAndreas Konopik .name = "tc277d-soc", 233*34602f99SAndreas Konopik .parent = TYPE_TC27X_SOC, 234*34602f99SAndreas Konopik .class_init = tc277d_soc_class_init, 235*34602f99SAndreas Konopik }, { 236*34602f99SAndreas Konopik .name = TYPE_TC27X_SOC, 237*34602f99SAndreas Konopik .parent = TYPE_SYS_BUS_DEVICE, 238*34602f99SAndreas Konopik .instance_size = sizeof(TC27XSoCState), 239*34602f99SAndreas Konopik .instance_init = tc27x_soc_init, 240*34602f99SAndreas Konopik .class_size = sizeof(TC27XSoCClass), 241*34602f99SAndreas Konopik .class_init = tc27x_soc_class_init, 242*34602f99SAndreas Konopik .abstract = true, 243*34602f99SAndreas Konopik }, 244*34602f99SAndreas Konopik }; 245*34602f99SAndreas Konopik 246*34602f99SAndreas Konopik DEFINE_TYPES(tc27x_soc_types) 247