Skip to content

Commit

Permalink
Merge tag 'pull-target-arm-20230908' of https://git.linaro.org/people…
Browse files Browse the repository at this point in the history
…/pmaydell/qemu-arm into staging

target-arm queue:
 * New CPU type: cortex-a710
 * Implement new architectural features:
    - FEAT_PACQARMA3
    - FEAT_EPAC
    - FEAT_Pauth2
    - FEAT_FPAC
    - FEAT_FPACCOMBINE
    - FEAT_TIDCP1
 * Xilinx Versal: Model the CFU/CFI
 * Implement RMR_ELx registers
 * Implement handling of HCR_EL2.TIDCP trap bit
 * arm/kvm: Enable support for KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE
 * hw/intc/arm_gicv3_its: Avoid maybe-uninitialized error in get_vte()
 * target/arm: Do not use gen_mte_checkN in trans_STGP
 * arm64: Restore trapless ptimer access

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmT7VEkZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3v7BEACENUKCxsFHRQSLmQkoBCT9
# Lc4SJrGCbVUC6b+4s5ligZSWIoFzp/kY6NPpeRYqFa0DCxozd2T5D81/j7TpSo0C
# wUFkZfUq1nGFJ4K5arYcDwhdTtJvvc07YrSbUqufBp6uNGqhR4YmDWPECqBfOlaj
# 7bgJM6axsg7FkJJh5zp4cQ4WEfp14MHWRPQWpVTI+9cxNmNymokSVRBhVFkM0Wen
# WD4C/nYud8bOxpDfR8GkIqJ+UnUMhUNEhp28QmHdwywgg0zLWOE4ysIxo55cM0+0
# FL3q45PL2e4S24UUx9dkxDBWnKEZ5qpQpPn9F6EhWzfm3n2dqr4uUnfWAEOg6NAi
# vnGS9MlL7nZo69OM3h8g7yKDfTKYm2vl9HVZ0ytFA6PLoSnaQyQwli58qnLtiid3
# 17MWPoNQlq6G8tHUTPkrJjdA8XLz0iNPXe5G2kwhuM/S0Lv7ORzDc2pq4qBYLvIw
# 9nV0oUWqzyE7zH6bRKxbbPw2sMI7c8qQr9QRyZeLHL7HdcY5ExvX9FH+qii5JDR/
# fZohi1pBoNNwYYTeSRnxgHiQ7OizYq0xQJhrdqcFF9voytZj1yZEZ0mp6Tq0/CIj
# YkC/vEyLYBqgrJ2JeUjbV3h1RIzQcVaXxnxwGsyMyceACd6MNMmdbjR7bZk0lNIu
# kh+aFEdKajPp56UseJiKBQ==
# =5Shq
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 08 Sep 2023 13:05:13 EDT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20230908' of https://git.linaro.org/people/pmaydell/qemu-arm: (26 commits)
  arm/kvm: Enable support for KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE
  target/arm: Enable SCTLR_EL1.TIDCP for user-only
  target/arm: Implement FEAT_TIDCP1
  target/arm: Implement HCR_EL2.TIDCP
  target/arm: Implement cortex-a710
  target/arm: Implement RMR_ELx
  arm64: Restore trapless ptimer access
  target/arm: Do not use gen_mte_checkN in trans_STGP
  hw/arm/versal: Connect the CFRAME_REG and CFRAME_BCAST_REG
  hw/arm/xlnx-versal: Connect the CFU_APB, CFU_FDRO and CFU_SFR
  hw/misc: Introduce a model of Xilinx Versal's CFRAME_BCAST_REG
  hw/misc: Introduce a model of Xilinx Versal's CFRAME_REG
  hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal's CFU_SFR
  hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal CFU_FDRO
  hw/misc: Introduce a model of Xilinx Versal's CFU_APB
  hw/misc: Introduce the Xilinx CFI interface
  hw/intc/arm_gicv3_its: Avoid maybe-uninitialized error in get_vte()
  target/arm: Implement FEAT_FPAC and FEAT_FPACCOMBINE
  target/arm: Inform helpers whether a PAC instruction is 'combined'
  target/arm: Implement FEAT_Pauth2
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Sep 11, 2023
2 parents c5ea91d + c8f2eb5 commit a7e8e30
Show file tree
Hide file tree
Showing 40 changed files with 3,183 additions and 156 deletions.
10 changes: 10 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,16 @@ S: Maintained
F: hw/ssi/xlnx-versal-ospi.c
F: include/hw/ssi/xlnx-versal-ospi.h

Xilinx Versal CFI
M: Francisco Iglesias <francisco.iglesias@amd.com>
S: Maintained
F: hw/misc/xlnx-cfi-if.c
F: include/hw/misc/xlnx-cfi-if.h
F: hw/misc/xlnx-versal-cfu.c
F: include/hw/misc/xlnx-versal-cfu.h
F: hw/misc/xlnx-versal-cframe-reg.c
F: include/hw/misc/xlnx-versal-cframe-reg.h

STM32F100
M: Alexandre Iooss <erdnaxe@crans.org>
L: qemu-arm@nongnu.org
Expand Down
1 change: 1 addition & 0 deletions accel/kvm/kvm-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -3763,6 +3763,7 @@ static void kvm_accel_instance_init(Object *obj)
/* KVM dirty ring is by default off */
s->kvm_dirty_ring_size = 0;
s->kvm_dirty_ring_with_bitmap = false;
s->kvm_eager_split_size = 0;
s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN;
s->notify_window = 0;
s->xen_version = 0;
Expand Down
21 changes: 13 additions & 8 deletions docs/system/arm/cpu-features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,20 @@ TCG VCPU Features
TCG VCPU features are CPU features that are specific to TCG.
Below is the list of TCG VCPU features and their descriptions.

``pauth``
Enable or disable ``FEAT_Pauth`` entirely.

``pauth-impdef``
When ``FEAT_Pauth`` is enabled, either the *impdef* (Implementation
Defined) algorithm is enabled or the *architected* QARMA algorithm
is enabled. By default the impdef algorithm is disabled, and QARMA
is enabled.

The architected QARMA algorithm has good cryptographic properties,
but can be quite slow to emulate. The impdef algorithm used by QEMU
is non-cryptographic but significantly faster.
When ``pauth`` is enabled, select the QEMU implementation defined algorithm.

``pauth-qarma3``
When ``pauth`` is enabled, select the architected QARMA3 algorithm.

Without either ``pauth-impdef`` or ``pauth-qarma3`` enabled,
the architected QARMA5 algorithm is used. The architected QARMA5
and QARMA3 algorithms have good cryptographic properties, but can
be quite slow to emulate. The impdef algorithm used by QEMU is
non-cryptographic but significantly faster.

SVE CPU Properties
==================
Expand Down
8 changes: 8 additions & 0 deletions docs/system/arm/emulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ the following architecture extensions:
- FEAT_DotProd (Advanced SIMD dot product instructions)
- FEAT_DoubleFault (Double Fault Extension)
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
- FEAT_EPAC (Enhanced pointer authentication)
- FEAT_ETS (Enhanced Translation Synchronization)
- FEAT_EVT (Enhanced Virtualization Traps)
- FEAT_FCMA (Floating-point complex number instructions)
- FEAT_FGT (Fine-Grained Traps)
- FEAT_FHM (Floating-point half-precision multiplication instructions)
- FEAT_FP16 (Half-precision floating-point data processing)
- FEAT_FPAC (Faulting on AUT* instructions)
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
- FEAT_FRINTTS (Floating-point to integer instructions)
- FEAT_FlagM (Flag manipulation instructions v2)
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
Expand All @@ -57,10 +60,14 @@ the following architecture extensions:
- FEAT_MTE (Memory Tagging Extension)
- FEAT_MTE2 (Memory Tagging Extension)
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
- FEAT_PACIMP (Pointer authentication - IMPLEMENTATION DEFINED algorithm)
- FEAT_PACQARMA3 (Pointer authentication - QARMA3 algorithm)
- FEAT_PACQARMA5 (Pointer authentication - QARMA5 algorithm)
- FEAT_PAN (Privileged access never)
- FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
- FEAT_PAuth (Pointer authentication)
- FEAT_PAuth2 (Enhacements to pointer authentication)
- FEAT_PMULL (PMULL, PMULL2 instructions)
- FEAT_PMUv3p1 (PMU Extensions v3.1)
- FEAT_PMUv3p4 (PMU Extensions v3.4)
Expand All @@ -85,6 +92,7 @@ the following architecture extensions:
- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
- FEAT_SPECRES (Speculation restriction instructions)
- FEAT_SSBS (Speculative Store Bypass Safe)
- FEAT_TIDCP1 (EL0 use of IMPLEMENTATION DEFINED functionality)
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
- FEAT_TLBIRANGE (TLB invalidate range instructions)
- FEAT_TTCNP (Translation table Common not private translations)
Expand Down
1 change: 1 addition & 0 deletions docs/system/arm/virt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Supported guest CPU types:
- ``cortex-a57`` (64-bit)
- ``cortex-a72`` (64-bit)
- ``cortex-a76`` (64-bit)
- ``cortex-a710`` (64-bit)
- ``a64fx`` (64-bit)
- ``host`` (with KVM only)
- ``neoverse-n1`` (64-bit)
Expand Down
1 change: 1 addition & 0 deletions hw/arm/virt.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ static const char *valid_cpus[] = {
ARM_CPU_TYPE_NAME("cortex-a55"),
ARM_CPU_TYPE_NAME("cortex-a72"),
ARM_CPU_TYPE_NAME("cortex-a76"),
ARM_CPU_TYPE_NAME("cortex-a710"),
ARM_CPU_TYPE_NAME("a64fx"),
ARM_CPU_TYPE_NAME("neoverse-n1"),
ARM_CPU_TYPE_NAME("neoverse-v1"),
Expand Down
155 changes: 154 additions & 1 deletion hw/arm/xlnx-versal.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
#define GEM_REVISION 0x40070106

#define VERSAL_NUM_PMC_APB_IRQS 3
#define VERSAL_NUM_PMC_APB_IRQS 18
#define NUM_OSPI_IRQ_LINES 3

static void versal_create_apu_cpus(Versal *s)
Expand Down Expand Up @@ -341,6 +341,7 @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
* - RTC
* - BBRAM
* - PMC SLCR
* - CFRAME regs (input 3 - 17 to the orgate)
*/
object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
&s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
Expand Down Expand Up @@ -570,6 +571,157 @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
}

static void versal_create_cfu(Versal *s, qemu_irq *pic)
{
SysBusDevice *sbd;
DeviceState *dev;
int i;
const struct {
uint64_t reg_base;
uint64_t fdri_base;
} cframe_addr[] = {
{ MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI },
{ MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI },
{ MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI },
{ MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI },
{ MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI },
{ MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI },
{ MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI },
{ MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI },
{ MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI },
{ MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI },
{ MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI },
{ MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI },
{ MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI },
{ MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI },
{ MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI },
};
const struct {
uint32_t blktype0_frames;
uint32_t blktype1_frames;
uint32_t blktype2_frames;
uint32_t blktype3_frames;
uint32_t blktype4_frames;
uint32_t blktype5_frames;
uint32_t blktype6_frames;
} cframe_cfg[] = {
[0] = { 34111, 3528, 12800, 11, 5, 1, 1 },
[1] = { 38498, 3841, 15361, 13, 7, 3, 1 },
[2] = { 38498, 3841, 15361, 13, 7, 3, 1 },
[3] = { 38498, 3841, 15361, 13, 7, 3, 1 },
};

/* CFU FDRO */
object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro,
TYPE_XLNX_VERSAL_CFU_FDRO);
sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro);

sysbus_realize(sbd, &error_fatal);
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO,
sysbus_mmio_get_region(sbd, 0));

/* CFRAME REG */
for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
g_autofree char *name = g_strdup_printf("cframe%d", i);

object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i],
TYPE_XLNX_VERSAL_CFRAME_REG);

sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]);
dev = DEVICE(&s->pmc.cframe[i]);

if (i < ARRAY_SIZE(cframe_cfg)) {
object_property_set_int(OBJECT(dev), "blktype0-frames",
cframe_cfg[i].blktype0_frames,
&error_abort);
object_property_set_int(OBJECT(dev), "blktype1-frames",
cframe_cfg[i].blktype1_frames,
&error_abort);
object_property_set_int(OBJECT(dev), "blktype2-frames",
cframe_cfg[i].blktype2_frames,
&error_abort);
object_property_set_int(OBJECT(dev), "blktype3-frames",
cframe_cfg[i].blktype3_frames,
&error_abort);
object_property_set_int(OBJECT(dev), "blktype4-frames",
cframe_cfg[i].blktype4_frames,
&error_abort);
object_property_set_int(OBJECT(dev), "blktype5-frames",
cframe_cfg[i].blktype5_frames,
&error_abort);
object_property_set_int(OBJECT(dev), "blktype6-frames",
cframe_cfg[i].blktype6_frames,
&error_abort);
}
object_property_set_link(OBJECT(dev), "cfu-fdro",
OBJECT(&s->pmc.cfu_fdro), &error_fatal);

sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base,
sysbus_mmio_get_region(sbd, 0));
memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base,
sysbus_mmio_get_region(sbd, 1));
sysbus_connect_irq(sbd, 0,
qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate),
3 + i));
}

/* CFRAME BCAST */
object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast,
TYPE_XLNX_VERSAL_CFRAME_BCAST_REG);

sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast);
dev = DEVICE(&s->pmc.cframe_bcast);

for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
g_autofree char *propname = g_strdup_printf("cframe%d", i);
object_property_set_link(OBJECT(dev), propname,
OBJECT(&s->pmc.cframe[i]), &error_fatal);
}

sysbus_realize(sbd, &error_fatal);

memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG,
sysbus_mmio_get_region(sbd, 0));
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI,
sysbus_mmio_get_region(sbd, 1));

/* CFU APB */
object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb,
TYPE_XLNX_VERSAL_CFU_APB);
sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb);
dev = DEVICE(&s->pmc.cfu_apb);

for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
g_autofree char *propname = g_strdup_printf("cframe%d", i);
object_property_set_link(OBJECT(dev), propname,
OBJECT(&s->pmc.cframe[i]), &error_fatal);
}

sysbus_realize(sbd, &error_fatal);
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB,
sysbus_mmio_get_region(sbd, 0));
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM,
sysbus_mmio_get_region(sbd, 1));
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2,
sysbus_mmio_get_region(sbd, 2));
sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]);

/* CFU SFR */
object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr,
TYPE_XLNX_VERSAL_CFU_SFR);

sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr);

object_property_set_link(OBJECT(&s->pmc.cfu_sfr),
"cfu", OBJECT(&s->pmc.cfu_apb), &error_abort);

sysbus_realize(sbd, &error_fatal);
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR,
sysbus_mmio_get_region(sbd, 0));
}

static void versal_create_crl(Versal *s, qemu_irq *pic)
{
SysBusDevice *sbd;
Expand Down Expand Up @@ -763,6 +915,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
versal_create_pmc_iou_slcr(s, pic);
versal_create_ospi(s, pic);
versal_create_crl(s, pic);
versal_create_cfu(s, pic);
versal_map_ddr(s);
versal_unimp(s);

Expand Down
15 changes: 6 additions & 9 deletions hw/intc/arm_gicv3_its.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,23 +330,20 @@ static MemTxResult get_vte(GICv3ITSState *s, uint32_t vpeid, VTEntry *vte)
if (entry_addr == -1) {
/* No L2 table entry, i.e. no valid VTE, or a memory error */
vte->valid = false;
goto out;
trace_gicv3_its_vte_read_fault(vpeid);
return MEMTX_OK;
}
vteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
if (res != MEMTX_OK) {
goto out;
trace_gicv3_its_vte_read_fault(vpeid);
return res;
}
vte->valid = FIELD_EX64(vteval, VTE, VALID);
vte->vptsize = FIELD_EX64(vteval, VTE, VPTSIZE);
vte->vptaddr = FIELD_EX64(vteval, VTE, VPTADDR);
vte->rdbase = FIELD_EX64(vteval, VTE, RDBASE);
out:
if (res != MEMTX_OK) {
trace_gicv3_its_vte_read_fault(vpeid);
} else {
trace_gicv3_its_vte_read(vpeid, vte->valid, vte->vptsize,
vte->vptaddr, vte->rdbase);
}
trace_gicv3_its_vte_read(vpeid, vte->valid, vte->vptsize,
vte->vptaddr, vte->rdbase);
return res;
}

Expand Down
3 changes: 3 additions & 0 deletions hw/misc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
'xlnx-versal-xramc.c',
'xlnx-versal-pmc-iou-slcr.c',
'xlnx-versal-cfu.c',
'xlnx-cfi-if.c',
'xlnx-versal-cframe-reg.c',
))
system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
Expand Down
34 changes: 34 additions & 0 deletions hw/misc/xlnx-cfi-if.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Xilinx CFI interface
*
* Copyright (C) 2023, Advanced Micro Devices, Inc.
*
* Written by Francisco Iglesias <francisco.iglesias@amd.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "hw/misc/xlnx-cfi-if.h"

void xlnx_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt)
{
XlnxCfiIfClass *xcic = XLNX_CFI_IF_GET_CLASS(cfi_if);

if (xcic->cfi_transfer_packet) {
xcic->cfi_transfer_packet(cfi_if, pkt);
}
}

static const TypeInfo xlnx_cfi_if_info = {
.name = TYPE_XLNX_CFI_IF,
.parent = TYPE_INTERFACE,
.class_size = sizeof(XlnxCfiIfClass),
};

static void xlnx_cfi_if_register_types(void)
{
type_register_static(&xlnx_cfi_if_info);
}

type_init(xlnx_cfi_if_register_types)

0 comments on commit a7e8e30

Please sign in to comment.