From patchwork Tue Oct 20 17:22:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shlomo Pongratz X-Patchwork-Id: 533088 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 8E486140307 for ; Wed, 21 Oct 2015 04:24:42 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=uimhPwzY; dkim-atps=neutral Received: from localhost ([::1]:47231 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZoaeO-0002nz-FV for incoming@patchwork.ozlabs.org; Tue, 20 Oct 2015 13:24:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51078) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zoabw-0000ca-5W for qemu-devel@nongnu.org; Tue, 20 Oct 2015 13:22:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zoabr-0003WS-7q for qemu-devel@nongnu.org; Tue, 20 Oct 2015 13:22:05 -0400 Received: from mail-wi0-x22e.google.com ([2a00:1450:400c:c05::22e]:34092) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zoabq-0003Vl-Uu for qemu-devel@nongnu.org; Tue, 20 Oct 2015 13:22:03 -0400 Received: by wikq8 with SMTP id q8so56811932wik.1 for ; Tue, 20 Oct 2015 10:22:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XLrkxTHr26BstETyGSyhw+2WYW+34wg/KDER2PUa7BM=; b=uimhPwzYAV79eQ+m9cvvBfmvCPrEH6ix+ssawriNc4U47gnfxGuTMEebroSfntb+TC rJp9IL7bCPak1GXQsaMvZ6in7FuBoeidr9AlYrum5rgQEoS1on7IZ4eX4xEPDWBWd+U5 yySM0d9jzbWxTyWOeP9gdksc4LqZsuEDqHrFjVdL1SHYD7iY08jR+XhOFi9zaZODGKEh QNfx2xUg3UrBQa4+pDlcSsMp8ruUM14/CJTxQoRFv/nkx29PFe4XH44ThsJUw7UlI2sF T1R6TcSdTQSoysjY4gj6kHbr8XAhy12DXYy9CcCHnRXCd3oJq6bK2i8iM+k3o8UQ1ag+ sCoQ== X-Received: by 10.180.35.199 with SMTP id k7mr6318806wij.13.1445361722281; Tue, 20 Oct 2015 10:22:02 -0700 (PDT) Received: from localhost.localdomain (bzq-79-181-26-227.red.bezeqint.net. [79.181.26.227]) by smtp.gmail.com with ESMTPSA id jd9sm3771828wic.0.2015.10.20.10.22.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 20 Oct 2015 10:22:01 -0700 (PDT) From: Shlomo Pongratz To: qemu-devel@nongnu.org Date: Tue, 20 Oct 2015 20:22:09 +0300 Message-Id: <1445361732-16257-7-git-send-email-shlomopongratz@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1445361732-16257-1-git-send-email-shlomopongratz@gmail.com> References: <1445361732-16257-1-git-send-email-shlomopongratz@gmail.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::22e Cc: peter.maydell@linaro.org, eric.auger@linaro.org, Shlomo Pongratz , p.fedin@samsung.com, shannon.zhao@linaro.org, ashoks@broadcom.com, imammedo@redhat.com Subject: [Qemu-devel] [PATCH RFC V5 6/9] hw/intc: arm_gicv3_spi_its X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Shlomo Pongratz This patch includes a placeholder code for future spi and its implementation. Signed-off-by: Shlomo Pongratz --- hw/intc/Makefile.objs | 1 + hw/intc/arm_gicv3_spi_its.c | 359 ++++++++++++++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_spi_its.h | 11 ++ 3 files changed, 371 insertions(+) create mode 100644 hw/intc/arm_gicv3_spi_its.c create mode 100644 hw/intc/arm_gicv3_spi_its.h diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 5e56acc..0e6784f 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -17,6 +17,7 @@ common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_interrupts.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpu_interface.o 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_spi_its.o common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o diff --git a/hw/intc/arm_gicv3_spi_its.c b/hw/intc/arm_gicv3_spi_its.c new file mode 100644 index 0000000..cd2b56d --- /dev/null +++ b/hw/intc/arm_gicv3_spi_its.c @@ -0,0 +1,359 @@ +#include "gicv3_internal.h" +#include "qom/cpu.h" +#include "arm_gicv3_spi_its.h" +#include "arm_gicv3_interrupts.h" + +/* ITS routines are stubs for future development */ +static uint64_t gic_its_readb(void *opaque, hwaddr offset) +{ + return 0; +} + +static uint64_t gic_its_readw(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_its_readb(opaque, offset); + val |= gic_its_readb(opaque, offset + 1) << 8; + return val; +} + +static uint64_t gic_its_readl(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_its_readw(opaque, offset); + val |= gic_its_readw(opaque, offset + 2) << 16; + return val; +} + +static uint64_t gic_its_readll(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_its_readl(opaque, offset); + val |= gic_its_readl(opaque, offset + 4) << 32; + return val; +} + +static void gic_its_writeb(void *opaque, hwaddr offset, + uint64_t value) +{ + GICv3State *s = (GICv3State *)opaque; + gicv3_update(s); + return; +} + +static void gic_its_writew(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_its_writeb(opaque, offset, value & 0xff); + gic_its_writeb(opaque, offset + 1, value >> 8); +} + +static void gic_its_writel(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_its_writel(opaque, offset, value & 0xffff); + gic_its_writel(opaque, offset + 2, value >> 16); +} + +static void gic_its_writell(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_its_writell(opaque, offset, value & 0xffffffff); + gic_its_writell(opaque, offset + 4, value >> 32); +} + +uint64_t gic_its_read(void *opaque, hwaddr addr, unsigned size) +{ + uint64_t data; + switch (size) { + case 1: + data = gic_its_readb(opaque, addr); + break; + case 2: + data = gic_its_readw(opaque, addr); + break; + case 4: + data = gic_its_readl(opaque, addr); + break; + case 8: + data = gic_its_readll(opaque, addr); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: size %u\n", __func__, size); + assert(0); + break; + } + DPRINTF("offset %p data %p\n", (void *) addr, (void *) data); + return data; +} + +void gic_its_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) +{ + DPRINTF("offset %p data %p\n", (void *) addr, (void *) data); + switch (size) { + case 1: + gic_its_writew(opaque, addr, data); + break; + case 2: + gic_its_writew(opaque, addr, data); + break; + case 4: + gic_its_writel(opaque, addr, data); + break; + case 8: + gic_its_writell(opaque, addr, data); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: size %u\n", __func__, size); + assert(0); + break; + } +} + +/* SPI routines are stubs for future development */ +static uint64_t gic_spi_readb(void *opaque, hwaddr offset) +{ + return 0; +} + +static uint64_t gic_spi_readw(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_spi_readb(opaque, offset); + val |= gic_spi_readb(opaque, offset + 1) << 8; + return val; +} + +static uint64_t gic_spi_readl(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_spi_readw(opaque, offset); + val |= gic_spi_readw(opaque, offset + 2) << 16; + return val; +} + +static uint64_t gic_spi_readll(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_spi_readl(opaque, offset); + val |= gic_spi_readl(opaque, offset + 4) << 32; + return val; +} + +static void gic_spi_writeb(void *opaque, hwaddr offset, + uint64_t value) +{ + GICv3State *s = (GICv3State *)opaque; + gicv3_update(s); + return; +} + +static void gic_spi_writew(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_spi_writeb(opaque, offset, value & 0xff); + gic_spi_writeb(opaque, offset + 1, value >> 8); +} + +static void gic_spi_writel(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_spi_writew(opaque, offset, value & 0xffff); + gic_spi_writew(opaque, offset + 2, value >> 16); +} + +static void gic_spi_writell(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_spi_writel(opaque, offset, value & 0xffffffff); + gic_spi_writel(opaque, offset + 4, value >> 32); +} + +uint64_t gic_spi_read(void *opaque, hwaddr addr, unsigned size) +{ + uint64_t data; + switch (size) { + case 1: + data = gic_spi_readb(opaque, addr); + break; + case 2: + data = gic_spi_readw(opaque, addr); + break; + case 4: + data = gic_spi_readl(opaque, addr); + break; + case 8: + data = gic_spi_readll(opaque, addr); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: size %u\n", __func__, size); + assert(0); + break; + } + DPRINTF("offset %p data %p\n", (void *) addr, (void *) data); + return data; +} + +void gic_spi_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) +{ + DPRINTF("offset %p data %p\n", (void *) addr, (void *) data); + switch (size) { + case 1: + gic_spi_writeb(opaque, addr, data); + break; + case 2: + gic_spi_writew(opaque, addr, data); + break; + case 4: + gic_spi_writel(opaque, addr, data); + break; + case 8: + gic_spi_writell(opaque, addr, data); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: size %u\n", __func__, size); + assert(0); + break; + } +} + +/* ITS control routines are stubs for future development */ +static uint64_t gic_its_cntrl_readb(void *opaque, hwaddr offset) +{ + GICv3State *s = (GICv3State *)opaque; + uint64_t res=0; + + if (offset < 0x100) { + if (offset == 0) + return 0; + if (offset == 4) + return 0; + if (offset < 0x08) + return s->num_cpu; + if (offset >= 0x80) { + return 0; + } + goto bad_reg; + } + return res; +bad_reg: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset %x\n", __func__, (int)offset); + return 0; +} + +static uint64_t gic_its_cntrl_readw(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_its_cntrl_readb(opaque, offset); + val |= gic_its_cntrl_readb(opaque, offset + 1) << 8; + return val; +} + +static uint64_t gic_its_cntrl_readl(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_its_cntrl_readw(opaque, offset); + val |= gic_its_cntrl_readw(opaque, offset + 2) << 16; + return val; +} + +static uint64_t gic_its_cntrl_readll(void *opaque, hwaddr offset) +{ + uint64_t val; + val = gic_its_cntrl_readl(opaque, offset); + val |= gic_its_cntrl_readl(opaque, offset + 4) << 32; + return val; +} + +static void gic_its_cntrl_writeb(void *opaque, hwaddr offset, + uint64_t value) +{ + GICv3State *s = (GICv3State *)opaque; + if (offset < 0x100) { + if (offset < 0x08) + s->num_cpu = value; + else + goto bad_reg; + } + gicv3_update(s); + return; +bad_reg: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Bad offset %x\n", __func__, (int)offset); +} + +static void gic_its_cntrl_writew(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_its_cntrl_writeb(opaque, offset, value & 0xff); + gic_its_cntrl_writeb(opaque, offset + 1, value >> 8); +} + +static void gic_its_cntrl_writel(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_its_cntrl_writew(opaque, offset, value & 0xffff); + gic_its_cntrl_writew(opaque, offset + 2, value >> 16); +} + +static void gic_its_cntrl_writell(void *opaque, hwaddr offset, + uint64_t value) +{ + gic_its_cntrl_writel(opaque, offset, value & 0xffffffff); + gic_its_cntrl_writel(opaque, offset + 4, value >> 32); +} + +uint64_t gic_its_cntrl_read(void *opaque, hwaddr addr, unsigned size) +{ + uint64_t data; + switch (size) { + case 1: + data = gic_its_cntrl_readb(opaque, addr); + break; + case 2: + data = gic_its_cntrl_readw(opaque, addr); + break; + case 4: + data = gic_its_cntrl_readl(opaque, addr); + break; + case 8: + data = gic_its_cntrl_readll(opaque, addr); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: size %u\n", __func__, size); + assert(0); + break; + } + DPRINTF("offset %p data %p\n", (void *) addr, (void *) data); + return data; +} + +void gic_its_cntrl_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) +{ + DPRINTF("offset %p data %p\n", (void *) addr, (void *) data); + switch (size) { + case 1: + gic_its_cntrl_writeb(opaque, addr, data); + break; + case 2: + gic_its_cntrl_writew(opaque, addr, data); + break; + case 4: + gic_its_cntrl_writel(opaque, addr, data); + break; + case 8: + gic_its_cntrl_writell(opaque, addr, data); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: size %u\n", __func__, size); + assert(0); + break; + } +} diff --git a/hw/intc/arm_gicv3_spi_its.h b/hw/intc/arm_gicv3_spi_its.h new file mode 100644 index 0000000..18e7c4b --- /dev/null +++ b/hw/intc/arm_gicv3_spi_its.h @@ -0,0 +1,11 @@ +#ifndef QEMU_ARM_GICV3_SPI_ITS_H +#define QEMU_ARM_GICV3_SPI_ITS_H + +uint64_t gic_its_read(void *opaque, hwaddr addr, unsigned size); +void gic_its_write(void *opaque, hwaddr addr, uint64_t data, unsigned size); +uint64_t gic_spi_read(void *opaque, hwaddr addr, unsigned size); +void gic_spi_write(void *opaque, hwaddr addr, uint64_t data, unsigned size); +uint64_t gic_its_cntrl_read(void *opaque, hwaddr addr, unsigned size); +void gic_its_cntrl_write(void *opaque, hwaddr addr, uint64_t data, unsigned size); + +#endif /* !QEMU_ARM_GIC_SPI_ITS_H */