From patchwork Mon Jul 4 12:22:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 9212555 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4AB5D60467 for ; Mon, 4 Jul 2016 12:46:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 37C94285A5 for ; Mon, 4 Jul 2016 12:46:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2A75E285F8; Mon, 4 Jul 2016 12:46:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 8FC35285A5 for ; Mon, 4 Jul 2016 12:46:13 +0000 (UTC) Received: from localhost ([::1]:47312 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK3GO-0005Kc-KN for patchwork-qemu-devel@patchwork.kernel.org; Mon, 04 Jul 2016 08:46:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43387) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK2u3-00031e-0F for qemu-devel@nongnu.org; Mon, 04 Jul 2016 08:23:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bK2u0-0004PB-3b for qemu-devel@nongnu.org; Mon, 04 Jul 2016 08:23:05 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:58075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bK2tz-0004O4-SC for qemu-devel@nongnu.org; Mon, 04 Jul 2016 08:23:04 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1bK2tx-00019F-4d for qemu-devel@nongnu.org; Mon, 04 Jul 2016 13:23:01 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 4 Jul 2016 13:22:44 +0100 Message-Id: <1467634974-32638-14-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1467634974-32638-1-git-send-email-peter.maydell@linaro.org> References: <1467634974-32638-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 13/23] register: Add block initialise helper 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: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Peter Crosthwaite Add a helper that will scan a static RegisterAccessInfo Array and populate a container MemoryRegion with registers as defined. Signed-off-by: Peter Crosthwaite Signed-off-by: Alistair Francis Message-id: 347b810b2799e413c98d5bbeca97bcb1557946c3.1467053537.git.alistair.francis@xilinx.com Signed-off-by: Peter Maydell --- hw/core/register.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/hw/register.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/hw/core/register.c b/hw/core/register.c index c7d7103..4bfbc50 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -229,6 +229,51 @@ uint64_t register_read_memory(void *opaque, hwaddr addr, return extract64(read_val, 0, size * 8); } +RegisterInfoArray *register_init_block32(DeviceState *owner, + const RegisterAccessInfo *rae, + int num, RegisterInfo *ri, + uint32_t *data, + const MemoryRegionOps *ops, + bool debug_enabled, + uint64_t memory_size) +{ + const char *device_prefix = object_get_typename(OBJECT(owner)); + RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1); + int i; + + r_array->r = g_new0(RegisterInfo *, num); + r_array->num_elements = num; + r_array->debug = debug_enabled; + r_array->prefix = device_prefix; + + for (i = 0; i < num; i++) { + int index = rae[i].addr / 4; + RegisterInfo *r = &ri[index]; + + *r = (RegisterInfo) { + .data = &data[index], + .data_size = sizeof(uint32_t), + .access = &rae[i], + .opaque = owner, + }; + register_init(r); + + r_array->r[i] = r; + } + + memory_region_init_io(&r_array->mem, OBJECT(owner), ops, r_array, + device_prefix, memory_size); + + return r_array; +} + +void register_finalize_block(RegisterInfoArray *r_array) +{ + object_unparent(OBJECT(&r_array->mem)); + g_free(r_array->r); + g_free(r_array); +} + static const TypeInfo register_info = { .name = TYPE_REGISTER, .parent = TYPE_DEVICE, diff --git a/include/hw/register.h b/include/hw/register.h index 61c53fb..8c12233 100644 --- a/include/hw/register.h +++ b/include/hw/register.h @@ -100,6 +100,8 @@ struct RegisterInfo { */ struct RegisterInfoArray { + MemoryRegion mem; + int num_elements; RegisterInfo **r; @@ -166,6 +168,44 @@ void register_write_memory(void *opaque, hwaddr addr, uint64_t value, uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size); +/** + * Init a block of registers into a container MemoryRegion. A + * number of constant register definitions are parsed to create a corresponding + * array of RegisterInfo's. + * + * @owner: device owning the registers + * @rae: Register definitions to init + * @num: number of registers to init (length of @rae) + * @ri: Register array to init, must already be allocated + * @data: Array to use for register data, must already be allocated + * @ops: Memory region ops to access registers. + * @debug enabled: turn on/off verbose debug information + * returns: A structure containing all of the registers and an initialized + * memory region (r_array->mem) the caller should add to a container. + */ + +RegisterInfoArray *register_init_block32(DeviceState *owner, + const RegisterAccessInfo *rae, + int num, RegisterInfo *ri, + uint32_t *data, + const MemoryRegionOps *ops, + bool debug_enabled, + uint64_t memory_size); + +/** + * This function should be called to cleanup the registers that were initialized + * when calling register_init_block32(). This function should only be called + * from the device's instance_finalize function. + * + * Any memory operations that the device performed that require cleanup (such + * as creating subregions) need to be called before calling this function. + * + * @r_array: A structure containing all of the registers, as returned by + * register_init_block32() + */ + +void register_finalize_block(RegisterInfoArray *r_array); + /* Define constants for a 32 bit register */ /* This macro will define A_FOO, for the byte address of a register