From patchwork Thu Feb 19 17:53:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 441705 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 407BB14009B for ; Fri, 20 Feb 2015 04:55:02 +1100 (AEDT) Received: from localhost ([::1]:57503 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOVJU-0007T7-IO for incoming@patchwork.ozlabs.org; Thu, 19 Feb 2015 12:55:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45902) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOVI2-0005LI-Im for qemu-devel@nongnu.org; Thu, 19 Feb 2015 12:53:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YOVHr-0005zZ-O5 for qemu-devel@nongnu.org; Thu, 19 Feb 2015 12:53:30 -0500 Received: from goliath.siemens.de ([192.35.17.28]:36999) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOVHr-0005zF-Bo for qemu-devel@nongnu.org; Thu, 19 Feb 2015 12:53:19 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.14.3/8.14.3) with ESMTP id t1JHrHqW011726; Thu, 19 Feb 2015 18:53:17 +0100 Received: from md1f2u6c.ww002.siemens.net (md1f2u6c.mch.sbs.de [139.25.40.156] (may be forged)) by mail1.siemens.de (8.14.3/8.14.3) with ESMTP id t1JHrH0p030088; Thu, 19 Feb 2015 18:53:17 +0100 From: Jan Kiszka To: qemu-devel , Peter Maydell Date: Thu, 19 Feb 2015 18:53:17 +0100 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 192.35.17.28 Subject: [Qemu-devel] [PATCH v2 2/2] integrator/cp: Implement CARDIN and WPROT signals 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 This allows to use the SD card emulation of the board: Forward the signals from the pl181 top the CP control register emulation, report the current state via CP_INTREG, deliver CARDIN IRQ to the secondary interrupt controller and also support clearing that line via CP_INTREG. Signed-off-by: Jan Kiszka --- hw/arm/integratorcp.c | 58 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index c5aa1f6..39803a9 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -416,18 +416,29 @@ typedef struct ICPCtrlRegsState { /*< public >*/ MemoryRegion iomem; + + qemu_irq mmc_irq; + uint32_t intreg_state; } ICPCtrlRegsState; +#define ICP_GPIO_MMC_WPROT 0 +#define ICP_GPIO_MMC_CARDIN 1 + +#define ICP_INTREG_WPROT (1 << 0) +#define ICP_INTREG_CARDIN (1 << 3) + static uint64_t icp_control_read(void *opaque, hwaddr offset, unsigned size) { + ICPCtrlRegsState *s = opaque; + switch (offset >> 2) { case 0: /* CP_IDFIELD */ return 0x41034003; case 1: /* CP_FLASHPROG */ return 0; case 2: /* CP_INTREG */ - return 0; + return s->intreg_state; case 3: /* CP_DECODE */ return 0x11; default: @@ -439,9 +450,14 @@ static uint64_t icp_control_read(void *opaque, hwaddr offset, static void icp_control_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { + ICPCtrlRegsState *s = opaque; + switch (offset >> 2) { - case 1: /* CP_FLASHPROG */ case 2: /* CP_INTREG */ + s->intreg_state &= ~(value & ICP_INTREG_CARDIN); + qemu_set_irq(s->mmc_irq, !!(s->intreg_state & ICP_INTREG_CARDIN)); + break; + case 1: /* CP_FLASHPROG */ case 3: /* CP_DECODE */ /* Nothing interesting implemented yet. */ break; @@ -456,14 +472,39 @@ static const MemoryRegionOps icp_control_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static void icp_control_gpio_set(void *opaque, int line, int level) +{ + ICPCtrlRegsState *s = opaque; + + switch (line) { + case ICP_GPIO_MMC_WPROT: + s->intreg_state &= ~ICP_INTREG_WPROT; + if (level) { + s->intreg_state |= ICP_INTREG_WPROT; + } + break; + case ICP_GPIO_MMC_CARDIN: + /* line is released by writing to CP_INTREG */ + if (level) { + s->intreg_state |= ICP_INTREG_CARDIN; + qemu_set_irq(s->mmc_irq, 1); + } + break; + } +} + static int icp_control_init(SysBusDevice *sbd) { ICPCtrlRegsState *s = ICP_CONTROL_REGS(sbd); + DeviceState *dev = DEVICE(sbd); memory_region_init_io(&s->iomem, OBJECT(s), &icp_control_ops, s, "icp_ctrl_regs", 0x00800000); sysbus_init_mmio(sbd, &s->iomem); + qdev_init_gpio_in(dev, icp_control_gpio_set, 2); + sysbus_init_irq(sbd, &s->mmc_irq); + return 0; } @@ -489,7 +530,7 @@ static void integratorcp_init(MachineState *machine) MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); qemu_irq pic[32]; - DeviceState *dev; + DeviceState *dev, *sic, *icp; int i; Error *err = NULL; @@ -547,17 +588,22 @@ static void integratorcp_init(MachineState *machine) for (i = 0; i < 32; i++) { pic[i] = qdev_get_gpio_in(dev, i); } - sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]); + sic = sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]); sysbus_create_varargs("integrator_pit", 0x13000000, pic[5], pic[6], pic[7], NULL); sysbus_create_simple("pl031", 0x15000000, pic[8]); sysbus_create_simple("pl011", 0x16000000, pic[1]); sysbus_create_simple("pl011", 0x17000000, pic[2]); - sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000, NULL); + icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000, + qdev_get_gpio_in(sic, 3)); sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]); sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]); sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0); - sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL); + + dev = sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL); + qdev_connect_gpio_out(dev, 0, qdev_get_gpio_in(icp, ICP_GPIO_MMC_WPROT)); + qdev_connect_gpio_out(dev, 1, qdev_get_gpio_in(icp, ICP_GPIO_MMC_CARDIN)); + if (nd_table[0].used) smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);