• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Révision00f05c02f9e7342fb423110061bdf66921fe80b2 (tree)
l'heure2022-01-28 23:29:46
AuteurFrancisco Iglesias <francisco.iglesias@xili...>
CommiterPeter Maydell

Message de Log

hw/dma/xlnx_csu_dma: Support starting a read transfer through a class method

An option on real hardware when embedding a DMA engine into a peripheral
is to make the peripheral control the engine through a custom DMA control
(hardware) interface between the two. Software drivers in this scenario
configure and trigger DMA operations through the controlling peripheral's
register API (for example, writing a specific bit in a register could
propagate down to a transfer start signal on the DMA control interface).
At the same time the status, results and interrupts for the transfer might
still be intended to be read and caught through the DMA engine's register
API (and signals).

This patch adds a class 'read' method for allowing to start read transfers
from peripherals embedding and controlling the Xilinx CSU DMA engine as in
above scenario.

Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com>
Reviewed-by: Luc Michel <luc@lmichel.fr>
Message-id: 20220121161141.14389-6-francisco.iglesias@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Change Summary

Modification

--- a/hw/dma/xlnx_csu_dma.c
+++ b/hw/dma/xlnx_csu_dma.c
@@ -472,6 +472,20 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val)
472472 return val & R_ADDR_MSB_ADDR_MSB_MASK;
473473 }
474474
475+static MemTxResult xlnx_csu_dma_class_read(XlnxCSUDMA *s, hwaddr addr,
476+ uint32_t len)
477+{
478+ RegisterInfo *reg = &s->regs_info[R_SIZE];
479+ uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
480+
481+ s->regs[R_ADDR] = addr;
482+ s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32;
483+
484+ register_write(reg, len, we, object_get_typename(OBJECT(s)), false);
485+
486+ return (s->regs[R_SIZE] == 0) ? MEMTX_OK : MEMTX_ERROR;
487+}
488+
475489 static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = {
476490 #define DMACH_REGINFO(NAME, snd) \
477491 (const RegisterAccessInfo []) { \
@@ -696,6 +710,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
696710 {
697711 DeviceClass *dc = DEVICE_CLASS(klass);
698712 StreamSinkClass *ssc = STREAM_SINK_CLASS(klass);
713+ XlnxCSUDMAClass *xcdc = XLNX_CSU_DMA_CLASS(klass);
699714
700715 dc->reset = xlnx_csu_dma_reset;
701716 dc->realize = xlnx_csu_dma_realize;
@@ -704,6 +719,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data)
704719
705720 ssc->push = xlnx_csu_dma_stream_push;
706721 ssc->can_push = xlnx_csu_dma_stream_can_push;
722+
723+ xcdc->read = xlnx_csu_dma_class_read;
707724 }
708725
709726 static void xlnx_csu_dma_init(Object *obj)
--- a/include/hw/dma/xlnx_csu_dma.h
+++ b/include/hw/dma/xlnx_csu_dma.h
@@ -51,7 +51,22 @@ typedef struct XlnxCSUDMA {
5151 RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX];
5252 } XlnxCSUDMA;
5353
54-#define XLNX_CSU_DMA(obj) \
55- OBJECT_CHECK(XlnxCSUDMA, (obj), TYPE_XLNX_CSU_DMA)
54+OBJECT_DECLARE_TYPE(XlnxCSUDMA, XlnxCSUDMAClass, XLNX_CSU_DMA)
55+
56+struct XlnxCSUDMAClass {
57+ SysBusDeviceClass parent_class;
58+
59+ /*
60+ * read: Start a read transfer on a Xilinx CSU DMA engine
61+ *
62+ * @s: the Xilinx CSU DMA engine to start the transfer on
63+ * @addr: the address to read
64+ * @len: the number of bytes to read at 'addr'
65+ *
66+ * @return a MemTxResult indicating whether the operation succeeded ('len'
67+ * bytes were read) or failed.
68+ */
69+ MemTxResult (*read)(XlnxCSUDMA *s, hwaddr addr, uint32_t len);
70+};
5671
5772 #endif