summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-07-28 15:25:24 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-07-28 15:25:24 +0100
commit8b89b3a8df0a7d1ddbc9744f66a495986af667ca (patch)
tree1877ea53996f0532a797a8f65ef176cb7cc7fe4e
parent5e868d2e5e4aff76bdef787e44bc2d1eca18901f (diff)
parent52579c681cb12bf64de793e85edc50d990f4d42f (diff)
downloadfocaccia-qemu-8b89b3a8df0a7d1ddbc9744f66a495986af667ca.tar.gz
focaccia-qemu-8b89b3a8df0a7d1ddbc9744f66a495986af667ca.zip
Merge remote-tracking branch 'remotes/lalrae/tags/mips-20150728' into staging
MIPS patches 2015-07-28

Changes:
* net/dp8393x fixes
* Vectored Interrupts bug fix
* fix for a bug in machine.c which was provoking a warning on FreeBSD

# gpg: Signature made Tue Jul 28 10:47:19 2015 BST using RSA key ID 0B29DA6B
# gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8DD3 2F98 5495 9D66 35D4  4FC0 5211 8E3C 0B29 DA6B

* remotes/lalrae/tags/mips-20150728:
  net/dp8393x: do not use memory_region_init_rom_device with NULL
  net/dp8393x: remove check of runt packets
  net/dp8393x: disable user creation
  target-mips: fix offset calculation for Interrupts
  target-mips: fix passing incompatible pointer type in machine.c

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/net/dp8393x.c17
-rw-r--r--target-mips/helper.c46
-rw-r--r--target-mips/machine.c3
-rw-r--r--target-mips/op_helper.c2
4 files changed, 33 insertions, 35 deletions
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 451ff72e50..ab607e4846 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -643,11 +643,6 @@ static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf,
     static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
     int i;
 
-    /* Check for runt packet (remember that checksum is not there) */
-    if (size < 64 - 4) {
-        return (s->regs[SONIC_RCR] & SONIC_RCR_RNT) ? 0 : -1;
-    }
-
     /* Check promiscuous mode */
     if ((s->regs[SONIC_RCR] & SONIC_RCR_PRO) && (buf[0] & 1) == 0) {
         return 0;
@@ -836,6 +831,7 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
     dp8393xState *s = DP8393X(dev);
     int i, checksum;
     uint8_t *prom;
+    Error *local_err = NULL;
 
     address_space_init(&s->as, s->dma_mr, "dp8393x");
     memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s,
@@ -848,8 +844,13 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
     s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
     s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
-    memory_region_init_rom_device(&s->prom, OBJECT(dev), NULL, NULL,
-                                  "dp8393x-prom", SONIC_PROM_SIZE, NULL);
+    memory_region_init_ram(&s->prom, OBJECT(dev),
+                           "dp8393x-prom", SONIC_PROM_SIZE, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    memory_region_set_readonly(&s->prom, true);
     prom = memory_region_get_ram_ptr(&s->prom);
     checksum = 0;
     for (i = 0; i < 6; i++) {
@@ -889,6 +890,8 @@ static void dp8393x_class_init(ObjectClass *klass, void *data)
     dc->reset = dp8393x_reset;
     dc->vmsd = &vmstate_dp8393x;
     dc->props = dp8393x_properties;
+    /* Reason: dma_mr property can't be set */
+    dc->cannot_instantiate_with_device_add_yet = true;
 }
 
 static const TypeInfo dp8393x_info = {
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 8e3204a3a0..04ba19fd44 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -565,34 +565,30 @@ void mips_cpu_do_interrupt(CPUState *cs)
         break;
     case EXCP_EXT_INTERRUPT:
         cause = 0;
-        if (env->CP0_Cause & (1 << CP0Ca_IV))
-            offset = 0x200;
-
-        if (env->CP0_Config3 & ((1 << CP0C3_VInt) | (1 << CP0C3_VEIC))) {
-            /* Vectored Interrupts.  */
-            unsigned int spacing;
-            unsigned int vector;
-            unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8;
-
-            pending &= env->CP0_Status >> 8;
-            /* Compute the Vector Spacing.  */
-            spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1);
-            spacing <<= 5;
-
-            if (env->CP0_Config3 & (1 << CP0C3_VInt)) {
-                /* For VInt mode, the MIPS computes the vector internally.  */
-                for (vector = 7; vector > 0; vector--) {
-                    if (pending & (1 << vector)) {
-                        /* Found it.  */
-                        break;
+        if (env->CP0_Cause & (1 << CP0Ca_IV)) {
+            uint32_t spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & 0x1f;
+
+            if ((env->CP0_Status & (1 << CP0St_BEV)) || spacing == 0) {
+                offset = 0x200;
+            } else {
+                uint32_t vector = 0;
+                uint32_t pending = (env->CP0_Cause & CP0Ca_IP_mask) >> CP0Ca_IP;
+
+                if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
+                    /* For VEIC mode, the external interrupt controller feeds
+                     * the vector through the CP0Cause IP lines.  */
+                    vector = pending;
+                } else {
+                    /* Vectored Interrupts
+                     * Mask with Status.IM7-IM0 to get enabled interrupts. */
+                    pending &= (env->CP0_Status >> CP0St_IM) & 0xff;
+                    /* Find the highest-priority interrupt. */
+                    while (pending >>= 1) {
+                        vector++;
                     }
                 }
-            } else {
-                /* For VEIC mode, the external interrupt controller feeds the
-                   vector through the CP0Cause IP lines.  */
-                vector = pending;
+                offset = 0x200 + (vector * (spacing << 5));
             }
-            offset = 0x200 + vector * spacing;
         }
         goto set_EPC;
     case EXCP_LTLBL:
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 8fa755cd39..b15c43a107 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -153,6 +153,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size)
 {
     r4k_tlb_t *v = pv;
 
+    uint8_t asid = v->ASID;
     uint16_t flags = ((v->EHINV << 15) |
                       (v->RI1 << 14) |
                       (v->RI0 << 13) |
@@ -168,7 +169,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size)
 
     qemu_put_betls(f, &v->VPN);
     qemu_put_be32s(f, &v->PageMask);
-    qemu_put_8s(f, &v->ASID);
+    qemu_put_8s(f, &asid);
     qemu_put_be16s(f, &flags);
     qemu_put_be64s(f, &v->PFN[0]);
     qemu_put_be64s(f, &v->PFN[1]);
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 9c28631dc1..db4f6b9463 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1432,7 +1432,6 @@ void helper_mttc0_status(CPUMIPSState *env, target_ulong arg1)
 
 void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
 {
-    /* vectored interrupts not implemented, no performance counters. */
     env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
 }
 
@@ -1473,7 +1472,6 @@ target_ulong helper_mftc0_ebase(CPUMIPSState *env)
 
 void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
 {
-    /* vectored interrupts not implemented */
     env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
 }