diff options
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/apic.c | 22 | ||||
-rw-r--r-- | hw/intc/ioapic.c | 20 | ||||
-rw-r--r-- | hw/intc/ioapic_common.c | 55 |
3 files changed, 74 insertions, 23 deletions
diff --git a/hw/intc/apic.c b/hw/intc/apic.c index 77b639cce8..0a840b851f 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 b527932382..de2dd4ba8e 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 8b7d11806c..65f6877d79 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); |