1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "hw/sysbus.h"
12#include "qemu/log.h"
13#include "qapi/error.h"
14
15#include "hw/hw.h"
16#include "hw/stream.h"
17#include "qemu/bitops.h"
18#include "sysemu/dma.h"
19#include "migration/vmstate.h"
20#include "hw/qdev-properties.h"
21#include "hw/register.h"
22#include "hw/zynqmp_aes_key.h"
23#include "hw/fdt_generic_util.h"
24
25#include "hw/misc/xlnx-aes.h"
26
27#ifndef ZYNQMP_CSU_AES_ERR_DEBUG
28#define ZYNQMP_CSU_AES_ERR_DEBUG 0
29#endif
30
31#define TYPE_ZYNQMP_CSU_AES "zynqmp,csu-aes"
32#define TYPE_ZYNQMP_CSU_DEVKEY_SINK "zynqmp.csu-aes.devkey-sink"
33
34#define ZYNQMP_CSU_AES(obj) \
35 OBJECT_CHECK(ZynqMPCSUAES, (obj), TYPE_ZYNQMP_CSU_AES)
36
37#define ZYNQMP_CSU_KEY_SINK(obj) \
38 OBJECT_CHECK(CSUKeySink, (obj), TYPE_ZYNQMP_CSU_DEVKEY_SINK)
39
40REG32(AES_STATUS, 0x00)
41 FIELD(AES_STATUS, OKR_ZEROED, 11, 1)
42 FIELD(AES_STATUS, BOOT_ZEROED, 10, 1)
43 FIELD(AES_STATUS, KUP_ZEROED, 9, 1)
44 FIELD(AES_STATUS, AES_KEY_ZEROED, 8, 1)
45 FIELD(AES_STATUS, BLACK_KEY_DONE, 5, 1)
46 FIELD(AES_STATUS, KEY_INIT_DONE, 4, 1)
47 FIELD(AES_STATUS, GCM_TAG_PASS, 3, 1)
48 FIELD(AES_STATUS, DONE, 2, 1)
49 FIELD(AES_STATUS, READY, 1, 1)
50 FIELD(AES_STATUS, BUSY, 0, 1)
51REG32(AES_KEY_SRC, 0x04)
52 FIELD(AES_KEY_SRC, KEY_SRC, 0, 4)
53
54#define AES_KEYSRC_KUP 0
55#define AES_KEYSRC_DEV 1
56
57REG32(AES_KEY_LOAD, 0x08)
58 FIELD(AES_KEY_LOAD, KEY_LOAD, 0, 1)
59REG32(AES_START_MSG, 0x0c)
60 FIELD(AES_START_MSG, START_MSG, 0, 1)
61REG32(AES_RESET, 0x10)
62 FIELD(AES_RESET, RESET, 0, 1)
63REG32(AES_KEY_CLEAR, 0x14)
64 FIELD(AES_KEY_CLEAR, AES_KUP_ZERO, 1, 1)
65 FIELD(AES_KEY_CLEAR, AES_KEY_ZERO, 0, 1)
66REG32(AES_CFG, 0x18)
67 FIELD(AES_CFG, ENCRYPT_DECRYPT_N, 0, 1)
68REG32(AES_KUP_WR, 0x1c)
69 FIELD(AES_KUP_WR, IV_WRITE, 1, 1)
70 FIELD(AES_KUP_WR, KUP_WRITE, 0, 1)
71REG32(AES_KUP_0, 0x020)
72REG32(AES_KUP_1, 0x24)
73REG32(AES_KUP_2, 0x28)
74REG32(AES_KUP_3, 0x2c)
75REG32(AES_KUP_4, 0x30)
76REG32(AES_KUP_5, 0x34)
77REG32(AES_KUP_6, 0x38)
78REG32(AES_KUP_7, 0x3c)
79REG32(AES_IV_0, 0x40)
80REG32(AES_IV_1, 0x44)
81REG32(AES_IV_2, 0x48)
82REG32(AES_IV_3, 0x4c)
83
84#define R_MAX (R_AES_IV_3 + 1)
85
86static const RegisterAccessInfo aes_regs_info[] = {
87 { .name = "AES_STATUS", .addr = A_AES_STATUS,
88 .reset = 0xf00,
89 .rsvd = 0xc0,
90 .ro = 0xfff,
91 },{ .name = "AES_KEY_SRC", .addr = A_AES_KEY_SRC,
92 },{ .name = "AES_KEY_LOAD", .addr = A_AES_KEY_LOAD,
93 },{ .name = "AES_START_MSG", .addr = A_AES_START_MSG,
94 },{ .name = "AES_RESET", .addr = A_AES_RESET,
95 },{ .name = "AES_KEY_CLEAR", .addr = A_AES_KEY_CLEAR,
96 },{ .name = "AES_CFG", .addr = A_AES_CFG,
97 },{ .name = "AES_KUP_WR", .addr = A_AES_KUP_WR,
98 },{ .name = "AES_KUP_0", .addr = A_AES_KUP_0,
99 },{ .name = "AES_KUP_1", .addr = A_AES_KUP_1,
100 },{ .name = "AES_KUP_2", .addr = A_AES_KUP_2,
101 },{ .name = "AES_KUP_3", .addr = A_AES_KUP_3,
102 },{ .name = "AES_KUP_4", .addr = A_AES_KUP_4,
103 },{ .name = "AES_KUP_5", .addr = A_AES_KUP_5,
104 },{ .name = "AES_KUP_6", .addr = A_AES_KUP_6,
105 },{ .name = "AES_KUP_7", .addr = A_AES_KUP_7,
106 },{ .name = "AES_IV_0", .addr = A_AES_IV_0,
107 .ro = 0xffffffff,
108 },{ .name = "AES_IV_1", .addr = A_AES_IV_1,
109 .ro = 0xffffffff,
110 },{ .name = "AES_IV_2", .addr = A_AES_IV_2,
111 .ro = 0xffffffff,
112 },{ .name = "AES_IV_3", .addr = A_AES_IV_3,
113 .ro = 0xffffffff,
114 }
115};
116
117typedef struct ZynqMPCSUAES ZynqMPCSUAES;
118
119typedef struct CSUKeySink {
120 Object parent;
121 ZynqMPCSUAES *tmr;
122
123 union {
124 uint8_t key[256 / 8];
125 uint32_t k32[256 / 32];
126 };
127} CSUKeySink;
128
129
130struct ZynqMPCSUAES {
131 SysBusDevice busdev;
132 MemoryRegion iomem;
133 StreamSink *tx_dev;
134 char *family_key_id;
135 char *puf_key_id;
136
137 XlnxAES *aes;
138 qemu_irq aes_rst;
139 bool in_reset;
140 bool aes_done;
141 bool aes_busy;
142
143 bool key_loaded;
144 uint32_t regs[R_MAX];
145 RegisterInfo regs_info[R_MAX];
146
147 union {
148 struct {
149 bool kup_write;
150 bool boot_write;
151 bool okr_write;
152 bool iv_write;
153 bool key_decrypt;
154 };
155 bool bl[5];
156 } inputs;
157
158 CSUKeySink bbram_key;
159 CSUKeySink boot_key;
160 CSUKeySink efuse_key;
161 CSUKeySink family_key;
162 CSUKeySink okr_key;
163 CSUKeySink puf_key;
164 CSUKeySink *dev_key;
165
166 struct {
167 uint32_t key[256 / 32];
168 uint32_t iv[128 / 32];
169 } feedback;
170
171 StreamCanPushNotifyFn notify;
172 void *notify_opaque;
173
174 const char *prefix;
175};
176
177
178
179
180
181
182static int xlx_aes_push_data(ZynqMPCSUAES *s,
183 uint8_t *data8x, int len,
184 bool last_word , int lw_len,
185 uint8_t *outbuf, int *outlen)
186{
187
188 return xlnx_aes_push_data(s->aes, data8x, len, false, last_word, lw_len,
189 outbuf, outlen);
190}
191
192static uint32_t shift_in_u32(uint32_t *a, unsigned int size, uint32_t data)
193{
194 unsigned int i;
195 uint32_t r = a[0];
196
197 for (i = 1; i < size; i++) {
198 a[i - 1] = a[i];
199 }
200 a[i - 1] = data;
201
202 return r;
203}
204
205static void update_devkey_sink(CSUKeySink *ks, void *key)
206{
207 memcpy(ks->key, key, sizeof(ks->key));
208}
209
210static void xlx_aes_feedback(ZynqMPCSUAES *s, unsigned char *buf, int len)
211{
212 bool key_feedback;
213 bool kup_key_feedback;
214 bool iv_feedback;
215 int i;
216
217 iv_feedback = s->inputs.iv_write;
218 iv_feedback |= s->regs[R_AES_KUP_WR] & R_AES_KUP_WR_IV_WRITE_MASK;
219
220 kup_key_feedback = s->inputs.kup_write;
221 kup_key_feedback |= s->regs[R_AES_KUP_WR] & R_AES_KUP_WR_KUP_WRITE_MASK;
222
223 key_feedback = kup_key_feedback;
224 key_feedback |= s->inputs.okr_write | s->inputs.boot_write;
225
226 assert((len & 3) == 0);
227
228 for (i = 0; i < len; i += 4) {
229 uint32_t data;
230 memcpy(&data, buf + i, 4);
231
232 if (iv_feedback) {
233 data = shift_in_u32(s->feedback.iv, ARRAY_SIZE(s->feedback.iv),
234 data);
235 }
236 if (key_feedback) {
237 shift_in_u32(s->feedback.key, ARRAY_SIZE(s->feedback.key), data);
238 }
239 }
240
241
242 if (iv_feedback) {
243 for (i = 0; i < ARRAY_SIZE(s->feedback.iv); i++) {
244 s->regs[R_AES_IV_0 + i] = s->feedback.iv[i];
245 }
246 }
247 if (s->inputs.kup_write | kup_key_feedback) {
248 for (i = 0; i < ARRAY_SIZE(s->feedback.key); i++) {
249 s->regs[R_AES_KUP_0 + i] = s->feedback.key[i];
250 }
251 }
252
253 if (s->inputs.boot_write) {
254 update_devkey_sink(&s->boot_key, s->feedback.key);
255 }
256 if (s->inputs.okr_write) {
257 update_devkey_sink(&s->okr_key, s->feedback.key);
258 }
259}
260
261static void bswap32_buf8(uint8_t *buf, int len)
262{
263 int i;
264
265 assert((len & 3) == 0);
266 for (i = 0; i < len; i += 4) {
267 uint8_t v[4];
268
269 v[0] = buf[i];
270 v[1] = buf[i + 1];
271 v[2] = buf[i + 2];
272 v[3] = buf[i + 3];
273 buf[i] = v[3];
274 buf[i + 1] = v[2];
275 buf[i + 2] = v[1];
276 buf[i + 3] = v[0];
277 }
278}
279
280static size_t xlx_aes_stream_push(StreamSink *obj, uint8_t *buf, size_t len,
281 bool eop)
282{
283 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
284 unsigned char outbuf[8 * 1024 + 16];
285 int outlen = 0;
286 bool feedback;
287 size_t ret;
288
289
290 if (len > (sizeof(outbuf) - 16)) {
291 len = sizeof(outbuf) - 16;
292 eop = false;
293 }
294
295 bswap32_buf8(buf, len);
296 ret = xlx_aes_push_data(s, buf, len, eop, 4, outbuf, &outlen);
297 bswap32_buf8(outbuf, outlen);
298
299
300 feedback = s->inputs.iv_write | s->inputs.kup_write;
301 feedback |= s->inputs.boot_write | s->inputs.okr_write;
302 feedback |= s->regs[R_AES_KUP_WR]
303 & (R_AES_KUP_WR_IV_WRITE_MASK | R_AES_KUP_WR_KUP_WRITE_MASK);
304 if (feedback) {
305 xlx_aes_feedback(s, outbuf, outlen);
306 memset(outbuf, 0, outlen);
307 }
308 stream_push(s->tx_dev, outbuf, outlen, eop);
309 return ret;
310}
311
312static bool xlx_aes_stream_can_push(StreamSink *obj,
313 StreamCanPushNotifyFn notify,
314 void *notify_opaque)
315{
316 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
317 return s->aes->inp_ready;
318}
319
320static void xlx_aes_write_key(ZynqMPCSUAES *s, unsigned int pos, uint32_t val)
321{
322 if (s->inputs.key_decrypt) {
323 xlx_aes_stream_push(STREAM_SINK(s), (void *) &val, sizeof val, 0);
324 } else {
325 xlnx_aes_write_key(s->aes, pos, val);
326 }
327}
328
329static void xlx_aes_load_key(ZynqMPCSUAES *s, int len)
330{
331 static uint32_t const zero_key[256 / 32] = { 0};
332 const uint32_t *k32;
333
334 unsigned int src, i;
335 src = (s->regs[R_AES_KEY_SRC] & R_AES_KEY_SRC_KEY_SRC_MASK)
336 >> R_AES_KEY_SRC_KEY_SRC_SHIFT;
337
338 switch (src) {
339 case AES_KEYSRC_KUP:
340 k32 = &s->regs[R_AES_KUP_0];
341 break;
342 case AES_KEYSRC_DEV:
343 k32 = s->dev_key ? s->dev_key->k32 : zero_key;
344 break;
345 default:
346 hw_error("%s: Unsupported AES Key source %d\n", s->prefix, src);
347 k32 = zero_key;
348 }
349
350 for (i = 0; i < 8; i++) {
351 xlx_aes_write_key(s, i, k32[i]);
352 }
353
354 if (!s->inputs.key_decrypt) {
355 xlnx_aes_load_key(s->aes, len);
356 }
357 s->key_loaded = true;
358}
359
360static uint64_t xlx_aes_read(void *opaque, hwaddr addr, unsigned size)
361{
362 RegisterInfoArray *reg_array = opaque;
363 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(reg_array->r[0]->opaque);
364 uint32_t v;
365
366 v = register_read_memory(opaque, addr, size);
367
368 addr >>= 2;
369 assert(addr < R_MAX);
370 switch (addr) {
371 case R_AES_KUP_0...R_AES_KUP_7:
372 v = 0;
373 break;
374 case R_AES_STATUS:
375 v = 0;
376 v |= R_AES_STATUS_BOOT_ZEROED_MASK;
377 v |= R_AES_STATUS_OKR_ZEROED_MASK;
378 v |= R_AES_STATUS_KUP_ZEROED_MASK;
379 v |= s->key_loaded ? R_AES_STATUS_KEY_INIT_DONE_MASK : 0;
380 v |= s->aes->key_zeroed ? R_AES_STATUS_AES_KEY_ZEROED_MASK : 0;
381 v |= s->aes->tag_ok ? R_AES_STATUS_GCM_TAG_PASS_MASK : 0;
382 v |= s->aes->inp_ready ? R_AES_STATUS_READY_MASK : 0;
383 v |= s->aes_busy ? R_AES_STATUS_BUSY_MASK : 0;
384 v |= s->aes_done ? R_AES_STATUS_DONE_MASK : 0;
385 break;
386 default:
387 break;
388 }
389 return v;
390}
391
392static void xlx_aes_reset(DeviceState *dev)
393{
394 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(dev);
395 int i;
396
397 s->in_reset = true;
398 for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
399 register_reset(&s->regs_info[i]);
400 }
401
402 qemu_irq_pulse(s->aes_rst);
403 s->key_loaded = false;
404
405 s->in_reset = false;
406}
407
408static void xlx_aes_write(void *opaque, hwaddr addr, uint64_t value,
409 unsigned size)
410{
411 RegisterInfoArray *reg_array = opaque;
412 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(reg_array->r[0]->opaque);
413
414 register_write_memory(opaque, addr, value, size);
415
416 addr >>= 2;
417 switch (addr) {
418 case R_AES_KEY_LOAD:
419 if (value) {
420 xlx_aes_load_key(s, 256);
421 }
422 break;
423 case R_AES_START_MSG:
424 if (value) {
425 xlnx_aes_start_message(s->aes,
426 s->regs[R_AES_CFG] & R_AES_CFG_ENCRYPT_DECRYPT_N_MASK);
427 }
428 break;
429 case R_AES_RESET:
430 if (value && !s->in_reset) {
431 xlx_aes_reset((void *)s);
432 }
433 break;
434 case R_AES_KEY_CLEAR:
435 if (value & R_AES_KEY_CLEAR_AES_KEY_ZERO_MASK) {
436 xlnx_aes_key_zero(s->aes);
437 s->regs[R_AES_KEY_CLEAR] &= ~R_AES_KEY_CLEAR_AES_KEY_ZERO_MASK;
438 s->key_loaded = false;
439 }
440 if (value & R_AES_KEY_CLEAR_AES_KUP_ZERO_MASK) {
441 s->regs[R_AES_KEY_CLEAR] &= ~R_AES_KEY_CLEAR_AES_KUP_ZERO_MASK;
442 memset(&s->regs[R_AES_KUP_0], 0, 8 * 4);
443 }
444 break;
445 default:
446 break;
447 }
448}
449
450static const MemoryRegionOps aes_ops = {
451 .read = xlx_aes_read,
452 .write = xlx_aes_write,
453 .endianness = DEVICE_LITTLE_ENDIAN,
454};
455
456static void gpio_key_write_ctrl(void *opaque, int n, int level)
457{
458 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
459 assert(n < ARRAY_SIZE(s->inputs.bl));
460
461 s->inputs.bl[n] = level;
462}
463
464static void aes_busy_update(void *opaque, int n, int level)
465{
466 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
467
468 s->aes_busy = level;
469}
470
471static void aes_done_update(void *opaque, int n, int level)
472{
473 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
474
475 s->aes_done = level;
476}
477
478static void aes_realize(DeviceState *dev, Error **errp)
479{
480 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(dev);
481
482 s->prefix = g_strdup_printf("%s:", object_get_canonical_path(OBJECT(s)));
483 s->aes->prefix = s->prefix;
484 qdev_init_gpio_in_named(dev, aes_busy_update, "busy", 1);
485 qdev_init_gpio_in_named(dev, aes_done_update, "done", 1);
486 qdev_init_gpio_out_named(dev, &s->aes_rst, "reset", 1);
487 qdev_init_gpio_in_named(dev, gpio_key_write_ctrl, "key-wr", 5);
488
489
490 xlnx_aes_k256_get_provided(OBJECT(s), "family-key-id",
491 NULL, s->family_key.key, NULL);
492}
493
494static void csu_devkey_sink_init(ZynqMPCSUAES *s,
495 const char *name, CSUKeySink *ks)
496{
497 char *ch_name;
498
499 ch_name = g_strdup_printf("zynqmp-aes-key-sink-%s-target", name);
500 object_initialize(ks, sizeof(*ks), TYPE_ZYNQMP_CSU_DEVKEY_SINK);
501 object_property_add_child(OBJECT(s), ch_name, (Object *)ks);
502 free(ch_name);
503
504
505 ks->tmr = s;
506}
507
508static void aes_init(Object *obj)
509{
510 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
511 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
512 RegisterInfoArray *reg_array;
513
514
515 csu_devkey_sink_init(s, "bbram", &s->bbram_key);
516 csu_devkey_sink_init(s, "boot", &s->boot_key);
517 csu_devkey_sink_init(s, "efuses", &s->efuse_key);
518 csu_devkey_sink_init(s, "family", &s->family_key);
519 csu_devkey_sink_init(s, "operational", &s->okr_key);
520 csu_devkey_sink_init(s, "puf", &s->puf_key);
521
522 if (s->family_key_id == NULL) {
523 s->family_key_id = g_strdup("xlnx-aes-family-key");
524 }
525 if (s->puf_key_id == NULL) {
526 s->puf_key_id = g_strdup("xlnx-aes-puf-key");
527 }
528
529
530 s->dev_key = NULL;
531
532 memory_region_init(&s->iomem, obj, TYPE_ZYNQMP_CSU_AES, R_MAX * 4);
533 reg_array =
534 register_init_block32(DEVICE(obj), aes_regs_info,
535 ARRAY_SIZE(aes_regs_info),
536 s->regs_info, s->regs,
537 &aes_ops,
538 ZYNQMP_CSU_AES_ERR_DEBUG,
539 R_MAX * 4);
540 memory_region_add_subregion(&s->iomem,
541 0x0,
542 ®_array->mem);
543 sysbus_init_mmio(sbd, &s->iomem);
544}
545
546static const VMStateDescription vmstate_aes = {
547 .name = "zynqmp_csu_aes",
548 .version_id = 1,
549 .minimum_version_id = 1,
550 .minimum_version_id_old = 1,
551 .fields = (VMStateField[]) {
552 VMSTATE_UINT32_ARRAY(regs, ZynqMPCSUAES, R_MAX),
553 VMSTATE_END_OF_LIST(),
554 }
555};
556
557static Property aes_properties[] = {
558 DEFINE_PROP_LINK("stream-connected-aes",
559 ZynqMPCSUAES, tx_dev,
560 TYPE_STREAM_SINK, StreamSink *),
561 DEFINE_PROP_LINK("aes-core",
562 ZynqMPCSUAES, aes,
563 TYPE_XLNX_AES, XlnxAES *),
564
565 DEFINE_PROP_STRING("family-key-id", ZynqMPCSUAES, family_key_id),
566 DEFINE_PROP_STRING("puf-key-id", ZynqMPCSUAES, puf_key_id),
567
568 DEFINE_PROP_END_OF_LIST(),
569};
570
571static const FDTGenericGPIOSet aes_gpios[] = {
572 {
573 .names = &fdt_generic_gpio_name_set_gpio,
574 .gpios = (FDTGenericGPIOConnection[]) {
575 { .name = "key-wr", .fdt_index = 0, .range = 5 },
576 { .name = "reset", .fdt_index = 5, .range = 1},
577 { },
578 },
579 },
580 { },
581};
582
583static void aes_select_device_key(ZynqMPAESKeySink *obj, uint8_t *key, size_t len)
584{
585 ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
586
587
588
589
590
591 assert(key);
592 assert(len == 1);
593
594 switch (key[0]) {
595 case 'M':
596 case 'm':
597 s->dev_key = &s->bbram_key;
598 break;
599 case 'E':
600 case 'e':
601 s->dev_key = &s->efuse_key;
602 break;
603 case 'B':
604 case 'b':
605 s->dev_key = &s->boot_key;
606 break;
607 case 'O':
608 case 'o':
609 s->dev_key = &s->okr_key;
610 break;
611 case 'F':
612 case 'f':
613 s->dev_key = &s->family_key;
614 break;
615 case 'P':
616 case 'p':
617 s->dev_key = &s->puf_key;
618 break;
619 default:
620 s->dev_key = NULL;
621 }
622
623 return;
624}
625
626static void aes_class_init(ObjectClass *klass, void *data)
627{
628 DeviceClass *dc = DEVICE_CLASS(klass);
629 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
630 ZynqMPAESKeySinkClass *ksc = ZYNQMP_AES_KEY_SINK_CLASS(klass);
631 FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
632
633
634 dc->reset = xlx_aes_reset;
635 dc->realize = aes_realize;
636 dc->vmsd = &vmstate_aes;
637 device_class_set_props(dc, aes_properties);
638
639 ssc->push = xlx_aes_stream_push;
640 ssc->can_push = xlx_aes_stream_can_push;
641
642 ksc->update = aes_select_device_key;
643 fggc->controller_gpios = aes_gpios;
644}
645
646static void csu_devkey_sink_update(ZynqMPAESKeySink *obj,
647 uint8_t *key, size_t len)
648{
649 CSUKeySink *ks = ZYNQMP_CSU_KEY_SINK(obj);
650
651 assert(len == sizeof(ks->key));
652 update_devkey_sink(ks, key);
653}
654
655static void csu_devkey_sink_class_init(ObjectClass *klass, void *data)
656{
657 ZynqMPAESKeySinkClass *c = ZYNQMP_AES_KEY_SINK_CLASS(klass);
658 c->update = csu_devkey_sink_update;
659}
660
661static const TypeInfo aes_info = {
662 .name = TYPE_ZYNQMP_CSU_AES,
663 .parent = TYPE_SYS_BUS_DEVICE,
664 .instance_size = sizeof(ZynqMPCSUAES),
665 .class_init = aes_class_init,
666 .instance_init = aes_init,
667 .interfaces = (InterfaceInfo[]) {
668 { TYPE_STREAM_SINK },
669 { TYPE_ZYNQMP_AES_KEY_SINK },
670 { TYPE_FDT_GENERIC_GPIO },
671 { }
672 }
673};
674
675static const TypeInfo csu_devkey_sink_info = {
676 .name = TYPE_ZYNQMP_CSU_DEVKEY_SINK,
677 .parent = TYPE_OBJECT,
678 .instance_size = sizeof(CSUKeySink),
679 .class_init = csu_devkey_sink_class_init,
680 .interfaces = (InterfaceInfo[]) {
681 { TYPE_ZYNQMP_AES_KEY_SINK },
682 { }
683 }
684};
685
686static void aes_register_types(void)
687{
688 type_register_static(&aes_info);
689 type_register_static(&csu_devkey_sink_info);
690}
691
692type_init(aes_register_types)
693