From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: "Corvin Köhne" <corvin.koehne@gmail.com>
Cc: qemu-devel@nongnu.org, "Yannick Voßen" <y.vossen@beckhoff.com>,
qemu-arm@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>,
"Alistair Francis" <alistair@alistair23.me>,
"Corvin Köhne" <c.koehne@beckhoff.com>,
"Paolo Bonzini" <pbonzini@redhat.com>
Subject: Re: [PATCH 09/21] hw/misc: Add dummy ZYNQ DDR controller
Date: Fri, 25 Apr 2025 18:45:36 +0200 [thread overview]
Message-ID: <aAu8MIQTmTPoRjIm@zapote> (raw)
In-Reply-To: <20250318130817.119636-10-corvin.koehne@gmail.com>
On Tue, Mar 18, 2025 at 02:08:00PM +0100, Corvin Köhne wrote:
> From: YannickV <Y.Vossen@beckhoff.com>
>
> A dummy DDR controller for ZYNQ has been added. While all registers are present,
> not all are functional. Read and write access is validated, and the user mode
> can be set. This provides a basic DDR controller initialization, preventing
> system hangs due to endless polling or similar issues.
>
> Signed-off-by: Yannick Voßen <y.vossen@beckhoff.com>
> ---
> hw/misc/Kconfig | 3 +
> hw/misc/meson.build | 1 +
> hw/misc/zynq_ddr-ctrl.c | 331 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 335 insertions(+)
> create mode 100644 hw/misc/zynq_ddr-ctrl.c
>
> diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
> index ec0fa5aa9f..1bc4228572 100644
> --- a/hw/misc/Kconfig
> +++ b/hw/misc/Kconfig
> @@ -222,4 +222,7 @@ config IOSB
> config XLNX_VERSAL_TRNG
> bool
>
> +config DDR_CTRLR
I suggest XLNX_ZYNQ_DDRC ?
And name the file accordingly, e.g xlnx-zynq-ddrc.c.
You may also want to consider using the register API, see for example
hw/misc/xlnx-versal-xramc.c, modelling another memory controller.
> + bool
> +
> source macio/Kconfig
> diff --git a/hw/misc/meson.build b/hw/misc/meson.build
> index 6d47de482c..8d4c4279c4 100644
> --- a/hw/misc/meson.build
> +++ b/hw/misc/meson.build
> @@ -91,6 +91,7 @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files(
> ))
> system_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
> system_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
> +system_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_ddr-ctrl.c'))
> system_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
> system_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
> system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
> diff --git a/hw/misc/zynq_ddr-ctrl.c b/hw/misc/zynq_ddr-ctrl.c
> new file mode 100644
> index 0000000000..8cdf8be743
> --- /dev/null
> +++ b/hw/misc/zynq_ddr-ctrl.c
> @@ -0,0 +1,331 @@
> +#include "qemu/osdep.h"
> +#include "hw/sysbus.h"
> +#include "hw/register.h"
> +#include "qemu/bitops.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "hw/registerfields.h"
> +#include "system/block-backend.h"
> +#include "exec/address-spaces.h"
> +#include "exec/memory.h"
> +#include "system/dma.h"
> +
> +#ifndef DDRCTRL_ERR_DEBUG
> +#define DDRCTRL_ERR_DEBUG 0
> +#endif
> +
> +#define DB_PRINT_L(level, ...) do { \
> + if (DDRCTRL_ERR_DEBUG > (level)) { \
> + fprintf(stderr, ": %s: ", __func__); \
> + fprintf(stderr, ## __VA_ARGS__); \
> + } \
> +} while (0)
> +
> +#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
> +
> +REG32(DDRC_CTRL, 0x00)
> +REG32(TWO_RANK_CFG, 0x04)
> +REG32(HPR_REG, 0x08)
> +REG32(LPR_REG, 0x0C)
> +REG32(WR_REG, 0x10)
> +REG32(DRAM_PARAM_REG0, 0x14)
> +REG32(DRAM_PARAM_REG1, 0x18)
> +REG32(DRAM_PARAM_REG2, 0x1C)
> +REG32(DRAM_PARAM_REG3, 0x20)
> +REG32(DRAM_PARAM_REG4, 0x24)
> +REG32(DRAM_INIT_PARAM, 0x28)
> +REG32(DRAM_EMR_REG, 0x2C)
> +REG32(DRAM_EMR_MR_REG, 0x30)
> +REG32(DRAM_BURST8_RDWR, 0x34)
> +REG32(DRAM_DISABLE_DQ, 0x38)
> +REG32(DRAM_ADDR_MAP_BANK, 0x3C)
> +REG32(DRAM_ADDR_MAP_COL, 0x40)
> +REG32(DRAM_ADDR_MAP_ROW, 0x44)
> +REG32(DRAM_ODT_REG, 0x48)
> +REG32(PHY_DBG_REG, 0x4C)
> +REG32(PHY_CMD_TIMEOUT_RDDA, 0x50)
> +REG32(TA_CPT, 0x50)
> +REG32(MODE_STS_REG, 0x54)
> + FIELD(MODE_STS_REG, DDR_REG_DBG_STALL, 3, 3)
> + FIELD(MODE_STS_REG, DDR_REG_OPERATING_MODE, 0, 2)
> +REG32(DLL_CALIB, 0x58)
> +REG32(ODT_DELAY_HOLD, 0x5C)
> +REG32(CTRL_REG1, 0x60)
> +REG32(CTRL_REG2, 0x64)
> +REG32(CTRL_REG3, 0x68)
> +REG32(CTRL_REG4, 0x6C)
> +REG32(CTRL_REG5, 0x78)
> +REG32(CTRL_REG6, 0x7C)
> +REG32(CHE_REFRESH_TIMER0, 0xA0)
> +REG32(CHE_T_ZQ, 0xA4)
> +REG32(CHE_T_ZQ_SHORT_INTERVAL_REG, 0xA8)
> +REG32(DEEP_PWRDWN_REG, 0xAC)
> +REG32(REG_2C, 0xB0)
> +REG32(REG_2D, 0xB4)
> +REG32(DFI_TIMING, 0xB8)
> +REG32(CHE_ECC_CONTROL_REG_OFFSET, 0xC4)
> +REG32(CHE_CORR_ECC_LOG_REG_OFFSET, 0xC8)
> +REG32(CHE_CORR_ECC_ADDR_REG_OFFSET, 0xCC)
> +REG32(CHE_CORR_ECC_DATA_31_0_REG_OFFSET, 0xD0)
> +REG32(CHE_CORR_ECC_DATA_63_32_REG_OFFSET, 0xD4)
> +REG32(CHE_CORR_ECC_DATA_71_64_REG_OFFSET, 0xD8)
> +REG32(CHE_UNCORR_ECC_LOG_REG_OFFSET, 0xDC)
> +REG32(CHE_UNCORR_ECC_ADDR_REG_OFFSET, 0xE0)
> +REG32(CHE_UNCORR_ECC_DATA_31_0_REG_OFFSET, 0xE4)
> +REG32(CHE_UNCORR_ECC_DATA_63_32_REG_OFFSET, 0xE8)
> +REG32(CHE_UNCORR_ECC_DATA_71_64_REG_OFFSET, 0xEC)
> +REG32(CHE_ECC_STATS_REG_OFFSET, 0xF0)
> +REG32(ECC_SCRUB, 0xF4)
> +REG32(CHE_ECC_CORR_BIT_MASK_31_0_REG_OFFSET, 0xF8)
> +REG32(CHE_ECC_CORR_BIT_MASK_63_32_REG_OFFSET, 0xFC)
> +REG32(PHY_RCVER_ENABLE, 0x114)
> +REG32(PHY_CONFIG0, 0x118)
> +REG32(PHY_CONFIG1, 0x11C)
> +REG32(PHY_CONFIG2, 0x120)
> +REG32(PHY_CONFIG3, 0x124)
> +REG32(PHY_INIT_RATIO0, 0x12C)
> +REG32(PHY_INIT_RATIO1, 0x130)
> +REG32(PHY_INIT_RATIO2, 0x134)
> +REG32(PHY_INIT_RATIO3, 0x138)
> +REG32(PHY_RD_DQS_CFG0, 0x140)
> +REG32(PHY_RD_DQS_CFG1, 0x144)
> +REG32(PHY_RD_DQS_CFG2, 0x148)
> +REG32(PHY_RD_DQS_CFG3, 0x14C)
> +REG32(PHY_WR_DQS_CFG0, 0x154)
> +REG32(PHY_WR_DQS_CFG1, 0x158)
> +REG32(PHY_WR_DQS_CFG2, 0x15C)
> +REG32(PHY_WR_DQS_CFG3, 0x160)
> +REG32(PHY_WE_CFG0, 0x168)
> +REG32(PHY_WE_CFG1, 0x16C)
> +REG32(PHY_WE_CFG2, 0x170)
> +REG32(PHY_WE_CFG3, 0x174)
> +REG32(WR_DATA_SLV0, 0x17C)
> +REG32(WR_DATA_SLV1, 0x180)
> +REG32(WR_DATA_SLV2, 0x184)
> +REG32(WR_DATA_SLV3, 0x188)
> +REG32(REG_64, 0x190)
> +REG32(REG_65, 0x194)
> +REG32(REG69_6A0, 0x1A4)
> +REG32(REG69_6A1, 0x1A8)
> +REG32(REG6C_6D2, 0x1B0)
> +REG32(REG6C_6D3, 0x1B4)
> +REG32(REG6E_710, 0x1B8)
> +REG32(REG6E_711, 0x1BC)
> +REG32(REG6E_712, 0x1C0)
> +REG32(REG6E_713, 0x1C4)
> +REG32(PHY_DLL_STS0, 0x1CC)
> +REG32(PHY_DLL_STS1, 0x1D0)
> +REG32(PHY_DLL_STS2, 0x1D4)
> +REG32(PHY_DLL_STS3, 0x1D8)
> +REG32(DLL_LOCK_STS, 0x1E0)
> +REG32(PHY_CTRL_STS, 0x1E4)
> +REG32(PHY_CTRL_STS_REG2, 0x1E8)
> +REG32(AXI_ID, 0x200)
> +REG32(PAGE_MASK, 0x204)
> +REG32(AXI_PRIORITY_WR_PORT0, 0x208)
> +REG32(AXI_PRIORITY_WR_PORT1, 0x20C)
> +REG32(AXI_PRIORITY_WR_PORT2, 0x210)
> +REG32(AXI_PRIORITY_WR_PORT3, 0x214)
> +REG32(AXI_PRIORITY_RD_PORT0, 0x218)
> +REG32(AXI_PRIORITY_RD_PORT1, 0x21C)
> +REG32(AXI_PRIORITY_RD_PORT2, 0x220)
> +REG32(AXI_PRIORITY_RD_PORT3, 0x224)
> +REG32(EXCL_ACCESS_CFG0, 0x294)
> +REG32(EXCL_ACCESS_CFG1, 0x298)
> +REG32(EXCL_ACCESS_CFG2, 0x29C)
> +REG32(EXCL_ACCESS_CFG3, 0x2A0)
> +REG32(MODE_REG_READ, 0x2A4)
> +REG32(LPDDR_CTRL0, 0x2A8)
> +REG32(LPDDR_CTRL1, 0x2AC)
> +REG32(LPDDR_CTRL2, 0x2B0)
> +REG32(LPDDR_CTRL3, 0x2B4)
> +
> +
> +#define ZYNQ_DDRCTRL_MMIO_SIZE 0x400
> +#define ZYNQ_DDRCTRL_NUM_REG (ZYNQ_DDRCTRL_MMIO_SIZE / 4)
> +
> +#define TYPE_DDRCTRL "zynq.ddr-ctlr"
> +#define DDRCTRL(obj) \
> + OBJECT_CHECK(DDRCTRLState, (obj), TYPE_DDRCTRL)
> +
> +typedef struct DDRCTRLState {
> + SysBusDevice parent_obj;
> +
> + MemoryRegion iomem;
> +
> + uint32_t reg[ZYNQ_DDRCTRL_NUM_REG];
> +} DDRCTRLState;
> +
> +
> +static bool zynq_ddrctrl_check_addr(hwaddr addr, bool rnw)
Since we always return true fore reads, I would suggest removing
the rnw argument, rename the function to check..._write or
moving this logic to zynq_ddrctrl_write().
> +{
> + switch (addr) {
> + case R_PHY_DBG_REG:
> + case R_MODE_STS_REG:
> + case R_CHE_CORR_ECC_LOG_REG_OFFSET ...
> + R_CHE_CORR_ECC_DATA_71_64_REG_OFFSET:
> + case R_CHE_UNCORR_ECC_ADDR_REG_OFFSET ...
> + R_CHE_UNCORR_ECC_DATA_71_64_REG_OFFSET:
> + case R_CHE_ECC_CORR_BIT_MASK_31_0_REG_OFFSET:
> + case R_CHE_ECC_CORR_BIT_MASK_63_32_REG_OFFSET:
> + case R_REG69_6A0 ... R_AXI_ID:
> + case R_MODE_REG_READ:
> + return rnw;
> + default:
> + return true;
> + }
> +}
> +
> +static void zynq_ddrctrl_reset_init(Object *obj, ResetType type)
> +{
> + DDRCTRLState *s = DDRCTRL(obj);
> +
> + DB_PRINT("RESET");
> +
> + s->reg[R_DDRC_CTRL] = 0x00000200;
> + s->reg[R_TWO_RANK_CFG] = 0x000C1076;
> + s->reg[R_HPR_REG] = 0x03C0780F;
> + s->reg[R_LPR_REG] = 0x03C0780F;
> + s->reg[R_WR_REG] = 0x0007F80F;
> + s->reg[R_DRAM_PARAM_REG0] = 0x00041016;
> + s->reg[R_DRAM_PARAM_REG1] = 0x351B48D9;
> + s->reg[R_DRAM_PARAM_REG2] = 0x83015904;
> + s->reg[R_DRAM_PARAM_REG3] = 0x250882D0;
> + s->reg[R_DRAM_PARAM_REG4] = 0x0000003C;
> + s->reg[R_DRAM_INIT_PARAM] = 0x00002007;
> + s->reg[R_DRAM_EMR_REG] = 0x00000008;
> + s->reg[R_DRAM_EMR_MR_REG] = 0x00000940;
> + s->reg[R_DRAM_BURST8_RDWR] = 0x00020034;
> + s->reg[R_DRAM_ADDR_MAP_BANK] = 0x00000F77;
> + s->reg[R_DRAM_ADDR_MAP_COL] = 0xFFF00000;
> + s->reg[R_DRAM_ADDR_MAP_ROW] = 0x0FF55555;
> + s->reg[R_DRAM_ODT_REG] = 0x00000249;
> + s->reg[R_PHY_CMD_TIMEOUT_RDDA] = 0x00010200;
> + s->reg[R_DLL_CALIB] = 0x00000101;
> + s->reg[R_ODT_DELAY_HOLD] = 0x00000023;
> + s->reg[R_CTRL_REG1] = 0x0000003E;
> + s->reg[R_CTRL_REG2] = 0x00020000;
> + s->reg[R_CTRL_REG3] = 0x00284027;
> + s->reg[R_CTRL_REG4] = 0x00001610;
> + s->reg[R_CTRL_REG5] = 0x00455111;
> + s->reg[R_CTRL_REG6] = 0x00032222;
> + s->reg[R_CHE_REFRESH_TIMER0] = 0x00008000;
> + s->reg[R_CHE_T_ZQ] = 0x10300802;
> + s->reg[R_CHE_T_ZQ_SHORT_INTERVAL_REG] = 0x0020003A;
> + s->reg[R_REG_2D] = 0x00000200;
> + s->reg[R_DFI_TIMING] = 0x00200067;
> + s->reg[R_ECC_SCRUB] = 0x00000008;
> + s->reg[R_PHY_CONFIG0] = 0x40000001;
> + s->reg[R_PHY_CONFIG1] = 0x40000001;
> + s->reg[R_PHY_CONFIG2] = 0x40000001;
> + s->reg[R_PHY_CONFIG3] = 0x40000001;
> + s->reg[R_PHY_RD_DQS_CFG0] = 0x00000040;
> + s->reg[R_PHY_RD_DQS_CFG1] = 0x00000040;
> + s->reg[R_PHY_RD_DQS_CFG2] = 0x00000040;
> + s->reg[R_PHY_RD_DQS_CFG3] = 0x00000040;
> + s->reg[R_PHY_WE_CFG0] = 0x00000040;
> + s->reg[R_PHY_WE_CFG1] = 0x00000040;
> + s->reg[R_PHY_WE_CFG2] = 0x00000040;
> + s->reg[R_PHY_WE_CFG3] = 0x00000040;
> + s->reg[R_WR_DATA_SLV0] = 0x00000080;
> + s->reg[R_WR_DATA_SLV1] = 0x00000080;
> + s->reg[R_WR_DATA_SLV2] = 0x00000080;
> + s->reg[R_WR_DATA_SLV3] = 0x00000080;
> + s->reg[R_REG_64] = 0x10020000;
> + s->reg[R_AXI_PRIORITY_WR_PORT0] = 0x000803FF;
> + s->reg[R_AXI_PRIORITY_WR_PORT1] = 0x000803FF;
> + s->reg[R_AXI_PRIORITY_WR_PORT2] = 0x000803FF;
> + s->reg[R_AXI_PRIORITY_WR_PORT3] = 0x000803FF;
> + s->reg[R_AXI_PRIORITY_RD_PORT0] = 0x000003FF;
> + s->reg[R_AXI_PRIORITY_RD_PORT1] = 0x000003FF;
> + s->reg[R_AXI_PRIORITY_RD_PORT2] = 0x000003FF;
> + s->reg[R_AXI_PRIORITY_RD_PORT3] = 0x000003FF;
> + s->reg[R_LPDDR_CTRL2] = 0x003C0015;
> + s->reg[R_LPDDR_CTRL3] = 0x00000601;
> +}
> +
> +static uint64_t zynq_ddrctrl_read(void *opaque, hwaddr addr, unsigned size)
> +{
> + DDRCTRLState *s = opaque;
> + addr /= 4;
> + uint32_t ret = s->reg[addr];
Declarations at the top.
> +
> + if (!zynq_ddrctrl_check_addr(addr, true)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid read access to "
> + " addr %" HWADDR_PRIx "\n", addr * 4);
> + return 0;
> + }
> +
> + DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx32 "\n", addr * 4, ret);
> + return ret;
> +}
> +
> +static void zynq_ddrctrl_write(void *opaque, hwaddr addr, uint64_t val,
> + unsigned size)
> +{
> + DDRCTRLState *s = opaque;
> + addr /= 4;
> +
> + if (!zynq_ddrctrl_check_addr(addr, false)) {
> + qemu_log_mask(LOG_GUEST_ERROR, "zynq_slcr: Invalid read access to "
Invalid write access to....
> + " addr %" HWADDR_PRIx "\n", addr * 4);
> + return;
> + }
> +
> + DB_PRINT("addr: %08" HWADDR_PRIx " data: %08" PRIx64 "\n", addr * 4, val);
> +
> + switch (addr) {
> + case R_DDRC_CTRL:
> + if (val & 0x1) {
> + s->reg[R_MODE_STS_REG] |=
> + (R_MODE_STS_REG_DDR_REG_OPERATING_MODE_MASK & 0x1);
> + } else {
> + s->reg[R_MODE_STS_REG] &=
> + ~R_MODE_STS_REG_DDR_REG_OPERATING_MODE_MASK;
> + }
> + break;
> + }
> +
> + s->reg[addr] = val;
> +}
> +
> +static const MemoryRegionOps ddrctrl_ops = {
> + .read = zynq_ddrctrl_read,
> + .write = zynq_ddrctrl_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static void zynq_ddrctrl_init(Object *obj)
> +{
> + DB_PRINT("Init\n");
> +
> + DDRCTRLState *s = DDRCTRL(obj);
Declarations at the start of a block.
> +
> + memory_region_init_io(&s->iomem, obj, &ddrctrl_ops, s, "ddrctrl",
> + ZYNQ_DDRCTRL_MMIO_SIZE);
> + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
> +}
> +
> +static void zynq_ddrctrl_class_init(ObjectClass *klass, void *data)
> +{
> + DB_PRINT("Class init\n");
> +
> + ResettableClass *rc = RESETTABLE_CLASS(klass);
Declarations at the start of a block.
> +
> + rc->phases.enter = zynq_ddrctrl_reset_init;
> +}
> +
> +static const TypeInfo ddrctrl_info = {
> + .name = TYPE_DDRCTRL,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(DDRCTRLState),
> + .class_init = zynq_ddrctrl_class_init,
> + .instance_init = zynq_ddrctrl_init,
> +};
> +
> +static void ddrctrl_register_types(void)
> +{
> + type_register_static(&ddrctrl_info);
> +}
> +
> +type_init(ddrctrl_register_types)
> --
> 2.49.0
>
next prev parent reply other threads:[~2025-04-25 16:46 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-18 13:07 [PATCH 00/21] Hi, Corvin Köhne
2025-03-18 13:07 ` [PATCH 01/21] hw/timer: Make frequency configurable Corvin Köhne
2025-03-18 13:07 ` [PATCH 02/21] hw/timer: Make PERIPHCLK period configurable Corvin Köhne
2025-03-18 13:07 ` [PATCH 03/21] hw/dma/zynq-devcfg: Handle bitstream loading via DMA to 0xffffffff Corvin Köhne
2025-04-25 15:47 ` Edgar E. Iglesias
2025-03-18 13:07 ` [PATCH 04/21] hw/arm/zynq-devcfg: Prevent unintended unlock during initialization Corvin Köhne
2025-04-25 15:52 ` Edgar E. Iglesias
2025-03-18 13:07 ` [PATCH 05/21] hw/dma/zynq: Notify devcfg on FPGA reset via SLCR control Corvin Köhne
2025-04-25 16:11 ` Edgar E. Iglesias
2025-05-13 7:04 ` Corvin Köhne
2025-03-18 13:07 ` [PATCH 06/21] hw/dma/zynq-devcfg: Simulate dummy PL reset Corvin Köhne
2025-04-25 16:20 ` Edgar E. Iglesias
2025-03-18 13:07 ` [PATCH 07/21] hw/dma/zynq-devcfg: Indicate power-up status of PL Corvin Köhne
2025-04-25 16:24 ` Edgar E. Iglesias
2025-03-18 13:07 ` [PATCH 08/21] hw/dma/zynq-devcfg: Fix register memory Corvin Köhne
2025-04-25 16:27 ` Edgar E. Iglesias
2025-03-18 13:08 ` [PATCH 09/21] hw/misc: Add dummy ZYNQ DDR controller Corvin Köhne
2025-04-25 16:45 ` Edgar E. Iglesias [this message]
2025-05-05 9:01 ` Corvin Köhne
2025-03-18 13:08 ` [PATCH 10/21] hw/misc/zynq_slcr: Add logic for DCI configuration Corvin Köhne
2025-04-25 19:56 ` Edgar E. Iglesias
2025-03-18 13:08 ` [PATCH 11/21] hw/misc: Add Beckhoff CCAT device Corvin Köhne
2025-03-18 13:08 ` [PATCH 12/21] hw/arm: Add new machine based on xilinx-zynq-a9 for Beckhoff CX7200 Corvin Köhne
2025-03-18 13:08 ` [PATCH 13/21] hw/arm/beckhoff_CX7200: Remove second SD controller Corvin Köhne
2025-05-06 13:17 ` Peter Maydell
2025-03-18 13:08 ` [PATCH 14/21] hw/arm/beckhoff_CX7200: Remove second GEM Corvin Köhne
2025-03-18 13:08 ` [PATCH 15/21] hw/arm/beckhoff_CX7200: Adjust Flashes and Busses Corvin Köhne
2025-03-18 13:08 ` [PATCH 16/21] hw/arm/beckhoff_CX7200: Remove usb interfaces Corvin Köhne
2025-03-18 13:08 ` [PATCH 17/21] hw/arm/beckhoff_CX7200: Remove unimplemented devices Corvin Köhne
2025-03-18 13:08 ` [PATCH 18/21] hw/arm/beckhoff_CX7200: Set CPU frequency and PERIPHCLK period Corvin Köhne
2025-03-18 13:08 ` [PATCH 19/21] hw/arm/beckhoff_CX7200: Add CCAT to CX7200 Corvin Köhne
2025-03-18 13:08 ` [PATCH 20/21] hw/arm/beckhoff_CX7200: Add dummy DDR CTRL " Corvin Köhne
2025-03-18 13:08 ` [PATCH 21/21] MAINTAINERS: add myself as reviewer for Beckhoff devices Corvin Köhne
2025-04-24 10:48 ` [PATCH 00/21] hw/arm: add CX7200 board emulation Corvin Köhne
2025-04-25 19:59 ` Edgar E. Iglesias
2025-05-05 8:57 ` Corvin Köhne
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aAu8MIQTmTPoRjIm@zapote \
--to=edgar.iglesias@gmail.com \
--cc=alistair@alistair23.me \
--cc=c.koehne@beckhoff.com \
--cc=corvin.koehne@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=y.vossen@beckhoff.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.