From patchwork Fri Oct 13 13:49:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stafford Horne X-Patchwork-Id: 10004779 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B67CC60360 for ; Fri, 13 Oct 2017 13:53:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7C9D29060 for ; Fri, 13 Oct 2017 13:53:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9CAD62907F; Fri, 13 Oct 2017 13:53:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CF48E29060 for ; Fri, 13 Oct 2017 13:53:33 +0000 (UTC) Received: from localhost ([::1]:50429 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e30P7-0001X6-0e for patchwork-qemu-devel@patchwork.kernel.org; Fri, 13 Oct 2017 09:53:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57766) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e30Lb-0007vo-Am for qemu-devel@nongnu.org; Fri, 13 Oct 2017 09:49:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e30LZ-0006aY-Eb for qemu-devel@nongnu.org; Fri, 13 Oct 2017 09:49:55 -0400 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]:45360) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e30LZ-0006a4-6W for qemu-devel@nongnu.org; Fri, 13 Oct 2017 09:49:53 -0400 Received: by mail-pf0-x241.google.com with SMTP id d28so10321288pfe.2 for ; Fri, 13 Oct 2017 06:49:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tZxa5m+hHTLQrNdGoE1qNPapFEDQOZhLpBXUdtSd2Fk=; b=VHWkWZu6u5mFAyTX74WDc25yOmnqKNmdxEEI7hZhXc0ccWgsnxUpu5F/cXk6x3PKc4 OSkvaV+0KtzG1cLCftNOAU8ZKeWqnvATwjcBjRTBCJraxSno61XSIaSr96dpOVai084z /JISK7VuOdYI/kKmsEH1+sdQtrrMhoqv1DcmvgXMwSFgp/YrSUL7ENhi50TiQI2Nkpsf gZ60+f5k6f1ywRtRS9cFWsc5Nt+A69ONFySAziypp+f6eo9Nov+yg2LrydrsqdaqBON1 Kl0VZAg2NI8LqsnYEnByPaadmgeZGRdORHBK7TBB4nHhQ6OhPWbuZDGOqHMI2l6E5mPC kATg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tZxa5m+hHTLQrNdGoE1qNPapFEDQOZhLpBXUdtSd2Fk=; b=PIrWE9bvqBK1NzEX1ZD2msRIRXA0zifgTsFsipHKDOka8Kh4jGs4HL+F1wTiHaJTX8 ctjrWRh2p48EYcHqjSl3Ruyng0vxXmKC5sjX/K8+A094dKEFEBfwPvT4INowpLBZZ5L9 yheOEdepDFHI56o7tdApl5C7fZ6HOsMDIgv1AYeM9C3XMz+WWf58yVyxvqv35ar4HaJD w7YAJjdi16vQ4sUJj4cr0lwcYlxLZb0aznIHGkGtEHjPiecgRcJfVJnRXevmqs9tntit FC+iKJcS6awqT8gws6+sPvkZWEuudlQOKy3odivi8v8buxlFjkzoJJ1DbJbawgTfsQK/ v+bQ== X-Gm-Message-State: AMCzsaU0A9GuvjGLF17hhljtjgqPk5/ZkEpAxYuODOX8s1tDVKQVWHTi bBZwX7FlheZeILSI2GfV1dAq59Kn X-Google-Smtp-Source: AOwi7QDii4Giu+T+QtuyKMpMpY0GYABtMv6QKXzF0lR0CStYfEfzEOH76brK8iEUgU17mWAYLjcQbA== X-Received: by 10.159.208.69 with SMTP id w5mr1447830plz.381.1507902592066; Fri, 13 Oct 2017 06:49:52 -0700 (PDT) Received: from localhost (g248.61-45-56.ppp.wakwak.ne.jp. [61.45.56.248]) by smtp.gmail.com with ESMTPSA id m16sm2683903pgn.76.2017.10.13.06.49.51 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 13 Oct 2017 06:49:51 -0700 (PDT) From: Stafford Horne To: QEMU Development Date: Fri, 13 Oct 2017 22:49:26 +0900 Message-Id: <20171013134930.32547-2-shorne@gmail.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171013134930.32547-1-shorne@gmail.com> References: <20171013134930.32547-1-shorne@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::241 Subject: [Qemu-devel] [PATCH v2 1/5] openrisc/ompic: Add OpenRISC Multicore PIC (OMPIC) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stafford Horne , Openrisc , Richard Henderson , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add OpenRISC Multicore PIC which handles inter processor interrupts (IPI) between cores. In OpenRISC all device interrupts are routed to each core enabling this device to be simple. Reviewed-by: Richard Henderson Signed-off-by: Stafford Horne --- default-configs/or1k-softmmu.mak | 1 + hw/intc/Makefile.objs | 1 + hw/intc/ompic.c | 179 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 hw/intc/ompic.c diff --git a/default-configs/or1k-softmmu.mak b/default-configs/or1k-softmmu.mak index 10bfa7abb8..6f5824fd48 100644 --- a/default-configs/or1k-softmmu.mak +++ b/default-configs/or1k-softmmu.mak @@ -2,3 +2,4 @@ CONFIG_SERIAL=y CONFIG_OPENCORES_ETH=y +CONFIG_OMPIC=y diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 78426a7daf..ae358569a1 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -43,3 +43,4 @@ obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o obj-$(CONFIG_MIPS_CPS) += mips_gic.o obj-$(CONFIG_NIOS2) += nios2_iic.o +obj-$(CONFIG_OMPIC) += ompic.o diff --git a/hw/intc/ompic.c b/hw/intc/ompic.c new file mode 100644 index 0000000000..c0e34d1268 --- /dev/null +++ b/hw/intc/ompic.c @@ -0,0 +1,179 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Authors: Stafford Horne + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "exec/memory.h" + +#define TYPE_OR1K_OMPIC "or1k-ompic" +#define OR1K_OMPIC(obj) OBJECT_CHECK(OR1KOMPICState, (obj), TYPE_OR1K_OMPIC) + +#define OMPIC_CTRL_IRQ_ACK (1 << 31) +#define OMPIC_CTRL_IRQ_GEN (1 << 30) +#define OMPIC_CTRL_DST(cpu) (((cpu) >> 16) & 0x3fff) + +#define OMPIC_REG(addr) (((addr) >> 2) & 0x1) +#define OMPIC_SRC_CPU(addr) (((addr) >> 3) & 0x4f) +#define OMPIC_DST_CPU(addr) (((addr) >> 3) & 0x4f) + +#define OMPIC_STATUS_IRQ_PENDING (1 << 30) +#define OMPIC_STATUS_SRC(cpu) (((cpu) & 0x3fff) << 16) +#define OMPIC_STATUS_DATA(data) ((data) & 0xffff) + +#define OMPIC_CONTROL 0 +#define OMPIC_STATUS 1 + +#define OMPIC_MAX_CPUS 4 /* Real max is much higher, but dont waste memory */ +#define OMPIC_ADDRSPACE_SZ (OMPIC_MAX_CPUS * 2 * 4) /* 2 32-bit regs per cpu */ + +typedef struct OR1KOMPICState OR1KOMPICState; +typedef struct OR1KOMPICCPUState OR1KOMPICCPUState; + +struct OR1KOMPICCPUState { + qemu_irq irq; + uint32_t status; + uint32_t control; +}; + +struct OR1KOMPICState { + SysBusDevice parent_obj; + MemoryRegion mr; + + OR1KOMPICCPUState cpus[OMPIC_MAX_CPUS]; + + uint32_t num_cpus; +}; + +static uint64_t ompic_read(void *opaque, hwaddr addr, unsigned size) +{ + OR1KOMPICState *s = opaque; + int src_cpu = OMPIC_SRC_CPU(addr); + + /* We can only write to control control, write control + update status */ + if (OMPIC_REG(addr) == OMPIC_CONTROL) { + return s->cpus[src_cpu].control; + } else { + return s->cpus[src_cpu].status; + } + +} + +static void ompic_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) +{ + OR1KOMPICState *s = opaque; + /* We can only write to control control, write control + update status */ + if (OMPIC_REG(addr) == OMPIC_CONTROL) { + int src_cpu = OMPIC_SRC_CPU(addr); + + s->cpus[src_cpu].control = data; + + if (data & OMPIC_CTRL_IRQ_GEN) { + int dst_cpu = OMPIC_CTRL_DST(data); + + s->cpus[dst_cpu].status = OMPIC_STATUS_IRQ_PENDING | + OMPIC_STATUS_SRC(src_cpu) | + OMPIC_STATUS_DATA(data); + + qemu_irq_raise(s->cpus[dst_cpu].irq); + } + if (data & OMPIC_CTRL_IRQ_ACK) { + s->cpus[src_cpu].status &= ~OMPIC_STATUS_IRQ_PENDING; + qemu_irq_lower(s->cpus[src_cpu].irq); + } + } +} + +static const MemoryRegionOps ompic_ops = { + .read = ompic_read, + .write = ompic_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .max_access_size = 8, + }, +}; + +static void or1k_ompic_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + OR1KOMPICState *s = OR1K_OMPIC(obj); + + memory_region_init_io(&s->mr, OBJECT(s), &ompic_ops, s, + "or1k-ompic", OMPIC_ADDRSPACE_SZ); + sysbus_init_mmio(sbd, &s->mr); +} + +static void or1k_ompic_realize(DeviceState *dev, Error **errp) +{ + OR1KOMPICState *s = OR1K_OMPIC(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + int i; + + if (s->num_cpus > OMPIC_MAX_CPUS) { + error_setg(errp, "Exceeded maximum CPUs %d", s->num_cpus); + return; + } + /* Init IRQ sources for all CPUs */ + for (i = 0; i < s->num_cpus; i++) { + sysbus_init_irq(sbd, &s->cpus[i].irq); + } +} + +static Property or1k_ompic_properties[] = { + DEFINE_PROP_UINT32("num-cpus", OR1KOMPICState, num_cpus, 1), + DEFINE_PROP_END_OF_LIST(), +}; + +static const VMStateDescription vmstate_or1k_ompic_cpu = { + .name = "or1k_ompic_cpu", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(status, OR1KOMPICCPUState), + VMSTATE_UINT32(control, OR1KOMPICCPUState), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_or1k_ompic = { + .name = TYPE_OR1K_OMPIC, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(cpus, OR1KOMPICState, OMPIC_MAX_CPUS, 1, + vmstate_or1k_ompic_cpu, OR1KOMPICCPUState), + VMSTATE_UINT32(num_cpus, OR1KOMPICState), + VMSTATE_END_OF_LIST() + } +}; + +static void or1k_ompic_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->props = or1k_ompic_properties; + dc->realize = or1k_ompic_realize; + dc->vmsd = &vmstate_or1k_ompic; +} + +static const TypeInfo or1k_ompic_info = { + .name = TYPE_OR1K_OMPIC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(OR1KOMPICState), + .instance_init = or1k_ompic_init, + .class_init = or1k_ompic_class_init, +}; + +static void or1k_ompic_register_types(void) +{ + type_register_static(&or1k_ompic_info); +} + +type_init(or1k_ompic_register_types)