xref: /openbmc/qemu/hw/misc/xlnx-versal-cfu.c (revision 28ae3179fc52d2e4d870b635c4a412aab99759e7)
186d916c6SFrancisco Iglesias /*
286d916c6SFrancisco Iglesias  * QEMU model of the CFU Configuration Unit.
386d916c6SFrancisco Iglesias  *
486d916c6SFrancisco Iglesias  * Copyright (C) 2023, Advanced Micro Devices, Inc.
586d916c6SFrancisco Iglesias  *
686d916c6SFrancisco Iglesias  * Written by Edgar E. Iglesias <edgar.iglesias@gmail.com>,
786d916c6SFrancisco Iglesias  *            Sai Pavan Boddu <sai.pavan.boddu@amd.com>,
886d916c6SFrancisco Iglesias  *            Francisco Iglesias <francisco.iglesias@amd.com>
986d916c6SFrancisco Iglesias  *
1086d916c6SFrancisco Iglesias  * SPDX-License-Identifier: GPL-2.0-or-later
1186d916c6SFrancisco Iglesias  */
1286d916c6SFrancisco Iglesias 
1386d916c6SFrancisco Iglesias #include "qemu/osdep.h"
1486d916c6SFrancisco Iglesias #include "hw/sysbus.h"
1586d916c6SFrancisco Iglesias #include "hw/register.h"
1686d916c6SFrancisco Iglesias #include "hw/irq.h"
1786d916c6SFrancisco Iglesias #include "qemu/bitops.h"
1886d916c6SFrancisco Iglesias #include "qemu/log.h"
1986d916c6SFrancisco Iglesias #include "qemu/units.h"
2086d916c6SFrancisco Iglesias #include "migration/vmstate.h"
2186d916c6SFrancisco Iglesias #include "hw/qdev-properties.h"
2286d916c6SFrancisco Iglesias #include "hw/qdev-properties-system.h"
2386d916c6SFrancisco Iglesias #include "hw/misc/xlnx-versal-cfu.h"
2486d916c6SFrancisco Iglesias 
2586d916c6SFrancisco Iglesias #ifndef XLNX_VERSAL_CFU_APB_ERR_DEBUG
2686d916c6SFrancisco Iglesias #define XLNX_VERSAL_CFU_APB_ERR_DEBUG 0
2786d916c6SFrancisco Iglesias #endif
2886d916c6SFrancisco Iglesias 
2986d916c6SFrancisco Iglesias #define KEYHOLE_STREAM_4K (4 * KiB)
3086d916c6SFrancisco Iglesias #define KEYHOLE_STREAM_256K (256 * KiB)
3186d916c6SFrancisco Iglesias #define CFRAME_BROADCAST_ROW 0x1F
3286d916c6SFrancisco Iglesias 
update_wfifo(hwaddr addr,uint64_t value,uint32_t * wfifo,uint32_t * wfifo_ret)3386d916c6SFrancisco Iglesias bool update_wfifo(hwaddr addr, uint64_t value,
3486d916c6SFrancisco Iglesias                   uint32_t *wfifo, uint32_t *wfifo_ret)
3586d916c6SFrancisco Iglesias {
3686d916c6SFrancisco Iglesias     unsigned int idx = extract32(addr, 2, 2);
3786d916c6SFrancisco Iglesias 
3886d916c6SFrancisco Iglesias     wfifo[idx] = value;
3986d916c6SFrancisco Iglesias 
4086d916c6SFrancisco Iglesias     if (idx == 3) {
4186d916c6SFrancisco Iglesias         memcpy(wfifo_ret, wfifo, WFIFO_SZ * sizeof(uint32_t));
4286d916c6SFrancisco Iglesias         memset(wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
4386d916c6SFrancisco Iglesias         return true;
4486d916c6SFrancisco Iglesias     }
4586d916c6SFrancisco Iglesias 
4686d916c6SFrancisco Iglesias     return false;
4786d916c6SFrancisco Iglesias }
4886d916c6SFrancisco Iglesias 
cfu_imr_update_irq(XlnxVersalCFUAPB * s)4986d916c6SFrancisco Iglesias static void cfu_imr_update_irq(XlnxVersalCFUAPB *s)
5086d916c6SFrancisco Iglesias {
5186d916c6SFrancisco Iglesias     bool pending = s->regs[R_CFU_ISR] & ~s->regs[R_CFU_IMR];
5286d916c6SFrancisco Iglesias     qemu_set_irq(s->irq_cfu_imr, pending);
5386d916c6SFrancisco Iglesias }
5486d916c6SFrancisco Iglesias 
cfu_isr_postw(RegisterInfo * reg,uint64_t val64)5586d916c6SFrancisco Iglesias static void cfu_isr_postw(RegisterInfo *reg, uint64_t val64)
5686d916c6SFrancisco Iglesias {
5786d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
5886d916c6SFrancisco Iglesias     cfu_imr_update_irq(s);
5986d916c6SFrancisco Iglesias }
6086d916c6SFrancisco Iglesias 
cfu_ier_prew(RegisterInfo * reg,uint64_t val64)6186d916c6SFrancisco Iglesias static uint64_t cfu_ier_prew(RegisterInfo *reg, uint64_t val64)
6286d916c6SFrancisco Iglesias {
6386d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
6486d916c6SFrancisco Iglesias     uint32_t val = val64;
6586d916c6SFrancisco Iglesias 
6686d916c6SFrancisco Iglesias     s->regs[R_CFU_IMR] &= ~val;
6786d916c6SFrancisco Iglesias     cfu_imr_update_irq(s);
6886d916c6SFrancisco Iglesias     return 0;
6986d916c6SFrancisco Iglesias }
7086d916c6SFrancisco Iglesias 
cfu_idr_prew(RegisterInfo * reg,uint64_t val64)7186d916c6SFrancisco Iglesias static uint64_t cfu_idr_prew(RegisterInfo *reg, uint64_t val64)
7286d916c6SFrancisco Iglesias {
7386d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
7486d916c6SFrancisco Iglesias     uint32_t val = val64;
7586d916c6SFrancisco Iglesias 
7686d916c6SFrancisco Iglesias     s->regs[R_CFU_IMR] |= val;
7786d916c6SFrancisco Iglesias     cfu_imr_update_irq(s);
7886d916c6SFrancisco Iglesias     return 0;
7986d916c6SFrancisco Iglesias }
8086d916c6SFrancisco Iglesias 
cfu_itr_prew(RegisterInfo * reg,uint64_t val64)8186d916c6SFrancisco Iglesias static uint64_t cfu_itr_prew(RegisterInfo *reg, uint64_t val64)
8286d916c6SFrancisco Iglesias {
8386d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
8486d916c6SFrancisco Iglesias     uint32_t val = val64;
8586d916c6SFrancisco Iglesias 
8686d916c6SFrancisco Iglesias     s->regs[R_CFU_ISR] |= val;
8786d916c6SFrancisco Iglesias     cfu_imr_update_irq(s);
8886d916c6SFrancisco Iglesias     return 0;
8986d916c6SFrancisco Iglesias }
9086d916c6SFrancisco Iglesias 
cfu_fgcr_postw(RegisterInfo * reg,uint64_t val64)9186d916c6SFrancisco Iglesias static void cfu_fgcr_postw(RegisterInfo *reg, uint64_t val64)
9286d916c6SFrancisco Iglesias {
9386d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
9486d916c6SFrancisco Iglesias     uint32_t val = (uint32_t)val64;
9586d916c6SFrancisco Iglesias 
9686d916c6SFrancisco Iglesias     /* Do a scan. It always looks good. */
9786d916c6SFrancisco Iglesias     if (FIELD_EX32(val, CFU_FGCR, SC_HBC_TRIGGER)) {
9886d916c6SFrancisco Iglesias         ARRAY_FIELD_DP32(s->regs, CFU_STATUS, SCAN_CLEAR_PASS, 1);
9986d916c6SFrancisco Iglesias         ARRAY_FIELD_DP32(s->regs, CFU_STATUS, SCAN_CLEAR_DONE, 1);
10086d916c6SFrancisco Iglesias     }
10186d916c6SFrancisco Iglesias }
10286d916c6SFrancisco Iglesias 
10386d916c6SFrancisco Iglesias static const RegisterAccessInfo cfu_apb_regs_info[] = {
10486d916c6SFrancisco Iglesias     {   .name = "CFU_ISR",  .addr = A_CFU_ISR,
10586d916c6SFrancisco Iglesias         .rsvd = 0xfffffc00,
10686d916c6SFrancisco Iglesias         .w1c = 0x3ff,
10786d916c6SFrancisco Iglesias         .post_write = cfu_isr_postw,
10886d916c6SFrancisco Iglesias     },{ .name = "CFU_IMR",  .addr = A_CFU_IMR,
10986d916c6SFrancisco Iglesias         .reset = 0x3ff,
11086d916c6SFrancisco Iglesias         .rsvd = 0xfffffc00,
11186d916c6SFrancisco Iglesias         .ro = 0x3ff,
11286d916c6SFrancisco Iglesias     },{ .name = "CFU_IER",  .addr = A_CFU_IER,
11386d916c6SFrancisco Iglesias         .rsvd = 0xfffffc00,
11486d916c6SFrancisco Iglesias         .pre_write = cfu_ier_prew,
11586d916c6SFrancisco Iglesias     },{ .name = "CFU_IDR",  .addr = A_CFU_IDR,
11686d916c6SFrancisco Iglesias         .rsvd = 0xfffffc00,
11786d916c6SFrancisco Iglesias         .pre_write = cfu_idr_prew,
11886d916c6SFrancisco Iglesias     },{ .name = "CFU_ITR",  .addr = A_CFU_ITR,
11986d916c6SFrancisco Iglesias         .rsvd = 0xfffffc00,
12086d916c6SFrancisco Iglesias         .pre_write = cfu_itr_prew,
12186d916c6SFrancisco Iglesias     },{ .name = "CFU_PROTECT",  .addr = A_CFU_PROTECT,
12286d916c6SFrancisco Iglesias         .reset = 0x1,
12386d916c6SFrancisco Iglesias     },{ .name = "CFU_FGCR",  .addr = A_CFU_FGCR,
12486d916c6SFrancisco Iglesias         .rsvd = 0xffff8000,
12586d916c6SFrancisco Iglesias         .post_write = cfu_fgcr_postw,
12686d916c6SFrancisco Iglesias     },{ .name = "CFU_CTL",  .addr = A_CFU_CTL,
12786d916c6SFrancisco Iglesias         .rsvd = 0xffff0000,
12886d916c6SFrancisco Iglesias     },{ .name = "CFU_CRAM_RW",  .addr = A_CFU_CRAM_RW,
12986d916c6SFrancisco Iglesias         .reset = 0x401f7d9,
13086d916c6SFrancisco Iglesias         .rsvd = 0xf8000000,
13186d916c6SFrancisco Iglesias     },{ .name = "CFU_MASK",  .addr = A_CFU_MASK,
13286d916c6SFrancisco Iglesias     },{ .name = "CFU_CRC_EXPECT",  .addr = A_CFU_CRC_EXPECT,
13386d916c6SFrancisco Iglesias     },{ .name = "CFU_CFRAME_LEFT_T0",  .addr = A_CFU_CFRAME_LEFT_T0,
13486d916c6SFrancisco Iglesias         .rsvd = 0xfff00000,
13586d916c6SFrancisco Iglesias     },{ .name = "CFU_CFRAME_LEFT_T1",  .addr = A_CFU_CFRAME_LEFT_T1,
13686d916c6SFrancisco Iglesias         .rsvd = 0xfff00000,
13786d916c6SFrancisco Iglesias     },{ .name = "CFU_CFRAME_LEFT_T2",  .addr = A_CFU_CFRAME_LEFT_T2,
13886d916c6SFrancisco Iglesias         .rsvd = 0xfff00000,
13986d916c6SFrancisco Iglesias     },{ .name = "CFU_ROW_RANGE",  .addr = A_CFU_ROW_RANGE,
14086d916c6SFrancisco Iglesias         .rsvd = 0xffffffc0,
14186d916c6SFrancisco Iglesias         .ro = 0x3f,
14286d916c6SFrancisco Iglesias     },{ .name = "CFU_STATUS",  .addr = A_CFU_STATUS,
14386d916c6SFrancisco Iglesias         .rsvd = 0x80000000,
14486d916c6SFrancisco Iglesias         .ro = 0x7fffffff,
14586d916c6SFrancisco Iglesias     },{ .name = "CFU_INTERNAL_STATUS",  .addr = A_CFU_INTERNAL_STATUS,
14686d916c6SFrancisco Iglesias         .rsvd = 0xff800000,
14786d916c6SFrancisco Iglesias         .ro = 0x7fffff,
14886d916c6SFrancisco Iglesias     },{ .name = "CFU_QWORD_CNT",  .addr = A_CFU_QWORD_CNT,
14986d916c6SFrancisco Iglesias         .ro = 0xffffffff,
15086d916c6SFrancisco Iglesias     },{ .name = "CFU_CRC_LIVE",  .addr = A_CFU_CRC_LIVE,
15186d916c6SFrancisco Iglesias         .ro = 0xffffffff,
15286d916c6SFrancisco Iglesias     },{ .name = "CFU_PENDING_READ_CNT",  .addr = A_CFU_PENDING_READ_CNT,
15386d916c6SFrancisco Iglesias         .rsvd = 0xfe000000,
15486d916c6SFrancisco Iglesias         .ro = 0x1ffffff,
15586d916c6SFrancisco Iglesias     },{ .name = "CFU_FDRI_CNT",  .addr = A_CFU_FDRI_CNT,
15686d916c6SFrancisco Iglesias         .ro = 0xffffffff,
15786d916c6SFrancisco Iglesias     },{ .name = "CFU_ECO1",  .addr = A_CFU_ECO1,
15886d916c6SFrancisco Iglesias     },{ .name = "CFU_ECO2",  .addr = A_CFU_ECO2,
15986d916c6SFrancisco Iglesias     }
16086d916c6SFrancisco Iglesias };
16186d916c6SFrancisco Iglesias 
cfu_apb_reset(DeviceState * dev)16286d916c6SFrancisco Iglesias static void cfu_apb_reset(DeviceState *dev)
16386d916c6SFrancisco Iglesias {
16486d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(dev);
16586d916c6SFrancisco Iglesias     unsigned int i;
16686d916c6SFrancisco Iglesias 
16786d916c6SFrancisco Iglesias     for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
16886d916c6SFrancisco Iglesias         register_reset(&s->regs_info[i]);
16986d916c6SFrancisco Iglesias     }
17086d916c6SFrancisco Iglesias     memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
17186d916c6SFrancisco Iglesias 
17286d916c6SFrancisco Iglesias     s->regs[R_CFU_STATUS] |= R_CFU_STATUS_HC_COMPLETE_MASK;
17386d916c6SFrancisco Iglesias     cfu_imr_update_irq(s);
17486d916c6SFrancisco Iglesias }
17586d916c6SFrancisco Iglesias 
17686d916c6SFrancisco Iglesias static const MemoryRegionOps cfu_apb_ops = {
17786d916c6SFrancisco Iglesias     .read = register_read_memory,
17886d916c6SFrancisco Iglesias     .write = register_write_memory,
17986d916c6SFrancisco Iglesias     .endianness = DEVICE_LITTLE_ENDIAN,
18086d916c6SFrancisco Iglesias     .valid = {
18186d916c6SFrancisco Iglesias         .min_access_size = 4,
18286d916c6SFrancisco Iglesias         .max_access_size = 4,
18386d916c6SFrancisco Iglesias     },
18486d916c6SFrancisco Iglesias };
18586d916c6SFrancisco Iglesias 
cfu_transfer_cfi_packet(XlnxVersalCFUAPB * s,uint8_t row_addr,XlnxCfiPacket * pkt)18686d916c6SFrancisco Iglesias static void cfu_transfer_cfi_packet(XlnxVersalCFUAPB *s, uint8_t row_addr,
18786d916c6SFrancisco Iglesias                                     XlnxCfiPacket *pkt)
18886d916c6SFrancisco Iglesias {
18986d916c6SFrancisco Iglesias     if (row_addr == CFRAME_BROADCAST_ROW) {
19086d916c6SFrancisco Iglesias         for (int i = 0; i < ARRAY_SIZE(s->cfg.cframe); i++) {
19186d916c6SFrancisco Iglesias             if (s->cfg.cframe[i]) {
19286d916c6SFrancisco Iglesias                 xlnx_cfi_transfer_packet(s->cfg.cframe[i], pkt);
19386d916c6SFrancisco Iglesias             }
19486d916c6SFrancisco Iglesias         }
19586d916c6SFrancisco Iglesias     } else {
19686d916c6SFrancisco Iglesias             assert(row_addr < ARRAY_SIZE(s->cfg.cframe));
19786d916c6SFrancisco Iglesias 
19886d916c6SFrancisco Iglesias             if (s->cfg.cframe[row_addr]) {
19986d916c6SFrancisco Iglesias                 xlnx_cfi_transfer_packet(s->cfg.cframe[row_addr], pkt);
20086d916c6SFrancisco Iglesias             }
20186d916c6SFrancisco Iglesias     }
20286d916c6SFrancisco Iglesias }
20386d916c6SFrancisco Iglesias 
cfu_stream_read(void * opaque,hwaddr addr,unsigned size)20486d916c6SFrancisco Iglesias static uint64_t cfu_stream_read(void *opaque, hwaddr addr, unsigned size)
20586d916c6SFrancisco Iglesias {
20686d916c6SFrancisco Iglesias     qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
20786d916c6SFrancisco Iglesias                   HWADDR_PRIx "\n", __func__, addr);
20886d916c6SFrancisco Iglesias     return 0;
20986d916c6SFrancisco Iglesias }
21086d916c6SFrancisco Iglesias 
cfu_stream_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)21186d916c6SFrancisco Iglesias static void cfu_stream_write(void *opaque, hwaddr addr, uint64_t value,
21286d916c6SFrancisco Iglesias                       unsigned size)
21386d916c6SFrancisco Iglesias {
21486d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(opaque);
21586d916c6SFrancisco Iglesias     uint32_t wfifo[WFIFO_SZ];
21686d916c6SFrancisco Iglesias 
21786d916c6SFrancisco Iglesias     if (update_wfifo(addr, value, s->wfifo, wfifo)) {
21886d916c6SFrancisco Iglesias         uint8_t packet_type, row_addr, reg_addr;
21986d916c6SFrancisco Iglesias 
22086d916c6SFrancisco Iglesias         packet_type = extract32(wfifo[0], 24, 8);
22186d916c6SFrancisco Iglesias         row_addr = extract32(wfifo[0], 16, 5);
22286d916c6SFrancisco Iglesias         reg_addr = extract32(wfifo[0], 8, 6);
22386d916c6SFrancisco Iglesias 
22486d916c6SFrancisco Iglesias         /* Compressed bitstreams are not supported yet. */
22586d916c6SFrancisco Iglesias         if (ARRAY_FIELD_EX32(s->regs, CFU_CTL, DECOMPRESS) == 0) {
22686d916c6SFrancisco Iglesias             if (s->regs[R_CFU_FDRI_CNT]) {
22786d916c6SFrancisco Iglesias                 XlnxCfiPacket pkt = {
22886d916c6SFrancisco Iglesias                     .reg_addr = CFRAME_FDRI,
22986d916c6SFrancisco Iglesias                     .data[0] = wfifo[0],
23086d916c6SFrancisco Iglesias                     .data[1] = wfifo[1],
23186d916c6SFrancisco Iglesias                     .data[2] = wfifo[2],
23286d916c6SFrancisco Iglesias                     .data[3] = wfifo[3]
23386d916c6SFrancisco Iglesias                 };
23486d916c6SFrancisco Iglesias 
23586d916c6SFrancisco Iglesias                 cfu_transfer_cfi_packet(s, s->fdri_row_addr, &pkt);
23686d916c6SFrancisco Iglesias 
23786d916c6SFrancisco Iglesias                 s->regs[R_CFU_FDRI_CNT]--;
23886d916c6SFrancisco Iglesias 
23986d916c6SFrancisco Iglesias             } else if (packet_type == PACKET_TYPE_CFU &&
24086d916c6SFrancisco Iglesias                        reg_addr == CFRAME_FDRI) {
24186d916c6SFrancisco Iglesias 
24286d916c6SFrancisco Iglesias                 /* Load R_CFU_FDRI_CNT, must be multiple of 25 */
24386d916c6SFrancisco Iglesias                 s->regs[R_CFU_FDRI_CNT] = wfifo[1];
24486d916c6SFrancisco Iglesias 
24586d916c6SFrancisco Iglesias                 /* Store target row_addr */
24686d916c6SFrancisco Iglesias                 s->fdri_row_addr = row_addr;
24786d916c6SFrancisco Iglesias 
24886d916c6SFrancisco Iglesias                 if (wfifo[1] % 25 != 0) {
24986d916c6SFrancisco Iglesias                     qemu_log_mask(LOG_GUEST_ERROR,
25086d916c6SFrancisco Iglesias                                   "CFU FDRI_CNT is not loaded with "
25186d916c6SFrancisco Iglesias                                   "a multiple of 25 value\n");
25286d916c6SFrancisco Iglesias                 }
25386d916c6SFrancisco Iglesias 
25486d916c6SFrancisco Iglesias             } else if (packet_type == PACKET_TYPE_CFRAME) {
25586d916c6SFrancisco Iglesias                 XlnxCfiPacket pkt = {
25686d916c6SFrancisco Iglesias                     .reg_addr = reg_addr,
25786d916c6SFrancisco Iglesias                     .data[0] = wfifo[1],
25886d916c6SFrancisco Iglesias                     .data[1] = wfifo[2],
25986d916c6SFrancisco Iglesias                     .data[2] = wfifo[3],
26086d916c6SFrancisco Iglesias                 };
26186d916c6SFrancisco Iglesias                 cfu_transfer_cfi_packet(s, row_addr, &pkt);
26286d916c6SFrancisco Iglesias             }
26386d916c6SFrancisco Iglesias         }
26486d916c6SFrancisco Iglesias     }
26586d916c6SFrancisco Iglesias }
26686d916c6SFrancisco Iglesias 
cfu_sfr_read(void * opaque,hwaddr addr,unsigned size)267975dd496SFrancisco Iglesias static uint64_t cfu_sfr_read(void *opaque, hwaddr addr, unsigned size)
268975dd496SFrancisco Iglesias {
269975dd496SFrancisco Iglesias     qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
270975dd496SFrancisco Iglesias                   HWADDR_PRIx "\n", __func__, addr);
271975dd496SFrancisco Iglesias     return 0;
272975dd496SFrancisco Iglesias }
273975dd496SFrancisco Iglesias 
cfu_sfr_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)274975dd496SFrancisco Iglesias static void cfu_sfr_write(void *opaque, hwaddr addr, uint64_t value,
275975dd496SFrancisco Iglesias                       unsigned size)
276975dd496SFrancisco Iglesias {
277975dd496SFrancisco Iglesias     XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(opaque);
278975dd496SFrancisco Iglesias     uint32_t wfifo[WFIFO_SZ];
279975dd496SFrancisco Iglesias 
280975dd496SFrancisco Iglesias     if (update_wfifo(addr, value, s->wfifo, wfifo)) {
281975dd496SFrancisco Iglesias         uint8_t row_addr = extract32(wfifo[0], 23, 5);
282975dd496SFrancisco Iglesias         uint32_t frame_addr = extract32(wfifo[0], 0, 23);
283975dd496SFrancisco Iglesias         XlnxCfiPacket pkt = { .reg_addr = CFRAME_SFR,
284975dd496SFrancisco Iglesias                               .data[0] = frame_addr };
285975dd496SFrancisco Iglesias 
286975dd496SFrancisco Iglesias         if (s->cfg.cfu) {
287975dd496SFrancisco Iglesias             cfu_transfer_cfi_packet(s->cfg.cfu, row_addr, &pkt);
288975dd496SFrancisco Iglesias         }
289975dd496SFrancisco Iglesias     }
290975dd496SFrancisco Iglesias }
291975dd496SFrancisco Iglesias 
cfu_fdro_read(void * opaque,hwaddr addr,unsigned size)292ebfdc494SFrancisco Iglesias static uint64_t cfu_fdro_read(void *opaque, hwaddr addr, unsigned size)
293ebfdc494SFrancisco Iglesias {
294ebfdc494SFrancisco Iglesias     XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(opaque);
295ebfdc494SFrancisco Iglesias     uint64_t ret = 0;
296ebfdc494SFrancisco Iglesias 
297ebfdc494SFrancisco Iglesias     if (!fifo32_is_empty(&s->fdro_data)) {
298ebfdc494SFrancisco Iglesias         ret = fifo32_pop(&s->fdro_data);
299ebfdc494SFrancisco Iglesias     }
300ebfdc494SFrancisco Iglesias 
301ebfdc494SFrancisco Iglesias     return ret;
302ebfdc494SFrancisco Iglesias }
303ebfdc494SFrancisco Iglesias 
cfu_fdro_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)304ebfdc494SFrancisco Iglesias static void cfu_fdro_write(void *opaque, hwaddr addr, uint64_t value,
305ebfdc494SFrancisco Iglesias                            unsigned size)
306ebfdc494SFrancisco Iglesias {
307ebfdc494SFrancisco Iglesias     qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported write from addr=%"
308ebfdc494SFrancisco Iglesias                   HWADDR_PRIx "\n", __func__, addr);
309ebfdc494SFrancisco Iglesias }
310ebfdc494SFrancisco Iglesias 
31186d916c6SFrancisco Iglesias static const MemoryRegionOps cfu_stream_ops = {
31286d916c6SFrancisco Iglesias     .read = cfu_stream_read,
31386d916c6SFrancisco Iglesias     .write = cfu_stream_write,
31486d916c6SFrancisco Iglesias     .endianness = DEVICE_LITTLE_ENDIAN,
31586d916c6SFrancisco Iglesias     .valid = {
31686d916c6SFrancisco Iglesias         .min_access_size = 4,
31786d916c6SFrancisco Iglesias         .max_access_size = 8,
31886d916c6SFrancisco Iglesias     },
31986d916c6SFrancisco Iglesias };
32086d916c6SFrancisco Iglesias 
321975dd496SFrancisco Iglesias static const MemoryRegionOps cfu_sfr_ops = {
322975dd496SFrancisco Iglesias     .read = cfu_sfr_read,
323975dd496SFrancisco Iglesias     .write = cfu_sfr_write,
324975dd496SFrancisco Iglesias     .endianness = DEVICE_LITTLE_ENDIAN,
325975dd496SFrancisco Iglesias     .valid = {
326975dd496SFrancisco Iglesias         .min_access_size = 4,
327975dd496SFrancisco Iglesias         .max_access_size = 4,
328975dd496SFrancisco Iglesias     },
329975dd496SFrancisco Iglesias };
330975dd496SFrancisco Iglesias 
331ebfdc494SFrancisco Iglesias static const MemoryRegionOps cfu_fdro_ops = {
332ebfdc494SFrancisco Iglesias     .read = cfu_fdro_read,
333ebfdc494SFrancisco Iglesias     .write = cfu_fdro_write,
334ebfdc494SFrancisco Iglesias     .endianness = DEVICE_LITTLE_ENDIAN,
335ebfdc494SFrancisco Iglesias     .valid = {
336ebfdc494SFrancisco Iglesias         .min_access_size = 4,
337ebfdc494SFrancisco Iglesias         .max_access_size = 4,
338ebfdc494SFrancisco Iglesias     },
339ebfdc494SFrancisco Iglesias };
340ebfdc494SFrancisco Iglesias 
cfu_apb_init(Object * obj)34186d916c6SFrancisco Iglesias static void cfu_apb_init(Object *obj)
34286d916c6SFrancisco Iglesias {
34386d916c6SFrancisco Iglesias     XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(obj);
34486d916c6SFrancisco Iglesias     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
34586d916c6SFrancisco Iglesias     RegisterInfoArray *reg_array;
34686d916c6SFrancisco Iglesias     unsigned int i;
34786d916c6SFrancisco Iglesias     char *name;
34886d916c6SFrancisco Iglesias 
34986d916c6SFrancisco Iglesias     memory_region_init(&s->iomem, obj, TYPE_XLNX_VERSAL_CFU_APB, R_MAX * 4);
35086d916c6SFrancisco Iglesias     reg_array =
35186d916c6SFrancisco Iglesias         register_init_block32(DEVICE(obj), cfu_apb_regs_info,
35286d916c6SFrancisco Iglesias                               ARRAY_SIZE(cfu_apb_regs_info),
35386d916c6SFrancisco Iglesias                               s->regs_info, s->regs,
35486d916c6SFrancisco Iglesias                               &cfu_apb_ops,
35586d916c6SFrancisco Iglesias                               XLNX_VERSAL_CFU_APB_ERR_DEBUG,
35686d916c6SFrancisco Iglesias                               R_MAX * 4);
35786d916c6SFrancisco Iglesias     memory_region_add_subregion(&s->iomem,
35886d916c6SFrancisco Iglesias                                 0x0,
35986d916c6SFrancisco Iglesias                                 &reg_array->mem);
36086d916c6SFrancisco Iglesias     sysbus_init_mmio(sbd, &s->iomem);
36186d916c6SFrancisco Iglesias     for (i = 0; i < NUM_STREAM; i++) {
36286d916c6SFrancisco Iglesias         name = g_strdup_printf(TYPE_XLNX_VERSAL_CFU_APB "-stream%d", i);
36386d916c6SFrancisco Iglesias         memory_region_init_io(&s->iomem_stream[i], obj, &cfu_stream_ops, s,
36486d916c6SFrancisco Iglesias                           name, i == 0 ? KEYHOLE_STREAM_4K :
36586d916c6SFrancisco Iglesias                                          KEYHOLE_STREAM_256K);
36686d916c6SFrancisco Iglesias         sysbus_init_mmio(sbd, &s->iomem_stream[i]);
36786d916c6SFrancisco Iglesias         g_free(name);
36886d916c6SFrancisco Iglesias     }
36986d916c6SFrancisco Iglesias     sysbus_init_irq(sbd, &s->irq_cfu_imr);
37086d916c6SFrancisco Iglesias }
37186d916c6SFrancisco Iglesias 
cfu_sfr_init(Object * obj)372975dd496SFrancisco Iglesias static void cfu_sfr_init(Object *obj)
373975dd496SFrancisco Iglesias {
374975dd496SFrancisco Iglesias     XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(obj);
375975dd496SFrancisco Iglesias     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
376975dd496SFrancisco Iglesias 
377975dd496SFrancisco Iglesias     memory_region_init_io(&s->iomem_sfr, obj, &cfu_sfr_ops, s,
378975dd496SFrancisco Iglesias                           TYPE_XLNX_VERSAL_CFU_SFR, KEYHOLE_STREAM_4K);
379975dd496SFrancisco Iglesias     sysbus_init_mmio(sbd, &s->iomem_sfr);
380975dd496SFrancisco Iglesias }
381975dd496SFrancisco Iglesias 
cfu_sfr_reset_enter(Object * obj,ResetType type)382975dd496SFrancisco Iglesias static void cfu_sfr_reset_enter(Object *obj, ResetType type)
383975dd496SFrancisco Iglesias {
384975dd496SFrancisco Iglesias     XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(obj);
385975dd496SFrancisco Iglesias 
386975dd496SFrancisco Iglesias     memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
387975dd496SFrancisco Iglesias }
388975dd496SFrancisco Iglesias 
cfu_fdro_init(Object * obj)389ebfdc494SFrancisco Iglesias static void cfu_fdro_init(Object *obj)
390ebfdc494SFrancisco Iglesias {
391ebfdc494SFrancisco Iglesias     XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
392ebfdc494SFrancisco Iglesias     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
393ebfdc494SFrancisco Iglesias 
394ebfdc494SFrancisco Iglesias     memory_region_init_io(&s->iomem_fdro, obj, &cfu_fdro_ops, s,
395ebfdc494SFrancisco Iglesias                           TYPE_XLNX_VERSAL_CFU_FDRO, KEYHOLE_STREAM_4K);
396ebfdc494SFrancisco Iglesias     sysbus_init_mmio(sbd, &s->iomem_fdro);
397ebfdc494SFrancisco Iglesias     fifo32_create(&s->fdro_data, 8 * KiB / sizeof(uint32_t));
398ebfdc494SFrancisco Iglesias }
399ebfdc494SFrancisco Iglesias 
cfu_fdro_finalize(Object * obj)400d30d590bSPeter Maydell static void cfu_fdro_finalize(Object *obj)
401d30d590bSPeter Maydell {
402d30d590bSPeter Maydell     XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
403d30d590bSPeter Maydell 
404d30d590bSPeter Maydell     fifo32_destroy(&s->fdro_data);
405d30d590bSPeter Maydell }
406d30d590bSPeter Maydell 
cfu_fdro_reset_enter(Object * obj,ResetType type)407ebfdc494SFrancisco Iglesias static void cfu_fdro_reset_enter(Object *obj, ResetType type)
408ebfdc494SFrancisco Iglesias {
409ebfdc494SFrancisco Iglesias     XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
410ebfdc494SFrancisco Iglesias 
411ebfdc494SFrancisco Iglesias     fifo32_reset(&s->fdro_data);
412ebfdc494SFrancisco Iglesias }
413ebfdc494SFrancisco Iglesias 
cfu_fdro_cfi_transfer_packet(XlnxCfiIf * cfi_if,XlnxCfiPacket * pkt)414ebfdc494SFrancisco Iglesias static void cfu_fdro_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt)
415ebfdc494SFrancisco Iglesias {
416ebfdc494SFrancisco Iglesias     XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(cfi_if);
417ebfdc494SFrancisco Iglesias 
418ebfdc494SFrancisco Iglesias     if (fifo32_num_free(&s->fdro_data) >= ARRAY_SIZE(pkt->data)) {
419ebfdc494SFrancisco Iglesias         for (int i = 0; i < ARRAY_SIZE(pkt->data); i++) {
420ebfdc494SFrancisco Iglesias             fifo32_push(&s->fdro_data, pkt->data[i]);
421ebfdc494SFrancisco Iglesias         }
422ebfdc494SFrancisco Iglesias     } else {
423ebfdc494SFrancisco Iglesias         /* It is a programming error to fill the fifo. */
424ebfdc494SFrancisco Iglesias         qemu_log_mask(LOG_GUEST_ERROR,
425ebfdc494SFrancisco Iglesias                       "CFU_FDRO: CFI data dropped due to full read fifo\n");
426ebfdc494SFrancisco Iglesias     }
427ebfdc494SFrancisco Iglesias }
428ebfdc494SFrancisco Iglesias 
42986d916c6SFrancisco Iglesias static Property cfu_props[] = {
43086d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe0", XlnxVersalCFUAPB, cfg.cframe[0],
43186d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
43286d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe1", XlnxVersalCFUAPB, cfg.cframe[1],
43386d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
43486d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe2", XlnxVersalCFUAPB, cfg.cframe[2],
43586d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
43686d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe3", XlnxVersalCFUAPB, cfg.cframe[3],
43786d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
43886d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe4", XlnxVersalCFUAPB, cfg.cframe[4],
43986d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
44086d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe5", XlnxVersalCFUAPB, cfg.cframe[5],
44186d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
44286d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe6", XlnxVersalCFUAPB, cfg.cframe[6],
44386d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
44486d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe7", XlnxVersalCFUAPB, cfg.cframe[7],
44586d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
44686d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe8", XlnxVersalCFUAPB, cfg.cframe[8],
44786d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
44886d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe9", XlnxVersalCFUAPB, cfg.cframe[9],
44986d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
45086d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe10", XlnxVersalCFUAPB, cfg.cframe[10],
45186d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
45286d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe11", XlnxVersalCFUAPB, cfg.cframe[11],
45386d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
45486d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe12", XlnxVersalCFUAPB, cfg.cframe[12],
45586d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
45686d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe13", XlnxVersalCFUAPB, cfg.cframe[13],
45786d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
45886d916c6SFrancisco Iglesias         DEFINE_PROP_LINK("cframe14", XlnxVersalCFUAPB, cfg.cframe[14],
45986d916c6SFrancisco Iglesias                          TYPE_XLNX_CFI_IF, XlnxCfiIf *),
46086d916c6SFrancisco Iglesias         DEFINE_PROP_END_OF_LIST(),
46186d916c6SFrancisco Iglesias };
46286d916c6SFrancisco Iglesias 
463975dd496SFrancisco Iglesias static Property cfu_sfr_props[] = {
464975dd496SFrancisco Iglesias         DEFINE_PROP_LINK("cfu", XlnxVersalCFUSFR, cfg.cfu,
465975dd496SFrancisco Iglesias                          TYPE_XLNX_VERSAL_CFU_APB, XlnxVersalCFUAPB *),
466975dd496SFrancisco Iglesias         DEFINE_PROP_END_OF_LIST(),
467975dd496SFrancisco Iglesias };
468975dd496SFrancisco Iglesias 
46986d916c6SFrancisco Iglesias static const VMStateDescription vmstate_cfu_apb = {
47086d916c6SFrancisco Iglesias     .name = TYPE_XLNX_VERSAL_CFU_APB,
47186d916c6SFrancisco Iglesias     .version_id = 1,
47286d916c6SFrancisco Iglesias     .minimum_version_id = 1,
473e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
47486d916c6SFrancisco Iglesias         VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFUAPB, 4),
47586d916c6SFrancisco Iglesias         VMSTATE_UINT32_ARRAY(regs, XlnxVersalCFUAPB, R_MAX),
47686d916c6SFrancisco Iglesias         VMSTATE_UINT8(fdri_row_addr, XlnxVersalCFUAPB),
47786d916c6SFrancisco Iglesias         VMSTATE_END_OF_LIST(),
47886d916c6SFrancisco Iglesias     }
47986d916c6SFrancisco Iglesias };
48086d916c6SFrancisco Iglesias 
481ebfdc494SFrancisco Iglesias static const VMStateDescription vmstate_cfu_fdro = {
482ebfdc494SFrancisco Iglesias     .name = TYPE_XLNX_VERSAL_CFU_FDRO,
483ebfdc494SFrancisco Iglesias     .version_id = 1,
484ebfdc494SFrancisco Iglesias     .minimum_version_id = 1,
485e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
486ebfdc494SFrancisco Iglesias         VMSTATE_FIFO32(fdro_data, XlnxVersalCFUFDRO),
487ebfdc494SFrancisco Iglesias         VMSTATE_END_OF_LIST(),
488ebfdc494SFrancisco Iglesias     }
489ebfdc494SFrancisco Iglesias };
490ebfdc494SFrancisco Iglesias 
491975dd496SFrancisco Iglesias static const VMStateDescription vmstate_cfu_sfr = {
492975dd496SFrancisco Iglesias     .name = TYPE_XLNX_VERSAL_CFU_SFR,
493975dd496SFrancisco Iglesias     .version_id = 1,
494975dd496SFrancisco Iglesias     .minimum_version_id = 1,
495e4ea952fSRichard Henderson     .fields = (const VMStateField[]) {
496975dd496SFrancisco Iglesias         VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFUSFR, 4),
497975dd496SFrancisco Iglesias         VMSTATE_END_OF_LIST(),
498975dd496SFrancisco Iglesias     }
499975dd496SFrancisco Iglesias };
500975dd496SFrancisco Iglesias 
cfu_apb_class_init(ObjectClass * klass,void * data)50186d916c6SFrancisco Iglesias static void cfu_apb_class_init(ObjectClass *klass, void *data)
50286d916c6SFrancisco Iglesias {
50386d916c6SFrancisco Iglesias     DeviceClass *dc = DEVICE_CLASS(klass);
50486d916c6SFrancisco Iglesias 
505*e3d08143SPeter Maydell     device_class_set_legacy_reset(dc, cfu_apb_reset);
50686d916c6SFrancisco Iglesias     dc->vmsd = &vmstate_cfu_apb;
50786d916c6SFrancisco Iglesias     device_class_set_props(dc, cfu_props);
50886d916c6SFrancisco Iglesias }
50986d916c6SFrancisco Iglesias 
cfu_fdro_class_init(ObjectClass * klass,void * data)510ebfdc494SFrancisco Iglesias static void cfu_fdro_class_init(ObjectClass *klass, void *data)
511ebfdc494SFrancisco Iglesias {
512ebfdc494SFrancisco Iglesias     DeviceClass *dc = DEVICE_CLASS(klass);
513ebfdc494SFrancisco Iglesias     ResettableClass *rc = RESETTABLE_CLASS(klass);
514ebfdc494SFrancisco Iglesias     XlnxCfiIfClass *xcic = XLNX_CFI_IF_CLASS(klass);
515ebfdc494SFrancisco Iglesias 
516ebfdc494SFrancisco Iglesias     dc->vmsd = &vmstate_cfu_fdro;
517ebfdc494SFrancisco Iglesias     xcic->cfi_transfer_packet = cfu_fdro_cfi_transfer_packet;
518ebfdc494SFrancisco Iglesias     rc->phases.enter = cfu_fdro_reset_enter;
519ebfdc494SFrancisco Iglesias }
520ebfdc494SFrancisco Iglesias 
cfu_sfr_class_init(ObjectClass * klass,void * data)521975dd496SFrancisco Iglesias static void cfu_sfr_class_init(ObjectClass *klass, void *data)
522975dd496SFrancisco Iglesias {
523975dd496SFrancisco Iglesias     DeviceClass *dc = DEVICE_CLASS(klass);
524975dd496SFrancisco Iglesias     ResettableClass *rc = RESETTABLE_CLASS(klass);
525975dd496SFrancisco Iglesias 
526975dd496SFrancisco Iglesias     device_class_set_props(dc, cfu_sfr_props);
527975dd496SFrancisco Iglesias     dc->vmsd = &vmstate_cfu_sfr;
528975dd496SFrancisco Iglesias     rc->phases.enter = cfu_sfr_reset_enter;
529975dd496SFrancisco Iglesias }
530975dd496SFrancisco Iglesias 
53186d916c6SFrancisco Iglesias static const TypeInfo cfu_apb_info = {
53286d916c6SFrancisco Iglesias     .name          = TYPE_XLNX_VERSAL_CFU_APB,
53386d916c6SFrancisco Iglesias     .parent        = TYPE_SYS_BUS_DEVICE,
53486d916c6SFrancisco Iglesias     .instance_size = sizeof(XlnxVersalCFUAPB),
53586d916c6SFrancisco Iglesias     .class_init    = cfu_apb_class_init,
53686d916c6SFrancisco Iglesias     .instance_init = cfu_apb_init,
53786d916c6SFrancisco Iglesias     .interfaces = (InterfaceInfo[]) {
53886d916c6SFrancisco Iglesias         { TYPE_XLNX_CFI_IF },
53986d916c6SFrancisco Iglesias         { }
54086d916c6SFrancisco Iglesias     }
54186d916c6SFrancisco Iglesias };
54286d916c6SFrancisco Iglesias 
543ebfdc494SFrancisco Iglesias static const TypeInfo cfu_fdro_info = {
544ebfdc494SFrancisco Iglesias     .name          = TYPE_XLNX_VERSAL_CFU_FDRO,
545ebfdc494SFrancisco Iglesias     .parent        = TYPE_SYS_BUS_DEVICE,
546ebfdc494SFrancisco Iglesias     .instance_size = sizeof(XlnxVersalCFUFDRO),
547ebfdc494SFrancisco Iglesias     .class_init    = cfu_fdro_class_init,
548ebfdc494SFrancisco Iglesias     .instance_init = cfu_fdro_init,
549d30d590bSPeter Maydell     .instance_finalize = cfu_fdro_finalize,
550ebfdc494SFrancisco Iglesias     .interfaces = (InterfaceInfo[]) {
551ebfdc494SFrancisco Iglesias         { TYPE_XLNX_CFI_IF },
552ebfdc494SFrancisco Iglesias         { }
553ebfdc494SFrancisco Iglesias     }
554ebfdc494SFrancisco Iglesias };
555ebfdc494SFrancisco Iglesias 
556975dd496SFrancisco Iglesias static const TypeInfo cfu_sfr_info = {
557975dd496SFrancisco Iglesias     .name          = TYPE_XLNX_VERSAL_CFU_SFR,
558975dd496SFrancisco Iglesias     .parent        = TYPE_SYS_BUS_DEVICE,
559975dd496SFrancisco Iglesias     .instance_size = sizeof(XlnxVersalCFUSFR),
560975dd496SFrancisco Iglesias     .class_init    = cfu_sfr_class_init,
561975dd496SFrancisco Iglesias     .instance_init = cfu_sfr_init,
562975dd496SFrancisco Iglesias };
563975dd496SFrancisco Iglesias 
cfu_apb_register_types(void)56486d916c6SFrancisco Iglesias static void cfu_apb_register_types(void)
56586d916c6SFrancisco Iglesias {
56686d916c6SFrancisco Iglesias     type_register_static(&cfu_apb_info);
567ebfdc494SFrancisco Iglesias     type_register_static(&cfu_fdro_info);
568975dd496SFrancisco Iglesias     type_register_static(&cfu_sfr_info);
56986d916c6SFrancisco Iglesias }
57086d916c6SFrancisco Iglesias 
57186d916c6SFrancisco Iglesias type_init(cfu_apb_register_types)
572