net: cadence_gem: Add support for selecting the DMA MemoryRegion
Add support for selecting the Memory Region that the GEM will do DMA to. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20181011021931.4249-7-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
e48fdd9d90
commit
84aec8efd6
|
@ -28,6 +28,7 @@
|
||||||
#include "hw/net/cadence_gem.h"
|
#include "hw/net/cadence_gem.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
#include "sysemu/dma.h"
|
||||||
#include "net/checksum.h"
|
#include "net/checksum.h"
|
||||||
|
|
||||||
#ifdef CADENCE_GEM_ERR_DEBUG
|
#ifdef CADENCE_GEM_ERR_DEBUG
|
||||||
|
@ -835,9 +836,9 @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
|
||||||
{
|
{
|
||||||
DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]);
|
DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]);
|
||||||
/* read current descriptor */
|
/* read current descriptor */
|
||||||
cpu_physical_memory_read(s->rx_desc_addr[q],
|
address_space_read(&s->dma_as, s->rx_desc_addr[q], MEMTXATTRS_UNSPECIFIED,
|
||||||
(uint8_t *)s->rx_desc[q],
|
(uint8_t *)s->rx_desc[q],
|
||||||
sizeof(uint32_t) * gem_get_desc_len(s, true));
|
sizeof(uint32_t) * gem_get_desc_len(s, true));
|
||||||
|
|
||||||
/* Descriptor owned by software ? */
|
/* Descriptor owned by software ? */
|
||||||
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
|
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
|
||||||
|
@ -956,10 +957,10 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||||
rx_desc_get_buffer(s->rx_desc[q]));
|
rx_desc_get_buffer(s->rx_desc[q]));
|
||||||
|
|
||||||
/* Copy packet data to emulated DMA buffer */
|
/* Copy packet data to emulated DMA buffer */
|
||||||
cpu_physical_memory_write(rx_desc_get_buffer(s, s->rx_desc[q]) +
|
address_space_write(&s->dma_as, rx_desc_get_buffer(s, s->rx_desc[q]) +
|
||||||
rxbuf_offset,
|
rxbuf_offset,
|
||||||
rxbuf_ptr,
|
MEMTXATTRS_UNSPECIFIED, rxbuf_ptr,
|
||||||
MIN(bytes_to_copy, rxbufsize));
|
MIN(bytes_to_copy, rxbufsize));
|
||||||
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
|
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
|
||||||
bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
|
bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
|
||||||
|
|
||||||
|
@ -993,9 +994,10 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Descriptor write-back. */
|
/* Descriptor write-back. */
|
||||||
cpu_physical_memory_write(s->rx_desc_addr[q],
|
address_space_write(&s->dma_as, s->rx_desc_addr[q],
|
||||||
(uint8_t *)s->rx_desc[q],
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
sizeof(uint32_t) * gem_get_desc_len(s, true));
|
(uint8_t *)s->rx_desc[q],
|
||||||
|
sizeof(uint32_t) * gem_get_desc_len(s, true));
|
||||||
|
|
||||||
/* Next descriptor */
|
/* Next descriptor */
|
||||||
if (rx_desc_get_wrap(s->rx_desc[q])) {
|
if (rx_desc_get_wrap(s->rx_desc[q])) {
|
||||||
|
@ -1099,9 +1101,9 @@ static void gem_transmit(CadenceGEMState *s)
|
||||||
packet_desc_addr = s->tx_desc_addr[q];
|
packet_desc_addr = s->tx_desc_addr[q];
|
||||||
|
|
||||||
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||||
cpu_physical_memory_read(packet_desc_addr,
|
address_space_read(&s->dma_as, packet_desc_addr,
|
||||||
(uint8_t *)desc,
|
MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
|
||||||
sizeof(uint32_t) * gem_get_desc_len(s, false));
|
sizeof(uint32_t) * gem_get_desc_len(s, false));
|
||||||
/* Handle all descriptors owned by hardware */
|
/* Handle all descriptors owned by hardware */
|
||||||
while (tx_desc_get_used(desc) == 0) {
|
while (tx_desc_get_used(desc) == 0) {
|
||||||
|
|
||||||
|
@ -1133,8 +1135,9 @@ static void gem_transmit(CadenceGEMState *s)
|
||||||
/* Gather this fragment of the packet from "dma memory" to our
|
/* Gather this fragment of the packet from "dma memory" to our
|
||||||
* contig buffer.
|
* contig buffer.
|
||||||
*/
|
*/
|
||||||
cpu_physical_memory_read(tx_desc_get_buffer(s, desc), p,
|
address_space_read(&s->dma_as, tx_desc_get_buffer(s, desc),
|
||||||
tx_desc_get_length(desc));
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
|
p, tx_desc_get_length(desc));
|
||||||
p += tx_desc_get_length(desc);
|
p += tx_desc_get_length(desc);
|
||||||
total_bytes += tx_desc_get_length(desc);
|
total_bytes += tx_desc_get_length(desc);
|
||||||
|
|
||||||
|
@ -1145,13 +1148,15 @@ static void gem_transmit(CadenceGEMState *s)
|
||||||
/* Modify the 1st descriptor of this packet to be owned by
|
/* Modify the 1st descriptor of this packet to be owned by
|
||||||
* the processor.
|
* the processor.
|
||||||
*/
|
*/
|
||||||
cpu_physical_memory_read(s->tx_desc_addr[q],
|
address_space_read(&s->dma_as, s->tx_desc_addr[q],
|
||||||
(uint8_t *)desc_first,
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
sizeof(desc_first));
|
(uint8_t *)desc_first,
|
||||||
|
sizeof(desc_first));
|
||||||
tx_desc_set_used(desc_first);
|
tx_desc_set_used(desc_first);
|
||||||
cpu_physical_memory_write(s->tx_desc_addr[q],
|
address_space_write(&s->dma_as, s->tx_desc_addr[q],
|
||||||
(uint8_t *)desc_first,
|
MEMTXATTRS_UNSPECIFIED,
|
||||||
sizeof(desc_first));
|
(uint8_t *)desc_first,
|
||||||
|
sizeof(desc_first));
|
||||||
/* Advance the hardware current descriptor past this packet */
|
/* Advance the hardware current descriptor past this packet */
|
||||||
if (tx_desc_get_wrap(desc)) {
|
if (tx_desc_get_wrap(desc)) {
|
||||||
s->tx_desc_addr[q] = s->regs[GEM_TXQBASE];
|
s->tx_desc_addr[q] = s->regs[GEM_TXQBASE];
|
||||||
|
@ -1204,8 +1209,9 @@ static void gem_transmit(CadenceGEMState *s)
|
||||||
packet_desc_addr += 4 * gem_get_desc_len(s, false);
|
packet_desc_addr += 4 * gem_get_desc_len(s, false);
|
||||||
}
|
}
|
||||||
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||||
cpu_physical_memory_read(packet_desc_addr, (uint8_t *)desc,
|
address_space_read(&s->dma_as, packet_desc_addr,
|
||||||
sizeof(uint32_t) * gem_get_desc_len(s, false));
|
MEMTXATTRS_UNSPECIFIED, (uint8_t *)desc,
|
||||||
|
sizeof(uint32_t) * gem_get_desc_len(s, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx_desc_get_used(desc)) {
|
if (tx_desc_get_used(desc)) {
|
||||||
|
@ -1496,6 +1502,9 @@ static void gem_realize(DeviceState *dev, Error **errp)
|
||||||
CadenceGEMState *s = CADENCE_GEM(dev);
|
CadenceGEMState *s = CADENCE_GEM(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
address_space_init(&s->dma_as,
|
||||||
|
s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
|
||||||
|
|
||||||
if (s->num_priority_queues == 0 ||
|
if (s->num_priority_queues == 0 ||
|
||||||
s->num_priority_queues > MAX_PRIORITY_QUEUES) {
|
s->num_priority_queues > MAX_PRIORITY_QUEUES) {
|
||||||
error_setg(errp, "Invalid num-priority-queues value: %" PRIx8,
|
error_setg(errp, "Invalid num-priority-queues value: %" PRIx8,
|
||||||
|
@ -1533,6 +1542,12 @@ static void gem_init(Object *obj)
|
||||||
"enet", sizeof(s->regs));
|
"enet", sizeof(s->regs));
|
||||||
|
|
||||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
||||||
|
|
||||||
|
object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
|
||||||
|
(Object **)&s->dma_mr,
|
||||||
|
qdev_prop_allow_set_link_before_realize,
|
||||||
|
OBJ_PROP_LINK_STRONG,
|
||||||
|
&error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_cadence_gem = {
|
static const VMStateDescription vmstate_cadence_gem = {
|
||||||
|
|
|
@ -45,6 +45,8 @@ typedef struct CadenceGEMState {
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
|
MemoryRegion *dma_mr;
|
||||||
|
AddressSpace dma_as;
|
||||||
NICState *nic;
|
NICState *nic;
|
||||||
NICConf conf;
|
NICConf conf;
|
||||||
qemu_irq irq[MAX_PRIORITY_QUEUES];
|
qemu_irq irq[MAX_PRIORITY_QUEUES];
|
||||||
|
|
Loading…
Reference in a new issue