From patchwork Thu May 12 22:45:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alistair Francis X-Patchwork-Id: 9086661 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 48D1F9F1C1 for ; Thu, 12 May 2016 22:52:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7D7C5201FE for ; Thu, 12 May 2016 22:52:11 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7484620142 for ; Thu, 12 May 2016 22:52:10 +0000 (UTC) Received: from localhost ([::1]:60104 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0zSi-00024C-VM for patchwork-qemu-devel@patchwork.kernel.org; Thu, 12 May 2016 18:52:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55832) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0zQC-0006FE-Na for qemu-devel@nongnu.org; Thu, 12 May 2016 18:49:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b0zQ8-0002Hd-Ac for qemu-devel@nongnu.org; Thu, 12 May 2016 18:49:31 -0400 Received: from mail-sn1nam02on0058.outbound.protection.outlook.com ([104.47.36.58]:47456 helo=NAM02-SN1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b0zQ8-0002HW-2J for qemu-devel@nongnu.org; Thu, 12 May 2016 18:49:28 -0400 Received: from SN1NAM02FT003.eop-nam02.prod.protection.outlook.com (10.152.72.58) by SN1NAM02HT015.eop-nam02.prod.protection.outlook.com (10.152.73.91) with Microsoft SMTP Server (TLS) id 15.1.492.8; Thu, 12 May 2016 22:49:26 +0000 Authentication-Results: spf=fail (sender IP is 149.199.60.96) smtp.mailfrom=xilinx.com; linaro.org; dkim=none (message not signed) header.d=none; linaro.org; dmarc=none action=none header.from=xilinx.com; Received-SPF: Fail (protection.outlook.com: domain of xilinx.com does not designate 149.199.60.96 as permitted sender) receiver=protection.outlook.com; client-ip=149.199.60.96; helo=xsj-tvapsmtpgw01; Received: from xsj-tvapsmtpgw01 (149.199.60.96) by SN1NAM02FT003.mail.protection.outlook.com (10.152.73.29) with Microsoft SMTP Server (TLS) id 15.1.492.8 via Frontend Transport; Thu, 12 May 2016 22:49:25 +0000 Received: from 172-16-1-203.xilinx.com ([172.16.1.203]:57345 helo=xsj-tvapsmtp02.xilinx.com) by xsj-tvapsmtpgw01 with esmtp (Exim 4.63) (envelope-from ) id 1b0zQ5-0007gX-BY; Thu, 12 May 2016 15:49:25 -0700 Received: from [127.0.0.1] (port=37952 helo=tsj-smtp-dlp1.xlnx.xilinx.com) by xsj-tvapsmtp02.xilinx.com with esmtp (Exim 4.63) (envelope-from ) id 1b0zQ5-0005f6-8K; Thu, 12 May 2016 15:49:25 -0700 Received: from xsj-tvapsmtp02 (xsj-tvapsmtp02.xilinx.com [172.16.1.203]) by tsj-smtp-dlp1.xlnx.xilinx.com (8.13.8/8.13.1) with ESMTP id u4CMh9bt016001; Thu, 12 May 2016 15:43:09 -0700 Received: from [172.19.74.182] (port=36114 helo=xsjalistai50.xlnx.xilinx.com) by xsj-tvapsmtp02 with esmtp (Exim 4.63) (envelope-from ) id 1b0zQ4-0005f3-EI; Thu, 12 May 2016 15:49:24 -0700 From: Alistair Francis To: , Date: Thu, 12 May 2016 15:45:58 -0700 Message-ID: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: X-RCIS-Action: ALLOW X-TM-AS-MML: disable X-TM-AS-Product-Ver: IMSS-7.1.0.1679-8.0.0.1202-22316.005 X-TM-AS-Result: No--9.651-7.0-31-10 X-imss-scan-details: No--9.651-7.0-31-10 X-TMASE-MatchedRID: NKGAuCCEJLOLwgJA7qJvFMnUT+eskUQPXs5nqGvDCfMTI3pLuil/foqN otXYNqA4kZ3T6ylBNAWvXn8ZlTtgDIRSqwm2ppCS3fn7n/ZHGqY7r2Gtb9iBYfFJXtgF4GFL3oz JRX7b4NnZo4bjogR4BhvcyOf/aYw3WU/fB/XFmJyHZXNSWjgdU+4dka7CjortQmK0/Pu7TUhPH2 OEh/+ebKNQ9G8CoCSLQnNuvhHhnyVFeTvsZXlu3QhWgIsZuXlPpfVcx39Kq+7ANHjiWWI+7e1YG 8CzyTZe7vMJVbwsM0eAMuqetGVetnyef22ep6XYOwBXM346/+wQfLfQK8mRSCcG31mFiP7c8Owt z6/g1FENTJ2tru9n+O7w4jhQCIJ9 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:149.199.60.96; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(1110001)(1109001)(339900001)(199003)(189002)(9170700003)(50226002)(87936001)(64026002)(8936002)(33646002)(36756003)(50986999)(76176999)(105606002)(92566002)(9786002)(47776003)(586003)(229853001)(86362001)(50466002)(5003600100002)(118296001)(5001770100001)(81166006)(71366001)(11100500001)(5008740100001)(106466001)(5003940100001)(1220700001)(2950100001)(189998001)(4326007)(2906002)(77096005)(85426001)(6806005)(19580395003)(19580405001)(48376002)(107986001); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1NAM02HT015; H:xsj-tvapsmtpgw01; FPR:; SPF:Fail; MLV:sfv; A:1; MX:1; LANG:en; MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 2f091f74-e7f0-49e9-c122-08d37ab7ab54 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1NAM02HT015; X-Microsoft-Antispam-PRVS: <35c4a960fbc24a3d9c68167c91f429c7@SN1NAM02HT015.eop-nam02.prod.protection.outlook.com> X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13017025)(13015025)(13018025)(13023025)(13024025)(5005006)(8121501046)(10201501046)(3002001)(6055026); SRVR:SN1NAM02HT015; BCL:0; PCL:0; RULEID:; SRVR:SN1NAM02HT015; X-Forefront-PRVS: 0940A19703 X-OriginatorOrg: xilinx.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 May 2016 22:49:25.8152 (UTC) X-MS-Exchange-CrossTenant-Id: 657af505-d5df-48d0-8300-c31994686c5c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=657af505-d5df-48d0-8300-c31994686c5c; Ip=[149.199.60.96]; Helo=[xsj-tvapsmtpgw01] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1NAM02HT015 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.36.58 Subject: [Qemu-devel] [PATCH v6 03/13] register: Add Memory API glue 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: edgar.iglesias@xilinx.com, alistair.francis@xilinx.com, crosthwaitepeter@gmail.com, edgar.iglesias@gmail.com, alex.bennee@linaro.org, afaerber@suse.de, fred.konrad@greensocs.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add memory io handlers that glue the register API to the memory API. Just translation functions at this stage. Although it does allow for devices to be created without all-in-one mmio r/w handlers. This patch also adds the RegisterInfoArray struct, which allows all of the individual RegisterInfo structs to be grouped into a single memory region. Signed-off-by: Peter Crosthwaite Signed-off-by: Alistair Francis --- V6: - Add the memory region later V5: - Convert to using only one memory region hw/core/register.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/register.h | 50 +++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/hw/core/register.c b/hw/core/register.c index 5e6f621..25196e6 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -147,3 +147,75 @@ void register_reset(RegisterInfo *reg) register_write_val(reg, reg->access->reset); } + +static inline void register_write_memory(void *opaque, hwaddr addr, + uint64_t value, unsigned size, bool be) +{ + RegisterInfoArray *reg_array = opaque; + RegisterInfo *reg = NULL; + uint64_t we = ~0; + int i, shift = 0; + + for (i = 0; i < reg_array->num_elements; i++) { + if (reg_array->r[i]->access->decode.addr == addr) { + reg = reg_array->r[i]; + break; + } + } + assert(reg); + + /* Generate appropriate write enable mask and shift values */ + if (reg->data_size < size) { + we = MAKE_64BIT_MASK(0, reg->data_size * 8); + shift = 8 * (be ? reg->data_size - size : 0); + } else if (reg->data_size >= size) { + we = MAKE_64BIT_MASK(0, size * 8); + } + + register_write(reg, value << shift, we << shift, reg_array->prefix, + reg_array->debug); +} + +void register_write_memory_be(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + register_write_memory(opaque, addr, value, size, true); +} + + +void register_write_memory_le(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + register_write_memory(opaque, addr, value, size, false); +} + +static inline uint64_t register_read_memory(void *opaque, hwaddr addr, + unsigned size, bool be) +{ + RegisterInfoArray *reg_array = opaque; + RegisterInfo *reg = NULL; + int i, shift; + + for (i = 0; i < reg_array->num_elements; i++) { + if (reg_array->r[i]->access->decode.addr == addr) { + reg = reg_array->r[i]; + break; + } + } + assert(reg); + + shift = 8 * (be ? reg->data_size - size : 0); + + return (register_read(reg, reg_array->prefix, reg_array->debug) >> shift) & + MAKE_64BIT_MASK(0, size * 8); +} + +uint64_t register_read_memory_be(void *opaque, hwaddr addr, unsigned size) +{ + return register_read_memory(opaque, addr, size, true); +} + +uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned size) +{ + return register_read_memory(opaque, addr, size, false); +} diff --git a/include/hw/register.h b/include/hw/register.h index 07d0616..786707b 100644 --- a/include/hw/register.h +++ b/include/hw/register.h @@ -15,6 +15,7 @@ typedef struct RegisterInfo RegisterInfo; typedef struct RegisterAccessInfo RegisterAccessInfo; +typedef struct RegisterInfoArray RegisterInfoArray; /** * Access description for a register that is part of guest accessible device @@ -51,6 +52,10 @@ struct RegisterAccessInfo { void (*post_write)(RegisterInfo *reg, uint64_t val); uint64_t (*post_read)(RegisterInfo *reg, uint64_t val); + + struct { + hwaddr addr; + } decode; }; /** @@ -79,6 +84,25 @@ struct RegisterInfo { }; /** + * This structure is used to group all of the individual registers which are + * modeled using the RegisterInfo strucutre. + * + * @r is an aray containing of all the relevent RegisterInfo structures. + * + * @num_elements is the number of elements in the array r + * + * @mem: optional Memory region for the register + */ + +struct RegisterInfoArray { + int num_elements; + RegisterInfo **r; + + bool debug; + const char *prefix; +}; + +/** * write a value to a register, subject to its restrictions * @reg: register to write to * @val: value to write @@ -107,4 +131,30 @@ uint64_t register_read(RegisterInfo *reg, const char* prefix, bool debug); void register_reset(RegisterInfo *reg); +/** + * Memory API MMIO write handler that will write to a Register API register. + * _be for big endian variant and _le for little endian. + * @opaque: RegisterInfo to write to + * @addr: Address to write + * @value: Value to write + * @size: Number of bytes to write + */ + +void register_write_memory_be(void *opaque, hwaddr addr, uint64_t value, + unsigned size); +void register_write_memory_le(void *opaque, hwaddr addr, uint64_t value, + unsigned size); + +/** + * Memory API MMIO read handler that will read from a Register API register. + * _be for big endian variant and _le for little endian. + * @opaque: RegisterInfo to read from + * @addr: Address to read + * @size: Number of bytes to read + * returns: Value read from register + */ + +uint64_t register_read_memory_be(void *opaque, hwaddr addr, unsigned size); +uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned size); + #endif