qemu/hw/misc/xilinx_zynqmp_rpu_ctrl.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the RPU Realtime Processing Unit
   3 *
   4 * Copyright (c) 2014 Xilinx Inc.
   5 *
   6 * Autogenerated by xregqemu.py 2014-02-05.
   7 * Updated by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
   8 * Updated by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
   9 *
  10 * Permission is hereby granted, free of charge, to any person obtaining a copy
  11 * of this software and associated documentation files (the "Software"), to deal
  12 * in the Software without restriction, including without limitation the rights
  13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14 * copies of the Software, and to permit persons to whom the Software is
  15 * furnished to do so, subject to the following conditions:
  16 *
  17 * The above copyright notice and this permission notice shall be included in
  18 * all copies or substantial portions of the Software.
  19 *
  20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26 * THE SOFTWARE.
  27 */
  28
  29#include "qemu/osdep.h"
  30#include "hw/sysbus.h"
  31#include "hw/register.h"
  32#include "qemu/bitops.h"
  33#include "qapi/error.h"
  34#include "qemu/log.h"
  35#include "qapi/qmp/qerror.h"
  36
  37#include "hw/fdt_generic_util.h"
  38#include "hw/intc/xlnx_scu_gic.h"
  39
  40#ifndef XILINX_RPU_ERR_DEBUG
  41#define XILINX_RPU_ERR_DEBUG 0
  42#endif
  43
  44#define TYPE_XILINX_RPU "xlnx.rpu-control"
  45
  46#define XILINX_RPU(obj) \
  47     OBJECT_CHECK(RPU, (obj), TYPE_XILINX_RPU)
  48
  49REG32(RPU_GLBL_CNTL, 0x0)
  50    FIELD(RPU_GLBL_CNTL, GIC_AXPROT, 1, 10)
  51    FIELD(RPU_GLBL_CNTL, SLRESETN, 1, 9)
  52    FIELD(RPU_GLBL_CNTL, TCM_CLK_CNTL, 1, 8)
  53    FIELD(RPU_GLBL_CNTL, TCM_WAIT, 1, 7)
  54    FIELD(RPU_GLBL_CNTL, TCM_COMB, 1, 6)
  55    FIELD(RPU_GLBL_CNTL, TEINIT, 1, 5)
  56    FIELD(RPU_GLBL_CNTL, SLCLAMP, 1, 4)
  57    FIELD(RPU_GLBL_CNTL, SLSPLIT, 1, 3)
  58    FIELD(RPU_GLBL_CNTL, DBGNOCLKSTOP, 1, 2)
  59    FIELD(RPU_GLBL_CNTL, CFGIE, 1, 1)
  60    FIELD(RPU_GLBL_CNTL, CFGEE, 1, 0)
  61REG32(RPU_GLBL_STATUS, 0x4)
  62    FIELD(RPU_GLBL_STATUS, DBGNOPWRDWN, 1, 0)
  63REG32(RPU_ERR_CNTL, 0x8)
  64    FIELD(RPU_ERR_CNTL, APB_ERR_RES, 1, 0)
  65REG32(RPU_RAM, 0xc)
  66    FIELD(RPU_RAM, RAMCONTROL1, 8, 8)
  67    FIELD(RPU_RAM, RAMCONTROL0, 8, 0)
  68REG32(RPU_CACHE_DATA, 0x10)
  69    FIELD(RPU_CACHE_DATA, DDIRTY_EMAS, 1, 29)
  70    FIELD(RPU_CACHE_DATA, DDIRTY_EMAW, 2, 27)
  71    FIELD(RPU_CACHE_DATA, DDIRTY_EMA, 3, 24)
  72    FIELD(RPU_CACHE_DATA, DTAG_EMAS, 1, 23)
  73    FIELD(RPU_CACHE_DATA, DTAG_EMAW, 2, 21)
  74    FIELD(RPU_CACHE_DATA, DTAG_EMA, 3, 18)
  75    FIELD(RPU_CACHE_DATA, DDATA_EMAS, 1, 17)
  76    FIELD(RPU_CACHE_DATA, DDATA_EMAW, 2, 15)
  77    FIELD(RPU_CACHE_DATA, DDATA_EMA, 3, 12)
  78    FIELD(RPU_CACHE_DATA, ITAG_EMAS, 1, 11)
  79    FIELD(RPU_CACHE_DATA, ITAG_EMAW, 2, 9)
  80    FIELD(RPU_CACHE_DATA, ITAG_EMA, 3, 6)
  81    FIELD(RPU_CACHE_DATA, IDATA_EMAS, 1, 5)
  82    FIELD(RPU_CACHE_DATA, IDATA_EMAW, 2, 3)
  83    FIELD(RPU_CACHE_DATA, IDATA_EMA, 3, 0)
  84REG32(RPU_CACHE_SYN, 0x14)
  85    FIELD(RPU_CACHE_SYN, DDIRTY_EMAS, 1, 29)
  86    FIELD(RPU_CACHE_SYN, DDIRTY_EMAW, 2, 27)
  87    FIELD(RPU_CACHE_SYN, DDIRTY_EMA, 3, 24)
  88    FIELD(RPU_CACHE_SYN, DTAG_EMAS, 1, 23)
  89    FIELD(RPU_CACHE_SYN, DTAG_EMAW, 2, 21)
  90    FIELD(RPU_CACHE_SYN, DTAG_EMA, 3, 18)
  91    FIELD(RPU_CACHE_SYN, DDATA_EMAS, 1, 17)
  92    FIELD(RPU_CACHE_SYN, DDATA_EMAW, 2, 15)
  93    FIELD(RPU_CACHE_SYN, DDATA_EMA, 3, 12)
  94    FIELD(RPU_CACHE_SYN, ITAG_EMAS, 1, 11)
  95    FIELD(RPU_CACHE_SYN, ITAG_EMAW, 2, 9)
  96    FIELD(RPU_CACHE_SYN, ITAG_EMA, 3, 6)
  97    FIELD(RPU_CACHE_SYN, IDATA_EMAS, 1, 5)
  98    FIELD(RPU_CACHE_SYN, IDATA_EMAW, 2, 3)
  99    FIELD(RPU_CACHE_SYN, IDATA_EMA, 3, 0)
 100REG32(RPU_TCM_DATA, 0x18)
 101    FIELD(RPU_TCM_DATA, B_EMAS, 1, 17)
 102    FIELD(RPU_TCM_DATA, B_EMAW, 2, 15)
 103    FIELD(RPU_TCM_DATA, B_EMA, 3, 12)
 104    FIELD(RPU_TCM_DATA, A_EMAS, 1, 5)
 105    FIELD(RPU_TCM_DATA, A_EMAW, 2, 3)
 106    FIELD(RPU_TCM_DATA, A_EMA, 3, 0)
 107REG32(RPU_TCM_SYN, 0x1c)
 108    FIELD(RPU_TCM_SYN, B_EMAS, 1, 23)
 109    FIELD(RPU_TCM_SYN, B_EMAW, 2, 21)
 110    FIELD(RPU_TCM_SYN, B_EMA, 3, 18)
 111    FIELD(RPU_TCM_SYN, A_EMAS, 1, 11)
 112    FIELD(RPU_TCM_SYN, A_EMAW, 2, 9)
 113    FIELD(RPU_TCM_SYN, A_EMA, 3, 6)
 114REG32(RPU_ERR_INJ, 0x20)
 115    FIELD(RPU_ERR_INJ, DCCMINP2, 8, 8)
 116    FIELD(RPU_ERR_INJ, DCCMINP, 8, 0)
 117REG32(RPU_CCF_MASK, 0x24)
 118    FIELD(RPU_CCF_MASK, TEST_MBIST_MODE, 1, 7)
 119    FIELD(RPU_CCF_MASK, TEST_SCAN_MODE_LP, 1, 6)
 120    FIELD(RPU_CCF_MASK, TEST_SCAN_MODE, 1, 5)
 121    FIELD(RPU_CCF_MASK, ISO, 1, 4)
 122    FIELD(RPU_CCF_MASK, PGE, 1, 3)
 123    FIELD(RPU_CCF_MASK, R50_DBG_RST, 1, 2)
 124    FIELD(RPU_CCF_MASK, R50_RST, 1, 1)
 125    FIELD(RPU_CCF_MASK, PGE_RST, 1, 0)
 126REG32(RPU_INTR_0, 0x28)
 127REG32(RPU_INTR_1, 0x2c)
 128REG32(RPU_INTR_2, 0x30)
 129REG32(RPU_INTR_3, 0x34)
 130REG32(RPU_INTR_4, 0x38)
 131REG32(RPU_INTR_MASK_0, 0x40)
 132REG32(RPU_INTR_MASK_1, 0x44)
 133REG32(RPU_INTR_MASK_2, 0x48)
 134REG32(RPU_INTR_MASK_3, 0x4c)
 135REG32(RPU_INTR_MASK_4, 0x50)
 136REG32(RPU_CCF_VAL, 0x54)
 137    FIELD(RPU_CCF_VAL, TEST_MBIST_MODE, 1, 7)
 138    FIELD(RPU_CCF_VAL, TEST_SCAN_MODE_LP, 1, 6)
 139    FIELD(RPU_CCF_VAL, TEST_SCAN_MODE, 1, 5)
 140    FIELD(RPU_CCF_VAL, ISO, 1, 4)
 141    FIELD(RPU_CCF_VAL, PGE, 1, 3)
 142    FIELD(RPU_CCF_VAL, R50_DBG_RST, 1, 2)
 143    FIELD(RPU_CCF_VAL, R50_RST, 1, 1)
 144    FIELD(RPU_CCF_VAL, PGE_RST, 1, 0)
 145REG32(RPU_SAFETY_CHK, 0xf0)
 146REG32(RPU, 0xf4)
 147REG32(RPU_0_CFG, 0x100)
 148    FIELD(RPU_0_CFG, CFGNMFI0, 1, 3)
 149    FIELD(RPU_0_CFG, VINITHI, 1, 2)
 150    FIELD(RPU_0_CFG, COHERENT, 1, 1)
 151    FIELD(RPU_0_CFG, NCPUHALT, 1, 0)
 152REG32(RPU_0_STATUS, 0x104)
 153    FIELD(RPU_0_STATUS, NVALRESET, 1, 5)
 154    FIELD(RPU_0_STATUS, NVALIRQ, 1, 4)
 155    FIELD(RPU_0_STATUS, NVALFIQ, 1, 3)
 156    FIELD(RPU_0_STATUS, NWFIPIPESTOPPED, 1, 2)
 157    FIELD(RPU_0_STATUS, NWFEPIPESTOPPED, 1, 1)
 158    FIELD(RPU_0_STATUS, NCLKSTOPPED, 1, 0)
 159REG32(RPU_0_PWRDWN, 0x108)
 160    FIELD(RPU_0_PWRDWN, EN, 1, 0)
 161REG32(RPU_0_ISR, 0x114)
 162    FIELD(RPU_0_ISR, FPUFC, 1, 24)
 163    FIELD(RPU_0_ISR, FPOFC, 1, 23)
 164    FIELD(RPU_0_ISR, FPIXC, 1, 22)
 165    FIELD(RPU_0_ISR, FPIOC, 1, 21)
 166    FIELD(RPU_0_ISR, FPIDC, 1, 20)
 167    FIELD(RPU_0_ISR, FPDZC, 1, 19)
 168    FIELD(RPU_0_ISR, TCM_ASLV_CE, 1, 18)
 169    FIELD(RPU_0_ISR, TCM_ASLV_FAT, 1, 17)
 170    FIELD(RPU_0_ISR, TCM_LST_CE, 1, 16)
 171    FIELD(RPU_0_ISR, TCM_PREFETCH_CE, 1, 15)
 172    FIELD(RPU_0_ISR, B1TCM_CE, 1, 14)
 173    FIELD(RPU_0_ISR, B0TCM_CE, 1, 13)
 174    FIELD(RPU_0_ISR, ATCM_CE, 1, 12)
 175    FIELD(RPU_0_ISR, B1TCM_UE, 1, 11)
 176    FIELD(RPU_0_ISR, B0TCM_UE, 1, 10)
 177    FIELD(RPU_0_ISR, ATCM_UE, 1, 9)
 178    FIELD(RPU_0_ISR, DTAG_DIRTY_FAT, 1, 8)
 179    FIELD(RPU_0_ISR, DDATA_FAT, 1, 7)
 180    FIELD(RPU_0_ISR, TCM_LST_FAT, 1, 6)
 181    FIELD(RPU_0_ISR, TCM_PREFETCH_FAT, 1, 5)
 182    FIELD(RPU_0_ISR, DDATA_CE, 1, 4)
 183    FIELD(RPU_0_ISR, DTAG_DIRTY_CE, 1, 3)
 184    FIELD(RPU_0_ISR, IDATA_CE, 1, 2)
 185    FIELD(RPU_0_ISR, ITAG_CE, 1, 1)
 186    FIELD(RPU_0_ISR, APB_ERR, 1, 0)
 187REG32(RPU_0_IMR, 0x118)
 188    FIELD(RPU_0_IMR, FPUFC, 1, 24)
 189    FIELD(RPU_0_IMR, FPOFC, 1, 23)
 190    FIELD(RPU_0_IMR, FPIXC, 1, 22)
 191    FIELD(RPU_0_IMR, FPIOC, 1, 21)
 192    FIELD(RPU_0_IMR, FPIDC, 1, 20)
 193    FIELD(RPU_0_IMR, FPDZC, 1, 19)
 194    FIELD(RPU_0_IMR, TCM_ASLV_CE, 1, 18)
 195    FIELD(RPU_0_IMR, TCM_ASLV_FAT, 1, 17)
 196    FIELD(RPU_0_IMR, TCM_LST_CE, 1, 16)
 197    FIELD(RPU_0_IMR, TCM_PREFETCH_CE, 1, 15)
 198    FIELD(RPU_0_IMR, B1TCM_CE, 1, 14)
 199    FIELD(RPU_0_IMR, B0TCM_CE, 1, 13)
 200    FIELD(RPU_0_IMR, ATCM_CE, 1, 12)
 201    FIELD(RPU_0_IMR, B1TCM_UE, 1, 11)
 202    FIELD(RPU_0_IMR, B0TCM_UE, 1, 10)
 203    FIELD(RPU_0_IMR, ATCM_UE, 1, 9)
 204    FIELD(RPU_0_IMR, DTAG_DIRTY_FAT, 1, 8)
 205    FIELD(RPU_0_IMR, DDATA_FAT, 1, 7)
 206    FIELD(RPU_0_IMR, TCM_LST_FAT, 1, 6)
 207    FIELD(RPU_0_IMR, TCM_PREFETCH_FAT, 1, 5)
 208    FIELD(RPU_0_IMR, DDATA_CE, 1, 4)
 209    FIELD(RPU_0_IMR, DTAG_DIRTY_CE, 1, 3)
 210    FIELD(RPU_0_IMR, IDATA_CE, 1, 2)
 211    FIELD(RPU_0_IMR, ITAG_CE, 1, 1)
 212    FIELD(RPU_0_IMR, APB_ERR, 1, 0)
 213REG32(RPU_0_IEN, 0x11c)
 214    FIELD(RPU_0_IEN, FPUFC, 1, 24)
 215    FIELD(RPU_0_IEN, FPOFC, 1, 23)
 216    FIELD(RPU_0_IEN, FPIXC, 1, 22)
 217    FIELD(RPU_0_IEN, FPIOC, 1, 21)
 218    FIELD(RPU_0_IEN, FPIDC, 1, 20)
 219    FIELD(RPU_0_IEN, FPDZC, 1, 19)
 220    FIELD(RPU_0_IEN, TCM_ASLV_CE, 1, 18)
 221    FIELD(RPU_0_IEN, TCM_ASLV_FAT, 1, 17)
 222    FIELD(RPU_0_IEN, TCM_LST_CE, 1, 16)
 223    FIELD(RPU_0_IEN, TCM_PREFETCH_CE, 1, 15)
 224    FIELD(RPU_0_IEN, B1TCM_CE, 1, 14)
 225    FIELD(RPU_0_IEN, B0TCM_CE, 1, 13)
 226    FIELD(RPU_0_IEN, ATCM_CE, 1, 12)
 227    FIELD(RPU_0_IEN, B1TCM_UE, 1, 11)
 228    FIELD(RPU_0_IEN, B0TCM_UE, 1, 10)
 229    FIELD(RPU_0_IEN, ATCM_UE, 1, 9)
 230    FIELD(RPU_0_IEN, DTAG_DIRTY_FAT, 1, 8)
 231    FIELD(RPU_0_IEN, DDATA_FAT, 1, 7)
 232    FIELD(RPU_0_IEN, TCM_LST_FAT, 1, 6)
 233    FIELD(RPU_0_IEN, TCM_PREFETCH_FAT, 1, 5)
 234    FIELD(RPU_0_IEN, DDATA_CE, 1, 4)
 235    FIELD(RPU_0_IEN, DTAG_DIRTY_CE, 1, 3)
 236    FIELD(RPU_0_IEN, IDATA_CE, 1, 2)
 237    FIELD(RPU_0_IEN, ITAG_CE, 1, 1)
 238    FIELD(RPU_0_IEN, APB_ERR, 1, 0)
 239REG32(RPU_0_IDS, 0x120)
 240    FIELD(RPU_0_IDS, FPUFC, 1, 24)
 241    FIELD(RPU_0_IDS, FPOFC, 1, 23)
 242    FIELD(RPU_0_IDS, FPIXC, 1, 22)
 243    FIELD(RPU_0_IDS, FPIOC, 1, 21)
 244    FIELD(RPU_0_IDS, FPIDC, 1, 20)
 245    FIELD(RPU_0_IDS, FPDZC, 1, 19)
 246    FIELD(RPU_0_IDS, TCM_ASLV_CE, 1, 18)
 247    FIELD(RPU_0_IDS, TCM_ASLV_FAT, 1, 17)
 248    FIELD(RPU_0_IDS, TCM_LST_CE, 1, 16)
 249    FIELD(RPU_0_IDS, TCM_PREFETCH_CE, 1, 15)
 250    FIELD(RPU_0_IDS, B1TCM_CE, 1, 14)
 251    FIELD(RPU_0_IDS, B0TCM_CE, 1, 13)
 252    FIELD(RPU_0_IDS, ATCM_CE, 1, 12)
 253    FIELD(RPU_0_IDS, B1TCM_UE, 1, 11)
 254    FIELD(RPU_0_IDS, B0TCM_UE, 1, 10)
 255    FIELD(RPU_0_IDS, ATCM_UE, 1, 9)
 256    FIELD(RPU_0_IDS, DTAG_DIRTY_FAT, 1, 8)
 257    FIELD(RPU_0_IDS, DDATA_FAT, 1, 7)
 258    FIELD(RPU_0_IDS, TCM_LST_FAT, 1, 6)
 259    FIELD(RPU_0_IDS, TCM_PREFETCH_FAT, 1, 5)
 260    FIELD(RPU_0_IDS, DDATA_CE, 1, 4)
 261    FIELD(RPU_0_IDS, DTAG_DIRTY_CE, 1, 3)
 262    FIELD(RPU_0_IDS, IDATA_CE, 1, 2)
 263    FIELD(RPU_0_IDS, ITAG_CE, 1, 1)
 264    FIELD(RPU_0_IDS, APB_ERR, 1, 0)
 265REG32(RPU_0_SLV_BASE, 0x124)
 266    FIELD(RPU_0_SLV_BASE, ADDR, 8, 0)
 267REG32(RPU_0_AXI_OVER, 0x128)
 268    FIELD(RPU_0_AXI_OVER, AWCACHE, 4, 6)
 269    FIELD(RPU_0_AXI_OVER, ARCACHE, 4, 2)
 270    FIELD(RPU_0_AXI_OVER, AWCACHE_EN, 1, 1)
 271    FIELD(RPU_0_AXI_OVER, ARCACHE_EN, 1, 0)
 272REG32(RPU_1_CFG, 0x200)
 273    FIELD(RPU_1_CFG, CFGNMFI1, 1, 3)
 274    FIELD(RPU_1_CFG, VINITHI, 1, 2)
 275    FIELD(RPU_1_CFG, COHERENT, 1, 1)
 276    FIELD(RPU_1_CFG, NCPUHALT, 1, 0)
 277REG32(RPU_1_STATUS, 0x204)
 278    FIELD(RPU_1_STATUS, NVALRESET, 1, 5)
 279    FIELD(RPU_1_STATUS, NVALIRQ, 1, 4)
 280    FIELD(RPU_1_STATUS, NVALFIQ, 1, 3)
 281    FIELD(RPU_1_STATUS, NWFIPIPESTOPPED, 1, 2)
 282    FIELD(RPU_1_STATUS, NWFEPIPESTOPPED, 1, 1)
 283    FIELD(RPU_1_STATUS, NCLKSTOPPED, 1, 0)
 284REG32(RPU_1_PWRDWN, 0x208)
 285    FIELD(RPU_1_PWRDWN, EN, 1, 0)
 286REG32(RPU_1_ISR, 0x214)
 287    FIELD(RPU_1_ISR, FPUFC, 1, 24)
 288    FIELD(RPU_1_ISR, FPOFC, 1, 23)
 289    FIELD(RPU_1_ISR, FPIXC, 1, 22)
 290    FIELD(RPU_1_ISR, FPIOC, 1, 21)
 291    FIELD(RPU_1_ISR, FPIDC, 1, 20)
 292    FIELD(RPU_1_ISR, FPDZC, 1, 19)
 293    FIELD(RPU_1_ISR, TCM_ASLV_CE, 1, 18)
 294    FIELD(RPU_1_ISR, TCM_ASLV_FAT, 1, 17)
 295    FIELD(RPU_1_ISR, TCM_LST_CE, 1, 16)
 296    FIELD(RPU_1_ISR, TCM_PREFETCH_CE, 1, 15)
 297    FIELD(RPU_1_ISR, B1TCM_CE, 1, 14)
 298    FIELD(RPU_1_ISR, B0TCM_CE, 1, 13)
 299    FIELD(RPU_1_ISR, ATCM_CE, 1, 12)
 300    FIELD(RPU_1_ISR, B1TCM_UE, 1, 11)
 301    FIELD(RPU_1_ISR, B0TCM_UE, 1, 10)
 302    FIELD(RPU_1_ISR, ATCM_UE, 1, 9)
 303    FIELD(RPU_1_ISR, DTAG_DIRTY_FAT, 1, 8)
 304    FIELD(RPU_1_ISR, DDATA_FAT, 1, 7)
 305    FIELD(RPU_1_ISR, TCM_LST_FAT, 1, 6)
 306    FIELD(RPU_1_ISR, TCM_PREFETCH_FAT, 1, 5)
 307    FIELD(RPU_1_ISR, DDATA_CE, 1, 4)
 308    FIELD(RPU_1_ISR, DTAG_DIRTY_CE, 1, 3)
 309    FIELD(RPU_1_ISR, IDATA_CE, 1, 2)
 310    FIELD(RPU_1_ISR, ITAG_CE, 1, 1)
 311    FIELD(RPU_1_ISR, APB_ERR, 1, 0)
 312REG32(RPU_1_IMR, 0x218)
 313    FIELD(RPU_1_IMR, FPUFC, 1, 24)
 314    FIELD(RPU_1_IMR, FPOFC, 1, 23)
 315    FIELD(RPU_1_IMR, FPIXC, 1, 22)
 316    FIELD(RPU_1_IMR, FPIOC, 1, 21)
 317    FIELD(RPU_1_IMR, FPIDC, 1, 20)
 318    FIELD(RPU_1_IMR, FPDZC, 1, 19)
 319    FIELD(RPU_1_IMR, TCM_ASLV_CE, 1, 18)
 320    FIELD(RPU_1_IMR, TCM_ASLV_FAT, 1, 17)
 321    FIELD(RPU_1_IMR, TCM_LST_CE, 1, 16)
 322    FIELD(RPU_1_IMR, TCM_PREFETCH_CE, 1, 15)
 323    FIELD(RPU_1_IMR, B1TCM_CE, 1, 14)
 324    FIELD(RPU_1_IMR, B0TCM_CE, 1, 13)
 325    FIELD(RPU_1_IMR, ATCM_CE, 1, 12)
 326    FIELD(RPU_1_IMR, B1TCM_UE, 1, 11)
 327    FIELD(RPU_1_IMR, B0TCM_UE, 1, 10)
 328    FIELD(RPU_1_IMR, ATCM_UE, 1, 9)
 329    FIELD(RPU_1_IMR, DTAG_DIRTY_FAT, 1, 8)
 330    FIELD(RPU_1_IMR, DDATA_FAT, 1, 7)
 331    FIELD(RPU_1_IMR, TCM_LST_FAT, 1, 6)
 332    FIELD(RPU_1_IMR, TCM_PREFETCH_FAT, 1, 5)
 333    FIELD(RPU_1_IMR, DDATA_CE, 1, 4)
 334    FIELD(RPU_1_IMR, DTAG_DIRTY_CE, 1, 3)
 335    FIELD(RPU_1_IMR, IDATA_CE, 1, 2)
 336    FIELD(RPU_1_IMR, ITAG_CE, 1, 1)
 337    FIELD(RPU_1_IMR, APB_ERR, 1, 0)
 338REG32(RPU_1_IEN, 0x21c)
 339    FIELD(RPU_1_IEN, FPUFC, 1, 24)
 340    FIELD(RPU_1_IEN, FPOFC, 1, 23)
 341    FIELD(RPU_1_IEN, FPIXC, 1, 22)
 342    FIELD(RPU_1_IEN, FPIOC, 1, 21)
 343    FIELD(RPU_1_IEN, FPIDC, 1, 20)
 344    FIELD(RPU_1_IEN, FPDZC, 1, 19)
 345    FIELD(RPU_1_IEN, TCM_ASLV_CE, 1, 18)
 346    FIELD(RPU_1_IEN, TCM_ASLV_FAT, 1, 17)
 347    FIELD(RPU_1_IEN, TCM_LST_CE, 1, 16)
 348    FIELD(RPU_1_IEN, TCM_PREFETCH_CE, 1, 15)
 349    FIELD(RPU_1_IEN, B1TCM_CE, 1, 14)
 350    FIELD(RPU_1_IEN, B0TCM_CE, 1, 13)
 351    FIELD(RPU_1_IEN, ATCM_CE, 1, 12)
 352    FIELD(RPU_1_IEN, B1TCM_UE, 1, 11)
 353    FIELD(RPU_1_IEN, B0TCM_UE, 1, 10)
 354    FIELD(RPU_1_IEN, ATCM_UE, 1, 9)
 355    FIELD(RPU_1_IEN, DTAG_DIRTY_FAT, 1, 8)
 356    FIELD(RPU_1_IEN, DDATA_FAT, 1, 7)
 357    FIELD(RPU_1_IEN, TCM_LST_FAT, 1, 6)
 358    FIELD(RPU_1_IEN, TCM_PREFETCH_FAT, 1, 5)
 359    FIELD(RPU_1_IEN, DDATA_CE, 1, 4)
 360    FIELD(RPU_1_IEN, DTAG_DIRTY_CE, 1, 3)
 361    FIELD(RPU_1_IEN, IDATA_CE, 1, 2)
 362    FIELD(RPU_1_IEN, ITAG_CE, 1, 1)
 363    FIELD(RPU_1_IEN, APB_ERR, 1, 0)
 364REG32(RPU_1_IDS, 0x220)
 365    FIELD(RPU_1_IDS, FPUFC, 1, 24)
 366    FIELD(RPU_1_IDS, FPOFC, 1, 23)
 367    FIELD(RPU_1_IDS, FPIXC, 1, 22)
 368    FIELD(RPU_1_IDS, FPIOC, 1, 21)
 369    FIELD(RPU_1_IDS, FPIDC, 1, 20)
 370    FIELD(RPU_1_IDS, FPDZC, 1, 19)
 371    FIELD(RPU_1_IDS, TCM_ASLV_CE, 1, 18)
 372    FIELD(RPU_1_IDS, TCM_ASLV_FAT, 1, 17)
 373    FIELD(RPU_1_IDS, TCM_LST_CE, 1, 16)
 374    FIELD(RPU_1_IDS, TCM_PREFETCH_CE, 1, 15)
 375    FIELD(RPU_1_IDS, B1TCM_CE, 1, 14)
 376    FIELD(RPU_1_IDS, B0TCM_CE, 1, 13)
 377    FIELD(RPU_1_IDS, ATCM_CE, 1, 12)
 378    FIELD(RPU_1_IDS, B1TCM_UE, 1, 11)
 379    FIELD(RPU_1_IDS, B0TCM_UE, 1, 10)
 380    FIELD(RPU_1_IDS, ATCM_UE, 1, 9)
 381    FIELD(RPU_1_IDS, DTAG_DIRTY_FAT, 1, 8)
 382    FIELD(RPU_1_IDS, DDATA_FAT, 1, 7)
 383    FIELD(RPU_1_IDS, TCM_LST_FAT, 1, 6)
 384    FIELD(RPU_1_IDS, TCM_PREFETCH_FAT, 1, 5)
 385    FIELD(RPU_1_IDS, DDATA_CE, 1, 4)
 386    FIELD(RPU_1_IDS, DTAG_DIRTY_CE, 1, 3)
 387    FIELD(RPU_1_IDS, IDATA_CE, 1, 2)
 388    FIELD(RPU_1_IDS, ITAG_CE, 1, 1)
 389    FIELD(RPU_1_IDS, APB_ERR, 1, 0)
 390REG32(RPU_1_SLV_BASE, 0x224)
 391    FIELD(RPU_1_SLV_BASE, ADDR, 8, 0)
 392REG32(RPU_1_AXI_OVER, 0x228)
 393    FIELD(RPU_1_AXI_OVER, AWCACHE, 4, 6)
 394    FIELD(RPU_1_AXI_OVER, ARCACHE, 4, 2)
 395    FIELD(RPU_1_AXI_OVER, AWCACHE_EN, 1, 1)
 396    FIELD(RPU_1_AXI_OVER, ARCACHE_EN, 1, 0)
 397
 398#define R_MAX (R_RPU_1_AXI_OVER + 1)
 399
 400/* Returns the interrupt bank from the register offset. */
 401#define INT_INJ_BANK_FROM_OFFSET(n) (((n) <= R_RPU_INTR_4)                     \
 402                                     ? ((n) - R_RPU_INTR_0)                    \
 403                                     : ((n) - R_RPU_INTR_MASK_0))
 404#define R_RPU_INTR(n) (n + R_RPU_INTR_0)
 405#define R_RPU_INTR_MASK(n) (n + R_RPU_INTR_MASK_0)
 406
 407typedef struct RPU {
 408    SysBusDevice parent_obj;
 409    MemoryRegion iomem;
 410    qemu_irq irq_rpu_1;
 411    qemu_irq irq_rpu_0;
 412
 413    MemoryRegion *atcm1_for_rpu0;
 414    MemoryRegion *btcm1_for_rpu0;
 415    MemoryRegion atcm1_mask;
 416    MemoryRegion btcm1_mask;
 417    MemoryRegion *rpu1_for_main_bus;
 418    /* MemoryRegion for the rpu1 caches. */
 419    MemoryRegion *icache_for_rpu1;
 420    MemoryRegion *dcache_for_rpu1;
 421    /* Second part of the DDR. */
 422    MemoryRegion *ddr;
 423
 424    /* GIC associated to the RPUs. */
 425    XlnxSCUGICState *gic;
 426
 427    /* WFIs towards PMU. */
 428    qemu_irq wfi_out[2];
 429    /* Comparators fault. */
 430    qemu_irq comp_fault[2];
 431
 432    bool cpu_in_wfi[2];
 433
 434    uint32_t regs[R_MAX];
 435    RegisterInfo regs_info[R_MAX];
 436} RPU;
 437
 438static void rpu_1_update_irq(RPU *s)
 439{
 440    bool pending = s->regs[R_RPU_1_ISR] & ~s->regs[R_RPU_1_IMR];
 441    qemu_set_irq(s->irq_rpu_1, pending);
 442}
 443
 444static void ronaldo_rpu_err_inj(RegisterInfo *reg, uint64_t val64)
 445{
 446    RPU *s = XILINX_RPU(reg->opaque);
 447    bool comp_0 = AF_EX32(s->regs, RPU_ERR_INJ, DCCMINP);
 448    bool comp_1 = AF_EX32(s->regs, RPU_ERR_INJ, DCCMINP2);
 449
 450    /* Inject an error in the comparator
 451     * Works even if the CLAMP bit is cleared.
 452     */
 453    qemu_set_irq(s->comp_fault[0], comp_0);
 454    qemu_set_irq(s->comp_fault[1], comp_1);
 455}
 456
 457static void rpu_1_isr_postw(RegisterInfo *reg, uint64_t val64)
 458{
 459    RPU *s = XILINX_RPU(reg->opaque);
 460    rpu_1_update_irq(s);
 461}
 462
 463static void ronaldo_rpu_update_irq_injection(RegisterInfo *reg, uint64_t val)
 464{
 465    RPU *s = XILINX_RPU(reg->opaque);
 466
 467    uint8_t bank = INT_INJ_BANK_FROM_OFFSET(reg->access->decode.addr >> 2);
 468    uint32_t irqs = s->regs[R_RPU_INTR(bank)] &
 469                    s->regs[R_RPU_INTR_MASK(bank)];
 470
 471    xlnx_scu_gic_set_intr(s->gic, bank, irqs, 0);
 472}
 473
 474static uint64_t rpu_1_ien_prew(RegisterInfo *reg, uint64_t val64)
 475{
 476    RPU *s = XILINX_RPU(reg->opaque);
 477    uint32_t val = val64;
 478
 479    s->regs[R_RPU_1_IMR] &= ~val;
 480    rpu_1_update_irq(s);
 481    return 0;
 482}
 483
 484static uint64_t rpu_1_ids_prew(RegisterInfo *reg, uint64_t val64)
 485{
 486    RPU *s = XILINX_RPU(reg->opaque);
 487    uint32_t val = val64;
 488
 489    s->regs[R_RPU_1_IMR] |= val;
 490    rpu_1_update_irq(s);
 491    return 0;
 492}
 493
 494static void rpu_0_update_irq(RPU *s)
 495{
 496    bool pending = s->regs[R_RPU_0_ISR] & ~s->regs[R_RPU_0_IMR];
 497    qemu_set_irq(s->irq_rpu_0, pending);
 498}
 499
 500static void rpu_0_isr_postw(RegisterInfo *reg, uint64_t val64)
 501{
 502    RPU *s = XILINX_RPU(reg->opaque);
 503    rpu_0_update_irq(s);
 504}
 505
 506static uint64_t rpu_0_ien_prew(RegisterInfo *reg, uint64_t val64)
 507{
 508    RPU *s = XILINX_RPU(reg->opaque);
 509    uint32_t val = val64;
 510
 511    s->regs[R_RPU_0_IMR] &= ~val;
 512    rpu_0_update_irq(s);
 513    return 0;
 514}
 515
 516static uint64_t rpu_0_ids_prew(RegisterInfo *reg, uint64_t val64)
 517{
 518    RPU *s = XILINX_RPU(reg->opaque);
 519    uint32_t val = val64;
 520
 521    s->regs[R_RPU_0_IMR] |= val;
 522    rpu_0_update_irq(s);
 523    return 0;
 524}
 525
 526static void rpu_rpu_glbl_cntl_postw(RegisterInfo *reg, uint64_t val64)
 527{
 528    RPU *s = XILINX_RPU(reg->opaque);
 529    bool tcm_comb = AF_EX32(s->regs, RPU_GLBL_CNTL, TCM_COMB);
 530    bool sls_split = AF_EX32(s->regs, RPU_GLBL_CNTL, SLSPLIT);
 531
 532    memory_region_set_enabled(&s->atcm1_mask, !tcm_comb);
 533    memory_region_set_enabled(&s->btcm1_mask, !tcm_comb);
 534
 535    memory_region_set_enabled(s->icache_for_rpu1, sls_split);
 536    memory_region_set_enabled(s->dcache_for_rpu1, sls_split);
 537    memory_region_set_enabled(s->ddr, sls_split);
 538}
 539
 540static void update_wfi_out(void *opaque)
 541{
 542    RPU *s = XILINX_RPU(opaque);
 543    unsigned int i, wfi_pending;
 544    unsigned int pwrdnreq[2];
 545
 546    pwrdnreq[0] = AF_EX32(s->regs, RPU_0_PWRDWN, EN);
 547    pwrdnreq[1] = AF_EX32(s->regs, RPU_1_PWRDWN, EN);
 548
 549    for (i = 0; i < 2; i++) {
 550        wfi_pending = pwrdnreq[i] && s->cpu_in_wfi[i];
 551        qemu_set_irq(s->wfi_out[i], wfi_pending);
 552    }
 553}
 554
 555static void zynqmp_rpu_pwrctl_post_write(RegisterInfo *reg, uint64_t val)
 556{
 557    RPU *s = XILINX_RPU(reg->opaque);
 558    update_wfi_out(s);
 559}
 560
 561static uint64_t rpu_1_cfg_pw(RegisterInfo *reg, uint64_t val)
 562{
 563    RPU *s = XILINX_RPU(reg->opaque);
 564
 565    /* Split-Mode: Remove R5-1 from hold upon request
 566     * LockStep-Mode: Keep R5-1 under hold, to make only R5-0 run
 567     *                in Lockstep.
 568     */
 569    if (!AF_EX32(s->regs, RPU_GLBL_CNTL, SLSPLIT)) {
 570        /* Lock-Step Mode, Clear the hold bit to keep the
 571         *  core in HOLD state.
 572         */
 573        val &= ~(R_RPU_1_CFG_NCPUHALT_MASK);
 574    }
 575    return val;
 576}
 577
 578static RegisterAccessInfo rpu_regs_info[] = {
 579    {   .name = "RPU_GLBL_CNTL",  .decode.addr = A_RPU_GLBL_CNTL,
 580        .gpios = (RegisterGPIOMapping[]) {
 581            { .name = "R5_SLSPLIT",
 582              .bit_pos = R_RPU_GLBL_CNTL_SLSPLIT_SHIFT, .width = 1,
 583              .polarity = REG_GPIO_POL_LOW },
 584            {},
 585        },
 586        .reset = 0x250,
 587        .post_write = rpu_rpu_glbl_cntl_postw,
 588        .inhibit_reset = 1u << 31,
 589    },{ .name = "RPU_GLBL_STATUS",  .decode.addr = A_RPU_GLBL_STATUS,
 590        .ro = 0x1,
 591    },{ .name = "RPU_ERR_CNTL",  .decode.addr = A_RPU_ERR_CNTL,
 592    },{ .name = "RPU_RAM",  .decode.addr = A_RPU_RAM,
 593    },{ .name = "RPU_CACHE_DATA",  .decode.addr = A_RPU_CACHE_DATA,
 594        .reset = 0xa28a28a,
 595    },{ .name = "RPU_CACHE_SYN",  .decode.addr = A_RPU_CACHE_SYN,
 596        .reset = 0xa28a28a,
 597    },{ .name = "RPU_TCM_DATA",  .decode.addr = A_RPU_TCM_DATA,
 598        .reset = 0xa00a,
 599    },{ .name = "RPU_TCM_SYN",  .decode.addr = A_RPU_TCM_SYN,
 600        .reset = 0x280280,
 601    },{ .name = "RPU_ERR_INJ",  .decode.addr = A_RPU_ERR_INJ,
 602        .post_write = ronaldo_rpu_err_inj,
 603    },{ .name = "RPU_CCF_MASK",  .decode.addr = A_RPU_CCF_MASK,
 604    },{ .name = "RPU_INTR_0",  .decode.addr = A_RPU_INTR_0,
 605        .post_write = ronaldo_rpu_update_irq_injection,
 606    },{ .name = "RPU_INTR_1",  .decode.addr = A_RPU_INTR_1,
 607        .post_write = ronaldo_rpu_update_irq_injection,
 608    },{ .name = "RPU_INTR_2",  .decode.addr = A_RPU_INTR_2,
 609        .post_write = ronaldo_rpu_update_irq_injection,
 610    },{ .name = "RPU_INTR_3",  .decode.addr = A_RPU_INTR_3,
 611        .post_write = ronaldo_rpu_update_irq_injection,
 612    },{ .name = "RPU_INTR_4",  .decode.addr = A_RPU_INTR_4,
 613        .post_write = ronaldo_rpu_update_irq_injection,
 614    },{ .name = "RPU_INTR_MASK_0",  .decode.addr = A_RPU_INTR_MASK_0,
 615        .post_write = ronaldo_rpu_update_irq_injection,
 616    },{ .name = "RPU_INTR_MASK_1",  .decode.addr = A_RPU_INTR_MASK_1,
 617        .post_write = ronaldo_rpu_update_irq_injection,
 618    },{ .name = "RPU_INTR_MASK_2",  .decode.addr = A_RPU_INTR_MASK_2,
 619        .post_write = ronaldo_rpu_update_irq_injection,
 620    },{ .name = "RPU_INTR_MASK_3",  .decode.addr = A_RPU_INTR_MASK_3,
 621        .post_write = ronaldo_rpu_update_irq_injection,
 622    },{ .name = "RPU_INTR_MASK_4",  .decode.addr = A_RPU_INTR_MASK_4,
 623        .post_write = ronaldo_rpu_update_irq_injection,
 624    },{ .name = "RPU_CCF_VAL",  .decode.addr = A_RPU_CCF_VAL,
 625        .reset = 0x7,
 626    },{ .name = "RPU_SAFETY_CHK",  .decode.addr = A_RPU_SAFETY_CHK,
 627    },{ .name = "RPU",  .decode.addr = A_RPU,
 628    },{ .name = "RPU_0_CFG",  .decode.addr = A_RPU_0_CFG,
 629        .reset = 0x5,
 630        .gpios = (RegisterGPIOMapping[]) {
 631            { .name = "R5_0_HALT",
 632              .bit_pos = R_RPU_0_CFG_NCPUHALT_SHIFT, .width = 1,
 633              .polarity = REG_GPIO_POL_LOW },
 634            { .name = "R5_0_VINITHI",
 635              .bit_pos = R_RPU_0_CFG_VINITHI_SHIFT, .width = 1 },
 636            {},
 637        },
 638    },{ .name = "RPU_0_STATUS",  .decode.addr = A_RPU_0_STATUS,
 639        .reset = 0x3f,
 640        .ro = 0x3f,
 641    },{ .name = "RPU_0_PWRDWN",  .decode.addr = A_RPU_0_PWRDWN,
 642        .gpios = (RegisterGPIOMapping[]) {
 643            { .name = "R5_0_PWRDWN_REQ",
 644              .bit_pos = R_RPU_0_PWRDWN_EN_SHIFT, .width = 1 },
 645            {},
 646        },
 647        .post_write = zynqmp_rpu_pwrctl_post_write,
 648    },{ .name = "RPU_0_ISR",  .decode.addr = A_RPU_0_ISR,
 649        .w1c = 0x1ffffff,
 650        .post_write = rpu_0_isr_postw,
 651    },{ .name = "RPU_0_IMR",  .decode.addr = A_RPU_0_IMR,
 652        .reset = 0x1ffffff,
 653        .ro = 0x1ffffff,
 654    },{ .name = "RPU_0_IEN",  .decode.addr = A_RPU_0_IEN,
 655        .pre_write = rpu_0_ien_prew,
 656    },{ .name = "RPU_0_IDS",  .decode.addr = A_RPU_0_IDS,
 657        .pre_write = rpu_0_ids_prew,
 658    },{ .name = "RPU_0_SLV_BASE",  .decode.addr = A_RPU_0_SLV_BASE,
 659    },{ .name = "RPU_0_AXI_OVER",  .decode.addr = A_RPU_0_AXI_OVER,
 660    },{ .name = "RPU_1_CFG",  .decode.addr = A_RPU_1_CFG,
 661        .reset = 0x5,
 662        .gpios = (RegisterGPIOMapping[]) {
 663            { .name = "R5_1_HALT",
 664              .bit_pos = R_RPU_1_CFG_NCPUHALT_SHIFT, .width = 1,
 665              .polarity = REG_GPIO_POL_LOW },
 666            { .name = "R5_1_VINITHI",
 667              .bit_pos = R_RPU_1_CFG_VINITHI_SHIFT, .width = 1 },
 668            {},
 669        },
 670        .pre_write = rpu_1_cfg_pw,
 671    },{ .name = "RPU_1_STATUS",  .decode.addr = A_RPU_1_STATUS,
 672        .reset = 0x3f,
 673        .ro = 0x3f,
 674    },{ .name = "RPU_1_PWRDWN",  .decode.addr = A_RPU_1_PWRDWN,
 675        .gpios = (RegisterGPIOMapping[]) {
 676            { .name = "R5_1_PWRDWN_REQ",
 677              .bit_pos = R_RPU_1_PWRDWN_EN_SHIFT, .width = 1 },
 678            {},
 679        },
 680        .post_write = zynqmp_rpu_pwrctl_post_write,
 681    },{ .name = "RPU_1_ISR",  .decode.addr = A_RPU_1_ISR,
 682        .w1c = 0x1ffffff,
 683        .post_write = rpu_1_isr_postw,
 684    },{ .name = "RPU_1_IMR",  .decode.addr = A_RPU_1_IMR,
 685        .reset = 0x1ffffff,
 686        .ro = 0x1ffffff,
 687    },{ .name = "RPU_1_IEN",  .decode.addr = A_RPU_1_IEN,
 688        .pre_write = rpu_1_ien_prew,
 689    },{ .name = "RPU_1_IDS",  .decode.addr = A_RPU_1_IDS,
 690        .pre_write = rpu_1_ids_prew,
 691    },{ .name = "RPU_1_SLV_BASE",  .decode.addr = A_RPU_1_SLV_BASE,
 692    },{ .name = "RPU_1_AXI_OVER",  .decode.addr = A_RPU_1_AXI_OVER,
 693    }
 694};
 695
 696static void rpu_reset(DeviceState *dev)
 697{
 698    RPU *s = XILINX_RPU(dev);
 699    unsigned int i;
 700
 701    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 702        register_reset(&s->regs_info[i]);
 703    }
 704
 705    rpu_1_update_irq(s);
 706    rpu_0_update_irq(s);
 707
 708    for (i = 0; i < 2; i++) {
 709        s->cpu_in_wfi[i] = false;
 710    }
 711    update_wfi_out(s);
 712}
 713
 714static uint64_t rpu_read(void *opaque, hwaddr addr, unsigned size)
 715{
 716    RPU *s = XILINX_RPU(opaque);
 717    RegisterInfo *r = &s->regs_info[addr / 4];
 718
 719    if (!r->data) {
 720        qemu_log_mask(LOG_GUEST_ERROR,
 721                 "%s: Decode error: read from %" HWADDR_PRIx "\n",
 722                 object_get_canonical_path(OBJECT(s)),
 723                 addr);
 724        return 0;
 725    }
 726    return register_read(r);
 727}
 728
 729static void rpu_write(void *opaque, hwaddr addr, uint64_t value,
 730                      unsigned size)
 731{
 732    RPU *s = XILINX_RPU(opaque);
 733    RegisterInfo *r = &s->regs_info[addr / 4];
 734
 735    if (!r->data) {
 736        qemu_log_mask(LOG_GUEST_ERROR,
 737                 "%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
 738                 object_get_canonical_path(OBJECT(s)),
 739                 addr, value);
 740        return;
 741    }
 742    register_write(r, value, ~0);
 743}
 744
 745static const MemoryRegionOps rpu_ops = {
 746    .read = rpu_read,
 747    .write = rpu_write,
 748    .endianness = DEVICE_LITTLE_ENDIAN,
 749    .valid = {
 750        .min_access_size = 4,
 751        .max_access_size = 4,
 752    },
 753};
 754
 755static uint64_t disabled_tcm_read(void *opaque, hwaddr addr, unsigned size)
 756{
 757    Object *obj = OBJECT(opaque);
 758
 759    qemu_log_mask(LOG_GUEST_ERROR, "%s: Read to unmapped TCM while RPU is in"
 760                  " lockstep mode @%" HWADDR_PRIx "\n",
 761                  object_get_canonical_path(obj), addr);
 762    return 0;
 763}
 764
 765static void disabled_tcm_write(void *opaque, hwaddr addr, uint64_t value,
 766                               unsigned size)
 767{
 768    Object *obj = OBJECT(opaque);
 769
 770    qemu_log_mask(LOG_GUEST_ERROR, "%s: Write to unmapped TCM while RPU is in"
 771                  " lockstep mode @%" HWADDR_PRIx "\n",
 772                  object_get_canonical_path(obj), addr);
 773}
 774
 775static const MemoryRegionOps disabled_tcm_ops = {
 776    .read = disabled_tcm_read,
 777    .write = disabled_tcm_write,
 778};
 779
 780static void zynqmp_rpu_0_handle_wfi(void *opaque, int irq, int level)
 781{
 782    RPU *s = XILINX_RPU(opaque);
 783
 784    s->cpu_in_wfi[0] = level;
 785    update_wfi_out(s);
 786}
 787
 788static void zynqmp_rpu_1_handle_wfi(void *opaque, int irq, int level)
 789{
 790    RPU *s = XILINX_RPU(opaque);
 791
 792    s->cpu_in_wfi[1] = level;
 793    update_wfi_out(s);
 794}
 795
 796static void rpu_realize(DeviceState *dev, Error **errp)
 797{
 798    RPU *s = XILINX_RPU(dev);
 799    const char *prefix = object_get_canonical_path(OBJECT(dev));
 800    unsigned int i;
 801    hwaddr region_addr;
 802    MemoryRegion *region_container;
 803    uint32_t region_priority;
 804
 805    for (i = 0; i < ARRAY_SIZE(rpu_regs_info); ++i) {
 806        RegisterInfo *r = &s->regs_info[rpu_regs_info[i].decode.addr/4];
 807
 808        *r = (RegisterInfo) {
 809            .data = (uint8_t *)&s->regs[
 810                    rpu_regs_info[i].decode.addr/4],
 811            .data_size = sizeof(uint32_t),
 812            .access = &rpu_regs_info[i],
 813            .debug = XILINX_RPU_ERR_DEBUG,
 814            .prefix = prefix,
 815            .opaque = s,
 816        };
 817        register_init(r);
 818        qdev_pass_all_gpios(DEVICE(r), dev);
 819    }
 820
 821    if (!s->atcm1_for_rpu0) {
 822        error_setg(errp, "atcm1-for-rpu0");
 823        return;
 824    }
 825
 826    if (!s->btcm1_for_rpu0) {
 827        error_setg(errp, "btcm1-for-rpu0");
 828        return;
 829    }
 830
 831    if (!s->icache_for_rpu1) {
 832        error_setg(errp, "icache-for-rpu1");
 833        return;
 834    }
 835
 836    if (!s->dcache_for_rpu1) {
 837        error_setg(errp, "dcache-for-rpu1");
 838        return;
 839    }
 840
 841    if (!s->ddr) {
 842        error_setg(errp, "ddr-mem-for-rpu");
 843        return;
 844    }
 845
 846    if (!s->gic) {
 847        error_setg(errp, "gic-for-rpu");
 848        return;
 849    }
 850
 851    /* RPUs starts in lockstep mode, so the rpu1 caches are not accessible. */
 852    memory_region_set_enabled(s->icache_for_rpu1, false);
 853    memory_region_set_enabled(s->dcache_for_rpu1, false);
 854    memory_region_set_enabled(s->ddr, false);
 855
 856    /* This initialize some "mask" memory region
 857     * Basically they hide what is behind so the *tcm are not accessible.
 858     */
 859    memory_region_init_io(&s->atcm1_mask, OBJECT(s), &disabled_tcm_ops, s,
 860                          "atcm1_mask", memory_region_size(s->atcm1_for_rpu0));
 861    region_container = MEMORY_REGION(object_property_get_link(
 862                                                OBJECT(s->atcm1_for_rpu0),
 863                                                "container", NULL));
 864    region_addr = object_property_get_int(OBJECT(s->atcm1_for_rpu0), "addr",
 865                                          NULL);
 866    region_priority = object_property_get_int(OBJECT(s->atcm1_for_rpu0),
 867                                              "priority", NULL) + 1;
 868    object_property_set_int(OBJECT(&s->atcm1_mask), region_priority, "priority",
 869                            NULL);
 870    memory_region_add_subregion(region_container, region_addr, &s->atcm1_mask);
 871
 872    memory_region_init_io(&s->btcm1_mask, OBJECT(s), &disabled_tcm_ops, s,
 873                          "btcm1_mask", memory_region_size(s->btcm1_for_rpu0));
 874    region_container = MEMORY_REGION(object_property_get_link(
 875                                                OBJECT(s->btcm1_for_rpu0),
 876                                                "container", NULL));
 877    region_addr = object_property_get_int(OBJECT(s->btcm1_for_rpu0), "addr",
 878                                          NULL);
 879    region_priority = object_property_get_int(OBJECT(s->btcm1_for_rpu0),
 880                                              "priority", NULL) + 1;
 881    object_property_set_int(OBJECT(&s->btcm1_mask), region_priority, "priority",
 882                            NULL);
 883    memory_region_add_subregion(region_container, region_addr, &s->btcm1_mask);
 884}
 885
 886static void rpu_init(Object *obj)
 887{
 888    RPU *s = XILINX_RPU(obj);
 889    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 890
 891    memory_region_init_io(&s->iomem, obj, &rpu_ops, s,
 892                          TYPE_XILINX_RPU, R_MAX * 4);
 893    sysbus_init_mmio(sbd, &s->iomem);
 894    sysbus_init_irq(sbd, &s->irq_rpu_1);
 895    sysbus_init_irq(sbd, &s->irq_rpu_0);
 896
 897    /* xtcm1-for-rpu0 are the aliases for the tcm in lockstep mode.
 898     * This link allows to enable/disable those aliases when we are in
 899     * lock-step/normal mode.
 900     */
 901    object_property_add_link(obj, "atcm1-for-rpu0", TYPE_MEMORY_REGION,
 902                             (Object **)&s->atcm1_for_rpu0,
 903                             qdev_prop_allow_set_link_before_realize,
 904                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 905                             &error_abort);
 906    object_property_add_link(obj, "btcm1-for-rpu0", TYPE_MEMORY_REGION,
 907                             (Object **)&s->btcm1_for_rpu0,
 908                             qdev_prop_allow_set_link_before_realize,
 909                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 910                             &error_abort);
 911    object_property_add_link(obj, "rpu1-for-main-bus", TYPE_MEMORY_REGION,
 912                             (Object **)&s->atcm1_for_rpu0,
 913                             qdev_prop_allow_set_link_before_realize,
 914                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 915                             &error_abort);
 916
 917    /* This link allows to enable/disable those memory region when we are in
 918     * lock-step/normal mode.
 919     */
 920    object_property_add_link(obj, "icache-for-rpu1", TYPE_MEMORY_REGION,
 921                             (Object **)&s->icache_for_rpu1,
 922                             qdev_prop_allow_set_link_before_realize,
 923                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 924                             &error_abort);
 925    object_property_add_link(obj, "dcache-for-rpu1", TYPE_MEMORY_REGION,
 926                             (Object **)&s->dcache_for_rpu1,
 927                             qdev_prop_allow_set_link_before_realize,
 928                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 929                             &error_abort);
 930
 931    /* Link to the second part of the DDR which is enabled in split mode and
 932     * disabled in lockstep mode.
 933     */
 934    object_property_add_link(obj, "ddr-mem-for-rpu", TYPE_MEMORY_REGION,
 935                             (Object **)&s->ddr,
 936                             qdev_prop_allow_set_link_before_realize,
 937                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 938                             &error_abort);
 939
 940    /* Link to the GIC which allow to inject irq through rpu_intr/rpu_mask
 941     * registers
 942     */
 943    object_property_add_link(obj, "gic-for-rpu", TYPE_XLNX_SCU_GIC,
 944                             (Object **)&s->gic,
 945                             qdev_prop_allow_set_link_before_realize,
 946                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
 947                             &error_abort);
 948
 949    /* comp_fault gpios are connected to the PMU. */
 950    qdev_init_gpio_out_named(DEVICE(obj), s->comp_fault, "comp_fault", 2);
 951    /* wfi_out is used to connect to PMU GPIs. */
 952    qdev_init_gpio_out_named(DEVICE(obj), s->wfi_out, "wfi_out", 2);
 953    /* wfi_in is used as input from CPUs as wfi request. */
 954    qdev_init_gpio_in_named(DEVICE(obj), zynqmp_rpu_0_handle_wfi, "wfi_in_0", 1);
 955    qdev_init_gpio_in_named(DEVICE(obj), zynqmp_rpu_1_handle_wfi, "wfi_in_1", 1);
 956}
 957
 958static const VMStateDescription vmstate_rpu = {
 959    .name = TYPE_XILINX_RPU,
 960    .version_id = 1,
 961    .minimum_version_id = 1,
 962    .minimum_version_id_old = 1,
 963    .fields = (VMStateField[]) {
 964        VMSTATE_UINT32_ARRAY(regs, RPU, R_MAX),
 965        VMSTATE_END_OF_LIST(),
 966    }
 967};
 968
 969static const FDTGenericGPIOSet rpu_controller_gpios [] = {
 970    {
 971        .names = &fdt_generic_gpio_name_set_gpio,
 972        .gpios = (FDTGenericGPIOConnection [])  {
 973            { .name = "R5_0_HALT",          .fdt_index = 0 },
 974            { .name = "R5_1_HALT",          .fdt_index = 1 },
 975            { .name = "R5_SLSPLIT",         .fdt_index = 2 },
 976            { .name = "R5_0_PWRDWN_REQ",    .fdt_index = 3 },
 977            { .name = "R5_1_PWRDWN_REQ",    .fdt_index = 4 },
 978            { .name = "wfi_in_0",           .fdt_index = 5 },
 979            { .name = "wfi_in_1",           .fdt_index = 6 },
 980            { .name = "R5_0_VINITHI",       .fdt_index = 7 },
 981            { .name = "R5_1_VINITHI",       .fdt_index = 8 },
 982            { },
 983        },
 984    },
 985    { },
 986};
 987
 988static const FDTGenericGPIOSet rpu_client_gpios [] = {
 989    {
 990        .names = &fdt_generic_gpio_name_set_gpio,
 991        .gpios = (FDTGenericGPIOConnection [])  {
 992            { .name = "comp_fault",         .fdt_index = 0, .range = 2 },
 993            { .name = "wfi_out",            .fdt_index = 2, .range = 2 },
 994            { },
 995        },
 996    },
 997    { },
 998};
 999
1000static void rpu_class_init(ObjectClass *klass, void *data)
1001{
1002    DeviceClass *dc = DEVICE_CLASS(klass);
1003    FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
1004
1005    dc->reset = rpu_reset;
1006    dc->realize = rpu_realize;
1007    dc->vmsd = &vmstate_rpu;
1008    fggc->controller_gpios = rpu_controller_gpios;
1009    fggc->client_gpios = rpu_client_gpios;
1010}
1011
1012static const TypeInfo rpu_info = {
1013    .name          = TYPE_XILINX_RPU,
1014    .parent        = TYPE_SYS_BUS_DEVICE,
1015    .instance_size = sizeof(RPU),
1016    .class_init    = rpu_class_init,
1017    .instance_init = rpu_init,
1018    .interfaces    = (InterfaceInfo[]) {
1019        { TYPE_FDT_GENERIC_GPIO },
1020        { }
1021    },
1022};
1023
1024static void rpu_register_types(void)
1025{
1026    type_register_static(&rpu_info);
1027}
1028
1029type_init(rpu_register_types)
1030