diff options
author | Peter Maydell | 2017-04-20 18:41:34 +0200 |
---|---|---|
committer | Peter Maydell | 2017-04-20 18:41:34 +0200 |
commit | da92ada855036c55bd08b0b0c64c7551d56f3586 (patch) | |
tree | c8364bf860d9eb2378cfa9c74bdfc2ed059c2ab7 /hw/net/cadence_gem.c | |
parent | Open 2.10 development tree (diff) | |
parent | arm: Remove workarounds for old M-profile exception return implementation (diff) | |
download | qemu-da92ada855036c55bd08b0b0c64c7551d56f3586.tar.gz qemu-da92ada855036c55bd08b0b0c64c7551d56f3586.tar.xz qemu-da92ada855036c55bd08b0b0c64c7551d56f3586.zip |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170420' into staging
target-arm queue:
* implement M profile exception return properly
* cadence GEM: fix multiqueue handling bugs
* pxa2xx.c: QOMify a device
* arm/kvm: Remove trailing newlines from error_report()
* stellaris: Don't hw_error() on bad register accesses
* Add assertion about FSC format for syndrome registers
* Move excnames[] array into arm_log_exceptions()
* exynos: minor code cleanups
* hw/arm/boot: take Linux/arm64 TEXT_OFFSET header field into account
* Fix APSR writes via M profile MSR
# gpg: Signature made Thu 20 Apr 2017 17:39:35 BST
# gpg: using RSA key 0x3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg: aka "Peter Maydell <pmaydell@gmail.com>"
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20170420: (24 commits)
arm: Remove workarounds for old M-profile exception return implementation
arm: Implement M profile exception return properly
arm: Track M profile handler mode state in TB flags
arm: Abstract out "are we singlestepping" test to utility function
arm: Move condition-failed codepath generation out of if()
arm: Move gen_set_condexec() and gen_set_pc_im() up in the file
arm: Factor out "generate right kind of step exception"
arm: Thumb shift operations should not permit interworking branches
arm: Don't implement BXJ on M-profile CPUs
xlnx-zynqmp: Set the Cadence GEM revision
cadence_gem: Make the revision a property
cadence_gem: Correct the interupt logic
cadence_gem: Correct the multi-queue can rx logic
cadence_gem: Read the correct queue descriptor
hw/arm: Qomify pxa2xx.c
arm/kvm: Remove trailing newlines from error_report()
stellaris: Don't hw_error() on bad register accesses
target/arm: Add assertion about FSC format for syndrome registers
arm: Move excnames[] array into arm_log_exceptions()
target/arm: Add missing entries to excnames[] for log strings
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/net/cadence_gem.c')
-rw-r--r-- | hw/net/cadence_gem.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index d4de8ad9f1..3943187572 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -300,6 +300,8 @@ #define DESC_1_RX_SOF 0x00004000 #define DESC_1_RX_EOF 0x00008000 +#define GEM_MODID_VALUE 0x00020118 + static inline unsigned tx_desc_get_buffer(unsigned *desc) { return desc[0]; @@ -481,14 +483,17 @@ static int gem_can_receive(NetClientState *nc) } for (i = 0; i < s->num_priority_queues; i++) { - if (rx_desc_get_ownership(s->rx_desc[i]) == 1) { - if (s->can_rx_state != 2) { - s->can_rx_state = 2; - DB_PRINT("can't receive - busy buffer descriptor (q%d) 0x%x\n", - i, s->rx_desc_addr[i]); - } - return 0; + if (rx_desc_get_ownership(s->rx_desc[i]) != 1) { + break; + } + }; + + if (i == s->num_priority_queues) { + if (s->can_rx_state != 2) { + s->can_rx_state = 2; + DB_PRINT("can't receive - all the buffer descriptors are busy\n"); } + return 0; } if (s->can_rx_state != 0) { @@ -506,7 +511,18 @@ static void gem_update_int_status(CadenceGEMState *s) { int i; - if ((s->num_priority_queues == 1) && s->regs[GEM_ISR]) { + if (!s->regs[GEM_ISR]) { + /* ISR isn't set, clear all the interrupts */ + for (i = 0; i < s->num_priority_queues; ++i) { + qemu_set_irq(s->irq[i], 0); + } + return; + } + + /* If we get here we know s->regs[GEM_ISR] is set, so we don't need to + * check it again. + */ + if (s->num_priority_queues == 1) { /* No priority queues, just trigger the interrupt */ DB_PRINT("asserting int.\n"); qemu_set_irq(s->irq[0], 1); @@ -790,8 +806,8 @@ static void gem_get_rx_desc(CadenceGEMState *s, int q) { DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]); /* read current descriptor */ - cpu_physical_memory_read(s->rx_desc_addr[0], - (uint8_t *)s->rx_desc[0], sizeof(s->rx_desc[0])); + cpu_physical_memory_read(s->rx_desc_addr[q], + (uint8_t *)s->rx_desc[q], sizeof(s->rx_desc[q])); /* Descriptor owned by software ? */ if (rx_desc_get_ownership(s->rx_desc[q]) == 1) { @@ -1209,7 +1225,7 @@ static void gem_reset(DeviceState *d) s->regs[GEM_TXPAUSE] = 0x0000ffff; s->regs[GEM_TXPARTIALSF] = 0x000003ff; s->regs[GEM_RXPARTIALSF] = 0x000003ff; - s->regs[GEM_MODID] = 0x00020118; + s->regs[GEM_MODID] = s->revision; s->regs[GEM_DESCONF] = 0x02500111; s->regs[GEM_DESCONF2] = 0x2ab13fff; s->regs[GEM_DESCONF5] = 0x002f2145; @@ -1271,7 +1287,6 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size) { CadenceGEMState *s; uint32_t retval; - int i; s = (CadenceGEMState *)opaque; offset >>= 2; @@ -1282,9 +1297,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size) switch (offset) { case GEM_ISR: DB_PRINT("lowering irqs on ISR read\n"); - for (i = 0; i < s->num_priority_queues; ++i) { - qemu_set_irq(s->irq[i], 0); - } + /* The interrupts get updated at the end of the function. */ break; case GEM_PHYMNTNC: if (retval & GEM_PHYMNTNC_OP_R) { @@ -1508,6 +1521,8 @@ static const VMStateDescription vmstate_cadence_gem = { static Property gem_properties[] = { DEFINE_NIC_PROPERTIES(CadenceGEMState, conf), + DEFINE_PROP_UINT32("revision", CadenceGEMState, revision, + GEM_MODID_VALUE), DEFINE_PROP_UINT8("num-priority-queues", CadenceGEMState, num_priority_queues, 1), DEFINE_PROP_UINT8("num-type1-screeners", CadenceGEMState, |