aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-09-25 21:52:30 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-09-25 21:52:30 +0100
commit9e071429e649346c14b2dc76902f84f8352d2333 (patch)
tree3d6d02ccaf6ce69c8008c12c0715197731dde958 /hw/intc
parent8bfbbb4bcb6e06aaf4a3e2264f53c8c44ed4c655 (diff)
parent8e9620a683925daf9900c2ac5f2dfa14b6439932 (diff)
downloadqemu-9e071429e649346c14b2dc76902f84f8352d2333.zip
qemu-9e071429e649346c14b2dc76902f84f8352d2333.tar.gz
qemu-9e071429e649346c14b2dc76902f84f8352d2333.tar.bz2
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* First batch of MAINTAINERS updates * IOAPIC fixes (to pass kvm-unit-tests with -machine kernel_irqchip=off) * NBD API upgrades from Daniel * strtosz fixes from Marc-André * improved support for readonly=on on scsi-generic devices * new "info ioapic" and "info lapic" monitor commands * Peter Crosthwaite's ELF_MACHINE cleanups * docs patches from Thomas and Daniel # gpg: Signature made Fri 25 Sep 2015 11:20:52 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream: (52 commits) doc: Refresh URLs in the qemu-tech documentation docs: describe the QEMU build system structure / design typedef: add typedef for QemuOpts i386: interrupt poll processing i386: partial revert of interrupt poll fix ppc: Rename ELF_MACHINE to be PPC specific i386: Rename ELF_MACHINE to be x86 specific alpha: Remove ELF_MACHINE from cpu.h mips: Remove ELF_MACHINE from cpu.h sparc: Remove ELF_MACHINE from cpu.h s390: Remove ELF_MACHINE from cpu.h sh4: Remove ELF_MACHINE from cpu.h xtensa: Remove ELF_MACHINE from cpu.h tricore: Remove ELF_MACHINE from cpu.h or32: Remove ELF_MACHINE from cpu.h lm32: Remove ELF_MACHINE from cpu.h unicore: Remove ELF_MACHINE from cpu.h moxie: Remove ELF_MACHINE from cpu.h cris: Remove ELF_MACHINE from cpu.h m68k: Remove ELF_MACHINE from cpu.h ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/apic.c22
-rw-r--r--hw/intc/ioapic.c20
-rw-r--r--hw/intc/ioapic_common.c55
3 files changed, 74 insertions, 23 deletions
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 77b639c..0a840b8 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -51,14 +51,6 @@ static int apic_ffs_bit(uint32_t value)
return ctz32(value);
}
-static inline void apic_set_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- tab[i] |= mask;
-}
-
static inline void apic_reset_bit(uint32_t *tab, int index)
{
int i, mask;
@@ -67,14 +59,6 @@ static inline void apic_reset_bit(uint32_t *tab, int index)
tab[i] &= ~mask;
}
-static inline int apic_get_bit(uint32_t *tab, int index)
-{
- int i, mask;
- i = index >> 5;
- mask = 1 << (index & 0x1f);
- return !!(tab[i] & mask);
-}
-
/* return -1 if no bit is set */
static int get_highest_priority_int(uint32_t *tab)
{
@@ -318,7 +302,7 @@ static uint8_t apic_get_tpr(APICCommonState *s)
return s->tpr >> 4;
}
-static int apic_get_ppr(APICCommonState *s)
+int apic_get_ppr(APICCommonState *s)
{
int tpr, isrv, ppr;
@@ -739,7 +723,7 @@ static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
val = s->divide_conf;
break;
default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
+ s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
val = 0;
break;
}
@@ -852,7 +836,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
}
break;
default:
- s->esr |= ESR_ILLEGAL_ADDRESS;
+ s->esr |= APIC_ESR_ILLEGAL_ADDRESS;
break;
}
}
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index b527932..de2dd4b 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -20,6 +20,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "monitor/monitor.h"
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/i386/ioapic.h"
@@ -98,7 +99,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
/* level triggered */
if (level) {
s->irr |= mask;
- ioapic_service(s);
+ if (!(entry & IOAPIC_LVT_REMOTE_IRR)) {
+ ioapic_service(s);
+ }
} else {
s->irr &= ~mask;
}
@@ -137,6 +140,17 @@ void ioapic_eoi_broadcast(int vector)
}
}
+void ioapic_dump_state(Monitor *mon, const QDict *qdict)
+{
+ int i;
+
+ for (i = 0; i < MAX_IOAPICS; i++) {
+ if (ioapics[i] != 0) {
+ ioapic_print_redtbl(mon, ioapics[i]);
+ }
+ }
+}
+
static uint64_t
ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
{
@@ -154,15 +168,13 @@ ioapic_mem_read(void *opaque, hwaddr addr, unsigned int size)
}
switch (s->ioregsel) {
case IOAPIC_REG_ID:
+ case IOAPIC_REG_ARB:
val = s->id << IOAPIC_ID_SHIFT;
break;
case IOAPIC_REG_VER:
val = IOAPIC_VERSION |
((IOAPIC_NUM_PINS - 1) << IOAPIC_VER_ENTRIES_SHIFT);
break;
- case IOAPIC_REG_ARB:
- val = 0;
- break;
default:
index = (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1;
if (index >= 0 && index < IOAPIC_NUM_PINS) {
diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c
index 8b7d118..65f6877 100644
--- a/hw/intc/ioapic_common.c
+++ b/hw/intc/ioapic_common.c
@@ -19,6 +19,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "monitor/monitor.h"
#include "hw/i386/ioapic.h"
#include "hw/i386/ioapic_internal.h"
#include "hw/sysbus.h"
@@ -31,6 +32,60 @@
*/
int ioapic_no;
+static void ioapic_irr_dump(Monitor *mon, const char *name, uint32_t bitmap)
+{
+ int i;
+
+ monitor_printf(mon, "%-10s ", name);
+ if (bitmap == 0) {
+ monitor_printf(mon, "(none)\n");
+ return;
+ }
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ if (bitmap & (1 << i)) {
+ monitor_printf(mon, "%-2u ", i);
+ }
+ }
+ monitor_printf(mon, "\n");
+}
+
+void ioapic_print_redtbl(Monitor *mon, IOAPICCommonState *s)
+{
+ static const char *delm_str[] = {
+ "fixed", "lowest", "SMI", "...", "NMI", "INIT", "...", "extINT"};
+ uint32_t remote_irr = 0;
+ int i;
+
+ monitor_printf(mon, "ioapic id=0x%02x sel=0x%02x", s->id, s->ioregsel);
+ if (s->ioregsel) {
+ monitor_printf(mon, " (redir[%u])\n",
+ (s->ioregsel - IOAPIC_REG_REDTBL_BASE) >> 1);
+ } else {
+ monitor_printf(mon, "\n");
+ }
+ for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+ uint64_t entry = s->ioredtbl[i];
+ uint32_t delm = (uint32_t)((entry & IOAPIC_LVT_DELIV_MODE) >>
+ IOAPIC_LVT_DELIV_MODE_SHIFT);
+ monitor_printf(mon, "pin %-2u 0x%016"PRIx64" dest=%"PRIx64
+ " vec=%-3"PRIu64" %s %-5s %-6s %-6s %s\n",
+ i, entry,
+ (entry >> IOAPIC_LVT_DEST_SHIFT) &
+ (entry & IOAPIC_LVT_DEST_MODE ? 0xff : 0xf),
+ entry & IOAPIC_VECTOR_MASK,
+ entry & IOAPIC_LVT_POLARITY ? "active-lo" : "active-hi",
+ entry & IOAPIC_LVT_TRIGGER_MODE ? "level" : "edge",
+ entry & IOAPIC_LVT_MASKED ? "masked" : "",
+ delm_str[delm],
+ entry & IOAPIC_LVT_DEST_MODE ? "logical" : "physical");
+
+ remote_irr |= entry & IOAPIC_LVT_TRIGGER_MODE ?
+ (entry & IOAPIC_LVT_REMOTE_IRR ? (1 << i) : 0) : 0;
+ }
+ ioapic_irr_dump(mon, "IRR", s->irr);
+ ioapic_irr_dump(mon, "Remote IRR", remote_irr);
+}
+
void ioapic_reset_common(DeviceState *dev)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);