Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* Thread Sanitizer fixes (Alex)
* Coverity fixes (David)
* test-qht fixes (Emilio)
* QOM interface for info irq/info pic (Hervé)
* -rtc clock=rt fix (Junlian)
* mux chardev fixes (Marc-André)
* nicer report on death by signal (Michal)
* qemu-tech TLC (Paolo)
* MSI support for edu device (Peter)
* qemu-nbd --offset fix (Tomáš)

# gpg: Signature made Fri 07 Oct 2016 17:25:10 BST
# gpg:                using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream: (39 commits)
  qemu-doc: merge qemu-tech and qemu-doc
  qemu-tech: rewrite some parts
  qemu-tech: reorganize content
  qemu-tech: move TCG test documentation to tests/tcg/README
  qemu-tech: move user mode emulation features from qemu-tech
  qemu-tech: document lazy condition code evaluation in cpu.h
  qemu-tech: move text from qemu-tech to tcg/README
  qemu-doc: drop installation and compilation notes
  qemu-doc: replace introduction with the one from the internals manual
  qemu-tech: drop index
  test-qht: perform lookups under rcu_read_lock
  qht: fix unlock-after-free segfault upon resizing
  qht: simplify qht_reset_size
  qemu-nbd: Shrink image size by specified offset
  qemu_kill_report: Report PID name too
  util: Introduce qemu_get_pid_name
  char: update read handler in all cases
  char: use a fixed idx for child muxed chr
  i8259: give ISA device when registering ISA ioports
  .travis.yml: add gcc sanitizer build
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2016-10-10 10:39:29 +01:00
51 changed files with 810 additions and 988 deletions
-2
View File
@@ -39,9 +39,7 @@
/qmp-introspect.[ch]
/qmp-marshal.c
/qemu-doc.html
/qemu-tech.html
/qemu-doc.info
/qemu-tech.info
/qemu-img
/qemu-nbd
/qemu-options.def
+45
View File
@@ -9,6 +9,7 @@ cache: ccache
addons:
apt:
packages:
# Build dependencies
- libaio-dev
- libattr1-dev
- libbrlapi-dev
@@ -89,6 +90,7 @@ matrix:
- env: CONFIG=""
os: osx
compiler: clang
# Plain Trusty Build
- env: CONFIG=""
sudo: required
addons:
@@ -99,3 +101,46 @@ matrix:
- sudo apt-get build-dep -qq qemu
- wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
- git submodule update --init --recursive
# Using newer GCC with sanitizers
- addons:
apt:
sources:
# PPAs for newer toolchains
- ubuntu-toolchain-r-test
packages:
# Extra toolchains
- gcc-5
- g++-5
# Build dependencies
- libaio-dev
- libattr1-dev
- libbrlapi-dev
- libcap-ng-dev
- libgnutls-dev
- libgtk-3-dev
- libiscsi-dev
- liblttng-ust-dev
- libnfs-dev
- libncurses5-dev
- libnss3-dev
- libpixman-1-dev
- libpng12-dev
- librados-dev
- libsdl1.2-dev
- libseccomp-dev
- libspice-protocol-dev
- libspice-server-dev
- libssh2-1-dev
- liburcu-dev
- libusb-1.0-0-dev
- libvte-2.90-dev
- sparse
- uuid-dev
language: generic
compiler: none
env:
- COMPILER_NAME=gcc CXX=g++-5 CC=gcc-5
- CONFIG="--cc=gcc-5 --cxx=g++-5 --disable-pie --disable-linux-user --with-coroutine=gthread"
- TEST_CMD=""
before_script:
- ./configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread -fuse-ld=gold" || cat config.log
+6 -7
View File
@@ -93,7 +93,7 @@ LIBS+=-lz $(LIBS_TOOLS)
HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
ifdef BUILD_DOCS
DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
DOCS=qemu-doc.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
ifdef CONFIG_VIRTFS
DOCS+=fsdev/virtfs-proxy-helper.1
endif
@@ -398,7 +398,6 @@ distclean: clean
rm -f qemu-doc.vr
rm -f config.log
rm -f linux-headers/asm
rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
for d in $(TARGET_DIRS); do \
rm -rf $$d || exit 1 ; \
done
@@ -434,7 +433,7 @@ endif
install-doc: $(DOCS)
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
$(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(qemu_docdir)"
$(INSTALL_DATA) qemu-doc.html "$(DESTDIR)$(qemu_docdir)"
$(INSTALL_DATA) $(SRC_PATH)/docs/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
ifdef CONFIG_POSIX
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
@@ -592,10 +591,10 @@ qemu-ga.8: qemu-ga.texi
$(POD2MAN) --section=8 --center=" " --release=" " qemu-ga.pod > $@, \
"GEN","$@")
dvi: qemu-doc.dvi qemu-tech.dvi
html: qemu-doc.html qemu-tech.html
info: qemu-doc.info qemu-tech.info
pdf: qemu-doc.pdf qemu-tech.pdf
dvi: qemu-doc.dvi
html: qemu-doc.html
info: qemu-doc.info
pdf: qemu-doc.pdf
qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \
qemu-img.texi qemu-nbd.texi qemu-options.texi qemu-option-trace.texi \
-2
View File
@@ -42,8 +42,6 @@ of other UNIX targets. The simple steps to build QEMU are:
../configure
make
Complete details of the process for building and configuring QEMU for
all supported host platforms can be found in the qemu-tech.html file.
Additional information can also be found online via the QEMU website:
http://qemu-project.org/Hosts/Linux
+4 -4
View File
@@ -192,7 +192,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
/* We were asked to stop executing TBs (probably a pending
* interrupt. We've now stopped, so clear the flag.
*/
cpu->tcg_exit_req = 0;
atomic_set(&cpu->tcg_exit_req, 0);
}
return ret;
}
@@ -490,8 +490,8 @@ static inline void cpu_handle_interrupt(CPUState *cpu,
*last_tb = NULL;
}
}
if (unlikely(cpu->exit_request || replay_has_interrupt())) {
cpu->exit_request = 0;
if (unlikely(atomic_read(&cpu->exit_request) || replay_has_interrupt())) {
atomic_set(&cpu->exit_request, 0);
cpu->exception_index = EXCP_INTERRUPT;
cpu_loop_exit(cpu);
}
@@ -503,7 +503,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
{
uintptr_t ret;
if (unlikely(cpu->exit_request)) {
if (unlikely(atomic_read(&cpu->exit_request))) {
return;
}
+6 -1
View File
@@ -52,7 +52,7 @@ size == 8 for the rest.
0x20 (RW) : status register, bitwise OR
0x01 -- computing factorial (RO)
0x80 -- raise interrupt 0x01 after finishing factorial computation
0x80 -- raise interrupt after finishing factorial computation
0x24 (RO) : interrupt status register
It contains values which raised the interrupt (see interrupt raise
@@ -87,6 +87,11 @@ An IRQ is generated when written to the interrupt raise register. The value
appears in interrupt status register when the interrupt is raised and has to
be written to the interrupt acknowledge register to lower it.
The device supports both INTx and MSI interrupt. By default, INTx is
used. Even if the driver disabled INTx and only uses MSI, it still
needs to update the acknowledge register at the end of the IRQ handler
routine.
DMA controller
--------------
One has to specify, source, destination, size, and start the transfer. One
+1 -16
View File
@@ -172,20 +172,12 @@ STEXI
Show the command line history.
ETEXI
#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \
defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64))
{
.name = "irq",
.args_type = "",
.params = "",
.help = "show the interrupts statistics (if available)",
#ifdef TARGET_SPARC
.cmd = sun4m_hmp_info_irq,
#elif defined(TARGET_LM32)
.cmd = lm32_hmp_info_irq,
#else
.cmd = hmp_info_irq,
#endif
},
STEXI
@@ -198,16 +190,9 @@ ETEXI
.name = "pic",
.args_type = "",
.params = "",
.help = "show i8259 (PIC) state",
#ifdef TARGET_SPARC
.cmd = sun4m_hmp_info_pic,
#elif defined(TARGET_LM32)
.cmd = lm32_hmp_info_pic,
#else
.help = "show PIC state",
.cmd = hmp_info_pic,
#endif
},
#endif
STEXI
@item info pic
+65
View File
@@ -36,6 +36,7 @@
#include "qemu-io.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "hw/intc/intc.h"
#ifdef CONFIG_SPICE
#include <spice/enums.h>
@@ -787,6 +788,70 @@ static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
}
}
static int hmp_info_irq_foreach(Object *obj, void *opaque)
{
InterruptStatsProvider *intc;
InterruptStatsProviderClass *k;
Monitor *mon = opaque;
if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
intc = INTERRUPT_STATS_PROVIDER(obj);
k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
uint64_t *irq_counts;
unsigned int nb_irqs, i;
if (k->get_statistics &&
k->get_statistics(intc, &irq_counts, &nb_irqs)) {
if (nb_irqs > 0) {
monitor_printf(mon, "IRQ statistics for %s:\n",
object_get_typename(obj));
for (i = 0; i < nb_irqs; i++) {
if (irq_counts[i] > 0) {
monitor_printf(mon, "%2d: %" PRId64 "\n", i,
irq_counts[i]);
}
}
}
} else {
monitor_printf(mon, "IRQ statistics not available for %s.\n",
object_get_typename(obj));
}
}
return 0;
}
void hmp_info_irq(Monitor *mon, const QDict *qdict)
{
object_child_foreach_recursive(object_get_root(),
hmp_info_irq_foreach, mon);
}
static int hmp_info_pic_foreach(Object *obj, void *opaque)
{
InterruptStatsProvider *intc;
InterruptStatsProviderClass *k;
Monitor *mon = opaque;
if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
intc = INTERRUPT_STATS_PROVIDER(obj);
k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
if (k->print_info) {
k->print_info(intc, mon);
} else {
monitor_printf(mon, "Interrupt controller information not available for %s.\n",
object_get_typename(obj));
}
}
return 0;
}
void hmp_info_pic(Monitor *mon, const QDict *qdict)
{
object_child_foreach_recursive(object_get_root(),
hmp_info_pic_foreach, mon);
}
void hmp_info_pci(Monitor *mon, const QDict *qdict)
{
PciInfoList *info_list, *info;
+2
View File
@@ -36,6 +36,8 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
void hmp_info_vnc(Monitor *mon, const QDict *qdict);
void hmp_info_spice(Monitor *mon, const QDict *qdict);
void hmp_info_balloon(Monitor *mon, const QDict *qdict);
void hmp_info_irq(Monitor *mon, const QDict *qdict);
void hmp_info_pic(Monitor *mon, const QDict *qdict);
void hmp_info_pci(Monitor *mon, const QDict *qdict);
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
void hmp_info_tpm(Monitor *mon, const QDict *qdict);
+13 -9
View File
@@ -143,10 +143,10 @@ static void amdvi_assign_andq(AMDVIState *s, hwaddr addr, uint64_t val)
static void amdvi_generate_msi_interrupt(AMDVIState *s)
{
MSIMessage msg;
MemTxAttrs attrs;
attrs.requester_id = pci_requester_id(&s->pci.dev);
MSIMessage msg = {};
MemTxAttrs attrs = {
.requester_id = pci_requester_id(&s->pci.dev)
};
if (msi_enabled(&s->pci.dev)) {
msg = msi_get_message(&s->pci.dev, 0);
@@ -185,7 +185,7 @@ static void amdvi_setevent_bits(uint64_t *buffer, uint64_t value, int start,
int length)
{
int index = start / 64, bitpos = start % 64;
uint64_t mask = ((1 << length) - 1) << bitpos;
uint64_t mask = MAKE_64BIT_MASK(start, length);
buffer[index] &= ~mask;
buffer[index] |= (value << bitpos) & mask;
}
@@ -333,8 +333,8 @@ static void amdvi_update_iotlb(AMDVIState *s, uint16_t devid,
uint64_t gpa, IOMMUTLBEntry to_cache,
uint16_t domid)
{
AMDVIIOTLBEntry *entry = g_malloc(sizeof(*entry));
uint64_t *key = g_malloc(sizeof(key));
AMDVIIOTLBEntry *entry = g_new(AMDVIIOTLBEntry, 1);
uint64_t *key = g_new(uint64_t, 1);
uint64_t gfn = gpa >> AMDVI_PAGE_SHIFT_4K;
/* don't cache erroneous translations */
@@ -1135,6 +1135,7 @@ static void amdvi_reset(DeviceState *dev)
static void amdvi_realize(DeviceState *dev, Error **err)
{
int ret = 0;
AMDVIState *s = AMD_IOMMU_DEVICE(dev);
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
PCIBus *bus = PC_MACHINE(qdev_get_machine())->bus;
@@ -1147,8 +1148,11 @@ static void amdvi_realize(DeviceState *dev, Error **err)
object_property_set_bool(OBJECT(&s->pci), true, "realized", err);
s->capab_offset = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
AMDVI_CAPAB_SIZE);
pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0, AMDVI_CAPAB_REG_SIZE);
pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0, AMDVI_CAPAB_REG_SIZE);
assert(s->capab_offset > 0);
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_MSI, 0, AMDVI_CAPAB_REG_SIZE);
assert(ret > 0);
ret = pci_add_capability(&s->pci.dev, PCI_CAP_ID_HT, 0, AMDVI_CAPAB_REG_SIZE);
assert(ret > 0);
/* set up MMIO */
memory_region_init_io(&s->mmio, OBJECT(s), &mmio_mem_ops, s, "amdvi-mmio",
+1
View File
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_dist.o
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_redist.o
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_its_common.o
common-obj-$(CONFIG_OPENPIC) += openpic.o
common-obj-y += intc.o
obj-$(CONFIG_APIC) += apic.o apic_common.o
obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
+37 -36
View File
@@ -29,6 +29,7 @@
#include "qemu/timer.h"
#include "qemu/log.h"
#include "hw/isa/i8259_internal.h"
#include "hw/intc/intc.h"
/* debug PIC */
//#define DEBUG_PIC
@@ -251,6 +252,35 @@ static void pic_reset(DeviceState *dev)
pic_init_reset(s);
}
static bool pic_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs)
{
PICCommonState *s = PIC_COMMON(obj);
if (s->master) {
#ifdef DEBUG_IRQ_COUNT
*irq_counts = irq_count;
*nb_irqs = ARRAY_SIZE(irq_count);
#else
return false;
#endif
} else {
*irq_counts = NULL;
*nb_irqs = 0;
}
return true;
}
static void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
{
PICCommonState *s = PIC_COMMON(obj);
monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d "
"irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
s->master ? 0 : 1, s->irr, s->imr, s->isr, s->priority_add,
s->irq_base, s->read_reg_select, s->elcr,
s->special_fully_nested_mode);
}
static void pic_ioport_write(void *opaque, hwaddr addr64,
uint64_t val64, unsigned size)
{
@@ -431,42 +461,6 @@ static void pic_realize(DeviceState *dev, Error **errp)
pc->parent_realize(dev, errp);
}
void hmp_info_pic(Monitor *mon, const QDict *qdict)
{
int i;
PICCommonState *s;
if (!isa_pic) {
return;
}
for (i = 0; i < 2; i++) {
s = i == 0 ? PIC_COMMON(isa_pic) : slave_pic;
monitor_printf(mon, "pic%d: irr=%02x imr=%02x isr=%02x hprio=%d "
"irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
i, s->irr, s->imr, s->isr, s->priority_add,
s->irq_base, s->read_reg_select, s->elcr,
s->special_fully_nested_mode);
}
}
void hmp_info_irq(Monitor *mon, const QDict *qdict)
{
#ifndef DEBUG_IRQ_COUNT
monitor_printf(mon, "irq statistic code not compiled.\n");
#else
int i;
int64_t count;
monitor_printf(mon, "IRQ statistics:\n");
for (i = 0; i < 16; i++) {
count = irq_count[i];
if (count > 0) {
monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
}
}
#endif
}
qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
{
qemu_irq *irq_set;
@@ -503,10 +497,13 @@ static void i8259_class_init(ObjectClass *klass, void *data)
{
PICClass *k = PIC_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
k->parent_realize = dc->realize;
dc->realize = pic_realize;
dc->reset = pic_reset;
ic->get_statistics = pic_get_statistics;
ic->print_info = pic_print_info;
}
static const TypeInfo i8259_info = {
@@ -515,6 +512,10 @@ static const TypeInfo i8259_info = {
.parent = TYPE_PIC_COMMON,
.class_init = i8259_class_init,
.class_size = sizeof(PICClass),
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
};
static void pic_register_types(void)
+3 -2
View File
@@ -70,10 +70,11 @@ static int pic_dispatch_post_load(void *opaque, int version_id)
static void pic_common_realize(DeviceState *dev, Error **errp)
{
PICCommonState *s = PIC_COMMON(dev);
ISADevice *isa = ISA_DEVICE(dev);
isa_register_ioport(NULL, &s->base_io, s->iobase);
isa_register_ioport(isa, &s->base_io, s->iobase);
if (s->elcr_addr != -1) {
isa_register_ioport(NULL, &s->elcr_io, s->elcr_addr);
isa_register_ioport(isa, &s->elcr_io, s->elcr_addr);
}
qdev_set_legacy_instance_id(dev, s->iobase, 1);
+41
View File
@@ -0,0 +1,41 @@
/*
* QEMU Generic Interrupt Controller
*
* Copyright (c) 2016 Hervé Poussineau
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "hw/intc/intc.h"
#include "qemu/module.h"
static const TypeInfo intctrl_info = {
.name = TYPE_INTERRUPT_STATS_PROVIDER,
.parent = TYPE_INTERFACE,
.class_size = sizeof(InterruptStatsProviderClass),
};
static void intc_register_types(void)
{
type_register_static(&intctrl_info);
}
type_init(intc_register_types)
+28 -35
View File
@@ -25,6 +25,7 @@
#include "hw/sysbus.h"
#include "trace.h"
#include "hw/lm32/lm32_pic.h"
#include "hw/intc/intc.h"
#define TYPE_LM32_PIC "lm32-pic"
#define LM32_PIC(obj) OBJECT_CHECK(LM32PicState, (obj), TYPE_LM32_PIC)
@@ -38,39 +39,10 @@ struct LM32PicState {
uint32_t irq_state;
/* statistics */
uint32_t stats_irq_count[32];
uint64_t stats_irq_count[32];
};
typedef struct LM32PicState LM32PicState;
static LM32PicState *pic;
void lm32_hmp_info_pic(Monitor *mon, const QDict *qdict)
{
if (pic == NULL) {
return;
}
monitor_printf(mon, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
pic->im, pic->ip, pic->irq_state);
}
void lm32_hmp_info_irq(Monitor *mon, const QDict *qdict)
{
int i;
uint32_t count;
if (pic == NULL) {
return;
}
monitor_printf(mon, "IRQ statistics:\n");
for (i = 0; i < 32; i++) {
count = pic->stats_irq_count[i];
if (count > 0) {
monitor_printf(mon, "%2d: %u\n", i, count);
}
}
}
static void update_irq(LM32PicState *s)
{
s->ip |= s->irq_state;
@@ -152,6 +124,22 @@ static void pic_reset(DeviceState *d)
}
}
static bool lm32_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs)
{
LM32PicState *s = LM32_PIC(obj);
*irq_counts = s->stats_irq_count;
*nb_irqs = ARRAY_SIZE(s->stats_irq_count);
return true;
}
static void lm32_print_info(InterruptStatsProvider *obj, Monitor *mon)
{
LM32PicState *s = LM32_PIC(obj);
monitor_printf(mon, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
s->im, s->ip, s->irq_state);
}
static void lm32_pic_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
@@ -160,19 +148,17 @@ static void lm32_pic_init(Object *obj)
qdev_init_gpio_in(dev, irq_handler, 32);
sysbus_init_irq(sbd, &s->parent_irq);
pic = s;
}
static const VMStateDescription vmstate_lm32_pic = {
.name = "lm32-pic",
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32(im, LM32PicState),
VMSTATE_UINT32(ip, LM32PicState),
VMSTATE_UINT32(irq_state, LM32PicState),
VMSTATE_UINT32_ARRAY(stats_irq_count, LM32PicState, 32),
VMSTATE_UINT64_ARRAY(stats_irq_count, LM32PicState, 32),
VMSTATE_END_OF_LIST()
}
};
@@ -180,9 +166,12 @@ static const VMStateDescription vmstate_lm32_pic = {
static void lm32_pic_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
dc->reset = pic_reset;
dc->vmsd = &vmstate_lm32_pic;
ic->get_statistics = lm32_get_statistics;
ic->print_info = lm32_print_info;
}
static const TypeInfo lm32_pic_info = {
@@ -191,6 +180,10 @@ static const TypeInfo lm32_pic_info = {
.instance_size = sizeof(LM32PicState),
.instance_init = lm32_pic_init,
.class_init = lm32_pic_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
};
static void lm32_pic_register_types(void)
+35 -32
View File
@@ -26,6 +26,7 @@
#include "hw/sparc/sun4m.h"
#include "monitor/monitor.h"
#include "hw/sysbus.h"
#include "hw/intc/intc.h"
#include "trace.h"
//#define DEBUG_IRQ_COUNT
@@ -210,38 +211,6 @@ static const MemoryRegionOps slavio_intctlm_mem_ops = {
},
};
void slavio_pic_info(Monitor *mon, DeviceState *dev)
{
SLAVIO_INTCTLState *s = SLAVIO_INTCTL(dev);
int i;
for (i = 0; i < MAX_CPUS; i++) {
monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
s->slaves[i].intreg_pending);
}
monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
s->intregm_pending, s->intregm_disabled);
}
void slavio_irq_info(Monitor *mon, DeviceState *dev)
{
#ifndef DEBUG_IRQ_COUNT
monitor_printf(mon, "irq statistic code not compiled.\n");
#else
SLAVIO_INTCTLState *s = SLAVIO_INTCTL(dev);
int i;
int64_t count;
s = SLAVIO_INTCTL(dev);
monitor_printf(mon, "IRQ statistics:\n");
for (i = 0; i < 32; i++) {
count = s->irq_count[i];
if (count > 0)
monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
}
#endif
}
static const uint32_t intbit_to_level[] = {
2, 3, 5, 7, 9, 11, 13, 2, 3, 5, 7, 9, 11, 13, 12, 12,
6, 13, 4, 10, 8, 9, 11, 0, 0, 0, 0, 15, 15, 15, 15, 0,
@@ -418,6 +387,31 @@ static void slavio_intctl_reset(DeviceState *d)
slavio_check_interrupts(s, 0);
}
#ifdef DEBUG_IRQ_COUNT
static bool slavio_intctl_get_statistics(InterruptStatsProvider *obj,
uint64_t **irq_counts,
unsigned int *nb_irqs)
{
SLAVIO_INTCTLState *s = SLAVIO_INTCTL(obj);
*irq_counts = s->irq_count;
*nb_irqs = ARRAY_SIZE(s->irq_count);
return true;
}
#endif
static void slavio_intctl_print_info(InterruptStatsProvider *obj, Monitor *mon)
{
SLAVIO_INTCTLState *s = SLAVIO_INTCTL(obj);
int i;
for (i = 0; i < MAX_CPUS; i++) {
monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
s->slaves[i].intreg_pending);
}
monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
s->intregm_pending, s->intregm_disabled);
}
static void slavio_intctl_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
@@ -449,9 +443,14 @@ static void slavio_intctl_init(Object *obj)
static void slavio_intctl_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
dc->reset = slavio_intctl_reset;
dc->vmsd = &vmstate_intctl;
#ifdef DEBUG_IRQ_COUNT
ic->get_statistics = slavio_intctl_get_statistics;
#endif
ic->print_info = slavio_intctl_print_info;
}
static const TypeInfo slavio_intctl_info = {
@@ -460,6 +459,10 @@ static const TypeInfo slavio_intctl_info = {
.instance_size = sizeof(SLAVIO_INTCTLState),
.instance_init = slavio_intctl_init,
.class_init = slavio_intctl_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
};
static void slavio_intctl_register_types(void)
+16 -2
View File
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
#include "qemu/timer.h"
#include "qemu/main-loop.h" /* iothread mutex */
#include "qapi/visitor.h"
@@ -69,11 +70,20 @@ typedef struct {
uint64_t dma_mask;
} EduState;
static bool edu_msi_enabled(EduState *edu)
{
return msi_enabled(&edu->pdev);
}
static void edu_raise_irq(EduState *edu, uint32_t val)
{
edu->irq_status |= val;
if (edu->irq_status) {
pci_set_irq(&edu->pdev, 1);
if (edu_msi_enabled(edu)) {
msi_notify(&edu->pdev, 0);
} else {
pci_set_irq(&edu->pdev, 1);
}
}
}
@@ -81,7 +91,7 @@ static void edu_lower_irq(EduState *edu, uint32_t val)
{
edu->irq_status &= ~val;
if (!edu->irq_status) {
if (!edu->irq_status && !edu_msi_enabled(edu)) {
pci_set_irq(&edu->pdev, 0);
}
}
@@ -342,6 +352,10 @@ static void pci_edu_realize(PCIDevice *pdev, Error **errp)
pci_config_set_interrupt_pin(pci_conf, 1);
if (msi_init(pdev, 0, 1, true, false, errp)) {
return;
}
memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
"edu-mmio", 1 << 20);
pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);
+1 -14
View File
@@ -159,20 +159,6 @@ static void nvram_init(Nvram *nvram, uint8_t *macaddr,
}
}
static DeviceState *slavio_intctl;
void sun4m_hmp_info_pic(Monitor *mon, const QDict *qdict)
{
if (slavio_intctl)
slavio_pic_info(mon, slavio_intctl);
}
void sun4m_hmp_info_irq(Monitor *mon, const QDict *qdict)
{
if (slavio_intctl)
slavio_irq_info(mon, slavio_intctl);
}
void cpu_check_irqs(CPUSPARCState *env)
{
CPUState *cs;
@@ -873,6 +859,7 @@ static void dummy_fdc_tc(void *opaque, int irq, int level)
static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
MachineState *machine)
{
DeviceState *slavio_intctl;
const char *cpu_model = machine->cpu_model;
unsigned int i;
void *iommu, *espdma, *ledma, *nvram;
+9 -1
View File
@@ -717,11 +717,18 @@ static void rtc_set_date_from_host(ISADevice *dev)
rtc_set_cmos(s, &tm);
}
static void rtc_pre_save(void *opaque)
{
RTCState *s = opaque;
rtc_update_time(s);
}
static int rtc_post_load(void *opaque, int version_id)
{
RTCState *s = opaque;
if (version_id <= 2) {
if (version_id <= 2 || rtc_clock == QEMU_CLOCK_REALTIME) {
rtc_set_time(s);
s->offset = 0;
check_update_timer(s);
@@ -764,6 +771,7 @@ static const VMStateDescription vmstate_rtc = {
.name = "mc146818rtc",
.version_id = 3,
.minimum_version_id = 1,
.pre_save = rtc_pre_save,
.post_load = rtc_post_load,
.fields = (VMStateField[]) {
VMSTATE_BUFFER(cmos_data, RTCState),
-2
View File
@@ -181,8 +181,6 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
qemu_irq *kvm_i8259_init(ISABus *bus);
int pic_read_irq(DeviceState *d);
int pic_get_output(DeviceState *d);
void hmp_info_pic(Monitor *mon, const QDict *qdict);
void hmp_info_irq(Monitor *mon, const QDict *qdict);
/* ioapic.c */

Some files were not shown because too many files have changed in this diff Show More