qemu/hw/misc/xlnx-versal-cpm-pcsr.c
<<
>>
Prefs
   1/*
   2 * QEMU model of the CPM_PCSR This block implements the standard PCSR interface for Reset/Initialization of CPM
   3 *
   4 * Copyright (c) 2019 Xilinx Inc.
   5 *
   6 * Autogenerated by xregqemu.py 2019-07-17.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a copy
   9 * of this software and associated documentation files (the "Software"), to deal
  10 * in the Software without restriction, including without limitation the rights
  11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12 * copies of the Software, and to permit persons to whom the Software is
  13 * furnished to do so, subject to the following conditions:
  14 *
  15 * The above copyright notice and this permission notice shall be included in
  16 * all copies or substantial portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24 * THE SOFTWARE.
  25 */
  26
  27#include "qemu/osdep.h"
  28#include "hw/sysbus.h"
  29#include "hw/register.h"
  30#include "qemu/bitops.h"
  31#include "qemu/log.h"
  32#include "migration/vmstate.h"
  33#include "hw/qdev-properties.h"
  34
  35#ifndef XILINX_CPM_PCSR_ERR_DEBUG
  36#define XILINX_CPM_PCSR_ERR_DEBUG 0
  37#endif
  38
  39#define TYPE_XILINX_CPM_PCSR "xlnx.versal_cpm_pcsr"
  40
  41#define XILINX_CPM_PCSR(obj) \
  42     OBJECT_CHECK(CPM_PCSR, (obj), TYPE_XILINX_CPM_PCSR)
  43
  44REG32(MASK, 0x0)
  45    FIELD(MASK, TEST_SAFE_WEN, 20, 1)
  46    FIELD(MASK, SLVERREN_WEN, 19, 1)
  47    FIELD(MASK, MEM_CLEAR_TRIGGER_WEN, 18, 1)
  48    FIELD(MASK, SYS_RST_MASK3_WEN, 17, 1)
  49    FIELD(MASK, SYS_RST_MASK2_WEN, 16, 1)
  50    FIELD(MASK, SYS_RST_MASK1_WEN, 15, 1)
  51    FIELD(MASK, PWRDN_WEN, 14, 1)
  52    FIELD(MASK, DISNPICLK_WEN, 13, 1)
  53    FIELD(MASK, APBEN_WEN, 12, 1)
  54    FIELD(MASK, SCAN_CLEAR_TRIGGER_WEN, 11, 1)
  55    FIELD(MASK, STARTCAL_WEN, 10, 1)
  56    FIELD(MASK, FABRICEN_WEN, 9, 1)
  57    FIELD(MASK, TRISTATE_WEN, 8, 1)
  58    FIELD(MASK, HOLDSTATE_WEN, 7, 1)
  59    FIELD(MASK, INITSTATE_WEN, 6, 1)
  60    FIELD(MASK, ODISABLE3_WEN, 5, 1)
  61    FIELD(MASK, ODISABLE2_WEN, 4, 1)
  62    FIELD(MASK, ODISABLE1_WEN, 3, 1)
  63    FIELD(MASK, ODISABLE0_WEN, 2, 1)
  64    FIELD(MASK, GATEREG_WEN, 1, 1)
  65    FIELD(MASK, PCOMPLETE_WEN, 0, 1)
  66REG32(PCR, 0x4)
  67    FIELD(PCR, TEST_SAFE, 20, 1)
  68    FIELD(PCR, SLVERREN, 19, 1)
  69    FIELD(PCR, MEM_CLEAR_TRIGGER, 18, 1)
  70    FIELD(PCR, SYS_RST_MASK3, 17, 1)
  71    FIELD(PCR, SYS_RST_MASK2, 16, 1)
  72    FIELD(PCR, SYS_RST_MASK1, 15, 1)
  73    FIELD(PCR, PWRDN, 14, 1)
  74    FIELD(PCR, DISNPICLK, 13, 1)
  75    FIELD(PCR, APBEN, 12, 1)
  76    FIELD(PCR, SCAN_CLEAR_TRIGGER, 11, 1)
  77    FIELD(PCR, STARTCAL, 10, 1)
  78    FIELD(PCR, FABRICEN, 9, 1)
  79    FIELD(PCR, TRISTATE, 8, 1)
  80    FIELD(PCR, HOLDSTATE, 7, 1)
  81    FIELD(PCR, INITSTATE, 6, 1)
  82    FIELD(PCR, ODISABLE3, 5, 1)
  83    FIELD(PCR, ODISABLE2, 4, 1)
  84    FIELD(PCR, ODISABLE1, 3, 1)
  85    FIELD(PCR, ODISABLE0, 2, 1)
  86    FIELD(PCR, GATEREG, 1, 1)
  87    FIELD(PCR, PCOMPLETE, 0, 1)
  88REG32(PSR, 0x8)
  89    FIELD(PSR, HARD_FAIL_AND, 11, 3)
  90    FIELD(PSR, HARD_FAIL_OR, 8, 3)
  91    FIELD(PSR, MEM_CLEAR_PASS, 7, 1)
  92    FIELD(PSR, MEM_CLEAR_DONE, 6, 1)
  93    FIELD(PSR, CALERROR, 5, 1)
  94    FIELD(PSR, CALDONE, 4, 1)
  95    FIELD(PSR, INCAL, 3, 1)
  96    FIELD(PSR, SCAN_CLEAR_PASS, 2, 1)
  97    FIELD(PSR, SCAN_CLEAR_DONE, 1, 1)
  98    FIELD(PSR, PCSRLOCK, 0, 1)
  99REG32(LOCK, 0xc)
 100
 101#define CPM_PCSR_R_MAX (R_LOCK + 1)
 102
 103typedef struct CPM_PCSR {
 104    SysBusDevice parent_obj;
 105    MemoryRegion iomem;
 106
 107    uint32_t regs[CPM_PCSR_R_MAX];
 108    RegisterInfo regs_info[CPM_PCSR_R_MAX];
 109} CPM_PCSR;
 110
 111static void cpm_pcsr_lock_postw(RegisterInfo *reg, uint64_t val)
 112{
 113    CPM_PCSR *s = reg->opaque;
 114
 115    if (val == 0xf9e8d7c6) {
 116        s->regs[R_PSR] &= ~R_PSR_PCSRLOCK_MASK;
 117    } else if (val == 1) {
 118        s->regs[R_PSR] |= R_PSR_PCSRLOCK_MASK;
 119    }
 120}
 121
 122static const RegisterAccessInfo cpm_pcsr_regs_info[] = {
 123    {   .name = "MASK",  .addr = A_MASK,
 124        .reset = 0x1fe,
 125        .rsvd = 0xffe00000,
 126    },{ .name = "PCR",  .addr = A_PCR,
 127        .reset = 0x1fe,
 128        .rsvd = 0xffe00000,
 129    },{ .name = "PSR",  .addr = A_PSR,
 130        .reset = R_PSR_PCSRLOCK_MASK |
 131                 R_PSR_SCAN_CLEAR_DONE_MASK |
 132                 R_PSR_SCAN_CLEAR_PASS_MASK |
 133                 R_PSR_CALDONE_MASK |
 134                 R_PSR_MEM_CLEAR_DONE_MASK |
 135                 R_PSR_MEM_CLEAR_PASS_MASK,
 136        .rsvd = 0xffffc000,
 137        .ro = 0xffffffff,
 138    },{ .name = "LOCK",  .addr = A_LOCK,
 139        .reset = 0x1,
 140        .post_write = cpm_pcsr_lock_postw,
 141    }
 142};
 143
 144static void cpm_pcsr_reset(DeviceState *dev)
 145{
 146    CPM_PCSR *s = XILINX_CPM_PCSR(dev);
 147    unsigned int i;
 148
 149    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
 150        register_reset(&s->regs_info[i]);
 151    }
 152
 153}
 154
 155static const MemoryRegionOps cpm_pcsr_ops = {
 156    .read = register_read_memory,
 157    .write = register_write_memory,
 158    .endianness = DEVICE_LITTLE_ENDIAN,
 159    .valid = {
 160        .min_access_size = 4,
 161        .max_access_size = 4,
 162    },
 163};
 164
 165static void cpm_pcsr_realize(DeviceState *dev, Error **errp)
 166{
 167    /* Delete this if you don't need it */
 168}
 169
 170static void cpm_pcsr_init(Object *obj)
 171{
 172    CPM_PCSR *s = XILINX_CPM_PCSR(obj);
 173    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 174    RegisterInfoArray *reg_array;
 175
 176    memory_region_init(&s->iomem, obj, TYPE_XILINX_CPM_PCSR, CPM_PCSR_R_MAX * 4);
 177    reg_array =
 178        register_init_block32(DEVICE(obj), cpm_pcsr_regs_info,
 179                              ARRAY_SIZE(cpm_pcsr_regs_info),
 180                              s->regs_info, s->regs,
 181                              &cpm_pcsr_ops,
 182                              XILINX_CPM_PCSR_ERR_DEBUG,
 183                              CPM_PCSR_R_MAX * 4);
 184    memory_region_add_subregion(&s->iomem,
 185                                0x0,
 186                                &reg_array->mem);
 187    sysbus_init_mmio(sbd, &s->iomem);
 188}
 189
 190static const VMStateDescription vmstate_cpm_pcsr = {
 191    .name = TYPE_XILINX_CPM_PCSR,
 192    .version_id = 1,
 193    .minimum_version_id = 1,
 194    .fields = (VMStateField[]) {
 195        VMSTATE_UINT32_ARRAY(regs, CPM_PCSR, CPM_PCSR_R_MAX),
 196        VMSTATE_END_OF_LIST(),
 197    }
 198};
 199
 200static void cpm_pcsr_class_init(ObjectClass *klass, void *data)
 201{
 202    DeviceClass *dc = DEVICE_CLASS(klass);
 203
 204    dc->reset = cpm_pcsr_reset;
 205    dc->realize = cpm_pcsr_realize;
 206    dc->vmsd = &vmstate_cpm_pcsr;
 207}
 208
 209static const TypeInfo cpm_pcsr_info = {
 210    .name          = TYPE_XILINX_CPM_PCSR,
 211    .parent        = TYPE_SYS_BUS_DEVICE,
 212    .instance_size = sizeof(CPM_PCSR),
 213    .class_init    = cpm_pcsr_class_init,
 214    .instance_init = cpm_pcsr_init,
 215};
 216
 217static void cpm_pcsr_register_types(void)
 218{
 219    type_register_static(&cpm_pcsr_info);
 220}
 221
 222type_init(cpm_pcsr_register_types)
 223