[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH v2 4/8] ppc/pnv: add a PnvICPState object
From: |
David Gibson |
Subject: |
Re: [Qemu-ppc] [PATCH v2 4/8] ppc/pnv: add a PnvICPState object |
Date: |
Thu, 23 Mar 2017 15:12:00 +1100 |
User-agent: |
Mutt/1.8.0 (2017-02-23) |
On Thu, Mar 16, 2017 at 03:35:08PM +0100, Cédric Le Goater wrote:
> This provides a new ICPState object for the PowerNV machine (POWER8).
> Access to the Interrupt Management area is done though a memory
> region. It contains the registers of the Interrupt Control Presenters
> of each thread which are used to accept, return, forward interrupts in
> the system.
>
> Signed-off-by: Cédric Le Goater <address@hidden>
Revieed-by: David Gibson <address@hidden>
> ---
>
> Changes since v1:
>
> - moved the memory region from PnvCore to a specific PnvICPState object
>
> hw/intc/Makefile.objs | 1 +
> hw/intc/xics_pnv.c | 180
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> include/hw/ppc/xics.h | 12 ++++
> 3 files changed, 193 insertions(+)
> create mode 100644 hw/intc/xics_pnv.c
>
> diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
> index adedd0da5fd8..78426a7dafcd 100644
> --- a/hw/intc/Makefile.objs
> +++ b/hw/intc/Makefile.objs
> @@ -35,6 +35,7 @@ obj-$(CONFIG_SH4) += sh_intc.o
> obj-$(CONFIG_XICS) += xics.o
> obj-$(CONFIG_XICS_SPAPR) += xics_spapr.o
> obj-$(CONFIG_XICS_KVM) += xics_kvm.o
> +obj-$(CONFIG_POWERNV) += xics_pnv.o
> obj-$(CONFIG_ALLWINNER_A10_PIC) += allwinner-a10-pic.o
> obj-$(CONFIG_S390_FLIC) += s390_flic.o
> obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
> diff --git a/hw/intc/xics_pnv.c b/hw/intc/xics_pnv.c
> new file mode 100644
> index 000000000000..68a3ef6097a6
> --- /dev/null
> +++ b/hw/intc/xics_pnv.c
> @@ -0,0 +1,180 @@
> +/*
> + * QEMU PowerPC PowerNV ICP model
> + *
> + * Copyright (c) 2016, IBM Corporation.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public License
> + * as published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "sysemu/sysemu.h"
> +#include "qapi/error.h"
> +#include "qemu/log.h"
> +#include "hw/ppc/xics.h"
> +
> +static uint64_t pnv_icp_read(void *opaque, hwaddr addr, unsigned width)
> +{
> + ICPState *icp = ICP(opaque);
> + PnvICPState *picp = PNV_ICP(opaque);
> + bool byte0 = (width == 1 && (addr & 0x3) == 0);
> + uint64_t val = 0xffffffff;
> +
> + switch (addr & 0xffc) {
> + case 0: /* poll */
> + val = icp_ipoll(icp, NULL);
> + if (byte0) {
> + val >>= 24;
> + } else if (width != 4) {
> + goto bad_access;
> + }
> + break;
> + case 4: /* xirr */
> + if (byte0) {
> + val = icp_ipoll(icp, NULL) >> 24;
> + } else if (width == 4) {
> + val = icp_accept(icp);
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 12:
> + if (byte0) {
> + val = icp->mfrr;
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 16:
> + if (width == 4) {
> + val = picp->links[0];
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 20:
> + if (width == 4) {
> + val = picp->links[1];
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 24:
> + if (width == 4) {
> + val = picp->links[2];
> + } else {
> + goto bad_access;
> + }
> + break;
> + default:
> +bad_access:
> + qemu_log_mask(LOG_GUEST_ERROR, "XICS: Bad ICP access 0x%"
> + HWADDR_PRIx"/%d\n", addr, width);
> + }
> +
> + return val;
> +}
> +
> +static void pnv_icp_write(void *opaque, hwaddr addr, uint64_t val,
> + unsigned width)
> +{
> + ICPState *icp = ICP(opaque);
> + PnvICPState *picp = PNV_ICP(opaque);
> + bool byte0 = (width == 1 && (addr & 0x3) == 0);
> +
> + switch (addr & 0xffc) {
> + case 4: /* xirr */
> + if (byte0) {
> + icp_set_cppr(icp, val);
> + } else if (width == 4) {
> + icp_eoi(icp, val);
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 12:
> + if (byte0) {
> + icp_set_mfrr(icp, val);
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 16:
> + if (width == 4) {
> + picp->links[0] = val;
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 20:
> + if (width == 4) {
> + picp->links[1] = val;
> + } else {
> + goto bad_access;
> + }
> + break;
> + case 24:
> + if (width == 4) {
> + picp->links[2] = val;
> + } else {
> + goto bad_access;
> + }
> + break;
> + default:
> +bad_access:
> + qemu_log_mask(LOG_GUEST_ERROR, "XICS: Bad ICP access 0x%"
> + HWADDR_PRIx"/%d\n", addr, width);
> + }
> +}
> +
> +static const MemoryRegionOps pnv_icp_ops = {
> + .read = pnv_icp_read,
> + .write = pnv_icp_write,
> + .valid.min_access_size = 1,
> + .valid.max_access_size = 4,
> + .impl.min_access_size = 1,
> + .impl.max_access_size = 4,
> + .endianness = DEVICE_BIG_ENDIAN,
> +};
> +
> +static void pnv_icp_realize(DeviceState *dev, Error **errp)
> +{
> + PnvICPState *icp = PNV_ICP(dev);
> +
> + memory_region_init_io(&icp->mmio, OBJECT(dev), &pnv_icp_ops,
> + icp, "icp-thread", 0x1000);
> +}
> +
> +static void pnv_icp_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + ICPStateClass *icpc = ICP_CLASS(klass);
> +
> + icpc->realize = pnv_icp_realize;
> + dc->desc = "PowerNV ICP";
> +}
> +
> +static const TypeInfo pnv_icp_info = {
> + .name = TYPE_PNV_ICP,
> + .parent = TYPE_ICP,
> + .instance_size = sizeof(PnvICPState),
> + .class_init = pnv_icp_class_init,
> + .class_size = sizeof(ICPStateClass),
> +};
> +
> +static void pnv_icp_register_types(void)
> +{
> + type_register_static(&pnv_icp_info);
> +}
> +
> +type_init(pnv_icp_register_types)
> diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
> index 0863e3a079f5..cfcf7ecece69 100644
> --- a/include/hw/ppc/xics.h
> +++ b/include/hw/ppc/xics.h
> @@ -41,10 +41,12 @@
> */
> typedef struct ICPStateClass ICPStateClass;
> typedef struct ICPState ICPState;
> +typedef struct PnvICPState PnvICPState;
> typedef struct ICSStateClass ICSStateClass;
> typedef struct ICSState ICSState;
> typedef struct ICSIRQState ICSIRQState;
> typedef struct XICSFabric XICSFabric;
> +typedef struct PowerPCCPU PowerPCCPU;
>
> #define TYPE_ICP "icp"
> #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP)
> @@ -52,6 +54,9 @@ typedef struct XICSFabric XICSFabric;
> #define TYPE_KVM_ICP "icp-kvm"
> #define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP)
>
> +#define TYPE_PNV_ICP "pnv-icp"
> +#define PNV_ICP(obj) OBJECT_CHECK(PnvICPState, (obj), TYPE_PNV_ICP)
> +
> #define ICP_CLASS(klass) \
> OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP)
> #define ICP_GET_CLASS(obj) \
> @@ -81,6 +86,13 @@ struct ICPState {
> XICSFabric *xics;
> };
>
> +struct PnvICPState {
> + ICPState parent_obj;
> +
> + MemoryRegion mmio;
> + uint32_t links[3];
> +};
> +
> #define TYPE_ICS_BASE "ics-base"
> #define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature
- [Qemu-ppc] [PATCH v2 0/8] ppc/pnv: interrupt controller (POWER8), Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 1/8] ppc/xics: introduce an ICPState backlink under PowerPCCPU, Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 2/8] spapr: move the IRQ server number mapping under the machine, Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 3/8] ppc/xics: add a realize() handler to ICPStateClass, Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 4/8] ppc/pnv: add a PnvICPState object, Cédric Le Goater, 2017/03/16
- Re: [Qemu-ppc] [PATCH v2 4/8] ppc/pnv: add a PnvICPState object,
David Gibson <=
- [Qemu-ppc] [PATCH v2 6/8] ppc/pnv: add a helper to calculate MMIO addresses registers, Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 5/8] ppc/pnv: create the ICP and ICS objects under the machine, Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 7/8] ppc/pnv: link the CPUs to the machine XICSFabric, Cédric Le Goater, 2017/03/16
- [Qemu-ppc] [PATCH v2 8/8] ppc/pnv: add memory regions for the ICP registers, Cédric Le Goater, 2017/03/16