From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55096) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aORRI-0004Sr-Ky for qemu-devel@nongnu.org; Wed, 27 Jan 2016 09:51:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aORRE-0007o2-7e for qemu-devel@nongnu.org; Wed, 27 Jan 2016 09:51:20 -0500 Received: from greensocs.com ([193.104.36.180]:43537) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aORRD-0007nh-UM for qemu-devel@nongnu.org; Wed, 27 Jan 2016 09:51:16 -0500 References: From: KONRAD Frederic Message-ID: <56A8D961.3000402@greensocs.com> Date: Wed, 27 Jan 2016 15:51:13 +0100 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v2 03/16] register: Add Memory API glue List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alistair Francis , qemu-devel@nongnu.org Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, crosthwaitepeter@gmail.com, afaerber@suse.de, edgar.iglesias@gmail.com Le 19/01/2016 23:35, Alistair Francis a =E9crit : > 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 > --- > changed from v2: > Added fast path to register_write_memory to skip endianness bitbashing > > hw/core/register.c | 48 ++++++++++++++++++++++++++++++++++++++++++= ++++++ > include/hw/register.h | 30 ++++++++++++++++++++++++++++++ > 2 files changed, 78 insertions(+) > > diff --git a/hw/core/register.c b/hw/core/register.c > index 02a4376..ca10cff 100644 > --- a/hw/core/register.c > +++ b/hw/core/register.c > @@ -184,3 +184,51 @@ void register_reset(RegisterInfo *reg) > =20 > 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 =3D opaque; Doesn't that need the QOM REGISTER(obj) conversion defined in patch 6? Fred > + uint64_t we =3D ~0; > + int shift =3D 0; > + > + if (reg->data_size !=3D size) { > + we =3D (size =3D=3D 8) ? ~0ull : (1ull << size * 8) - 1; > + shift =3D 8 * (be ? reg->data_size - size - addr : addr); > + } > + > + assert(size + addr <=3D reg->data_size); > + register_write(reg, value << shift, we << shift); > +} > + > +void register_write_memory_be(void *opaque, hwaddr addr, uint64_t valu= e, > + unsigned size) > +{ > + register_write_memory(opaque, addr, value, size, true); > +} > + > + > +void register_write_memory_le(void *opaque, hwaddr addr, uint64_t valu= e, > + 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 =3D opaque; > + int shift =3D 8 * (be ? reg->data_size - size - addr : addr); > + > + return register_read(reg) >> shift; > +} > + > +uint64_t register_read_memory_be(void *opaque, hwaddr addr, unsigned s= ize) > +{ > + return register_read_memory(opaque, addr, size, true); > +} > + > +uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned s= ize) > +{ > + return register_read_memory(opaque, addr, size, false); > +} > diff --git a/include/hw/register.h b/include/hw/register.h > index 249f458..a3c41db 100644 > --- a/include/hw/register.h > +++ b/include/hw/register.h > @@ -86,6 +86,8 @@ struct RegisterAccessInfo { > * @prefix: String prefix for log and debug messages > * > * @opaque: Opaque data for the register > + * > + * @mem: optional Memory region for the register > */ > =20 > struct RegisterInfo { > @@ -103,6 +105,8 @@ struct RegisterInfo { > =20 > bool read_lite; > bool write_lite; > + > + MemoryRegion mem; > }; > =20 > /** > @@ -129,4 +133,30 @@ uint64_t register_read(RegisterInfo *reg); > =20 > void register_reset(RegisterInfo *reg); > =20 > +/** > + * Memory API MMIO write handler that will write to a Register API reg= ister. > + * _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 valu= e, > + unsigned size); > +void register_write_memory_le(void *opaque, hwaddr addr, uint64_t valu= e, > + unsigned size); > + > +/** > + * Memory API MMIO read handler that will read from a Register API reg= ister. > + * _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 s= ize); > +uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned s= ize); > + > #endif