From patchwork Fri Feb 19 00:52:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Asherah Connor X-Patchwork-Id: 1441950 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=kivikakk.ee header.i=@kivikakk.ee header.a=rsa-sha256 header.s=fm3 header.b=jwGmExA4; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm2 header.b=ojvnRXSO; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DhY3d1qgzz9rx8 for ; Fri, 19 Feb 2021 11:53:33 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2366A82786; Fri, 19 Feb 2021 01:53:07 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=kivikakk.ee Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=kivikakk.ee header.i=@kivikakk.ee header.b="jwGmExA4"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="ojvnRXSO"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8C49C82790; Fri, 19 Feb 2021 01:53:06 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from wout1-smtp.messagingengine.com (wout1-smtp.messagingengine.com [64.147.123.24]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C9EBC8276E for ; Fri, 19 Feb 2021 01:53:01 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=kivikakk.ee Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ashe@kivikakk.ee Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.west.internal (Postfix) with ESMTP id A1D249CC; Thu, 18 Feb 2021 19:52:59 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Thu, 18 Feb 2021 19:53:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kivikakk.ee; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm3; bh=4pKFUYGi4bn1t hYLjeS5ntvbE0jVUEAlaXXQncxNQUs=; b=jwGmExA4C7VX62jkCd3Ln1on1aMKX ceHP+KJrfEI5taRLPAodMYIZQXN9jfua/kCKl0gPZ8nO2lCNzcTpWxXL3UHeJzEJ csPKQQlpJIeQ0RX5LQuM+SJG2t57KgkXs7PG0Dkox6UwGicllLnKzgUwiU0J1nPz GwaZ5lk0m2DjHGO/q1S944DW76fx9Qt6c5v+08G2cZ8Gyhx//Z7v0vsXhKX8b1hY 3DAcJPiFzAij/2Rbuc/+rspnv3e0X8+lrEj66KwDx65KGCq4WDtvPrfD9RSa+/sW 95WTyqr395OGKkjFCNZ8nDtVD+Ihvd34wyYqR5LqvY9v3ZUK0jyMMGIJA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=4pKFUYGi4bn1thYLjeS5ntvbE0jVUEAlaXXQncxNQUs=; b=ojvnRXSO OmvK3iekAnXkN59fjI20uBRVLmNKZoJsWba3nqg4J+erM1TmTnAyYZPBy+ugX7v9 mOygRzAyGkrqaAX4yoPh9AzxPUqIHH+v86bfnTnx8tk+rFECMYwFXSrFhy0M7end TV/fx9RhFBmlqpD6H5BPzhfCwBak0a/L+jY5SOJnTmMIn8/MKVwCQPMmR6DayH+2 y8y5znGLQwupBJtEWrgMW17Z+DilT4dhXCIAxS6U6/bVogbfGrlDRPOsgc7P6UfQ t39fVkgbClsoO2mDfQe0htLRKO8+7VAheWO8/6IJjWhEn6gDMfzGWLKpF71gCtm0 Ul0yrT+oE3fcfw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrjeehgddvjecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomheptehshhgvrhgr hhcuvehonhhnohhruceorghshhgvsehkihhvihhkrghkkhdrvggvqeenucggtffrrghtth gvrhhnpeeijeffuefgueelgeeijefhgeffvefhhfejudelfeeukeefjeeugfdvvdekieej teenucffohhmrghinhepghhithhhuhgsrdgtohhmnecukfhppeduudelrddukedrfedurd dufeehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhep rghshhgvsehkihhvihhkrghkkhdrvggv X-ME-Proxy: Received: from tapioca-debian.localdomain (119-18-31-135.77121f.mel.static.aussiebb.net [119.18.31.135]) by mail.messagingengine.com (Postfix) with ESMTPA id 1AF61108005C; Thu, 18 Feb 2021 19:52:56 -0500 (EST) From: Asherah Connor To: u-boot@lists.denx.de Cc: Asherah Connor , Bharat Gooty , Heinrich Schuchardt , Rayagonda Kokatanur , Sughosh Ganu , Tom Rini Subject: [PATCH 1/1] arm: qemu: support qfw Date: Fri, 19 Feb 2021 11:52:34 +1100 Message-Id: <20210219005235.17387-2-ashe@kivikakk.ee> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210219005235.17387-1-ashe@kivikakk.ee> References: <20210219005235.17387-1-ashe@kivikakk.ee> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Adds support for QFW on Arm platforms by checking the device tree for a "qemu,fw-cfg-mmio"-compatible node in arch_early_init_r and initialising the driver if found. Both MMIO and DMA are supported on this architecture. Signed-off-by: Asherah Connor --- arch/arm/Kconfig | 1 + arch/arm/Makefile | 1 + arch/arm/mach-qemu/Kconfig | 2 + arch/arm/mach-qemu/Makefile | 1 + arch/arm/mach-qemu/qemu.c | 109 ++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+) create mode 100644 arch/arm/mach-qemu/Makefile create mode 100644 arch/arm/mach-qemu/qemu.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d51abbeaf0..3841ae3ba2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -937,6 +937,7 @@ config ARCH_QEMU imply DM_RNG imply DM_RTC imply RTC_PL031 + imply QFW config ARCH_RMOBILE bool "Renesas ARM SoCs" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 28b523b37c..90fc3d2d1a 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -70,6 +70,7 @@ machine-$(CONFIG_ARCH_NEXELL) += nexell machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 machine-$(CONFIG_ARCH_ORION5X) += orion5x machine-$(CONFIG_ARCH_OWL) += owl +machine-$(CONFIG_ARCH_QEMU) += qemu machine-$(CONFIG_ARCH_RMOBILE) += rmobile machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig index 186c3582eb..50cbfc5efe 100644 --- a/arch/arm/mach-qemu/Kconfig +++ b/arch/arm/mach-qemu/Kconfig @@ -19,11 +19,13 @@ config TARGET_QEMU_ARM_32BIT select BOARD_LATE_INIT select CPU_V7A select SYS_ARCH_TIMER + select ARCH_EARLY_INIT_R if QFW config TARGET_QEMU_ARM_64BIT bool "ARMv8, 64bit" select ARM64 select BOARD_LATE_INIT + select ARCH_EARLY_INIT_R if QFW endchoice diff --git a/arch/arm/mach-qemu/Makefile b/arch/arm/mach-qemu/Makefile new file mode 100644 index 0000000000..5f5915fb6e --- /dev/null +++ b/arch/arm/mach-qemu/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_QFW) += qemu.o diff --git a/arch/arm/mach-qemu/qemu.c b/arch/arm/mach-qemu/qemu.c new file mode 100644 index 0000000000..742cf81d6e --- /dev/null +++ b/arch/arm/mach-qemu/qemu.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021, Asherah Connor + */ +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * on Arm, qfw registers are MMIO at offsets; see + * https://github.com/qemu/qemu/blob/1af56296/docs/specs/fw_cfg.txt + */ +struct qemu_arm_fwcfg_mmio { + /* + * Each access to the 64-bit data register can be 8/16/32/64 bits wide. + */ + union { + u8 data8; + u16 data16; + u32 data32; + u64 data64; + }; + u16 selector; + u8 padding[6]; + u64 dma; +}; + +static volatile struct qemu_arm_fwcfg_mmio *mmio; + +static void qemu_arm_fwcfg_read_entry_pio(uint16_t entry, uint32_t size, + void *address) +{ + /* + * using FW_CFG_INVALID selector will resume a previous read at its last + * offset, otherwise read will start at 0 for new selector + * + * MMIO selector register is big-endian + */ + if (entry != FW_CFG_INVALID) + mmio->selector = cpu_to_be16(entry); + + /* data register is string-preserving */ + while (size >= 8) { + *(u64 *)address = mmio->data64; + address += 8; + size -= 8; + } + while (size >= 4) { + *(u32 *)address = mmio->data32; + address += 4; + size -= 4; + } + while (size >= 2) { + *(u16 *)address = mmio->data16; + address += 2; + size -= 2; + } + while (size >= 1) { + *(u8 *)address = mmio->data8; + address += 1; + size -= 1; + } +} + +static void qemu_arm_fwcfg_read_entry_dma(struct fw_cfg_dma_access *dma) +{ + /* the DMA address register is big-endian */ + mmio->dma = cpu_to_be64((uintptr_t)dma); + + while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR) + __asm__ __volatile__ ("yield"); +} + +static struct fw_cfg_arch_ops fwcfg_arm_ops = { + .arch_read_pio = qemu_arm_fwcfg_read_entry_pio, + .arch_read_dma = qemu_arm_fwcfg_read_entry_dma +}; + +int arch_early_init_r(void) +{ + /* Try to init QFW from device tree. */ + int offset; + fdt32_t *reg; + u64 mmio_offset, mmio_size; + int addr_cells = fdt_address_cells(gd->fdt_blob, 0); + int size_cells = fdt_size_cells(gd->fdt_blob, 0); + + offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1, + "qemu,fw-cfg-mmio"); + if (offset >= 0) { + reg = (fdt32_t *)fdt_getprop(gd->fdt_blob, offset, "reg", 0); + if (reg) { + mmio_offset = fdt_read_number(reg, addr_cells); + reg += addr_cells; + mmio_size = fdt_read_number(reg, size_cells); + + /* Sanity check: at least data+selector wide. */ + if (mmio_size >= 10) { + mmio = (struct qemu_arm_fwcfg_mmio + *)mmio_offset; + qemu_fwcfg_init(&fwcfg_arm_ops); + } + } + } + + return 0; +}