1c6766f5bSFrancisco Iglesias /*
2c6766f5bSFrancisco Iglesias * QEMU model of the Configuration Frame Control module
3c6766f5bSFrancisco Iglesias *
4c6766f5bSFrancisco Iglesias * Copyright (C) 2023, Advanced Micro Devices, Inc.
5c6766f5bSFrancisco Iglesias *
6c6766f5bSFrancisco Iglesias * Written by Francisco Iglesias <francisco.iglesias@amd.com>
7c6766f5bSFrancisco Iglesias *
8c6766f5bSFrancisco Iglesias * SPDX-License-Identifier: GPL-2.0-or-later
9c6766f5bSFrancisco Iglesias */
10c6766f5bSFrancisco Iglesias
11c6766f5bSFrancisco Iglesias #include "qemu/osdep.h"
12c6766f5bSFrancisco Iglesias #include "hw/sysbus.h"
13c6766f5bSFrancisco Iglesias #include "hw/register.h"
14c6766f5bSFrancisco Iglesias #include "hw/registerfields.h"
15c6766f5bSFrancisco Iglesias #include "qemu/bitops.h"
16c6766f5bSFrancisco Iglesias #include "qemu/log.h"
17c6766f5bSFrancisco Iglesias #include "qemu/units.h"
18c6766f5bSFrancisco Iglesias #include "qapi/error.h"
19c6766f5bSFrancisco Iglesias #include "hw/qdev-properties.h"
20c6766f5bSFrancisco Iglesias #include "migration/vmstate.h"
21c6766f5bSFrancisco Iglesias #include "hw/irq.h"
22c6766f5bSFrancisco Iglesias #include "hw/misc/xlnx-versal-cframe-reg.h"
23c6766f5bSFrancisco Iglesias
24c6766f5bSFrancisco Iglesias #ifndef XLNX_VERSAL_CFRAME_REG_ERR_DEBUG
25c6766f5bSFrancisco Iglesias #define XLNX_VERSAL_CFRAME_REG_ERR_DEBUG 0
26c6766f5bSFrancisco Iglesias #endif
27c6766f5bSFrancisco Iglesias
28c6766f5bSFrancisco Iglesias #define KEYHOLE_STREAM_4K (4 * KiB)
29c6766f5bSFrancisco Iglesias #define N_WORDS_128BIT 4
30c6766f5bSFrancisco Iglesias
31c6766f5bSFrancisco Iglesias #define MAX_BLOCKTYPE 6
32c6766f5bSFrancisco Iglesias #define MAX_BLOCKTYPE_FRAMES 0xFFFFF
33c6766f5bSFrancisco Iglesias
34c6766f5bSFrancisco Iglesias enum {
35c6766f5bSFrancisco Iglesias CFRAME_CMD_WCFG = 1,
36c6766f5bSFrancisco Iglesias CFRAME_CMD_ROWON = 2,
37c6766f5bSFrancisco Iglesias CFRAME_CMD_ROWOFF = 3,
38c6766f5bSFrancisco Iglesias CFRAME_CMD_RCFG = 4,
39c6766f5bSFrancisco Iglesias CFRAME_CMD_DLPARK = 5,
40c6766f5bSFrancisco Iglesias };
41c6766f5bSFrancisco Iglesias
int_cmp(gconstpointer a,gconstpointer b,gpointer user_data)42c6766f5bSFrancisco Iglesias static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
43c6766f5bSFrancisco Iglesias {
44c6766f5bSFrancisco Iglesias guint ua = GPOINTER_TO_UINT(a);
45c6766f5bSFrancisco Iglesias guint ub = GPOINTER_TO_UINT(b);
46c6766f5bSFrancisco Iglesias return (ua > ub) - (ua < ub);
47c6766f5bSFrancisco Iglesias }
48c6766f5bSFrancisco Iglesias
cfrm_imr_update_irq(XlnxVersalCFrameReg * s)49c6766f5bSFrancisco Iglesias static void cfrm_imr_update_irq(XlnxVersalCFrameReg *s)
50c6766f5bSFrancisco Iglesias {
51c6766f5bSFrancisco Iglesias bool pending = s->regs[R_CFRM_ISR0] & ~s->regs[R_CFRM_IMR0];
52c6766f5bSFrancisco Iglesias qemu_set_irq(s->irq_cfrm_imr, pending);
53c6766f5bSFrancisco Iglesias }
54c6766f5bSFrancisco Iglesias
cfrm_isr_postw(RegisterInfo * reg,uint64_t val64)55c6766f5bSFrancisco Iglesias static void cfrm_isr_postw(RegisterInfo *reg, uint64_t val64)
56c6766f5bSFrancisco Iglesias {
57c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
58c6766f5bSFrancisco Iglesias cfrm_imr_update_irq(s);
59c6766f5bSFrancisco Iglesias }
60c6766f5bSFrancisco Iglesias
cfrm_ier_prew(RegisterInfo * reg,uint64_t val64)61c6766f5bSFrancisco Iglesias static uint64_t cfrm_ier_prew(RegisterInfo *reg, uint64_t val64)
62c6766f5bSFrancisco Iglesias {
63c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
64c6766f5bSFrancisco Iglesias
65c6766f5bSFrancisco Iglesias s->regs[R_CFRM_IMR0] &= ~s->regs[R_CFRM_IER0];
66c6766f5bSFrancisco Iglesias s->regs[R_CFRM_IER0] = 0;
67c6766f5bSFrancisco Iglesias cfrm_imr_update_irq(s);
68c6766f5bSFrancisco Iglesias return 0;
69c6766f5bSFrancisco Iglesias }
70c6766f5bSFrancisco Iglesias
cfrm_idr_prew(RegisterInfo * reg,uint64_t val64)71c6766f5bSFrancisco Iglesias static uint64_t cfrm_idr_prew(RegisterInfo *reg, uint64_t val64)
72c6766f5bSFrancisco Iglesias {
73c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
74c6766f5bSFrancisco Iglesias
75c6766f5bSFrancisco Iglesias s->regs[R_CFRM_IMR0] |= s->regs[R_CFRM_IDR0];
76c6766f5bSFrancisco Iglesias s->regs[R_CFRM_IDR0] = 0;
77c6766f5bSFrancisco Iglesias cfrm_imr_update_irq(s);
78c6766f5bSFrancisco Iglesias return 0;
79c6766f5bSFrancisco Iglesias }
80c6766f5bSFrancisco Iglesias
cfrm_itr_prew(RegisterInfo * reg,uint64_t val64)81c6766f5bSFrancisco Iglesias static uint64_t cfrm_itr_prew(RegisterInfo *reg, uint64_t val64)
82c6766f5bSFrancisco Iglesias {
83c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
84c6766f5bSFrancisco Iglesias
85c6766f5bSFrancisco Iglesias s->regs[R_CFRM_ISR0] |= s->regs[R_CFRM_ITR0];
86c6766f5bSFrancisco Iglesias s->regs[R_CFRM_ITR0] = 0;
87c6766f5bSFrancisco Iglesias cfrm_imr_update_irq(s);
88c6766f5bSFrancisco Iglesias return 0;
89c6766f5bSFrancisco Iglesias }
90c6766f5bSFrancisco Iglesias
cframe_incr_far(XlnxVersalCFrameReg * s)91c6766f5bSFrancisco Iglesias static void cframe_incr_far(XlnxVersalCFrameReg *s)
92c6766f5bSFrancisco Iglesias {
93c6766f5bSFrancisco Iglesias uint32_t faddr = ARRAY_FIELD_EX32(s->regs, FAR0, FRAME_ADDR);
94c6766f5bSFrancisco Iglesias uint32_t blktype = ARRAY_FIELD_EX32(s->regs, FAR0, BLOCKTYPE);
95c6766f5bSFrancisco Iglesias
96c6766f5bSFrancisco Iglesias assert(blktype <= MAX_BLOCKTYPE);
97c6766f5bSFrancisco Iglesias
98c6766f5bSFrancisco Iglesias faddr++;
99c6766f5bSFrancisco Iglesias if (faddr > s->cfg.blktype_num_frames[blktype]) {
100c6766f5bSFrancisco Iglesias /* Restart from 0 and increment block type */
101c6766f5bSFrancisco Iglesias faddr = 0;
102c6766f5bSFrancisco Iglesias blktype++;
103c6766f5bSFrancisco Iglesias
104c6766f5bSFrancisco Iglesias assert(blktype <= MAX_BLOCKTYPE);
105c6766f5bSFrancisco Iglesias
106c6766f5bSFrancisco Iglesias ARRAY_FIELD_DP32(s->regs, FAR0, BLOCKTYPE, blktype);
107c6766f5bSFrancisco Iglesias }
108c6766f5bSFrancisco Iglesias
109c6766f5bSFrancisco Iglesias ARRAY_FIELD_DP32(s->regs, FAR0, FRAME_ADDR, faddr);
110c6766f5bSFrancisco Iglesias }
111c6766f5bSFrancisco Iglesias
cfrm_fdri_post_write(RegisterInfo * reg,uint64_t val)112c6766f5bSFrancisco Iglesias static void cfrm_fdri_post_write(RegisterInfo *reg, uint64_t val)
113c6766f5bSFrancisco Iglesias {
114c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
115c6766f5bSFrancisco Iglesias
116c6766f5bSFrancisco Iglesias if (s->row_configured && s->rowon && s->wcfg) {
117c6766f5bSFrancisco Iglesias
118c6766f5bSFrancisco Iglesias if (fifo32_num_free(&s->new_f_data) >= N_WORDS_128BIT) {
119c6766f5bSFrancisco Iglesias fifo32_push(&s->new_f_data, s->regs[R_FDRI0]);
120c6766f5bSFrancisco Iglesias fifo32_push(&s->new_f_data, s->regs[R_FDRI1]);
121c6766f5bSFrancisco Iglesias fifo32_push(&s->new_f_data, s->regs[R_FDRI2]);
122c6766f5bSFrancisco Iglesias fifo32_push(&s->new_f_data, s->regs[R_FDRI3]);
123c6766f5bSFrancisco Iglesias }
124c6766f5bSFrancisco Iglesias
125c6766f5bSFrancisco Iglesias if (fifo32_is_full(&s->new_f_data)) {
126c6766f5bSFrancisco Iglesias uint32_t addr = extract32(s->regs[R_FAR0], 0, 23);
127c6766f5bSFrancisco Iglesias XlnxCFrame *f = g_new(XlnxCFrame, 1);
128c6766f5bSFrancisco Iglesias
129c6766f5bSFrancisco Iglesias for (int i = 0; i < FRAME_NUM_WORDS; i++) {
130c6766f5bSFrancisco Iglesias f->data[i] = fifo32_pop(&s->new_f_data);
131c6766f5bSFrancisco Iglesias }
132c6766f5bSFrancisco Iglesias
133c6766f5bSFrancisco Iglesias g_tree_replace(s->cframes, GUINT_TO_POINTER(addr), f);
134c6766f5bSFrancisco Iglesias
135c6766f5bSFrancisco Iglesias cframe_incr_far(s);
136c6766f5bSFrancisco Iglesias
137c6766f5bSFrancisco Iglesias fifo32_reset(&s->new_f_data);
138c6766f5bSFrancisco Iglesias }
139c6766f5bSFrancisco Iglesias }
140c6766f5bSFrancisco Iglesias }
141c6766f5bSFrancisco Iglesias
cfrm_readout_frames(XlnxVersalCFrameReg * s,uint32_t start_addr,uint32_t end_addr)142c6766f5bSFrancisco Iglesias static void cfrm_readout_frames(XlnxVersalCFrameReg *s, uint32_t start_addr,
143c6766f5bSFrancisco Iglesias uint32_t end_addr)
144c6766f5bSFrancisco Iglesias {
145c6766f5bSFrancisco Iglesias /*
146c6766f5bSFrancisco Iglesias * NB: when our minimum glib version is at least 2.68 we can improve the
147c6766f5bSFrancisco Iglesias * performance of the cframe traversal by using g_tree_lookup_node and
148c6766f5bSFrancisco Iglesias * g_tree_node_next (instead of calling g_tree_lookup for finding each
149c6766f5bSFrancisco Iglesias * cframe).
150c6766f5bSFrancisco Iglesias */
151c6766f5bSFrancisco Iglesias for (uint32_t addr = start_addr; addr < end_addr; addr++) {
152c6766f5bSFrancisco Iglesias XlnxCFrame *f = g_tree_lookup(s->cframes, GUINT_TO_POINTER(addr));
153c6766f5bSFrancisco Iglesias
154c6766f5bSFrancisco Iglesias /* Transmit the data if a frame was found */
155c6766f5bSFrancisco Iglesias if (f) {
156c6766f5bSFrancisco Iglesias for (int i = 0; i < FRAME_NUM_WORDS; i += 4) {
157c6766f5bSFrancisco Iglesias XlnxCfiPacket pkt = {};
158c6766f5bSFrancisco Iglesias
159c6766f5bSFrancisco Iglesias pkt.data[0] = f->data[i];
160c6766f5bSFrancisco Iglesias pkt.data[1] = f->data[i + 1];
161c6766f5bSFrancisco Iglesias pkt.data[2] = f->data[i + 2];
162c6766f5bSFrancisco Iglesias pkt.data[3] = f->data[i + 3];
163c6766f5bSFrancisco Iglesias
164c6766f5bSFrancisco Iglesias if (s->cfg.cfu_fdro) {
165c6766f5bSFrancisco Iglesias xlnx_cfi_transfer_packet(s->cfg.cfu_fdro, &pkt);
166c6766f5bSFrancisco Iglesias }
167c6766f5bSFrancisco Iglesias }
168c6766f5bSFrancisco Iglesias }
169c6766f5bSFrancisco Iglesias }
170c6766f5bSFrancisco Iglesias }
171c6766f5bSFrancisco Iglesias
cfrm_frcnt_post_write(RegisterInfo * reg,uint64_t val)172c6766f5bSFrancisco Iglesias static void cfrm_frcnt_post_write(RegisterInfo *reg, uint64_t val)
173c6766f5bSFrancisco Iglesias {
174c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
175c6766f5bSFrancisco Iglesias
176c6766f5bSFrancisco Iglesias if (s->row_configured && s->rowon && s->rcfg) {
177c6766f5bSFrancisco Iglesias uint32_t start_addr = extract32(s->regs[R_FAR0], 0, 23);
178c6766f5bSFrancisco Iglesias uint32_t end_addr = start_addr + s->regs[R_FRCNT0] / FRAME_NUM_QWORDS;
179c6766f5bSFrancisco Iglesias
180c6766f5bSFrancisco Iglesias cfrm_readout_frames(s, start_addr, end_addr);
181c6766f5bSFrancisco Iglesias }
182c6766f5bSFrancisco Iglesias }
183c6766f5bSFrancisco Iglesias
cfrm_cmd_post_write(RegisterInfo * reg,uint64_t val)184c6766f5bSFrancisco Iglesias static void cfrm_cmd_post_write(RegisterInfo *reg, uint64_t val)
185c6766f5bSFrancisco Iglesias {
186c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
187c6766f5bSFrancisco Iglesias
188c6766f5bSFrancisco Iglesias if (s->row_configured) {
189c6766f5bSFrancisco Iglesias uint8_t cmd = ARRAY_FIELD_EX32(s->regs, CMD0, CMD);
190c6766f5bSFrancisco Iglesias
191c6766f5bSFrancisco Iglesias switch (cmd) {
192c6766f5bSFrancisco Iglesias case CFRAME_CMD_WCFG:
193c6766f5bSFrancisco Iglesias s->wcfg = true;
194c6766f5bSFrancisco Iglesias break;
195c6766f5bSFrancisco Iglesias case CFRAME_CMD_ROWON:
196c6766f5bSFrancisco Iglesias s->rowon = true;
197c6766f5bSFrancisco Iglesias break;
198c6766f5bSFrancisco Iglesias case CFRAME_CMD_ROWOFF:
199c6766f5bSFrancisco Iglesias s->rowon = false;
200c6766f5bSFrancisco Iglesias break;
201c6766f5bSFrancisco Iglesias case CFRAME_CMD_RCFG:
202c6766f5bSFrancisco Iglesias s->rcfg = true;
203c6766f5bSFrancisco Iglesias break;
204c6766f5bSFrancisco Iglesias case CFRAME_CMD_DLPARK:
205c6766f5bSFrancisco Iglesias s->wcfg = false;
206c6766f5bSFrancisco Iglesias s->rcfg = false;
207c6766f5bSFrancisco Iglesias break;
208c6766f5bSFrancisco Iglesias default:
209c6766f5bSFrancisco Iglesias break;
210c6766f5bSFrancisco Iglesias };
211c6766f5bSFrancisco Iglesias }
212c6766f5bSFrancisco Iglesias }
213c6766f5bSFrancisco Iglesias
cfrm_last_frame_bot_post_read(RegisterInfo * reg,uint64_t val64)214c6766f5bSFrancisco Iglesias static uint64_t cfrm_last_frame_bot_post_read(RegisterInfo *reg,
215c6766f5bSFrancisco Iglesias uint64_t val64)
216c6766f5bSFrancisco Iglesias {
217c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
218c6766f5bSFrancisco Iglesias uint64_t val = 0;
219c6766f5bSFrancisco Iglesias
220c6766f5bSFrancisco Iglesias switch (reg->access->addr) {
221c6766f5bSFrancisco Iglesias case A_LAST_FRAME_BOT0:
222c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_BOT0, BLOCKTYPE1_LAST_FRAME_LSB,
223c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[1]);
224c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_BOT0, BLOCKTYPE0_LAST_FRAME,
225c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[0]);
226c6766f5bSFrancisco Iglesias break;
227c6766f5bSFrancisco Iglesias case A_LAST_FRAME_BOT1:
228c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_BOT1, BLOCKTYPE3_LAST_FRAME_LSB,
229c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[3]);
230c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_BOT1, BLOCKTYPE2_LAST_FRAME,
231c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[2]);
232c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_BOT1, BLOCKTYPE1_LAST_FRAME_MSB,
233c6766f5bSFrancisco Iglesias (s->cfg.blktype_num_frames[1] >> 12));
234c6766f5bSFrancisco Iglesias break;
235c6766f5bSFrancisco Iglesias case A_LAST_FRAME_BOT2:
236c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_BOT2, BLOCKTYPE3_LAST_FRAME_MSB,
237c6766f5bSFrancisco Iglesias (s->cfg.blktype_num_frames[3] >> 4));
238c6766f5bSFrancisco Iglesias break;
239c6766f5bSFrancisco Iglesias case A_LAST_FRAME_BOT3:
240c6766f5bSFrancisco Iglesias default:
241c6766f5bSFrancisco Iglesias break;
242c6766f5bSFrancisco Iglesias }
243c6766f5bSFrancisco Iglesias
244c6766f5bSFrancisco Iglesias return val;
245c6766f5bSFrancisco Iglesias }
246c6766f5bSFrancisco Iglesias
cfrm_last_frame_top_post_read(RegisterInfo * reg,uint64_t val64)247c6766f5bSFrancisco Iglesias static uint64_t cfrm_last_frame_top_post_read(RegisterInfo *reg,
248c6766f5bSFrancisco Iglesias uint64_t val64)
249c6766f5bSFrancisco Iglesias {
250c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
251c6766f5bSFrancisco Iglesias uint64_t val = 0;
252c6766f5bSFrancisco Iglesias
253c6766f5bSFrancisco Iglesias switch (reg->access->addr) {
254c6766f5bSFrancisco Iglesias case A_LAST_FRAME_TOP0:
255c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_TOP0, BLOCKTYPE5_LAST_FRAME_LSB,
256c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[5]);
257c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_TOP0, BLOCKTYPE4_LAST_FRAME,
258c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[4]);
259c6766f5bSFrancisco Iglesias break;
260c6766f5bSFrancisco Iglesias case A_LAST_FRAME_TOP1:
261c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_TOP1, BLOCKTYPE6_LAST_FRAME,
262c6766f5bSFrancisco Iglesias s->cfg.blktype_num_frames[6]);
263c6766f5bSFrancisco Iglesias val = FIELD_DP32(val, LAST_FRAME_TOP1, BLOCKTYPE5_LAST_FRAME_MSB,
264c6766f5bSFrancisco Iglesias (s->cfg.blktype_num_frames[5] >> 12));
265c6766f5bSFrancisco Iglesias break;
266c6766f5bSFrancisco Iglesias case A_LAST_FRAME_TOP2:
267c6766f5bSFrancisco Iglesias case A_LAST_FRAME_BOT3:
268c6766f5bSFrancisco Iglesias default:
269c6766f5bSFrancisco Iglesias break;
270c6766f5bSFrancisco Iglesias }
271c6766f5bSFrancisco Iglesias
272c6766f5bSFrancisco Iglesias return val;
273c6766f5bSFrancisco Iglesias }
274c6766f5bSFrancisco Iglesias
cfrm_far_sfr_post_write(RegisterInfo * reg,uint64_t val)275c6766f5bSFrancisco Iglesias static void cfrm_far_sfr_post_write(RegisterInfo *reg, uint64_t val)
276c6766f5bSFrancisco Iglesias {
277c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
278c6766f5bSFrancisco Iglesias
279c6766f5bSFrancisco Iglesias if (s->row_configured && s->rowon && s->rcfg) {
280c6766f5bSFrancisco Iglesias uint32_t start_addr = extract32(s->regs[R_FAR_SFR0], 0, 23);
281c6766f5bSFrancisco Iglesias
282c6766f5bSFrancisco Iglesias /* Readback 1 frame */
283c6766f5bSFrancisco Iglesias cfrm_readout_frames(s, start_addr, start_addr + 1);
284c6766f5bSFrancisco Iglesias }
285c6766f5bSFrancisco Iglesias }
286c6766f5bSFrancisco Iglesias
287c6766f5bSFrancisco Iglesias static const RegisterAccessInfo cframe_reg_regs_info[] = {
288c6766f5bSFrancisco Iglesias { .name = "CRC0", .addr = A_CRC0,
289c6766f5bSFrancisco Iglesias .rsvd = 0x00000000,
290c6766f5bSFrancisco Iglesias },{ .name = "CRC1", .addr = A_CRC0,
291c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
292c6766f5bSFrancisco Iglesias },{ .name = "CRC2", .addr = A_CRC0,
293c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
294c6766f5bSFrancisco Iglesias },{ .name = "CRC3", .addr = A_CRC0,
295c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
296c6766f5bSFrancisco Iglesias },{ .name = "FAR0", .addr = A_FAR0,
297c6766f5bSFrancisco Iglesias .rsvd = 0xfe000000,
298c6766f5bSFrancisco Iglesias },{ .name = "FAR1", .addr = A_FAR1,
299c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
300c6766f5bSFrancisco Iglesias },{ .name = "FAR2", .addr = A_FAR2,
301c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
302c6766f5bSFrancisco Iglesias },{ .name = "FAR3", .addr = A_FAR3,
303c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
304c6766f5bSFrancisco Iglesias },{ .name = "FAR_SFR0", .addr = A_FAR_SFR0,
305c6766f5bSFrancisco Iglesias .rsvd = 0xff800000,
306c6766f5bSFrancisco Iglesias },{ .name = "FAR_SFR1", .addr = A_FAR_SFR1,
307c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
308c6766f5bSFrancisco Iglesias },{ .name = "FAR_SFR2", .addr = A_FAR_SFR2,
309c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
310c6766f5bSFrancisco Iglesias },{ .name = "FAR_SFR3", .addr = A_FAR_SFR3,
311c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
312c6766f5bSFrancisco Iglesias .post_write = cfrm_far_sfr_post_write,
313c6766f5bSFrancisco Iglesias },{ .name = "FDRI0", .addr = A_FDRI0,
314c6766f5bSFrancisco Iglesias },{ .name = "FDRI1", .addr = A_FDRI1,
315c6766f5bSFrancisco Iglesias },{ .name = "FDRI2", .addr = A_FDRI2,
316c6766f5bSFrancisco Iglesias },{ .name = "FDRI3", .addr = A_FDRI3,
317c6766f5bSFrancisco Iglesias .post_write = cfrm_fdri_post_write,
318c6766f5bSFrancisco Iglesias },{ .name = "FRCNT0", .addr = A_FRCNT0,
319c6766f5bSFrancisco Iglesias .rsvd = 0x00000000,
320c6766f5bSFrancisco Iglesias },{ .name = "FRCNT1", .addr = A_FRCNT1,
321c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
322c6766f5bSFrancisco Iglesias },{ .name = "FRCNT2", .addr = A_FRCNT2,
323c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
324c6766f5bSFrancisco Iglesias },{ .name = "FRCNT3", .addr = A_FRCNT3,
325c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
326c6766f5bSFrancisco Iglesias .post_write = cfrm_frcnt_post_write
327c6766f5bSFrancisco Iglesias },{ .name = "CMD0", .addr = A_CMD0,
328c6766f5bSFrancisco Iglesias .rsvd = 0xffffffe0,
329c6766f5bSFrancisco Iglesias },{ .name = "CMD1", .addr = A_CMD1,
330c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
331c6766f5bSFrancisco Iglesias },{ .name = "CMD2", .addr = A_CMD2,
332c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
333c6766f5bSFrancisco Iglesias },{ .name = "CMD3", .addr = A_CMD3,
334c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
335c6766f5bSFrancisco Iglesias .post_write = cfrm_cmd_post_write
336c6766f5bSFrancisco Iglesias },{ .name = "CR_MASK0", .addr = A_CR_MASK0,
337c6766f5bSFrancisco Iglesias .rsvd = 0x00000000,
338c6766f5bSFrancisco Iglesias },{ .name = "CR_MASK1", .addr = A_CR_MASK1,
339c6766f5bSFrancisco Iglesias .rsvd = 0x00000000,
340c6766f5bSFrancisco Iglesias },{ .name = "CR_MASK2", .addr = A_CR_MASK2,
341c6766f5bSFrancisco Iglesias .rsvd = 0x00000000,
342c6766f5bSFrancisco Iglesias },{ .name = "CR_MASK3", .addr = A_CR_MASK3,
343c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
344c6766f5bSFrancisco Iglesias },{ .name = "CTL0", .addr = A_CTL0,
345c6766f5bSFrancisco Iglesias .rsvd = 0xfffffff8,
346c6766f5bSFrancisco Iglesias },{ .name = "CTL1", .addr = A_CTL1,
347c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
348c6766f5bSFrancisco Iglesias },{ .name = "CTL2", .addr = A_CTL2,
349c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
350c6766f5bSFrancisco Iglesias },{ .name = "CTL3", .addr = A_CTL3,
351c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
352c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ISR0", .addr = A_CFRM_ISR0,
353c6766f5bSFrancisco Iglesias .rsvd = 0xffc04000,
354c6766f5bSFrancisco Iglesias .w1c = 0x3bfff,
355c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ISR1", .addr = A_CFRM_ISR1,
356c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
357c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ISR2", .addr = A_CFRM_ISR2,
358c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
359c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ISR3", .addr = A_CFRM_ISR3,
360c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
361c6766f5bSFrancisco Iglesias .post_write = cfrm_isr_postw,
362c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IMR0", .addr = A_CFRM_IMR0,
363c6766f5bSFrancisco Iglesias .rsvd = 0xffc04000,
364c6766f5bSFrancisco Iglesias .ro = 0xfffff,
365c6766f5bSFrancisco Iglesias .reset = 0x3bfff,
366c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IMR1", .addr = A_CFRM_IMR1,
367c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
368c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IMR2", .addr = A_CFRM_IMR2,
369c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
370c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IMR3", .addr = A_CFRM_IMR3,
371c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
372c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IER0", .addr = A_CFRM_IER0,
373c6766f5bSFrancisco Iglesias .rsvd = 0xffc04000,
374c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IER1", .addr = A_CFRM_IER1,
375c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
376c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IER2", .addr = A_CFRM_IER2,
377c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
378c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IER3", .addr = A_CFRM_IER3,
379c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
380c6766f5bSFrancisco Iglesias .pre_write = cfrm_ier_prew,
381c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IDR0", .addr = A_CFRM_IDR0,
382c6766f5bSFrancisco Iglesias .rsvd = 0xffc04000,
383c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IDR1", .addr = A_CFRM_IDR1,
384c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
385c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IDR2", .addr = A_CFRM_IDR2,
386c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
387c6766f5bSFrancisco Iglesias },{ .name = "CFRM_IDR3", .addr = A_CFRM_IDR3,
388c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
389c6766f5bSFrancisco Iglesias .pre_write = cfrm_idr_prew,
390c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ITR0", .addr = A_CFRM_ITR0,
391c6766f5bSFrancisco Iglesias .rsvd = 0xffc04000,
392c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ITR1", .addr = A_CFRM_ITR1,
393c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
394c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ITR2", .addr = A_CFRM_ITR2,
395c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
396c6766f5bSFrancisco Iglesias },{ .name = "CFRM_ITR3", .addr = A_CFRM_ITR3,
397c6766f5bSFrancisco Iglesias .rsvd = 0xffffffff,
398c6766f5bSFrancisco Iglesias .pre_write = cfrm_itr_prew,
399c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM00", .addr = A_SEU_SYNDRM00,
400c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM01", .addr = A_SEU_SYNDRM01,
401c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM02", .addr = A_SEU_SYNDRM02,
402c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM03", .addr = A_SEU_SYNDRM03,
403c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM10", .addr = A_SEU_SYNDRM10,
404c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM11", .addr = A_SEU_SYNDRM11,
405c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM12", .addr = A_SEU_SYNDRM12,
406c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM13", .addr = A_SEU_SYNDRM13,
407c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM20", .addr = A_SEU_SYNDRM20,
408c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM21", .addr = A_SEU_SYNDRM21,
409c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM22", .addr = A_SEU_SYNDRM22,
410c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM23", .addr = A_SEU_SYNDRM23,
411c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM30", .addr = A_SEU_SYNDRM30,
412c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM31", .addr = A_SEU_SYNDRM31,
413c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM32", .addr = A_SEU_SYNDRM32,
414c6766f5bSFrancisco Iglesias },{ .name = "SEU_SYNDRM33", .addr = A_SEU_SYNDRM33,
415c6766f5bSFrancisco Iglesias },{ .name = "SEU_VIRTUAL_SYNDRM0", .addr = A_SEU_VIRTUAL_SYNDRM0,
416c6766f5bSFrancisco Iglesias },{ .name = "SEU_VIRTUAL_SYNDRM1", .addr = A_SEU_VIRTUAL_SYNDRM1,
417c6766f5bSFrancisco Iglesias },{ .name = "SEU_VIRTUAL_SYNDRM2", .addr = A_SEU_VIRTUAL_SYNDRM2,
418c6766f5bSFrancisco Iglesias },{ .name = "SEU_VIRTUAL_SYNDRM3", .addr = A_SEU_VIRTUAL_SYNDRM3,
419c6766f5bSFrancisco Iglesias },{ .name = "SEU_CRC0", .addr = A_SEU_CRC0,
420c6766f5bSFrancisco Iglesias },{ .name = "SEU_CRC1", .addr = A_SEU_CRC1,
421c6766f5bSFrancisco Iglesias },{ .name = "SEU_CRC2", .addr = A_SEU_CRC2,
422c6766f5bSFrancisco Iglesias },{ .name = "SEU_CRC3", .addr = A_SEU_CRC3,
423c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_BOT0", .addr = A_CFRAME_FAR_BOT0,
424c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_BOT1", .addr = A_CFRAME_FAR_BOT1,
425c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_BOT2", .addr = A_CFRAME_FAR_BOT2,
426c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_BOT3", .addr = A_CFRAME_FAR_BOT3,
427c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_TOP0", .addr = A_CFRAME_FAR_TOP0,
428c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_TOP1", .addr = A_CFRAME_FAR_TOP1,
429c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_TOP2", .addr = A_CFRAME_FAR_TOP2,
430c6766f5bSFrancisco Iglesias },{ .name = "CFRAME_FAR_TOP3", .addr = A_CFRAME_FAR_TOP3,
431c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_BOT0", .addr = A_LAST_FRAME_BOT0,
432c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
433c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_bot_post_read,
434c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_BOT1", .addr = A_LAST_FRAME_BOT1,
435c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
436c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_bot_post_read,
437c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_BOT2", .addr = A_LAST_FRAME_BOT2,
438c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
439c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_bot_post_read,
440c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_BOT3", .addr = A_LAST_FRAME_BOT3,
441c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
442c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_bot_post_read,
443c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_TOP0", .addr = A_LAST_FRAME_TOP0,
444c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
445c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_top_post_read,
446c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_TOP1", .addr = A_LAST_FRAME_TOP1,
447c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
448c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_top_post_read,
449c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_TOP2", .addr = A_LAST_FRAME_TOP2,
450c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
451c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_top_post_read,
452c6766f5bSFrancisco Iglesias },{ .name = "LAST_FRAME_TOP3", .addr = A_LAST_FRAME_TOP3,
453c6766f5bSFrancisco Iglesias .ro = 0xffffffff,
454c6766f5bSFrancisco Iglesias .post_read = cfrm_last_frame_top_post_read,
455c6766f5bSFrancisco Iglesias }
456c6766f5bSFrancisco Iglesias };
457c6766f5bSFrancisco Iglesias
cframe_reg_cfi_transfer_packet(XlnxCfiIf * cfi_if,XlnxCfiPacket * pkt)458c6766f5bSFrancisco Iglesias static void cframe_reg_cfi_transfer_packet(XlnxCfiIf *cfi_if,
459c6766f5bSFrancisco Iglesias XlnxCfiPacket *pkt)
460c6766f5bSFrancisco Iglesias {
461c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(cfi_if);
462c6766f5bSFrancisco Iglesias uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
463c6766f5bSFrancisco Iglesias
464c6766f5bSFrancisco Iglesias if (!s->row_configured) {
465c6766f5bSFrancisco Iglesias return;
466c6766f5bSFrancisco Iglesias }
467c6766f5bSFrancisco Iglesias
468c6766f5bSFrancisco Iglesias switch (pkt->reg_addr) {
469c6766f5bSFrancisco Iglesias case CFRAME_FAR:
470c6766f5bSFrancisco Iglesias s->regs[R_FAR0] = pkt->data[0];
471c6766f5bSFrancisco Iglesias break;
472c6766f5bSFrancisco Iglesias case CFRAME_SFR:
473c6766f5bSFrancisco Iglesias s->regs[R_FAR_SFR0] = pkt->data[0];
474c6766f5bSFrancisco Iglesias register_write(&s->regs_info[R_FAR_SFR3], 0,
475c6766f5bSFrancisco Iglesias we, object_get_typename(OBJECT(s)),
476c6766f5bSFrancisco Iglesias XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
477c6766f5bSFrancisco Iglesias break;
478c6766f5bSFrancisco Iglesias case CFRAME_FDRI:
479c6766f5bSFrancisco Iglesias s->regs[R_FDRI0] = pkt->data[0];
480c6766f5bSFrancisco Iglesias s->regs[R_FDRI1] = pkt->data[1];
481c6766f5bSFrancisco Iglesias s->regs[R_FDRI2] = pkt->data[2];
482c6766f5bSFrancisco Iglesias register_write(&s->regs_info[R_FDRI3], pkt->data[3],
483c6766f5bSFrancisco Iglesias we, object_get_typename(OBJECT(s)),
484c6766f5bSFrancisco Iglesias XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
485c6766f5bSFrancisco Iglesias break;
486c6766f5bSFrancisco Iglesias case CFRAME_CMD:
487c6766f5bSFrancisco Iglesias ARRAY_FIELD_DP32(s->regs, CMD0, CMD, pkt->data[0]);
488c6766f5bSFrancisco Iglesias
489c6766f5bSFrancisco Iglesias register_write(&s->regs_info[R_CMD3], 0,
490c6766f5bSFrancisco Iglesias we, object_get_typename(OBJECT(s)),
491c6766f5bSFrancisco Iglesias XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
492c6766f5bSFrancisco Iglesias break;
493c6766f5bSFrancisco Iglesias default:
494c6766f5bSFrancisco Iglesias break;
495c6766f5bSFrancisco Iglesias }
496c6766f5bSFrancisco Iglesias }
497c6766f5bSFrancisco Iglesias
cframe_reg_fdri_read(void * opaque,hwaddr addr,unsigned size)498c6766f5bSFrancisco Iglesias static uint64_t cframe_reg_fdri_read(void *opaque, hwaddr addr, unsigned size)
499c6766f5bSFrancisco Iglesias {
500c6766f5bSFrancisco Iglesias qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
501c6766f5bSFrancisco Iglesias HWADDR_PRIx "\n", __func__, addr);
502c6766f5bSFrancisco Iglesias return 0;
503c6766f5bSFrancisco Iglesias }
504c6766f5bSFrancisco Iglesias
cframe_reg_fdri_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)505c6766f5bSFrancisco Iglesias static void cframe_reg_fdri_write(void *opaque, hwaddr addr, uint64_t value,
506c6766f5bSFrancisco Iglesias unsigned size)
507c6766f5bSFrancisco Iglesias {
508c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(opaque);
509c6766f5bSFrancisco Iglesias uint32_t wfifo[WFIFO_SZ];
510c6766f5bSFrancisco Iglesias
511c6766f5bSFrancisco Iglesias if (update_wfifo(addr, value, s->wfifo, wfifo)) {
512c6766f5bSFrancisco Iglesias uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
513c6766f5bSFrancisco Iglesias
514c6766f5bSFrancisco Iglesias s->regs[R_FDRI0] = wfifo[0];
515c6766f5bSFrancisco Iglesias s->regs[R_FDRI1] = wfifo[1];
516c6766f5bSFrancisco Iglesias s->regs[R_FDRI2] = wfifo[2];
517c6766f5bSFrancisco Iglesias register_write(&s->regs_info[R_FDRI3], wfifo[3],
518c6766f5bSFrancisco Iglesias we, object_get_typename(OBJECT(s)),
519c6766f5bSFrancisco Iglesias XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
520c6766f5bSFrancisco Iglesias }
521c6766f5bSFrancisco Iglesias }
522c6766f5bSFrancisco Iglesias
cframe_reg_reset_enter(Object * obj,ResetType type)523c6766f5bSFrancisco Iglesias static void cframe_reg_reset_enter(Object *obj, ResetType type)
524c6766f5bSFrancisco Iglesias {
525c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
526c6766f5bSFrancisco Iglesias unsigned int i;
527c6766f5bSFrancisco Iglesias
528c6766f5bSFrancisco Iglesias for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
529c6766f5bSFrancisco Iglesias register_reset(&s->regs_info[i]);
530c6766f5bSFrancisco Iglesias }
531c6766f5bSFrancisco Iglesias memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
532c6766f5bSFrancisco Iglesias fifo32_reset(&s->new_f_data);
533c6766f5bSFrancisco Iglesias
534c6766f5bSFrancisco Iglesias if (g_tree_nnodes(s->cframes)) {
535c6766f5bSFrancisco Iglesias /*
536c6766f5bSFrancisco Iglesias * Take a reference so when g_tree_destroy() unrefs it we keep the
537c6766f5bSFrancisco Iglesias * GTree and only destroy its contents. NB: when our minimum
538c6766f5bSFrancisco Iglesias * glib version is at least 2.70 we could use g_tree_remove_all().
539c6766f5bSFrancisco Iglesias */
540c6766f5bSFrancisco Iglesias g_tree_ref(s->cframes);
541c6766f5bSFrancisco Iglesias g_tree_destroy(s->cframes);
542c6766f5bSFrancisco Iglesias }
543c6766f5bSFrancisco Iglesias }
544c6766f5bSFrancisco Iglesias
cframe_reg_reset_hold(Object * obj,ResetType type)545*ad80e367SPeter Maydell static void cframe_reg_reset_hold(Object *obj, ResetType type)
546c6766f5bSFrancisco Iglesias {
547c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
548c6766f5bSFrancisco Iglesias
549c6766f5bSFrancisco Iglesias cfrm_imr_update_irq(s);
550c6766f5bSFrancisco Iglesias }
551c6766f5bSFrancisco Iglesias
552c6766f5bSFrancisco Iglesias static const MemoryRegionOps cframe_reg_ops = {
553c6766f5bSFrancisco Iglesias .read = register_read_memory,
554c6766f5bSFrancisco Iglesias .write = register_write_memory,
555c6766f5bSFrancisco Iglesias .endianness = DEVICE_LITTLE_ENDIAN,
556c6766f5bSFrancisco Iglesias .valid = {
557c6766f5bSFrancisco Iglesias .min_access_size = 4,
558c6766f5bSFrancisco Iglesias .max_access_size = 4,
559c6766f5bSFrancisco Iglesias },
560c6766f5bSFrancisco Iglesias };
561c6766f5bSFrancisco Iglesias
562c6766f5bSFrancisco Iglesias static const MemoryRegionOps cframe_reg_fdri_ops = {
563c6766f5bSFrancisco Iglesias .read = cframe_reg_fdri_read,
564c6766f5bSFrancisco Iglesias .write = cframe_reg_fdri_write,
565c6766f5bSFrancisco Iglesias .endianness = DEVICE_LITTLE_ENDIAN,
566c6766f5bSFrancisco Iglesias .valid = {
567c6766f5bSFrancisco Iglesias .min_access_size = 4,
568c6766f5bSFrancisco Iglesias .max_access_size = 4,
569c6766f5bSFrancisco Iglesias },
570c6766f5bSFrancisco Iglesias };
571c6766f5bSFrancisco Iglesias
cframes_bcast_reg_read(void * opaque,hwaddr addr,unsigned size)572eadd3343SFrancisco Iglesias static uint64_t cframes_bcast_reg_read(void *opaque, hwaddr addr, unsigned size)
573eadd3343SFrancisco Iglesias {
574eadd3343SFrancisco Iglesias qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
575eadd3343SFrancisco Iglesias HWADDR_PRIx "\n", __func__, addr);
576eadd3343SFrancisco Iglesias return 0;
577eadd3343SFrancisco Iglesias }
578eadd3343SFrancisco Iglesias
cframes_bcast_write(XlnxVersalCFrameBcastReg * s,uint8_t reg_addr,uint32_t * wfifo)579eadd3343SFrancisco Iglesias static void cframes_bcast_write(XlnxVersalCFrameBcastReg *s, uint8_t reg_addr,
580eadd3343SFrancisco Iglesias uint32_t *wfifo)
581eadd3343SFrancisco Iglesias {
582eadd3343SFrancisco Iglesias XlnxCfiPacket pkt = {
583eadd3343SFrancisco Iglesias .reg_addr = reg_addr,
584eadd3343SFrancisco Iglesias .data[0] = wfifo[0],
585eadd3343SFrancisco Iglesias .data[1] = wfifo[1],
586eadd3343SFrancisco Iglesias .data[2] = wfifo[2],
587eadd3343SFrancisco Iglesias .data[3] = wfifo[3]
588eadd3343SFrancisco Iglesias };
589eadd3343SFrancisco Iglesias
590eadd3343SFrancisco Iglesias for (int i = 0; i < ARRAY_SIZE(s->cfg.cframe); i++) {
591eadd3343SFrancisco Iglesias if (s->cfg.cframe[i]) {
592eadd3343SFrancisco Iglesias xlnx_cfi_transfer_packet(s->cfg.cframe[i], &pkt);
593eadd3343SFrancisco Iglesias }
594eadd3343SFrancisco Iglesias }
595eadd3343SFrancisco Iglesias }
596eadd3343SFrancisco Iglesias
cframes_bcast_reg_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)597eadd3343SFrancisco Iglesias static void cframes_bcast_reg_write(void *opaque, hwaddr addr, uint64_t value,
598eadd3343SFrancisco Iglesias unsigned size)
599eadd3343SFrancisco Iglesias {
600eadd3343SFrancisco Iglesias XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(opaque);
601eadd3343SFrancisco Iglesias uint32_t wfifo[WFIFO_SZ];
602eadd3343SFrancisco Iglesias
603eadd3343SFrancisco Iglesias if (update_wfifo(addr, value, s->wfifo, wfifo)) {
604eadd3343SFrancisco Iglesias uint8_t reg_addr = extract32(addr, 4, 6);
605eadd3343SFrancisco Iglesias
606eadd3343SFrancisco Iglesias cframes_bcast_write(s, reg_addr, wfifo);
607eadd3343SFrancisco Iglesias }
608eadd3343SFrancisco Iglesias }
609eadd3343SFrancisco Iglesias
cframes_bcast_fdri_read(void * opaque,hwaddr addr,unsigned size)610eadd3343SFrancisco Iglesias static uint64_t cframes_bcast_fdri_read(void *opaque, hwaddr addr,
611eadd3343SFrancisco Iglesias unsigned size)
612eadd3343SFrancisco Iglesias {
613eadd3343SFrancisco Iglesias qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
614eadd3343SFrancisco Iglesias HWADDR_PRIx "\n", __func__, addr);
615eadd3343SFrancisco Iglesias return 0;
616eadd3343SFrancisco Iglesias }
617eadd3343SFrancisco Iglesias
cframes_bcast_fdri_write(void * opaque,hwaddr addr,uint64_t value,unsigned size)618eadd3343SFrancisco Iglesias static void cframes_bcast_fdri_write(void *opaque, hwaddr addr, uint64_t value,
619eadd3343SFrancisco Iglesias unsigned size)
620eadd3343SFrancisco Iglesias {
621eadd3343SFrancisco Iglesias XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(opaque);
622eadd3343SFrancisco Iglesias uint32_t wfifo[WFIFO_SZ];
623eadd3343SFrancisco Iglesias
624eadd3343SFrancisco Iglesias if (update_wfifo(addr, value, s->wfifo, wfifo)) {
625eadd3343SFrancisco Iglesias cframes_bcast_write(s, CFRAME_FDRI, wfifo);
626eadd3343SFrancisco Iglesias }
627eadd3343SFrancisco Iglesias }
628eadd3343SFrancisco Iglesias
629eadd3343SFrancisco Iglesias static const MemoryRegionOps cframes_bcast_reg_reg_ops = {
630eadd3343SFrancisco Iglesias .read = cframes_bcast_reg_read,
631eadd3343SFrancisco Iglesias .write = cframes_bcast_reg_write,
632eadd3343SFrancisco Iglesias .endianness = DEVICE_LITTLE_ENDIAN,
633eadd3343SFrancisco Iglesias .valid = {
634eadd3343SFrancisco Iglesias .min_access_size = 4,
635eadd3343SFrancisco Iglesias .max_access_size = 4,
636eadd3343SFrancisco Iglesias },
637eadd3343SFrancisco Iglesias };
638eadd3343SFrancisco Iglesias
639eadd3343SFrancisco Iglesias static const MemoryRegionOps cframes_bcast_reg_fdri_ops = {
640eadd3343SFrancisco Iglesias .read = cframes_bcast_fdri_read,
641eadd3343SFrancisco Iglesias .write = cframes_bcast_fdri_write,
642eadd3343SFrancisco Iglesias .endianness = DEVICE_LITTLE_ENDIAN,
643eadd3343SFrancisco Iglesias .valid = {
644eadd3343SFrancisco Iglesias .min_access_size = 4,
645eadd3343SFrancisco Iglesias .max_access_size = 4,
646eadd3343SFrancisco Iglesias },
647eadd3343SFrancisco Iglesias };
648eadd3343SFrancisco Iglesias
cframe_reg_realize(DeviceState * dev,Error ** errp)649c6766f5bSFrancisco Iglesias static void cframe_reg_realize(DeviceState *dev, Error **errp)
650c6766f5bSFrancisco Iglesias {
651c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(dev);
652c6766f5bSFrancisco Iglesias
653c6766f5bSFrancisco Iglesias for (int i = 0; i < ARRAY_SIZE(s->cfg.blktype_num_frames); i++) {
654c6766f5bSFrancisco Iglesias if (s->cfg.blktype_num_frames[i] > MAX_BLOCKTYPE_FRAMES) {
655c6766f5bSFrancisco Iglesias error_setg(errp,
656c6766f5bSFrancisco Iglesias "blktype-frames%d > 0xFFFFF (max frame per block)",
657c6766f5bSFrancisco Iglesias i);
658c6766f5bSFrancisco Iglesias return;
659c6766f5bSFrancisco Iglesias }
660c6766f5bSFrancisco Iglesias if (s->cfg.blktype_num_frames[i]) {
661c6766f5bSFrancisco Iglesias s->row_configured = true;
662c6766f5bSFrancisco Iglesias }
663c6766f5bSFrancisco Iglesias }
664c6766f5bSFrancisco Iglesias }
665c6766f5bSFrancisco Iglesias
cframe_reg_init(Object * obj)666c6766f5bSFrancisco Iglesias static void cframe_reg_init(Object *obj)
667c6766f5bSFrancisco Iglesias {
668c6766f5bSFrancisco Iglesias XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
669c6766f5bSFrancisco Iglesias SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
670c6766f5bSFrancisco Iglesias RegisterInfoArray *reg_array;
671c6766f5bSFrancisco Iglesias
672c6766f5bSFrancisco Iglesias memory_region_init(&s->iomem, obj, TYPE_XLNX_VERSAL_CFRAME_REG,
673c6766f5bSFrancisco Iglesias CFRAME_REG_R_MAX * 4);
674c6766f5bSFrancisco Iglesias reg_array =
675c6766f5bSFrancisco Iglesias register_init_block32(DEVICE(obj), cframe_reg_regs_info,
676c6766f5bSFrancisco Iglesias ARRAY_SIZE(cframe_reg_regs_info),
677c6766f5bSFrancisco Iglesias s->regs_info, s->regs,
678c6766f5bSFrancisco Iglesias &cframe_reg_ops,
679c6766f5bSFrancisco Iglesias XLNX_VERSAL_CFRAME_REG_ERR_DEBUG,
680c6766f5bSFrancisco Iglesias CFRAME_REG_R_MAX * 4);
681c6766f5bSFrancisco Iglesias memory_region_add_subregion(&s->iomem,
682c6766f5bSFrancisco Iglesias 0x0,
683c6766f5bSFrancisco Iglesias ®_array->mem);
684c6766f5bSFrancisco Iglesias sysbus_init_mmio(sbd, &s->iomem);
685c6766f5bSFrancisco Iglesias memory_region_init_io(&s->iomem_fdri, obj, &cframe_reg_fdri_ops, s,
686c6766f5bSFrancisco Iglesias TYPE_XLNX_VERSAL_CFRAME_REG "-fdri",
687c6766f5bSFrancisco Iglesias KEYHOLE_STREAM_4K);
688c6766f5bSFrancisco Iglesias sysbus_init_mmio(sbd, &s->iomem_fdri);
689c6766f5bSFrancisco Iglesias sysbus_init_irq(sbd, &s->irq_cfrm_imr);
690c6766f5bSFrancisco Iglesias
691c6766f5bSFrancisco Iglesias s->cframes = g_tree_new_full((GCompareDataFunc)int_cmp, NULL,
692c6766f5bSFrancisco Iglesias NULL, (GDestroyNotify)g_free);
693c6766f5bSFrancisco Iglesias fifo32_create(&s->new_f_data, FRAME_NUM_WORDS);
694c6766f5bSFrancisco Iglesias }
695c6766f5bSFrancisco Iglesias
696c6766f5bSFrancisco Iglesias static const VMStateDescription vmstate_cframe = {
697c6766f5bSFrancisco Iglesias .name = "cframe",
698c6766f5bSFrancisco Iglesias .version_id = 1,
699c6766f5bSFrancisco Iglesias .minimum_version_id = 1,
700e4ea952fSRichard Henderson .fields = (const VMStateField[]) {
701c6766f5bSFrancisco Iglesias VMSTATE_UINT32_ARRAY(data, XlnxCFrame, FRAME_NUM_WORDS),
702c6766f5bSFrancisco Iglesias VMSTATE_END_OF_LIST()
703c6766f5bSFrancisco Iglesias }
704c6766f5bSFrancisco Iglesias };
705c6766f5bSFrancisco Iglesias
706c6766f5bSFrancisco Iglesias static const VMStateDescription vmstate_cframe_reg = {
707c6766f5bSFrancisco Iglesias .name = TYPE_XLNX_VERSAL_CFRAME_REG,
708c6766f5bSFrancisco Iglesias .version_id = 1,
709c6766f5bSFrancisco Iglesias .minimum_version_id = 1,
710e4ea952fSRichard Henderson .fields = (const VMStateField[]) {
711c6766f5bSFrancisco Iglesias VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFrameReg, 4),
712c6766f5bSFrancisco Iglesias VMSTATE_UINT32_ARRAY(regs, XlnxVersalCFrameReg, CFRAME_REG_R_MAX),
713c6766f5bSFrancisco Iglesias VMSTATE_BOOL(rowon, XlnxVersalCFrameReg),
714c6766f5bSFrancisco Iglesias VMSTATE_BOOL(wcfg, XlnxVersalCFrameReg),
715c6766f5bSFrancisco Iglesias VMSTATE_BOOL(rcfg, XlnxVersalCFrameReg),
716c6766f5bSFrancisco Iglesias VMSTATE_GTREE_DIRECT_KEY_V(cframes, XlnxVersalCFrameReg, 1,
717c6766f5bSFrancisco Iglesias &vmstate_cframe, XlnxCFrame),
718c6766f5bSFrancisco Iglesias VMSTATE_FIFO32(new_f_data, XlnxVersalCFrameReg),
719c6766f5bSFrancisco Iglesias VMSTATE_END_OF_LIST(),
720c6766f5bSFrancisco Iglesias }
721c6766f5bSFrancisco Iglesias };
722c6766f5bSFrancisco Iglesias
723c6766f5bSFrancisco Iglesias static Property cframe_regs_props[] = {
724c6766f5bSFrancisco Iglesias DEFINE_PROP_LINK("cfu-fdro", XlnxVersalCFrameReg, cfg.cfu_fdro,
725c6766f5bSFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
726c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype0-frames", XlnxVersalCFrameReg,
727c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[0], 0),
728c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype1-frames", XlnxVersalCFrameReg,
729c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[1], 0),
730c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype2-frames", XlnxVersalCFrameReg,
731c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[2], 0),
732c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype3-frames", XlnxVersalCFrameReg,
733c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[3], 0),
734c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype4-frames", XlnxVersalCFrameReg,
735c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[4], 0),
736c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype5-frames", XlnxVersalCFrameReg,
737c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[5], 0),
738c6766f5bSFrancisco Iglesias DEFINE_PROP_UINT32("blktype6-frames", XlnxVersalCFrameReg,
739c6766f5bSFrancisco Iglesias cfg.blktype_num_frames[6], 0),
740c6766f5bSFrancisco Iglesias DEFINE_PROP_END_OF_LIST(),
741c6766f5bSFrancisco Iglesias };
742c6766f5bSFrancisco Iglesias
cframe_bcast_reg_init(Object * obj)743eadd3343SFrancisco Iglesias static void cframe_bcast_reg_init(Object *obj)
744eadd3343SFrancisco Iglesias {
745eadd3343SFrancisco Iglesias XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(obj);
746eadd3343SFrancisco Iglesias SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
747eadd3343SFrancisco Iglesias
748eadd3343SFrancisco Iglesias memory_region_init_io(&s->iomem_reg, obj, &cframes_bcast_reg_reg_ops, s,
749eadd3343SFrancisco Iglesias TYPE_XLNX_VERSAL_CFRAME_BCAST_REG, KEYHOLE_STREAM_4K);
750eadd3343SFrancisco Iglesias memory_region_init_io(&s->iomem_fdri, obj, &cframes_bcast_reg_fdri_ops, s,
751eadd3343SFrancisco Iglesias TYPE_XLNX_VERSAL_CFRAME_BCAST_REG "-fdri",
752eadd3343SFrancisco Iglesias KEYHOLE_STREAM_4K);
753eadd3343SFrancisco Iglesias sysbus_init_mmio(sbd, &s->iomem_reg);
754eadd3343SFrancisco Iglesias sysbus_init_mmio(sbd, &s->iomem_fdri);
755eadd3343SFrancisco Iglesias }
756eadd3343SFrancisco Iglesias
cframe_bcast_reg_reset_enter(Object * obj,ResetType type)757eadd3343SFrancisco Iglesias static void cframe_bcast_reg_reset_enter(Object *obj, ResetType type)
758eadd3343SFrancisco Iglesias {
759eadd3343SFrancisco Iglesias XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(obj);
760eadd3343SFrancisco Iglesias
761eadd3343SFrancisco Iglesias memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
762eadd3343SFrancisco Iglesias }
763eadd3343SFrancisco Iglesias
764eadd3343SFrancisco Iglesias static const VMStateDescription vmstate_cframe_bcast_reg = {
765eadd3343SFrancisco Iglesias .name = TYPE_XLNX_VERSAL_CFRAME_BCAST_REG,
766eadd3343SFrancisco Iglesias .version_id = 1,
767eadd3343SFrancisco Iglesias .minimum_version_id = 1,
768e4ea952fSRichard Henderson .fields = (const VMStateField[]) {
769eadd3343SFrancisco Iglesias VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFrameBcastReg, 4),
770eadd3343SFrancisco Iglesias VMSTATE_END_OF_LIST(),
771eadd3343SFrancisco Iglesias }
772eadd3343SFrancisco Iglesias };
773eadd3343SFrancisco Iglesias
774eadd3343SFrancisco Iglesias static Property cframe_bcast_regs_props[] = {
775eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe0", XlnxVersalCFrameBcastReg, cfg.cframe[0],
776eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
777eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe1", XlnxVersalCFrameBcastReg, cfg.cframe[1],
778eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
779eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe2", XlnxVersalCFrameBcastReg, cfg.cframe[2],
780eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
781eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe3", XlnxVersalCFrameBcastReg, cfg.cframe[3],
782eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
783eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe4", XlnxVersalCFrameBcastReg, cfg.cframe[4],
784eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
785eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe5", XlnxVersalCFrameBcastReg, cfg.cframe[5],
786eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
787eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe6", XlnxVersalCFrameBcastReg, cfg.cframe[6],
788eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
789eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe7", XlnxVersalCFrameBcastReg, cfg.cframe[7],
790eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
791eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe8", XlnxVersalCFrameBcastReg, cfg.cframe[8],
792eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
793eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe9", XlnxVersalCFrameBcastReg, cfg.cframe[9],
794eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
795eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe10", XlnxVersalCFrameBcastReg, cfg.cframe[10],
796eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
797eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe11", XlnxVersalCFrameBcastReg, cfg.cframe[11],
798eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
799eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe12", XlnxVersalCFrameBcastReg, cfg.cframe[12],
800eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
801eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe13", XlnxVersalCFrameBcastReg, cfg.cframe[13],
802eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
803eadd3343SFrancisco Iglesias DEFINE_PROP_LINK("cframe14", XlnxVersalCFrameBcastReg, cfg.cframe[14],
804eadd3343SFrancisco Iglesias TYPE_XLNX_CFI_IF, XlnxCfiIf *),
805eadd3343SFrancisco Iglesias DEFINE_PROP_END_OF_LIST(),
806eadd3343SFrancisco Iglesias };
807eadd3343SFrancisco Iglesias
cframe_reg_class_init(ObjectClass * klass,void * data)808c6766f5bSFrancisco Iglesias static void cframe_reg_class_init(ObjectClass *klass, void *data)
809c6766f5bSFrancisco Iglesias {
810c6766f5bSFrancisco Iglesias ResettableClass *rc = RESETTABLE_CLASS(klass);
811c6766f5bSFrancisco Iglesias DeviceClass *dc = DEVICE_CLASS(klass);
812c6766f5bSFrancisco Iglesias XlnxCfiIfClass *xcic = XLNX_CFI_IF_CLASS(klass);
813c6766f5bSFrancisco Iglesias
814c6766f5bSFrancisco Iglesias dc->vmsd = &vmstate_cframe_reg;
815c6766f5bSFrancisco Iglesias dc->realize = cframe_reg_realize;
816c6766f5bSFrancisco Iglesias rc->phases.enter = cframe_reg_reset_enter;
817c6766f5bSFrancisco Iglesias rc->phases.hold = cframe_reg_reset_hold;
818c6766f5bSFrancisco Iglesias device_class_set_props(dc, cframe_regs_props);
819c6766f5bSFrancisco Iglesias xcic->cfi_transfer_packet = cframe_reg_cfi_transfer_packet;
820c6766f5bSFrancisco Iglesias }
821c6766f5bSFrancisco Iglesias
cframe_bcast_reg_class_init(ObjectClass * klass,void * data)822eadd3343SFrancisco Iglesias static void cframe_bcast_reg_class_init(ObjectClass *klass, void *data)
823eadd3343SFrancisco Iglesias {
824eadd3343SFrancisco Iglesias DeviceClass *dc = DEVICE_CLASS(klass);
825eadd3343SFrancisco Iglesias ResettableClass *rc = RESETTABLE_CLASS(klass);
826eadd3343SFrancisco Iglesias
827eadd3343SFrancisco Iglesias dc->vmsd = &vmstate_cframe_bcast_reg;
828eadd3343SFrancisco Iglesias device_class_set_props(dc, cframe_bcast_regs_props);
829eadd3343SFrancisco Iglesias rc->phases.enter = cframe_bcast_reg_reset_enter;
830eadd3343SFrancisco Iglesias }
831eadd3343SFrancisco Iglesias
832c6766f5bSFrancisco Iglesias static const TypeInfo cframe_reg_info = {
833c6766f5bSFrancisco Iglesias .name = TYPE_XLNX_VERSAL_CFRAME_REG,
834c6766f5bSFrancisco Iglesias .parent = TYPE_SYS_BUS_DEVICE,
835c6766f5bSFrancisco Iglesias .instance_size = sizeof(XlnxVersalCFrameReg),
836c6766f5bSFrancisco Iglesias .class_init = cframe_reg_class_init,
837c6766f5bSFrancisco Iglesias .instance_init = cframe_reg_init,
838c6766f5bSFrancisco Iglesias .interfaces = (InterfaceInfo[]) {
839c6766f5bSFrancisco Iglesias { TYPE_XLNX_CFI_IF },
840c6766f5bSFrancisco Iglesias { }
841c6766f5bSFrancisco Iglesias }
842c6766f5bSFrancisco Iglesias };
843c6766f5bSFrancisco Iglesias
844eadd3343SFrancisco Iglesias static const TypeInfo cframe_bcast_reg_info = {
845eadd3343SFrancisco Iglesias .name = TYPE_XLNX_VERSAL_CFRAME_BCAST_REG,
846eadd3343SFrancisco Iglesias .parent = TYPE_SYS_BUS_DEVICE,
847eadd3343SFrancisco Iglesias .instance_size = sizeof(XlnxVersalCFrameBcastReg),
848eadd3343SFrancisco Iglesias .class_init = cframe_bcast_reg_class_init,
849eadd3343SFrancisco Iglesias .instance_init = cframe_bcast_reg_init,
850eadd3343SFrancisco Iglesias };
851eadd3343SFrancisco Iglesias
cframe_reg_register_types(void)852c6766f5bSFrancisco Iglesias static void cframe_reg_register_types(void)
853c6766f5bSFrancisco Iglesias {
854c6766f5bSFrancisco Iglesias type_register_static(&cframe_reg_info);
855eadd3343SFrancisco Iglesias type_register_static(&cframe_bcast_reg_info);
856c6766f5bSFrancisco Iglesias }
857c6766f5bSFrancisco Iglesias
858c6766f5bSFrancisco Iglesias type_init(cframe_reg_register_types)
859