hw/intc: Implement GIC-500 base class
This class is to be used by both software and KVM implementations of GICv3 Currently it is mostly a placeholder, but in future it is supposed to hold qemu's representation of GICv3 state, which is necessary for migration. The interface of this class is fully compatible with GICv2 one. This is done in order to simplify integration with existing code. Signed-off-by: Shlomo Pongratz <shlomo.pongratz@huawei.com> Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Reviewed-by: Eric Auger <eric.auger@linaro.org> Tested-by: Ashok kumar <ashoks@broadcom.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: aff8baaee493cdcab0694b4a1d4dd5ff27c37ed2.1441784344.git.p.fedin@samsung.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
fefa4b128d
commit
ff8f06ee76
@ -12,6 +12,7 @@ common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o
|
||||
common-obj-$(CONFIG_OPENPIC) += openpic.o
|
||||
|
||||
obj-$(CONFIG_APIC) += apic.o apic_common.o
|
||||
|
140
hw/intc/arm_gicv3_common.c
Normal file
140
hw/intc/arm_gicv3_common.c
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* ARM GICv3 support - common bits of emulated and KVM kernel model
|
||||
*
|
||||
* Copyright (c) 2012 Linaro Limited
|
||||
* Copyright (c) 2015 Huawei.
|
||||
* Written by Peter Maydell
|
||||
* Extended to 64 cores by Shlomo Pongratz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "hw/intc/arm_gicv3_common.h"
|
||||
|
||||
static void gicv3_pre_save(void *opaque)
|
||||
{
|
||||
GICv3State *s = (GICv3State *)opaque;
|
||||
ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s);
|
||||
|
||||
if (c->pre_save) {
|
||||
c->pre_save(s);
|
||||
}
|
||||
}
|
||||
|
||||
static int gicv3_post_load(void *opaque, int version_id)
|
||||
{
|
||||
GICv3State *s = (GICv3State *)opaque;
|
||||
ARMGICv3CommonClass *c = ARM_GICV3_COMMON_GET_CLASS(s);
|
||||
|
||||
if (c->post_load) {
|
||||
c->post_load(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_gicv3 = {
|
||||
.name = "arm_gicv3",
|
||||
.unmigratable = 1,
|
||||
.pre_save = gicv3_pre_save,
|
||||
.post_load = gicv3_post_load,
|
||||
};
|
||||
|
||||
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||
const MemoryRegionOps *ops)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
|
||||
int i;
|
||||
|
||||
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
|
||||
* GPIO array layout is thus:
|
||||
* [0..N-1] spi
|
||||
* [N..N+31] PPIs for CPU 0
|
||||
* [N+32..N+63] PPIs for CPU 1
|
||||
* ...
|
||||
*/
|
||||
i = s->num_irq - GIC_INTERNAL + GIC_INTERNAL * s->num_cpu;
|
||||
qdev_init_gpio_in(DEVICE(s), handler, i);
|
||||
|
||||
s->parent_irq = g_malloc(s->num_cpu * sizeof(qemu_irq));
|
||||
s->parent_fiq = g_malloc(s->num_cpu * sizeof(qemu_irq));
|
||||
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
sysbus_init_irq(sbd, &s->parent_irq[i]);
|
||||
}
|
||||
for (i = 0; i < s->num_cpu; i++) {
|
||||
sysbus_init_irq(sbd, &s->parent_fiq[i]);
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
|
||||
"gicv3_dist", 0x10000);
|
||||
memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s,
|
||||
"gicv3_redist", 0x20000 * s->num_cpu);
|
||||
|
||||
sysbus_init_mmio(sbd, &s->iomem_dist);
|
||||
sysbus_init_mmio(sbd, &s->iomem_redist);
|
||||
}
|
||||
|
||||
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
GICv3State *s = ARM_GICV3_COMMON(dev);
|
||||
|
||||
/* revision property is actually reserved and currently used only in order
|
||||
* to keep the interface compatible with GICv2 code, avoiding extra
|
||||
* conditions. However, in future it could be used, for example, if we
|
||||
* implement GICv4.
|
||||
*/
|
||||
if (s->revision != 3) {
|
||||
error_setg(errp, "unsupported GIC revision %d", s->revision);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void arm_gicv3_common_reset(DeviceState *dev)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static Property arm_gicv3_common_properties[] = {
|
||||
DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1),
|
||||
DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
|
||||
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
|
||||
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void arm_gicv3_common_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = arm_gicv3_common_reset;
|
||||
dc->realize = arm_gicv3_common_realize;
|
||||
dc->props = arm_gicv3_common_properties;
|
||||
dc->vmsd = &vmstate_gicv3;
|
||||
}
|
||||
|
||||
static const TypeInfo arm_gicv3_common_type = {
|
||||
.name = TYPE_ARM_GICV3_COMMON,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(GICv3State),
|
||||
.class_size = sizeof(ARMGICv3CommonClass),
|
||||
.class_init = arm_gicv3_common_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
type_register_static(&arm_gicv3_common_type);
|
||||
}
|
||||
|
||||
type_init(register_types)
|
68
include/hw/intc/arm_gicv3_common.h
Normal file
68
include/hw/intc/arm_gicv3_common.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ARM GIC support
|
||||
*
|
||||
* Copyright (c) 2012 Linaro Limited
|
||||
* Copyright (c) 2015 Huawei.
|
||||
* Written by Peter Maydell
|
||||
* Extended to 64 cores by Shlomo Pongratz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_ARM_GICV3_COMMON_H
|
||||
#define HW_ARM_GICV3_COMMON_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/intc/arm_gic_common.h"
|
||||
|
||||
typedef struct GICv3State {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
qemu_irq *parent_irq;
|
||||
qemu_irq *parent_fiq;
|
||||
|
||||
MemoryRegion iomem_dist; /* Distributor */
|
||||
MemoryRegion iomem_redist; /* Redistributors */
|
||||
|
||||
uint32_t num_cpu;
|
||||
uint32_t num_irq;
|
||||
uint32_t revision;
|
||||
bool security_extn;
|
||||
|
||||
int dev_fd; /* kvm device fd if backed by kvm vgic support */
|
||||
} GICv3State;
|
||||
|
||||
#define TYPE_ARM_GICV3_COMMON "arm-gicv3-common"
|
||||
#define ARM_GICV3_COMMON(obj) \
|
||||
OBJECT_CHECK(GICv3State, (obj), TYPE_ARM_GICV3_COMMON)
|
||||
#define ARM_GICV3_COMMON_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(ARMGICv3CommonClass, (klass), TYPE_ARM_GICV3_COMMON)
|
||||
#define ARM_GICV3_COMMON_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ARMGICv3CommonClass, (obj), TYPE_ARM_GICV3_COMMON)
|
||||
|
||||
typedef struct ARMGICv3CommonClass {
|
||||
/*< private >*/
|
||||
SysBusDeviceClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
void (*pre_save)(GICv3State *s);
|
||||
void (*post_load)(GICv3State *s);
|
||||
} ARMGICv3CommonClass;
|
||||
|
||||
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||
const MemoryRegionOps *ops);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user