qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

xlnx-versal-xramc.c (7425B)


      1 /*
      2  * QEMU model of the Xilinx XRAM Controller.
      3  *
      4  * Copyright (c) 2021 Xilinx Inc.
      5  * SPDX-License-Identifier: GPL-2.0-or-later
      6  * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
      7  */
      8 
      9 #include "qemu/osdep.h"
     10 #include "qemu/units.h"
     11 #include "qapi/error.h"
     12 #include "migration/vmstate.h"
     13 #include "hw/sysbus.h"
     14 #include "hw/register.h"
     15 #include "hw/qdev-properties.h"
     16 #include "hw/irq.h"
     17 #include "hw/misc/xlnx-versal-xramc.h"
     18 
     19 #ifndef XLNX_XRAM_CTRL_ERR_DEBUG
     20 #define XLNX_XRAM_CTRL_ERR_DEBUG 0
     21 #endif
     22 
     23 static void xram_update_irq(XlnxXramCtrl *s)
     24 {
     25     bool pending = s->regs[R_XRAM_ISR] & ~s->regs[R_XRAM_IMR];
     26     qemu_set_irq(s->irq, pending);
     27 }
     28 
     29 static void xram_isr_postw(RegisterInfo *reg, uint64_t val64)
     30 {
     31     XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
     32     xram_update_irq(s);
     33 }
     34 
     35 static uint64_t xram_ien_prew(RegisterInfo *reg, uint64_t val64)
     36 {
     37     XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
     38     uint32_t val = val64;
     39 
     40     s->regs[R_XRAM_IMR] &= ~val;
     41     xram_update_irq(s);
     42     return 0;
     43 }
     44 
     45 static uint64_t xram_ids_prew(RegisterInfo *reg, uint64_t val64)
     46 {
     47     XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
     48     uint32_t val = val64;
     49 
     50     s->regs[R_XRAM_IMR] |= val;
     51     xram_update_irq(s);
     52     return 0;
     53 }
     54 
     55 static const RegisterAccessInfo xram_ctrl_regs_info[] = {
     56     {   .name = "XRAM_ERR_CTRL",  .addr = A_XRAM_ERR_CTRL,
     57         .reset = 0xf,
     58         .rsvd = 0xfffffff0,
     59     },{ .name = "XRAM_ISR",  .addr = A_XRAM_ISR,
     60         .rsvd = 0xfffff800,
     61         .w1c = 0x7ff,
     62         .post_write = xram_isr_postw,
     63     },{ .name = "XRAM_IMR",  .addr = A_XRAM_IMR,
     64         .reset = 0x7ff,
     65         .rsvd = 0xfffff800,
     66         .ro = 0x7ff,
     67     },{ .name = "XRAM_IEN",  .addr = A_XRAM_IEN,
     68         .rsvd = 0xfffff800,
     69         .pre_write = xram_ien_prew,
     70     },{ .name = "XRAM_IDS",  .addr = A_XRAM_IDS,
     71         .rsvd = 0xfffff800,
     72         .pre_write = xram_ids_prew,
     73     },{ .name = "XRAM_ECC_CNTL",  .addr = A_XRAM_ECC_CNTL,
     74         .rsvd = 0xfffffff8,
     75     },{ .name = "XRAM_CLR_EXE",  .addr = A_XRAM_CLR_EXE,
     76         .rsvd = 0xffffff00,
     77     },{ .name = "XRAM_CE_FFA",  .addr = A_XRAM_CE_FFA,
     78         .rsvd = 0xfff00000,
     79         .ro = 0xfffff,
     80     },{ .name = "XRAM_CE_FFD0",  .addr = A_XRAM_CE_FFD0,
     81         .ro = 0xffffffff,
     82     },{ .name = "XRAM_CE_FFD1",  .addr = A_XRAM_CE_FFD1,
     83         .ro = 0xffffffff,
     84     },{ .name = "XRAM_CE_FFD2",  .addr = A_XRAM_CE_FFD2,
     85         .ro = 0xffffffff,
     86     },{ .name = "XRAM_CE_FFD3",  .addr = A_XRAM_CE_FFD3,
     87         .ro = 0xffffffff,
     88     },{ .name = "XRAM_CE_FFE",  .addr = A_XRAM_CE_FFE,
     89         .rsvd = 0xffff0000,
     90         .ro = 0xffff,
     91     },{ .name = "XRAM_UE_FFA",  .addr = A_XRAM_UE_FFA,
     92         .rsvd = 0xfff00000,
     93         .ro = 0xfffff,
     94     },{ .name = "XRAM_UE_FFD0",  .addr = A_XRAM_UE_FFD0,
     95         .ro = 0xffffffff,
     96     },{ .name = "XRAM_UE_FFD1",  .addr = A_XRAM_UE_FFD1,
     97         .ro = 0xffffffff,
     98     },{ .name = "XRAM_UE_FFD2",  .addr = A_XRAM_UE_FFD2,
     99         .ro = 0xffffffff,
    100     },{ .name = "XRAM_UE_FFD3",  .addr = A_XRAM_UE_FFD3,
    101         .ro = 0xffffffff,
    102     },{ .name = "XRAM_UE_FFE",  .addr = A_XRAM_UE_FFE,
    103         .rsvd = 0xffff0000,
    104         .ro = 0xffff,
    105     },{ .name = "XRAM_FI_D0",  .addr = A_XRAM_FI_D0,
    106     },{ .name = "XRAM_FI_D1",  .addr = A_XRAM_FI_D1,
    107     },{ .name = "XRAM_FI_D2",  .addr = A_XRAM_FI_D2,
    108     },{ .name = "XRAM_FI_D3",  .addr = A_XRAM_FI_D3,
    109     },{ .name = "XRAM_FI_SY",  .addr = A_XRAM_FI_SY,
    110         .rsvd = 0xffff0000,
    111     },{ .name = "XRAM_RMW_UE_FFA",  .addr = A_XRAM_RMW_UE_FFA,
    112         .rsvd = 0xfff00000,
    113         .ro = 0xfffff,
    114     },{ .name = "XRAM_FI_CNTR",  .addr = A_XRAM_FI_CNTR,
    115         .rsvd = 0xff000000,
    116     },{ .name = "XRAM_IMP",  .addr = A_XRAM_IMP,
    117         .reset = 0x4,
    118         .rsvd = 0xfffffff0,
    119         .ro = 0xf,
    120     },{ .name = "XRAM_PRDY_DBG",  .addr = A_XRAM_PRDY_DBG,
    121         .reset = 0xffff,
    122         .rsvd = 0xffff0000,
    123         .ro = 0xffff,
    124     },{ .name = "XRAM_SAFETY_CHK",  .addr = A_XRAM_SAFETY_CHK,
    125     }
    126 };
    127 
    128 static void xram_ctrl_reset_enter(Object *obj, ResetType type)
    129 {
    130     XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    131     unsigned int i;
    132 
    133     for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
    134         register_reset(&s->regs_info[i]);
    135     }
    136 
    137     ARRAY_FIELD_DP32(s->regs, XRAM_IMP, SIZE, s->cfg.encoded_size);
    138 }
    139 
    140 static void xram_ctrl_reset_hold(Object *obj)
    141 {
    142     XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    143 
    144     xram_update_irq(s);
    145 }
    146 
    147 static const MemoryRegionOps xram_ctrl_ops = {
    148     .read = register_read_memory,
    149     .write = register_write_memory,
    150     .endianness = DEVICE_LITTLE_ENDIAN,
    151     .valid = {
    152         .min_access_size = 4,
    153         .max_access_size = 4,
    154     },
    155 };
    156 
    157 static void xram_ctrl_realize(DeviceState *dev, Error **errp)
    158 {
    159     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    160     XlnxXramCtrl *s = XLNX_XRAM_CTRL(dev);
    161 
    162     switch (s->cfg.size) {
    163     case 64 * KiB:
    164         s->cfg.encoded_size = 0;
    165         break;
    166     case 128 * KiB:
    167         s->cfg.encoded_size = 1;
    168         break;
    169     case 256 * KiB:
    170         s->cfg.encoded_size = 2;
    171         break;
    172     case 512 * KiB:
    173         s->cfg.encoded_size = 3;
    174         break;
    175     case 1 * MiB:
    176         s->cfg.encoded_size = 4;
    177         break;
    178     default:
    179         error_setg(errp, "Unsupported XRAM size %" PRId64, s->cfg.size);
    180         return;
    181     }
    182 
    183     memory_region_init_ram(&s->ram, OBJECT(s),
    184                            object_get_canonical_path_component(OBJECT(s)),
    185                            s->cfg.size, &error_fatal);
    186     sysbus_init_mmio(sbd, &s->ram);
    187 }
    188 
    189 static void xram_ctrl_init(Object *obj)
    190 {
    191     XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    192     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    193 
    194     s->reg_array =
    195         register_init_block32(DEVICE(obj), xram_ctrl_regs_info,
    196                               ARRAY_SIZE(xram_ctrl_regs_info),
    197                               s->regs_info, s->regs,
    198                               &xram_ctrl_ops,
    199                               XLNX_XRAM_CTRL_ERR_DEBUG,
    200                               XRAM_CTRL_R_MAX * 4);
    201     sysbus_init_mmio(sbd, &s->reg_array->mem);
    202     sysbus_init_irq(sbd, &s->irq);
    203 }
    204 
    205 static void xram_ctrl_finalize(Object *obj)
    206 {
    207     XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
    208     register_finalize_block(s->reg_array);
    209 }
    210 
    211 static const VMStateDescription vmstate_xram_ctrl = {
    212     .name = TYPE_XLNX_XRAM_CTRL,
    213     .version_id = 1,
    214     .minimum_version_id = 1,
    215     .fields = (VMStateField[]) {
    216         VMSTATE_UINT32_ARRAY(regs, XlnxXramCtrl, XRAM_CTRL_R_MAX),
    217         VMSTATE_END_OF_LIST(),
    218     }
    219 };
    220 
    221 static Property xram_ctrl_properties[] = {
    222     DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB),
    223     DEFINE_PROP_END_OF_LIST(),
    224 };
    225 
    226 static void xram_ctrl_class_init(ObjectClass *klass, void *data)
    227 {
    228     ResettableClass *rc = RESETTABLE_CLASS(klass);
    229     DeviceClass *dc = DEVICE_CLASS(klass);
    230 
    231     dc->realize = xram_ctrl_realize;
    232     dc->vmsd = &vmstate_xram_ctrl;
    233     device_class_set_props(dc, xram_ctrl_properties);
    234 
    235     rc->phases.enter = xram_ctrl_reset_enter;
    236     rc->phases.hold = xram_ctrl_reset_hold;
    237 }
    238 
    239 static const TypeInfo xram_ctrl_info = {
    240     .name              = TYPE_XLNX_XRAM_CTRL,
    241     .parent            = TYPE_SYS_BUS_DEVICE,
    242     .instance_size     = sizeof(XlnxXramCtrl),
    243     .class_init        = xram_ctrl_class_init,
    244     .instance_init     = xram_ctrl_init,
    245     .instance_finalize = xram_ctrl_finalize,
    246 };
    247 
    248 static void xram_ctrl_register_types(void)
    249 {
    250     type_register_static(&xram_ctrl_info);
    251 }
    252 
    253 type_init(xram_ctrl_register_types)