From patchwork Thu Nov 17 12:24:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benoit Canet X-Patchwork-Id: 126198 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 26562B71E2 for ; Thu, 17 Nov 2011 23:25:35 +1100 (EST) Received: from localhost ([::1]:60376 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RR123-0003IO-EY for incoming@patchwork.ozlabs.org; Thu, 17 Nov 2011 07:25:31 -0500 Received: from eggs.gnu.org ([140.186.70.92]:49347) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RR11j-00033Y-Gy for qemu-devel@nongnu.org; Thu, 17 Nov 2011 07:25:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RR11h-0001gm-Vn for qemu-devel@nongnu.org; Thu, 17 Nov 2011 07:25:11 -0500 Received: from mail-ww0-f53.google.com ([74.125.82.53]:50945) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RR11h-0001fC-AT for qemu-devel@nongnu.org; Thu, 17 Nov 2011 07:25:09 -0500 Received: by mail-ww0-f53.google.com with SMTP id 27so2500674wwf.10 for ; Thu, 17 Nov 2011 04:25:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=Yhk3Kp54Rjt/HLELeKngrGadrM8VpQKdOtcuU+Jw8Sw=; b=JEYY6FfT7Tou8wCpeNTIITm0IxGvciqxpYqSVKXUnlo+L8VLJk7zW4o8sy/lEvc9cf RYc+3nDKcInovBPuJOLV2vJCqAi/Utou4gWV77EgSPdKGQRicI7JPu1jAB7t9vD4ZZTr vuH1EIMrs27NRkVDenD2jLYYaApWYxn5bRi8I= Received: by 10.216.180.66 with SMTP id i44mr5885624wem.95.1321532708929; Thu, 17 Nov 2011 04:25:08 -0800 (PST) Received: from Laure.box.in.chocolate-blue.net ([109.190.18.76]) by mx.google.com with ESMTPS id a27sm36537832wbp.16.2011.11.17.04.25.07 (version=SSLv3 cipher=OTHER); Thu, 17 Nov 2011 04:25:08 -0800 (PST) From: =?UTF-8?q?Beno=C3=AEt=20Canet?= To: qemu-devel@nongnu.org Date: Thu, 17 Nov 2011 13:24:59 +0100 Message-Id: <1321532700-8929-5-git-send-email-benoit.canet@gmail.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1321532700-8929-1-git-send-email-benoit.canet@gmail.com> References: <1321532700-8929-1-git-send-email-benoit.canet@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.53 Cc: =?UTF-8?q?Beno=C3=AEt=20Canet?= , avi@redhat.com Subject: [Qemu-devel] [PATCH 4/5] sh_intc: convert interrupt controller to memory API 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 Signed-off-by: Benoit Canet --- hw/sh7750.c | 2 +- hw/sh_intc.c | 87 ++++++++++++++++++++++++++++++++++---------------- hw/sh_intc.h | 7 +++- target-sh4/helper.c | 3 ++ 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/hw/sh7750.c b/hw/sh7750.c index e181305..930d212 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -756,7 +756,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu, MemoryRegion *sysmem) "cache-and-tlb", 0x08000000); memory_region_add_subregion(sysmem, 0xf0000000, &s->mmct_iomem); - sh_intc_init(&s->intc, NR_SOURCES, + sh_intc_init(sysmem, &s->intc, NR_SOURCES, _INTC_ARRAY(mask_registers), _INTC_ARRAY(prio_registers)); diff --git a/hw/sh_intc.c b/hw/sh_intc.c index e07424f..38cefc9 100644 --- a/hw/sh_intc.c +++ b/hw/sh_intc.c @@ -219,7 +219,8 @@ static void sh_intc_toggle_mask(struct intc_desc *desc, intc_enum id, #endif } -static uint32_t sh_intc_read(void *opaque, target_phys_addr_t offset) +static uint64_t sh_intc_read(void *opaque, target_phys_addr_t offset, + unsigned size) { struct intc_desc *desc = opaque; intc_enum *enum_ids = NULL; @@ -238,7 +239,7 @@ static uint32_t sh_intc_read(void *opaque, target_phys_addr_t offset) } static void sh_intc_write(void *opaque, target_phys_addr_t offset, - uint32_t value) + uint64_t value, unsigned size) { struct intc_desc *desc = opaque; intc_enum *enum_ids = NULL; @@ -282,16 +283,10 @@ static void sh_intc_write(void *opaque, target_phys_addr_t offset, #endif } -static CPUReadMemoryFunc * const sh_intc_readfn[] = { - sh_intc_read, - sh_intc_read, - sh_intc_read -}; - -static CPUWriteMemoryFunc * const sh_intc_writefn[] = { - sh_intc_write, - sh_intc_write, - sh_intc_write +static const struct MemoryRegionOps sh_intc_ops = { + .read = sh_intc_read, + .write = sh_intc_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id) @@ -302,15 +297,36 @@ struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id) return NULL; } -static void sh_intc_register(struct intc_desc *desc, - unsigned long address) +static unsigned int sh_intc_register(MemoryRegion *sysmem, + struct intc_desc *desc, + const unsigned long address, + const char *type, + const char *action, + const unsigned int index) { - if (address) { - cpu_register_physical_memory_offset(P4ADDR(address), 4, - desc->iomemtype, INTC_A7(address)); - cpu_register_physical_memory_offset(A7ADDR(address), 4, - desc->iomemtype, INTC_A7(address)); + char name[60]; + MemoryRegion *iomem, *iomem_p4, *iomem_a7; + + if (!address) { + return 0; } + + iomem = &desc->iomem; + iomem_p4 = desc->iomem_aliases + index; + iomem_a7 = iomem_p4 + 1; + +#define SH_INTC_IOMEM_FORMAT "interrupt-controller-%s-%s-%s" + snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "p4"); + memory_region_init_alias(iomem_p4, name, iomem, INTC_A7(address), 4); + memory_region_add_subregion(sysmem, P4ADDR(address), iomem_p4); + + snprintf(name, sizeof(name), SH_INTC_IOMEM_FORMAT, type, action, "a7"); + memory_region_init_alias(iomem_a7, name, iomem, INTC_A7(address), 4); + memory_region_add_subregion(sysmem, A7ADDR(address), iomem_a7); +#undef SH_INTC_IOMEM_FORMAT + + /* used to increment aliases index */ + return 2; } static void sh_intc_register_source(struct intc_desc *desc, @@ -415,14 +431,15 @@ void sh_intc_register_sources(struct intc_desc *desc, } } -int sh_intc_init(struct intc_desc *desc, +int sh_intc_init(MemoryRegion *sysmem, + struct intc_desc *desc, int nr_sources, struct intc_mask_reg *mask_regs, int nr_mask_regs, struct intc_prio_reg *prio_regs, int nr_prio_regs) { - unsigned int i; + unsigned int i, j; desc->pending = 0; desc->nr_sources = nr_sources; @@ -430,7 +447,11 @@ int sh_intc_init(struct intc_desc *desc, desc->nr_mask_regs = nr_mask_regs; desc->prio_regs = prio_regs; desc->nr_prio_regs = nr_prio_regs; + /* Allocate 4 MemoryRegions per register (2 actions * 2 aliases). */ + desc->iomem_aliases = g_new0(MemoryRegion, + (nr_mask_regs + nr_prio_regs) * 4); + j = 0; i = sizeof(struct intc_source) * nr_sources; desc->sources = g_malloc0(i); @@ -442,15 +463,19 @@ int sh_intc_init(struct intc_desc *desc, desc->irqs = qemu_allocate_irqs(sh_intc_set_irq, desc, nr_sources); - desc->iomemtype = cpu_register_io_memory(sh_intc_readfn, - sh_intc_writefn, desc, - DEVICE_NATIVE_ENDIAN); + memory_region_init_io(&desc->iomem, &sh_intc_ops, desc, + "interrupt-controller", 0x100000000ULL); + +#define INT_REG_PARAMS(reg_struct, type, action, j) \ + reg_struct->action##_reg, #type, #action, j if (desc->mask_regs) { for (i = 0; i < desc->nr_mask_regs; i++) { struct intc_mask_reg *mr = desc->mask_regs + i; - sh_intc_register(desc, mr->set_reg); - sh_intc_register(desc, mr->clr_reg); + j += sh_intc_register(sysmem, desc, + INT_REG_PARAMS(mr, mask, set, j)); + j += sh_intc_register(sysmem, desc, + INT_REG_PARAMS(mr, mask, clr, j)); } } @@ -458,10 +483,16 @@ int sh_intc_init(struct intc_desc *desc, for (i = 0; i < desc->nr_prio_regs; i++) { struct intc_prio_reg *pr = desc->prio_regs + i; - sh_intc_register(desc, pr->set_reg); - sh_intc_register(desc, pr->clr_reg); + j += sh_intc_register(sysmem, desc, + INT_REG_PARAMS(pr, prio, set, j)); + j += sh_intc_register(sysmem, desc, + INT_REG_PARAMS(pr, prio, clr, j)); } } +#undef INT_REG_PARAMS + /* free unused MemoryRegions */ + desc->iomem_aliases = g_realloc(desc->iomem_aliases, + sizeof(MemoryRegion)*j); return 0; } diff --git a/hw/sh_intc.h b/hw/sh_intc.h index c117d6f..8916e8c 100644 --- a/hw/sh_intc.h +++ b/hw/sh_intc.h @@ -3,6 +3,7 @@ #include "qemu-common.h" #include "irq.h" +#include "exec-memory.h" typedef unsigned char intc_enum; @@ -46,6 +47,8 @@ struct intc_source { }; struct intc_desc { + MemoryRegion iomem; + MemoryRegion *iomem_aliases; qemu_irq *irqs; struct intc_source *sources; int nr_sources; @@ -53,7 +56,6 @@ struct intc_desc { int nr_mask_regs; struct intc_prio_reg *prio_regs; int nr_prio_regs; - int iomemtype; int pending; /* number of interrupt sources that has pending set */ }; @@ -68,7 +70,8 @@ void sh_intc_register_sources(struct intc_desc *desc, struct intc_group *groups, int nr_groups); -int sh_intc_init(struct intc_desc *desc, +int sh_intc_init(MemoryRegion *sysmem, + struct intc_desc *desc, int nr_sources, struct intc_mask_reg *mask_regs, int nr_mask_regs, diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 5a1e15e..f4dda48 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -24,7 +24,10 @@ #include #include "cpu.h" + +#if !defined(CONFIG_USER_ONLY) #include "hw/sh_intc.h" +#endif #if defined(CONFIG_USER_ONLY)