From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46693) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTGb8-0003aI-V2 for qemu-devel@nongnu.org; Tue, 09 Feb 2016 17:17:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aTGb4-0000wj-3y for qemu-devel@nongnu.org; Tue, 09 Feb 2016 17:17:26 -0500 Received: from mail-sn1nam02on0040.outbound.protection.outlook.com ([104.47.36.40]:64992 helo=NAM02-SN1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTGb3-0000wV-TI for qemu-devel@nongnu.org; Tue, 09 Feb 2016 17:17:22 -0500 From: Alistair Francis Date: Tue, 9 Feb 2016 14:14:43 -0800 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [PATCH v4 03/16] register: Add Memory API glue List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, peter.maydell@linaro.org 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 From: Peter Crosthwaite 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. Signed-off-by: Peter Crosthwaite Signed-off-by: Alistair Francis --- hw/core/register.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/register.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/hw/core/register.c b/hw/core/register.c index 7e47df5..9cd50c8 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -150,3 +150,51 @@ 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) +{ + RegisterInfo *reg = opaque; + uint64_t we = ~0; + int shift = 0; + + if (reg->data_size != size) { + we = (size == 8) ? ~0ull : (1ull << size * 8) - 1; + shift = 8 * (be ? reg->data_size - size - addr : addr); + } + + assert(size + addr <= reg->data_size); + register_write(reg, value << shift, we << shift); +} + +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) +{ + RegisterInfo *reg = opaque; + int shift = 8 * (be ? reg->data_size - size - addr : addr); + + return register_read(reg) >> shift; +} + +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 444239c..9aa9cfc 100644 --- a/include/hw/register.h +++ b/include/hw/register.h @@ -69,9 +69,14 @@ struct RegisterAccessInfo { * @prefix: String prefix for log and debug messages * * @opaque: Opaque data for the register + * + * @mem: optional Memory region for the register */ struct RegisterInfo { + /* */ + MemoryRegion mem; + /* */ void *data; int data_size; @@ -108,4 +113,30 @@ uint64_t register_read(RegisterInfo *reg); 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 -- 2.5.0