From patchwork Fri Oct 20 22:05:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stafford Horne X-Patchwork-Id: 10021083 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 88E3060211 for ; Fri, 20 Oct 2017 22:07:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B21E28F6D for ; Fri, 20 Oct 2017 22:07:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6FFD528F71; Fri, 20 Oct 2017 22:07:25 +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 D53BE28F6D for ; Fri, 20 Oct 2017 22:07:24 +0000 (UTC) Received: from localhost ([::1]:55835 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e5fRs-0001qg-37 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Oct 2017 18:07:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35333) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e5fQP-0001p4-1q for qemu-devel@nongnu.org; Fri, 20 Oct 2017 18:05:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e5fQM-0003mw-Bh for qemu-devel@nongnu.org; Fri, 20 Oct 2017 18:05:53 -0400 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]:54672) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e5fQM-0003mZ-3i for qemu-devel@nongnu.org; Fri, 20 Oct 2017 18:05:50 -0400 Received: by mail-pf0-x241.google.com with SMTP id n89so12857158pfk.11 for ; Fri, 20 Oct 2017 15:05:50 -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=iliATzf0JvzSZSw78H1IbHKg9eS2IZVO7hPYqEtj7k4/1xpHQzfXK+Y9LuZSBi9JWV U+BmFpbMTIhV/PhLAQmm9koyWDqxHyhLzaqYrejOq76J+BW/MX3G35LeuQoi+21KjikA QPm90MdD/JgIMdpdZoto/EV79yEFjXN8TwirTaJ+uDW8ryyofj3i9U6IextYL4K4urMf Q+V/pVMKD4bl+FoeBEWDqkmXPqZEX68J7fGFTb1UBptP2u6AI7O7S4To0Ljy9u9rs4al i9Qf/H6kgu0e9mRQSiJPHP9HqV4XATF4ErQ1Nq1dg3qG3O95YQ3XHkE2S/5ecuB0ZtyW uZwg== 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=qfeuahGmznx/m/g4l2xv/iD4mtcJOy4KC0fNdWMsYX6Q01KrRXqEUNoC8y7LXyhKnm GMy3YSQG2uaq60WN5ucrwH/p28mRTrIRndxHYQ8HtAZJsgqhnKCdBXA+GFtdxax6EYyW DoJONYtOHVbegmnwOhhaQm5ul+9IdUKLf3CUWcjKJuGGPvQCMe5TpnsaW8P34mrufFGv ej1fp8uu4AaHvxFgEjqjJZVtm37J1KuxnXd+THs2DZWj4B2tbZqQkQ9k9PIPYHC2h7hk FbY58TqHosEJHakEs4bDJTheEoXTV0yGHjX3r+xH8GJkfxK9DTiozZ7bpu3ffzLxmK2X xHcg== X-Gm-Message-State: AMCzsaX8i/Pb0v1FxQEJmD8KtwQJYMywVS3bPHXO4WPQDrqa64yAmeqS MQxbyr9tOAheo7FX07yU0kCutWer X-Google-Smtp-Source: ABhQp+SYk1SfFZ1LzbK1AxSawTcHTfmhe3v77VGcnWjtOBYc/MsGqTjyu9gj+jJ+jyxlqGoexpGEzA== X-Received: by 10.98.192.195 with SMTP id g64mr6122924pfk.95.1508537149221; Fri, 20 Oct 2017 15:05:49 -0700 (PDT) Received: from localhost (g183.61-45-92.ppp.wakwak.ne.jp. [61.45.92.183]) by smtp.gmail.com with ESMTPSA id h67sm3396342pfh.74.2017.10.20.15.05.48 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Oct 2017 15:05:48 -0700 (PDT) From: Stafford Horne To: Peter Maydell , QEMU Development Date: Sat, 21 Oct 2017 07:05:29 +0900 Message-Id: <20171020220533.29186-2-shorne@gmail.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171020220533.29186-1-shorne@gmail.com> References: <20171020220533.29186-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] [PULL 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 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)