From patchwork Mon Jul 4 12:18:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 644087 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 3rjmT75QZ7z9s9r for ; Mon, 4 Jul 2016 22:26:03 +1000 (AEST) Received: from localhost ([::1]:47195 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK2wp-0008JM-OH for incoming@patchwork.ozlabs.org; Mon, 04 Jul 2016 08:25:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42781) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK2rO-0007VV-3E for qemu-devel@nongnu.org; Mon, 04 Jul 2016 08:20:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bK2rI-0003v0-1c for qemu-devel@nongnu.org; Mon, 04 Jul 2016 08:20:21 -0400 Received: from 11.mo3.mail-out.ovh.net ([87.98.184.158]:56007) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK2rH-0003ul-Om for qemu-devel@nongnu.org; Mon, 04 Jul 2016 08:20:15 -0400 Received: from player761.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo3.mail-out.ovh.net (Postfix) with ESMTP id D67E7FFBEC4 for ; Mon, 4 Jul 2016 14:20:14 +0200 (CEST) Received: from hermes.kaod.org (LFbn-1-2234-107.w90-76.abo.wanadoo.fr [90.76.55.107]) (Authenticated sender: clg@kaod.org) by player761.ha.ovh.net (Postfix) with ESMTPSA id 037B74800A3; Mon, 4 Jul 2016 14:20:03 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell , Peter Crosthwaite Date: Mon, 4 Jul 2016 14:18:56 +0200 Message-Id: <1467634738-28642-6-git-send-email-clg@kaod.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1467634738-28642-1-git-send-email-clg@kaod.org> References: <1467634738-28642-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 6087459325574023953 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeltddrvddvgdegkecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 87.98.184.158 Subject: [Qemu-devel] [PATCH 5/7] ast2400: handle SPI flash Command mode (read only) 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: Andrew Jeffery , qemu-arm@nongnu.org, qemu-devel@nongnu.org, mar.krzeminski@gmail.com, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" To handle memory accesses when the SPI flash slave is configured in Command mode, let's change the memory region of the SPI flash object to a ROM memory region (like the pflash_cfi* object). The m25p80 flash object creation is changed accordingly to use the new memory region as a storage. Only read only accesses are handled. Supporting write accesses would demand using internal routines of the m25p80 flash model. This is not required for the moment. Signed-off-by: Cédric Le Goater --- hw/arm/palmetto-bmc.c | 2 ++ hw/ssi/aspeed_smc.c | 60 +++++++++++++++++++++++++++++++++++++++++---- include/hw/ssi/aspeed_smc.h | 1 + 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c index c0bb922f6406..b00757dcbc69 100644 --- a/hw/arm/palmetto-bmc.c +++ b/hw/arm/palmetto-bmc.c @@ -20,6 +20,7 @@ #include "qemu/log.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" +#include "hw/block/flash.h" static struct arm_boot_info palmetto_bmc_binfo = { .loader_start = AST2400_SDRAM_BASE, @@ -51,6 +52,7 @@ static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char *flashtype, qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo), errp); } + m25p80_set_rom_storage(fl->flash, &fl->mmio); qdev_init_nofail(fl->flash); cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0); diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index cb0b23750bcf..f88edf953dee 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -23,11 +23,13 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "sysemu/sysemu.h" #include "qemu/log.h" #include "include/qemu/error-report.h" #include "exec/address-spaces.h" +#include "hw/block/flash.h" #include "hw/ssi/aspeed_smc.h" @@ -198,6 +200,37 @@ static inline bool aspeed_smc_is_writable(const AspeedSMCState *s, int cs) return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + cs)); } +/* + * Sanity checks on the command mode and the SPI flash command being + * used + */ +static inline bool aspeed_smc_check_mode(const AspeedSMCState *s, int cs) +{ + uint8_t mode = aspeed_smc_flash_mode(s, cs); + uint8_t cmd = (s->regs[s->r_ctrl0 + cs] >> CTRL_CMD_SHIFT) && CTRL_CMD_MASK; + bool ret; + + switch (mode) { + case CTRL_READMODE: + ret = (cmd == 0x3 || cmd == 0x0); + break; + case CTRL_FREADMODE: + ret = true; + break; + case CTRL_WRITEMODE: + default: + ret = false; + break; + } + + if (!ret) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mode/command: %d/%d\n", + __func__, cmd, mode); + } + + return ret; +} + static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size) { AspeedSMCFlash *fl = opaque; @@ -210,9 +243,11 @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size) ret |= ssi_transfer(s->spi, 0x0) << (8 * i); } } else { - qemu_log_mask(LOG_UNIMP, "%s: usermode not implemented\n", - __func__); - ret = -1; + if (aspeed_smc_check_mode(s, fl->id)) { + for (i = 0; i < size; i++) { + ret = fl->storage[addr + i] << (8 * i); + } + } } return ret; @@ -336,6 +371,12 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data, */ s->regs[addr] = value; if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) { + int i; + + for (i = 0; i < s->num_cs; ++i) { + memory_region_rom_device_set_romd(&s->flashes[i].mmio, + !aspeed_smc_is_usermode(s, i)); + } aspeed_smc_update_cs(s); } } @@ -355,6 +396,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp) int i; char name[32]; hwaddr offset = 0; + Error *err = NULL; s->ctrl = mc->ctrl; @@ -409,8 +451,16 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp) fl->id = i; fl->controller = s; fl->size = s->ctrl->segments[i].size; - memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops, - fl, name, fl->size); + memory_region_init_rom_device(&fl->mmio, OBJECT(s), + &aspeed_smc_flash_ops, + fl, name, fl->size, &err); + if (err) { + error_propagate(errp, err); + return; + } + vmstate_register_ram(&fl->mmio, DEVICE(s)); + fl->storage = memory_region_get_ram_ptr(&fl->mmio); + memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio); offset += fl->size; } diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index def3b4507e75..4796b4ca0138 100644 --- a/include/hw/ssi/aspeed_smc.h +++ b/include/hw/ssi/aspeed_smc.h @@ -47,6 +47,7 @@ typedef struct AspeedSMCController { typedef struct AspeedSMCFlash { const struct AspeedSMCState *controller; + uint8_t *storage; uint8_t id; uint32_t size;