Re: [Qemu-devel] [PATCH] configure: more resilient Python version capture

2019-08-24 Thread tony.nguyen
> -python_version=$($python -V 2>&1 | sed -e 's/Python\ //')
> +python_version=$(python2 -c 'import sys; print("%d.%d.%d" % 
> (sys.version_info[0], sys.version_info[1], sys.version_info[2]))' 2>/dev/null)

On a Python 3 only system, configure will no longer print the version.

e.g. 
/* snip */
install   install
pythonpython3 -B ()
slirp support git 
/* snip */

> @@ -6511,6 +6511,7 @@ if ! $python -c 'import sys; sys.exit(sys.version_info 
> < (3,0))'; then
>echo
>echo "warning: Python 2 support is deprecated" >&2 
>echo "warning: Python 3 will be required for building future versions of 
> QEMU" >&2 
> +  python2="y"
>  fi  
...
> -echo "PYTHON_VERSION=$python_version" >> $config_host_mak
> +echo "PYTHON2=$python2" >> $config_host_mak
...
> -ifneq ($(findstring v2,"v$(PYTHON_VERSION)"),v2)
> +ifneq ($(PYTHON2),y)

Succinctly, if Python 3.

We can further ween the world off Python 2 by replacing python2="y" for 
python3="y" and PYTHON2 for PYTHON3.


Re: [Qemu-devel] [PATCH v9 00/20] Invert Endian bit in SPARCv9 MMU TTE

2019-08-23 Thread tony.nguyen
On 8/22/19 12:29 PM, Richard Henderson wrote:
> So... after an hour only the cover letter has arrived.
> I'm thinking that it didn't work.

Frustratingly, I keep getting blocked.

Perhaps new GMail and Mail.com accounts sending in bulk on behalf of bt.com
falls foul of spam filters.

*sigh*

I am mindful tcg-next has a subset of the series.

Again, thanks for the patience. 

Warm Regards,
Tony


Re: [Qemu-devel] [PATCH v7 00/42] Invert Endian bit in SPARCv9 MMU TTE

2019-08-16 Thread tony.nguyen
Hi Phillippe,

On 8/16/19 7:58 PM, Philippe Mathieu-Daudé wrote:
>On 8/16/19 8:28 AM, tony.ngu...@bt.com wrote:
>> This patchset implements the IE (Invert Endian) bit in SPARCv9 MMU TTE.
>>
>> v7:
>[...]
>> - Re-declared many native endian devices as little or big endian. This is why
>>   v7 has +16 patches.
>
>Why are you doing that? What is the rational?

While collapsing the byte swaps, it was suggested in patch #11 of v5 that
consistent use of MemOp simplified endian comparisons. This lead to the
deprecation of enum device_endian by MemOp.

As MO_TE is conditional upon NEED_CPU_H, the s/DEVICE_NATIVE_ENDIAN/MO_TE/
required changing some device object files from common-obj-* to obj-*. In patch
#15 of v6 Paolo noted that most devices should not of been DEVICE_NATIVE_ENDIAN
and hinted at a clean up.

The +16 patches in v7 is the clean up effort.

>Anyhow if this not required by your series, you should split it out of
>it, and send it on your principal changes are merged.
>I'm worried because this these new patches involve many subsystems (thus
>maintainers) and reviewing them will now take a fair amount of time.

Yes, lets split these patches out. They are very much a tangent to the series
purpose.

>> For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
>> targets from the set of target/hw/*/device.o.
>>
>> If the set of targets are all little or all big endian, re-declare
>> the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
>> respectively.
>
>If only little endian targets use a device, that doesn't mean the device
>is designed in little endian...
>
>Then if a big endian target plan to use this device, it will require
>more work and you might have introduced regressions...
>
>I'm not sure this is a safe move.
>
>> This *naive* deduction may result in genuinely native endian devices
>> being incorrectly declared as little or big endian, but should not
>> introduce regressions for current targets.
>

Roger. Evidently too naive. TBH, most devices I've never heard of...

Regards,
Tony


[Qemu-devel] [PATCH v7 37/42] cputlb: Replace size and endian operands for MemOp

2019-08-16 Thread tony.nguyen
Preparation for collapsing the two byte swaps adjust_endianness and
handle_bswap into the former.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c   | 172 +--
 include/exec/memop.h |   6 ++
 memory.c |  11 +---
 3 files changed, 90 insertions(+), 99 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 0aff6a3..8022c81 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -881,7 +881,7 @@ static void tlb_fill(CPUState *cpu, target_ulong addr, int 
size,

 static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
  int mmu_idx, target_ulong addr, uintptr_t retaddr,
- MMUAccessType access_type, int size)
+ MMUAccessType access_type, MemOp op)
 {
 CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
@@ -906,15 +906,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_read(mr, mr_offset, ,
-size_memop(size) | MO_TE,
-iotlbentry->attrs);
+r = memory_region_dispatch_read(mr, mr_offset, , op, 
iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
 section->offset_within_region;

-cpu_transaction_failed(cpu, physaddr, addr, size, access_type,
+cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), 
access_type,
mmu_idx, iotlbentry->attrs, r, retaddr);
 }
 if (locked) {
@@ -926,7 +924,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,

 static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
   int mmu_idx, uint64_t val, target_ulong addr,
-  uintptr_t retaddr, int size)
+  uintptr_t retaddr, MemOp op)
 {
 CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
@@ -948,16 +946,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_write(mr, mr_offset, val,
- size_memop(size) | MO_TE,
- iotlbentry->attrs);
+r = memory_region_dispatch_write(mr, mr_offset, val, op, 
iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
 section->offset_within_region;

-cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
-   mmu_idx, iotlbentry->attrs, r, retaddr);
+cpu_transaction_failed(cpu, physaddr, addr, memop_size(op),
+   MMU_DATA_STORE, mmu_idx, iotlbentry->attrs, r,
+   retaddr);
 }
 if (locked) {
 qemu_mutex_unlock_iothread();
@@ -1218,14 +1215,15 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
  * access type.
  */

-static inline uint64_t handle_bswap(uint64_t val, int size, bool big_endian)
+static inline uint64_t handle_bswap(uint64_t val, MemOp op)
 {
-if ((big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP)) {
-switch (size) {
-case 1: return val;
-case 2: return bswap16(val);
-case 4: return bswap32(val);
-case 8: return bswap64(val);
+if ((memop_big_endian(op) && NEED_BE_BSWAP) ||
+(!memop_big_endian(op) && NEED_LE_BSWAP)) {
+switch (op & MO_SIZE) {
+case MO_8: return val;
+case MO_16: return bswap16(val);
+case MO_32: return bswap32(val);
+case MO_64: return bswap64(val);
 default:
 g_assert_not_reached();
 }
@@ -1248,7 +1246,7 @@ typedef uint64_t FullLoadHelper(CPUArchState *env, 
target_ulong addr,

 static inline uint64_t __attribute__((always_inline))
 load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
-uintptr_t retaddr, size_t size, bool big_endian, bool code_read,
+uintptr_t retaddr, MemOp op, bool code_read,
 FullLoadHelper *full_load)
 {
 uintptr_t mmu_idx = get_mmuidx(oi);
@@ -1262,6 +1260,7 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 unsigned a_bits = get_alignment_bits(get_memop(oi));
 void *haddr;
 uint64_t res;
+size_t size = memop_size(op);

 /* Handle CPU specific unaligned behaviour */
 if (addr & ((1 << a_bits) - 1)) {
@@ -1307,9 +1306,10 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 }
 }

+/* FIXME: io_readx ignores MO_BSWAP.  */
 res = io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
-   mmu_idx, addr, retaddr, 

[Qemu-devel] [PATCH v7 40/42] cputlb: Byte swap memory transaction attribute

2019-08-16 Thread tony.nguyen
Notice new attribute, byte swap, and force the transaction through the
memory slow path.

Required by architectures that can invert endianness of memory
transaction, e.g. SPARC64 has the Invert Endian TTE bit.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 accel/tcg/cputlb.c  | 11 +++
 include/exec/memattrs.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index bb2f55d..adfa4f2 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -738,6 +738,9 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong 
vaddr,
  */
 address |= TLB_RECHECK;
 }
+if (attrs.byte_swap) {
+address |= TLB_FORCE_SLOW;
+}
 if (!memory_region_is_ram(section->mr) &&
 !memory_region_is_romd(section->mr)) {
 /* IO memory case */
@@ -891,6 +894,10 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -933,6 +940,10 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index d4a3477..95f2d20 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
 unsigned int user:1;
 /* Requester ID (for MSI for example) */
 unsigned int requester_id:16;
+/* Invert endianness for this page */
+unsigned int byte_swap:1;
 /*
  * The following are target-specific page-table bits.  These are not
  * related to actual memory transactions at all.  However, this structure
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 39/42] cpu: TLB_FLAGS_MASK bit to force memory slow path

2019-08-16 Thread tony.nguyen
The fast path is taken when TLB_FLAGS_MASK is all zero.

TLB_FORCE_SLOW is simply a TLB_FLAGS_MASK bit to force the slow path,
there are no other side effects.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/cpu-all.h | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 536ea58..e496f99 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -331,12 +331,18 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #define TLB_MMIO(1 << (TARGET_PAGE_BITS - 3))
 /* Set if TLB entry must have MMU lookup repeated for every access */
 #define TLB_RECHECK (1 << (TARGET_PAGE_BITS - 4))
+/* Set if TLB entry must take the slow path.  */
+#define TLB_FORCE_SLOW  (1 << (TARGET_PAGE_BITS - 5))

 /* Use this mask to check interception with an alignment mask
  * in a TCG backend.
  */
-#define TLB_FLAGS_MASK  (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
- | TLB_RECHECK)
+#define TLB_FLAGS_MASK \
+(TLB_INVALID_MASK  \
+ | TLB_NOTDIRTY\
+ | TLB_MMIO\
+ | TLB_RECHECK \
+ | TLB_FORCE_SLOW)

 /**
  * tlb_hit_page: return true if page aligned @addr is a hit against the
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 34/42] exec: Delete device_endian

2019-08-16 Thread tony.nguyen
device_endian has been made redundant by MemOp.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/cpu-common.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 01a29ba..7eeb78c 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -18,14 +18,6 @@ void tcg_flush_softmmu_tlb(CPUState *cs);

 #include "exec/memop.h"

-enum device_endian {
-#ifdef NEED_CPU_H
-DEVICE_NATIVE_ENDIAN = MO_TE,
-#endif
-DEVICE_BIG_ENDIAN = MO_BE,
-DEVICE_LITTLE_ENDIAN = MO_LE,
-};
-
 #if defined(HOST_WORDS_BIGENDIAN)
 #define DEVICE_HOST_ENDIAN MO_BE
 #else
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 42/42] target/sparc: sun4u Invert Endian TTE bit

2019-08-16 Thread tony.nguyen
This bit configures endianness of PCI MMIO devices. It is used by
Solaris and OpenBSD sunhme drivers.

Tested working on OpenBSD.

Unfortunately Solaris 10 had a unrelated keyboard issue blocking
testing... another inch towards Solaris 10 on SPARC64 =)

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Tested-by: Mark Cave-Ayland 
---
 target/sparc/cpu.h| 2 ++
 target/sparc/mmu_helper.c | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 1406f0b..c6bafa8 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -275,6 +275,7 @@ enum {

 #define TTE_VALID_BIT   (1ULL << 63)
 #define TTE_NFO_BIT (1ULL << 60)
+#define TTE_IE_BIT  (1ULL << 59)
 #define TTE_USED_BIT(1ULL << 41)
 #define TTE_LOCKED_BIT  (1ULL <<  6)
 #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
@@ -291,6 +292,7 @@ enum {

 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
 #define TTE_IS_NFO(tte) ((tte) & TTE_NFO_BIT)
+#define TTE_IS_IE(tte)  ((tte) & TTE_IE_BIT)
 #define TTE_IS_USED(tte)((tte) & TTE_USED_BIT)
 #define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
 #define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index 826e14b..77dc86a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -537,6 +537,10 @@ static int get_physical_address_data(CPUSPARCState *env, 
hwaddr *physical,
 if (ultrasparc_tag_match(>dtlb[i], address, context, physical)) {
 int do_fault = 0;

+if (TTE_IS_IE(env->dtlb[i].tte)) {
+attrs->byte_swap = true;
+}
+
 /* access ok? */
 /* multiple bits in SFSR.FT may be set on TT_DFAULT */
 if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
@@ -792,7 +796,7 @@ void dump_mmu(CPUSPARCState *env)
 }
 if (TTE_IS_VALID(env->dtlb[i].tte)) {
 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
-", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
+", %s, %s, %s, %s, ie %s, ctx %" PRId64 " %s\n",
 i,
 env->dtlb[i].tag & (uint64_t)~0x1fffULL,
 TTE_PA(env->dtlb[i].tte),
@@ -801,6 +805,8 @@ void dump_mmu(CPUSPARCState *env)
 TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
 TTE_IS_LOCKED(env->dtlb[i].tte) ?
 "locked" : "unlocked",
+TTE_IS_IE(env->dtlb[i].tte) ?
+"yes" : "no",
 env->dtlb[i].tag & (uint64_t)0x1fffULL,
 TTE_IS_GLOBAL(env->dtlb[i].tte) ?
 "global" : "local");
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 30/42] hw/timer: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/timer/a9gtimer.c | 4 ++--
 hw/timer/arm_mptimer.c  | 4 ++--
 hw/timer/arm_timer.c| 4 ++--
 hw/timer/armv7m_systick.c   | 2 +-
 hw/timer/aspeed_rtc.c   | 2 +-
 hw/timer/cadence_ttc.c  | 2 +-
 hw/timer/grlib_gptimer.c| 2 +-
 hw/timer/hpet.c | 2 +-
 hw/timer/imx_epit.c | 2 +-
 hw/timer/imx_gpt.c  | 2 +-
 hw/timer/lm32_timer.c   | 2 +-
 hw/timer/milkymist-sysctl.c | 2 +-
 hw/timer/mss-timer.c| 2 +-
 hw/timer/pl031.c| 2 +-
 hw/timer/stm32f2xx_timer.c  | 2 +-
 hw/timer/sun4v-rtc.c| 2 +-
 16 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index 09e2a7b..8bb5f6e 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -254,7 +254,7 @@ static const MemoryRegionOps a9_gtimer_this_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const MemoryRegionOps a9_gtimer_ops = {
@@ -264,7 +264,7 @@ static const MemoryRegionOps a9_gtimer_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void a9_gtimer_reset(DeviceState *dev)
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 93044aa..9397218 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -190,7 +190,7 @@ static const MemoryRegionOps arm_thistimer_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const MemoryRegionOps timerblock_ops = {
@@ -200,7 +200,7 @@ static const MemoryRegionOps timerblock_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void timerblock_reset(TimerBlock *tb)
diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c
index f0a7534..22ce3ff 100644
--- a/hw/timer/arm_timer.c
+++ b/hw/timer/arm_timer.c
@@ -265,7 +265,7 @@ static void sp804_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps sp804_ops = {
 .read = sp804_read,
 .write = sp804_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const VMStateDescription vmstate_sp804 = {
@@ -346,7 +346,7 @@ static void icp_pit_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps icp_pit_ops = {
 .read = icp_pit_read,
 .write = icp_pit_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void icp_pit_init(Object *obj)
diff --git a/hw/timer/armv7m_systick.c b/hw/timer/armv7m_systick.c
index 9464074..3c34fd0 100644
--- a/hw/timer/armv7m_systick.c
+++ b/hw/timer/armv7m_systick.c
@@ -191,7 +191,7 @@ static MemTxResult systick_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps systick_ops = {
 .read_with_attrs = systick_read,
 .write_with_attrs = systick_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
 };
diff --git a/hw/timer/aspeed_rtc.c b/hw/timer/aspeed_rtc.c
index 19f061c..c528e47 100644
--- a/hw/timer/aspeed_rtc.c
+++ b/hw/timer/aspeed_rtc.c
@@ -130,7 +130,7 @@ static void aspeed_rtc_reset(DeviceState *d)
 static const MemoryRegionOps aspeed_rtc_ops = {
 .read = aspeed_rtc_read,
 .write = aspeed_rtc_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const VMStateDescription vmstate_aspeed_rtc = {
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index 115d935..d422efe 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -389,7 +389,7 @@ static void cadence_ttc_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps cadence_ttc_ops = {
 .read = cadence_ttc_read,
 .write = cadence_ttc_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void cadence_timer_reset(CadenceTimerState *s)
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
index e45a490..dc3b028 100644
--- a/hw/timer/grlib_gptimer.c
+++ 

[Qemu-devel] [PATCH v7 32/42] exec: Map device_endian onto MemOp

2019-08-16 Thread tony.nguyen
Preparation to replace device_endian with MemOp.

Mapping device_endian onto MemOp limits behaviour changes to this
relatively smaller patch.

The next patch will replace all device_endian usages with the
equivalent MemOp. That patch will be large but have no behaviour
changes.

A subsequent patch will then delete unused device_endian.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 hw/char/serial.c  | 18 ++
 include/exec/cpu-common.h | 10 +++---
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 7c42a2a..521c76b 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -1012,22 +1012,15 @@ static void serial_mm_write(void *opaque, hwaddr addr,
 serial_ioport_write(s, addr >> s->it_shift, value, 1);
 }

-static const MemoryRegionOps serial_mm_ops[3] = {
-[DEVICE_NATIVE_ENDIAN] = {
-.read = serial_mm_read,
-.write = serial_mm_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
-.valid.max_access_size = 8,
-.impl.max_access_size = 8,
-},
-[DEVICE_LITTLE_ENDIAN] = {
+static const MemoryRegionOps serial_mm_ops[2] = {
+[0] = {
 .read = serial_mm_read,
 .write = serial_mm_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid.max_access_size = 8,
 .impl.max_access_size = 8,
 },
-[DEVICE_BIG_ENDIAN] = {
+[1] = {
 .read = serial_mm_read,
 .write = serial_mm_write,
 .endianness = DEVICE_BIG_ENDIAN,
@@ -1053,8 +1046,9 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
 serial_realize_core(s, _fatal);
 vmstate_register(NULL, base, _serial, s);

-memory_region_init_io(>io, NULL, _mm_ops[end], s,
-  "serial", 8 << it_shift);
+memory_region_init_io(>io, NULL,
+  _mm_ops[end == DEVICE_BIG_ENDIAN],
+  s, "serial", 8 << it_shift);
 memory_region_add_subregion(address_space, base, >io);
 return s;
 }
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index f7dbe75..c388453 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -16,10 +16,14 @@ void tcg_flush_softmmu_tlb(CPUState *cs);

 #if !defined(CONFIG_USER_ONLY)

+#include "exec/memop.h"
+
 enum device_endian {
-DEVICE_NATIVE_ENDIAN,
-DEVICE_BIG_ENDIAN,
-DEVICE_LITTLE_ENDIAN,
+#ifdef NEED_CPU_H
+DEVICE_NATIVE_ENDIAN = MO_TE,
+#endif
+DEVICE_BIG_ENDIAN = MO_BE,
+DEVICE_LITTLE_ENDIAN = MO_LE,
 };

 #if defined(HOST_WORDS_BIGENDIAN)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 38/42] memory: Single byte swap along the I/O path

2019-08-16 Thread tony.nguyen
Now that MemOp has been pushed down into the memory API, and
callers are encoding endianness, we can collapse byte swaps
along the I/O path into the accelerator and target independent
adjust_endianness.

Collapsing byte swaps along the I/O path enables additional endian
inversion logic, e.g. SPARC64 Invert Endian TTE bit, with redundant
byte swaps cancelling out.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c | 42 +++--
 hw/virtio/virtio-pci.c | 10 
 memory.c   | 33 ++
 memory_ldst.inc.c  | 63 --
 4 files changed, 19 insertions(+), 129 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 8022c81..bb2f55d 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1200,38 +1200,6 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 cpu_loop_exit_atomic(env_cpu(env), retaddr);
 }

-#ifdef TARGET_WORDS_BIGENDIAN
-#define NEED_BE_BSWAP 0
-#define NEED_LE_BSWAP 1
-#else
-#define NEED_BE_BSWAP 1
-#define NEED_LE_BSWAP 0
-#endif
-
-/*
- * Byte Swap Helper
- *
- * This should all dead code away depending on the build host and
- * access type.
- */
-
-static inline uint64_t handle_bswap(uint64_t val, MemOp op)
-{
-if ((memop_big_endian(op) && NEED_BE_BSWAP) ||
-(!memop_big_endian(op) && NEED_LE_BSWAP)) {
-switch (op & MO_SIZE) {
-case MO_8: return val;
-case MO_16: return bswap16(val);
-case MO_32: return bswap32(val);
-case MO_64: return bswap64(val);
-default:
-g_assert_not_reached();
-}
-} else {
-return val;
-}
-}
-
 /*
  * Load Helpers
  *
@@ -1306,10 +1274,8 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 }
 }

-/* FIXME: io_readx ignores MO_BSWAP.  */
-res = io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
-   mmu_idx, addr, retaddr, access_type, op);
-return handle_bswap(res, op);
+return io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
+mmu_idx, addr, retaddr, access_type, op);
 }

 /* Handle slow unaligned access (it spans two pages or IO).  */
@@ -1552,10 +1518,8 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,
 }
 }

-/* FIXME: io_writex ignores MO_BSWAP.  */
 io_writex(env, _tlb(env)->d[mmu_idx].iotlb[index], mmu_idx,
-  handle_bswap(val, op),
-  addr, retaddr, op);
+  val, addr, retaddr, op);
 return;
 }

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index ad06c12..84f820d 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -542,16 +542,15 @@ void virtio_address_space_write(VirtIOPCIProxy *proxy, 
hwaddr addr,
 val = pci_get_byte(buf);
 break;
 case 2:
-val = cpu_to_le16(pci_get_word(buf));
+val = pci_get_word(buf);
 break;
 case 4:
-val = cpu_to_le32(pci_get_long(buf));
+val = pci_get_long(buf);
 break;
 default:
 /* As length is under guest control, handle illegal values. */
 return;
 }
-/* FIXME: memory_region_dispatch_write ignores MO_BSWAP.  */
 memory_region_dispatch_write(mr, addr, val, size_memop(len) | MO_LE,
  MEMTXATTRS_UNSPECIFIED);
 }
@@ -576,7 +575,6 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));

-/* FIXME: memory_region_dispatch_read ignores MO_BSWAP.  */
 memory_region_dispatch_read(mr, addr, , size_memop(len) | MO_LE,
 MEMTXATTRS_UNSPECIFIED);
 switch (len) {
@@ -584,10 +582,10 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 pci_set_byte(buf, val);
 break;
 case 2:
-pci_set_word(buf, le16_to_cpu(val));
+pci_set_word(buf, val);
 break;
 case 4:
-pci_set_long(buf, le32_to_cpu(val));
+pci_set_long(buf, val);
 break;
 default:
 /* As length is under guest control, handle illegal values. */
diff --git a/memory.c b/memory.c
index 01fd29d..ebe0066 100644
--- a/memory.c
+++ b/memory.c
@@ -343,32 +343,23 @@ static void flatview_simplify(FlatView *view)
 }
 }

-static bool memory_region_wrong_endianness(MemoryRegion *mr)
+static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-return mr->ops->endianness == MO_LE;
-#else
-return mr->ops->endianness == MO_BE;
-#endif
-}
-
-static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
-{
-if (memory_region_wrong_endianness(mr)) {
-switch (size) {
-case 1:
+if ((op & MO_BSWAP) != 

[Qemu-devel] [PATCH v7 28/42] hw/sd: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/sd/pl181.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 81b406d..f2027aa 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -449,7 +449,7 @@ static void pl181_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl181_ops = {
 .read = pl181_read,
 .write = pl181_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl181_reset(DeviceState *d)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 36/42] memory: Access MemoryRegion with endianness

2019-08-16 Thread tony.nguyen
Preparation for collapsing the two byte swaps adjust_endianness and
handle_bswap into the former.

Call memory_region_dispatch_{read|write} with endianness encoded into
the "MemOp op" operand.

This patch does not change any behaviour as
memory_region_dispatch_{read|write} is yet to handle the endianness.

Once it does handle endianness, callers with byte swaps can collapse
them into adjust_endianness.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c   |  6 --
 exec.c   |  5 +++--
 hw/intc/armv7m_nvic.c| 15 ---
 hw/s390x/s390-pci-inst.c |  6 --
 hw/vfio/pci-quirks.c |  5 +++--
 hw/virtio/virtio-pci.c   |  6 --
 memory_ldst.inc.c| 18 --
 7 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 6c83878..0aff6a3 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -906,7 +906,8 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_read(mr, mr_offset, , size_memop(size),
+r = memory_region_dispatch_read(mr, mr_offset, ,
+size_memop(size) | MO_TE,
 iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
@@ -947,7 +948,8 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_write(mr, mr_offset, val, size_memop(size),
+r = memory_region_dispatch_write(mr, mr_offset, val,
+ size_memop(size) | MO_TE,
  iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
diff --git a/exec.c b/exec.c
index 303f9a7..562fb5b 100644
--- a/exec.c
+++ b/exec.c
@@ -3335,7 +3335,8 @@ static MemTxResult flatview_write_continue(FlatView *fv, 
hwaddr addr,
potential bugs */
 val = ldn_p(buf, l);
 result |= memory_region_dispatch_write(mr, addr1, val,
-   size_memop(l), attrs);
+   size_memop(l) | MO_TE,
+   attrs);
 } else {
 /* RAM case */
 ptr = qemu_ram_ptr_length(mr->ram_block, addr1, , false);
@@ -3397,7 +3398,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr 
addr,
 release_lock |= prepare_mmio_access(mr);
 l = memory_access_size(mr, l, addr1);
 result |= memory_region_dispatch_read(mr, addr1, ,
-  size_memop(l), attrs);
+  size_memop(l) | MO_TE, 
attrs);
 stn_p(buf, l, val);
 } else {
 /* RAM case */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 975d7cc..e150f9a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2346,8 +2346,8 @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_write(mr, addr, value, size_memop(size),
-attrs);
+return memory_region_dispatch_write(mr, addr, value,
+size_memop(size) | MO_TE, attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2366,8 +2366,8 @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_read(mr, addr, data, size_memop(size),
-   attrs);
+return memory_region_dispatch_read(mr, addr, data,
+   size_memop(size) | MO_TE, attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2393,8 +2393,8 @@ static MemTxResult nvic_systick_write(void *opaque, 
hwaddr addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_write(mr, addr, value, size_memop(size),
-attrs);
+return memory_region_dispatch_write(mr, addr, value,
+size_memop(size) | MO_TE, attrs);
 }

 static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
@@ -2406,7 +2406,8 @@ static MemTxResult nvic_systick_read(void *opaque, hwaddr 
addr,

 /* Direct the 

[Qemu-devel] [PATCH v7 35/42] exec: Delete DEVICE_HOST_ENDIAN

2019-08-16 Thread tony.nguyen
DEVICE_HOST_ENDIAN is conditional upon HOST_WORDS_BIGENDIAN.

Code is cleaner if the single use of DEVICE_HOST_ENDIAN is instead
directly conditional upon HOST_WORDS_BIGENDIAN.

Signed-off-by: Tony Nguyen 
---
 include/exec/cpu-common.h | 8 
 memory.c  | 2 +-
 2 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 7eeb78c..b33dc0c 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -16,14 +16,6 @@ void tcg_flush_softmmu_tlb(CPUState *cs);

 #if !defined(CONFIG_USER_ONLY)

-#include "exec/memop.h"
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define DEVICE_HOST_ENDIAN MO_BE
-#else
-#define DEVICE_HOST_ENDIAN MO_LE
-#endif
-
 /* address in the RAM (different from a physical address) */
 #if defined(CONFIG_XEN_BACKEND)
 typedef uint64_t ram_addr_t;
diff --git a/memory.c b/memory.c
index 3cabb52..689390f 100644
--- a/memory.c
+++ b/memory.c
@@ -1362,7 +1362,7 @@ static void memory_region_ram_device_write(void *opaque, 
hwaddr addr,
 static const MemoryRegionOps ram_device_mem_ops = {
 .read = memory_region_ram_device_read,
 .write = memory_region_ram_device_write,
-.endianness = DEVICE_HOST_ENDIAN,
+.endianness = 0, /* Host endianness */
 .valid = {
 .min_access_size = 1,
 .max_access_size = 8,
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 19/42] hw/dma: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/dma/bcm2835_dma.c | 4 ++--
 hw/dma/etraxfs_dma.c | 2 +-
 hw/dma/pl080.c   | 2 +-
 hw/dma/pl330.c   | 2 +-
 hw/dma/puv3_dma.c| 2 +-
 hw/dma/sparc32_dma.c | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c
index a39e8f4..907d25c 100644
--- a/hw/dma/bcm2835_dma.c
+++ b/hw/dma/bcm2835_dma.c
@@ -288,7 +288,7 @@ static void bcm2835_dma15_write(void *opaque, hwaddr 
offset, uint64_t value,
 static const MemoryRegionOps bcm2835_dma0_ops = {
 .read = bcm2835_dma0_read,
 .write = bcm2835_dma0_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
 };
@@ -296,7 +296,7 @@ static const MemoryRegionOps bcm2835_dma0_ops = {
 static const MemoryRegionOps bcm2835_dma15_ops = {
 .read = bcm2835_dma15_read,
 .write = bcm2835_dma15_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
 };
diff --git a/hw/dma/etraxfs_dma.c b/hw/dma/etraxfs_dma.c
index 85783eb..df3ba09 100644
--- a/hw/dma/etraxfs_dma.c
+++ b/hw/dma/etraxfs_dma.c
@@ -697,7 +697,7 @@ dma_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps dma_ops = {
  .read = dma_read,
  .write = dma_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
  .valid = {
  .min_access_size = 1,
  .max_access_size = 4
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 7e57624..644eadb 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -346,7 +346,7 @@ static void pl080_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl080_ops = {
 .read = pl080_read,
 .write = pl080_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl080_reset(DeviceState *dev)
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index a56a3e7..4c51f2d 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -1493,7 +1493,7 @@ static uint64_t pl330_iomem_read(void *opaque, hwaddr 
offset,
 static const MemoryRegionOps pl330_ops = {
 .read = pl330_iomem_read,
 .write = pl330_iomem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/dma/puv3_dma.c b/hw/dma/puv3_dma.c
index 122f87a..7002373 100644
--- a/hw/dma/puv3_dma.c
+++ b/hw/dma/puv3_dma.c
@@ -75,7 +75,7 @@ static const MemoryRegionOps puv3_dma_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void puv3_dma_realize(DeviceState *dev, Error **errp)
diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index 88765d0..6b32372 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -224,7 +224,7 @@ static void dma_mem_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps dma_mem_ops = {
 .read = dma_mem_read,
 .write = dma_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 26/42] hw/net: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/net/allwinner_emac.c | 2 +-
 hw/net/imx_fec.c| 2 +-
 hw/net/lan9118.c| 4 ++--
 hw/net/lance.c  | 2 +-
 hw/net/smc91c111.c  | 2 +-
 hw/net/stellaris_enet.c | 2 +-
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index eecda52..97e22e7 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -418,7 +418,7 @@ static void aw_emac_set_link(NetClientState *nc)
 static const MemoryRegionOps aw_emac_mem_ops = {
 .read = aw_emac_read,
 .write = aw_emac_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 404154e..76d42c8 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1278,7 +1278,7 @@ static const MemoryRegionOps imx_eth_ops = {
 .write = imx_eth_write,
 .valid.min_access_size = 4,
 .valid.max_access_size = 4,
-.endianness= DEVICE_NATIVE_ENDIAN,
+.endianness= DEVICE_LITTLE_ENDIAN,
 };

 static void imx_eth_cleanup(NetClientState *nc)
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index f6120be..bb1bbb3 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -1304,13 +1304,13 @@ static uint64_t lan9118_16bit_mode_read(void *opaque, 
hwaddr offset,
 static const MemoryRegionOps lan9118_mem_ops = {
 .read = lan9118_readl,
 .write = lan9118_writel,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const MemoryRegionOps lan9118_16bit_mem_ops = {
 .read = lan9118_16bit_mode_read,
 .write = lan9118_16bit_mode_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static NetClientInfo net_lan9118_info = {
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 2978c01..d95f170 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -74,7 +74,7 @@ static uint64_t lance_mem_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps lance_mem_ops = {
 .read = lance_mem_read,
 .write = lance_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 2,
 .max_access_size = 2,
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index 4a612ee..49e4bf5 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -757,7 +757,7 @@ static const MemoryRegionOps smc91c111_mem_ops = {
 .write = smc91c111_writefn,
 .valid.min_access_size = 1,
 .valid.max_access_size = 4,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static NetClientInfo net_smc91c111_info = {
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 2f645bf..15ec227 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -456,7 +456,7 @@ static void stellaris_enet_write(void *opaque, hwaddr 
offset,
 static const MemoryRegionOps stellaris_enet_ops = {
 .read = stellaris_enet_read,
 .write = stellaris_enet_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void stellaris_enet_reset(DeviceState *dev)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 29/42] hw/ssi: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/ssi/mss-spi.c   | 2 +-
 hw/ssi/pl022.c | 2 +-
 hw/ssi/stm32f2xx_spi.c | 2 +-
 hw/ssi/xilinx_spips.c  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index 4c9da5d..71fd138 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -359,7 +359,7 @@ static void spi_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps spi_ops = {
 .read = spi_read,
 .write = spi_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
 .max_access_size = 4
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index fec73ca..10d1995 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -226,7 +226,7 @@ static void pl022_reset(DeviceState *dev)
 static const MemoryRegionOps pl022_ops = {
 .read = pl022_read,
 .write = pl022_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static int pl022_post_load(void *opaque, int version_id)
diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c
index 4249101..e1e5ab5 100644
--- a/hw/ssi/stm32f2xx_spi.c
+++ b/hw/ssi/stm32f2xx_spi.c
@@ -166,7 +166,7 @@ static void stm32f2xx_spi_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps stm32f2xx_spi_ops = {
 .read = stm32f2xx_spi_read,
 .write = stm32f2xx_spi_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const VMStateDescription vmstate_stm32f2xx_spi = {
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index b29e0a4..8cadc4e 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -1238,7 +1238,7 @@ static MemTxResult lqspi_write(void *opaque, hwaddr 
offset, uint64_t value,
 static const MemoryRegionOps lqspi_ops = {
 .read_with_attrs = lqspi_read,
 .write_with_attrs = lqspi_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 4,
 .max_access_size = 4,
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 23/42] hw/intc: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/intc/arm_gic.c | 12 ++--
 hw/intc/arm_gicv3.c   |  4 ++--
 hw/intc/etraxfs_pic.c |  2 +-
 hw/intc/imx_avic.c|  2 +-
 hw/intc/imx_gpcv2.c   |  2 +-
 hw/intc/pl190.c   |  2 +-
 hw/intc/puv3_intc.c   |  2 +-
 7 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 77427a4..283a63a 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -1999,38 +1999,38 @@ static const MemoryRegionOps gic_ops[2] = {
 {
 .read_with_attrs = gic_dist_read,
 .write_with_attrs = gic_dist_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 },
 {
 .read_with_attrs = gic_thiscpu_read,
 .write_with_attrs = gic_thiscpu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 }
 };

 static const MemoryRegionOps gic_cpu_ops = {
 .read_with_attrs = gic_do_cpu_read,
 .write_with_attrs = gic_do_cpu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const MemoryRegionOps gic_virt_ops[2] = {
 {
 .read_with_attrs = gic_thiscpu_hyp_read,
 .write_with_attrs = gic_thiscpu_hyp_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 },
 {
 .read_with_attrs = gic_thisvcpu_read,
 .write_with_attrs = gic_thisvcpu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 }
 };

 static const MemoryRegionOps gic_viface_ops = {
 .read_with_attrs = gic_do_hyp_read,
 .write_with_attrs = gic_do_hyp_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void arm_gic_realize(DeviceState *dev, Error **errp)
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
index 66eaa97..9b4d5ba 100644
--- a/hw/intc/arm_gicv3.c
+++ b/hw/intc/arm_gicv3.c
@@ -352,12 +352,12 @@ static const MemoryRegionOps gic_ops[] = {
 {
 .read_with_attrs = gicv3_dist_read,
 .write_with_attrs = gicv3_dist_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 },
 {
 .read_with_attrs = gicv3_redist_read,
 .write_with_attrs = gicv3_redist_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 }
 };

diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c
index 20e1391..d4a27d1 100644
--- a/hw/intc/etraxfs_pic.c
+++ b/hw/intc/etraxfs_pic.c
@@ -111,7 +111,7 @@ static void pic_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps pic_ops = {
 .read = pic_read,
 .write = pic_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4
diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index 83a4101..4bef842 100644
--- a/hw/intc/imx_avic.c
+++ b/hw/intc/imx_avic.c
@@ -308,7 +308,7 @@ static void imx_avic_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps imx_avic_ops = {
 .read = imx_avic_read,
 .write = imx_avic_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void imx_avic_reset(DeviceState *dev)
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
index a8b..f37e6b5 100644
--- a/hw/intc/imx_gpcv2.c
+++ b/hw/intc/imx_gpcv2.c
@@ -64,7 +64,7 @@ static void imx_gpcv2_write(void *opaque, hwaddr offset,
 static const struct MemoryRegionOps imx_gpcv2_ops = {
 .read = imx_gpcv2_read,
 .write = imx_gpcv2_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 /*
  * Our device would not work correctly if the guest was doing
diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c
index b4f31ef..e6eab1e 100644
--- a/hw/intc/pl190.c
+++ b/hw/intc/pl190.c
@@ -220,7 +220,7 @@ static void pl190_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl190_ops = {
 .read = pl190_read,
 .write = pl190_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl190_reset(DeviceState *d)
diff --git a/hw/intc/puv3_intc.c b/hw/intc/puv3_intc.c
index e2f6d98..97999cc 100644
--- 

[Qemu-devel] [PATCH v7 25/42] hw/misc: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/misc/a9scu.c| 2 +-
 hw/misc/applesmc.c | 6 +++---
 hw/misc/arm11scu.c | 2 +-
 hw/misc/arm_l2x0.c | 2 +-
 hw/misc/puv3_pm.c  | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/misc/a9scu.c b/hw/misc/a9scu.c
index 4307f00..3de8cd3 100644
--- a/hw/misc/a9scu.c
+++ b/hw/misc/a9scu.c
@@ -94,7 +94,7 @@ static void a9_scu_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps a9_scu_ops = {
 .read = a9_scu_read,
 .write = a9_scu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void a9_scu_reset(DeviceState *dev)
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 2d7eb3c..6c91f29 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -285,7 +285,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
 static const MemoryRegionOps applesmc_data_io_ops = {
 .write = applesmc_io_data_write,
 .read = applesmc_io_data_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -295,7 +295,7 @@ static const MemoryRegionOps applesmc_data_io_ops = {
 static const MemoryRegionOps applesmc_cmd_io_ops = {
 .write = applesmc_io_cmd_write,
 .read = applesmc_io_cmd_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
@@ -305,7 +305,7 @@ static const MemoryRegionOps applesmc_cmd_io_ops = {
 static const MemoryRegionOps applesmc_err_io_ops = {
 .write = applesmc_io_err_write,
 .read = applesmc_io_err_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
diff --git a/hw/misc/arm11scu.c b/hw/misc/arm11scu.c
index 84275df..59fd7c0 100644
--- a/hw/misc/arm11scu.c
+++ b/hw/misc/arm11scu.c
@@ -57,7 +57,7 @@ static void mpcore_scu_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps mpcore_scu_ops = {
 .read = mpcore_scu_read,
 .write = mpcore_scu_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void arm11_scu_realize(DeviceState *dev, Error **errp)
diff --git a/hw/misc/arm_l2x0.c b/hw/misc/arm_l2x0.c
index b88f40a..72ecf46 100644
--- a/hw/misc/arm_l2x0.c
+++ b/hw/misc/arm_l2x0.c
@@ -157,7 +157,7 @@ static void l2x0_priv_reset(DeviceState *dev)
 static const MemoryRegionOps l2x0_mem_ops = {
 .read = l2x0_priv_read,
 .write = l2x0_priv_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
  };

 static void l2x0_priv_init(Object *obj)
diff --git a/hw/misc/puv3_pm.c b/hw/misc/puv3_pm.c
index b538b4a..cd82b69 100644
--- a/hw/misc/puv3_pm.c
+++ b/hw/misc/puv3_pm.c
@@ -118,7 +118,7 @@ static const MemoryRegionOps puv3_pm_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void puv3_pm_realize(DeviceState *dev, Error **errp)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 24/42] hw/isa: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/isa/vt82c686.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 12c460590..adf65d3 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -108,7 +108,7 @@ static uint64_t superio_ioport_readb(void *opaque, hwaddr 
addr, unsigned size)
 static const MemoryRegionOps superio_ops = {
 .read = superio_ioport_readb,
 .write = superio_ioport_writeb,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 17/42] hw/char: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/char/cadence_uart.c   | 2 +-
 hw/char/escc.c   | 2 +-
 hw/char/etraxfs_ser.c| 2 +-
 hw/char/grlib_apbuart.c  | 2 +-
 hw/char/imx_serial.c | 2 +-
 hw/char/lm32_uart.c  | 2 +-
 hw/char/milkymist-uart.c | 2 +-
 hw/char/pl011.c  | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index fa25fe2..6c7b904 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -457,7 +457,7 @@ static uint64_t uart_read(void *opaque, hwaddr offset,
 static const MemoryRegionOps uart_ops = {
 .read = uart_read,
 .write = uart_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void cadence_uart_reset(DeviceState *dev)
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 8ddbb4b..36182d9 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -574,7 +574,7 @@ static uint64_t escc_mem_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps escc_mem_ops = {
 .read = escc_mem_read,
 .write = escc_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 1,
 .max_access_size = 1,
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index 9745bca..cda687b 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -155,7 +155,7 @@ ser_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps ser_ops = {
 .read = ser_read,
 .write = ser_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
index c2bb3ac..119fc84 100644
--- a/hw/char/grlib_apbuart.c
+++ b/hw/char/grlib_apbuart.c
@@ -237,7 +237,7 @@ static void grlib_apbuart_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps grlib_apbuart_ops = {
 .write  = grlib_apbuart_write,
 .read   = grlib_apbuart_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };

 static void grlib_apbuart_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 0655a95..7c66551 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -332,7 +332,7 @@ static void imx_event(void *opaque, int event)
 static const struct MemoryRegionOps imx_serial_ops = {
 .read = imx_serial_read,
 .write = imx_serial_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void imx_serial_realize(DeviceState *dev, Error **errp)
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index d047a44..2fe5f60 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -205,7 +205,7 @@ static void uart_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps uart_ops = {
 .read = uart_read,
 .write = uart_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 8a78fcc..bdb8282 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -156,7 +156,7 @@ static const MemoryRegionOps uart_mmio_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };

 static void uart_rx(void *opaque, const uint8_t *buf, int size)
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index c1ae2f3..5fb95d2 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -287,7 +287,7 @@ static void pl011_event(void *opaque, int event)
 static const MemoryRegionOps pl011_ops = {
 .read = pl011_read,
 .write = pl011_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const VMStateDescription vmstate_pl011 = {
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 41/42] target/sparc: Add TLB entry with attributes

2019-08-16 Thread tony.nguyen
Append MemTxAttrs to interfaces so we can pass along up coming Invert
Endian TTE bit on SPARC64.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 target/sparc/mmu_helper.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index cbd1e91..826e14b 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -88,7 +88,7 @@ static const int perm_table[2][8] = {
 };

 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -219,6 +219,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 target_ulong page_size;
 int error_code = 0, prot, access_index;
+MemTxAttrs attrs = {};

 /*
  * TODO: If we ever need tlb_vaddr_to_host for this target,
@@ -229,7 +230,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 assert(!probe);

 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 vaddr = address;
@@ -490,8 +491,8 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 return 0;
 }

-static int get_physical_address_data(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int rw, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -608,8 +609,8 @@ static int get_physical_address_data(CPUSPARCState *env,
 return 1;
 }

-static int get_physical_address_code(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_code(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -686,7 +687,7 @@ static int get_physical_address_code(CPUSPARCState *env,
 }

 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -716,11 +717,11 @@ static int get_physical_address(CPUSPARCState *env, 
hwaddr *physical,
 }

 if (rw == 2) {
-return get_physical_address_code(env, physical, prot, address,
+return get_physical_address_code(env, physical, prot, attrs, address,
  mmu_idx);
 } else {
-return get_physical_address_data(env, physical, prot, address, rw,
- mmu_idx);
+return get_physical_address_data(env, physical, prot, attrs, address,
+ rw, mmu_idx);
 }
 }

@@ -734,10 +735,11 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 hwaddr paddr;
 target_ulong page_size;
+MemTxAttrs attrs = {};
 int error_code = 0, prot, access_index;

 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 if (likely(error_code == 0)) {
@@ -747,7 +749,8 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
env->dmmu.mmu_primary_context,
env->dmmu.mmu_secondary_context);

-tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
+tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx,
+page_size);
 return true;
 }
 if (probe) {
@@ -849,9 +852,10 @@ static int cpu_sparc_get_phys_page(CPUSPARCState *env, 
hwaddr *phys,
 {
 target_ulong page_size;
 int prot, access_index;
+MemTxAttrs attrs = {};

-return get_physical_address(env, phys, , _index, addr, rw,
-mmu_idx, _size);
+return get_physical_address(env, phys, , _index, , addr,
+rw, mmu_idx, _size);
 }

 #if defined(TARGET_SPARC64)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 22/42] hw/input: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/input/pl050.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index b79bf16..4c0fe0b 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -137,7 +137,7 @@ static void pl050_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl050_ops = {
 .read = pl050_read,
 .write = pl050_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl050_realize(DeviceState *dev, Error **errp)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 31/42] build: Correct non-common common-obj-* to obj-*

2019-08-16 Thread tony.nguyen
Preparation for replacing device_endian with MemOp.

Device realizing code with MemorRegionOps endianness as
DEVICE_NATIVE_ENDIAN is not common code.

Corrected devices were identified by making the declaration of
DEVICE_NATIVE_ENDIAN conditional upon NEED_CPU_H and then listing
what failed to compile.

Signed-off-by: Tony Nguyen 
---
 hw/audio/Makefile.objs|  3 ++-
 hw/block/Makefile.objs|  6 +++---
 hw/char/Makefile.objs |  4 ++--
 hw/core/Makefile.objs |  2 +-
 hw/display/Makefile.objs  |  6 +++---
 hw/dma/Makefile.objs  |  6 +++---
 hw/gpio/Makefile.objs |  2 +-
 hw/i2c/Makefile.objs  |  2 +-
 hw/input/Makefile.objs|  2 +-
 hw/intc/Makefile.objs |  6 +++---
 hw/ipack/Makefile.objs|  2 +-
 hw/misc/Makefile.objs | 10 +-
 hw/net/Makefile.objs  |  2 +-
 hw/pci-host/Makefile.objs |  2 +-
 hw/scsi/Makefile.objs |  2 +-
 hw/ssi/Makefile.objs  |  2 +-
 hw/timer/Makefile.objs|  6 +++---
 hw/virtio/Makefile.objs   |  2 +-
 18 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
index 63db383..13133b4 100644
--- a/hw/audio/Makefile.objs
+++ b/hw/audio/Makefile.objs
@@ -5,7 +5,8 @@ common-obj-$(CONFIG_AC97) += ac97.o
 common-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o
 common-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o
 common-obj-$(CONFIG_CS4231A) += cs4231a.o
-common-obj-$(CONFIG_HDA) += intel-hda.o hda-codec.o
+common-obj-$(CONFIG_HDA) += hda-codec.o
+obj-$(CONFIG_HDA) += intel-hda.o

 common-obj-$(CONFIG_PCSPK) += pcspk.o
 common-obj-$(CONFIG_WM8750) += wm8750.o
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index f5f643f..04ed4d7 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -1,9 +1,9 @@
 common-obj-y += block.o cdrom.o hd-geometry.o
-common-obj-$(CONFIG_FDC) += fdc.o
+obj-$(CONFIG_FDC) += fdc.o
 common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
 common-obj-$(CONFIG_NAND) += nand.o
-common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
-common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
+obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
+obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 common-obj-$(CONFIG_XEN) += xen-block.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 02d8a66..215c02b 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -1,7 +1,6 @@
 common-obj-$(CONFIG_IPACK) += ipoctal232.o
 common-obj-$(CONFIG_ESCC) += escc.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_uart.o
-common-obj-$(CONFIG_PARALLEL) += parallel.o
 common-obj-$(CONFIG_ISA_BUS) += parallel-isa.o
 common-obj-$(CONFIG_PL011) += pl011.o
 common-obj-$(CONFIG_SERIAL) += serial.o
@@ -9,7 +8,6 @@ common-obj-$(CONFIG_SERIAL_ISA) += serial-isa.o
 common-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
 common-obj-$(CONFIG_SERIAL_PCI_MULTI) += serial-pci-multi.o
 common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
-common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
 common-obj-$(CONFIG_XEN) += xen_console.o
 common-obj-$(CONFIG_CADENCE) += cadence_uart.o

@@ -21,6 +19,8 @@ obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
 obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 obj-$(CONFIG_RASPI) += bcm2835_aux.o
+obj-$(CONFIG_PARALLEL) += parallel.o
+obj-$(CONFIG_XILINX) += xilinx_uartlite.o

 common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index f8481d9..1b336c6 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -9,7 +9,7 @@ common-obj-y += hotplug.o
 common-obj-$(CONFIG_SOFTMMU) += nmi.o
 common-obj-$(CONFIG_SOFTMMU) += vm-change-state-handler.o

-common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
+obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 common-obj-$(CONFIG_XILINX_AXI) += stream.o
 common-obj-$(CONFIG_PTIMER) += ptimer.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index a64998f..facc1d4 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -8,7 +8,7 @@ common-obj-$(CONFIG_ADS7846) += ads7846.o
 common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
 common-obj-$(call 
land,$(CONFIG_VGA_CIRRUS),$(CONFIG_VGA_ISA))+=cirrus_vga_isa.o
 common-obj-$(CONFIG_G364FB) += g364fb.o
-common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
+obj-$(CONFIG_JAZZ_LED) += jazz_led.o
 common-obj-$(CONFIG_PL110) += pl110.o
 common-obj-$(CONFIG_SII9022) += sii9022.o
 common-obj-$(CONFIG_SSD0303) += ssd0303.o
@@ -17,12 +17,12 @@ common-obj-$(CONFIG_XEN) += xenfb.o

 common-obj-$(CONFIG_VGA_PCI) += vga-pci.o
 common-obj-$(CONFIG_VGA_ISA) += vga-isa.o
-common-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
+obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
 common-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
 common-obj-$(CONFIG_BOCHS_DISPLAY) += bochs-display.o

 common-obj-$(CONFIG_BLIZZARD) += blizzard.o

[Qemu-devel] [PATCH v7 16/42] hw/block: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/block/onenand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index b3644f7..66152e7 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -769,7 +769,7 @@ static void onenand_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps onenand_ops = {
 .read = onenand_read,
 .write = onenand_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void onenand_realize(DeviceState *dev, Error **errp)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 21/42] hw/i2c: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/i2c/imx_i2c.c   | 2 +-
 hw/i2c/mpc_i2c.c   | 2 +-
 hw/i2c/versatile_i2c.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
index ce7a94c..de1107b 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -276,7 +276,7 @@ static const MemoryRegionOps imx_i2c_ops = {
 .write = imx_i2c_write,
 .valid.min_access_size = 1,
 .valid.max_access_size = 2,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static const VMStateDescription imx_i2c_vmstate = {
diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c
index e9a1127..181228d 100644
--- a/hw/i2c/mpc_i2c.c
+++ b/hw/i2c/mpc_i2c.c
@@ -304,7 +304,7 @@ static const MemoryRegionOps i2c_ops = {
 .read =  mpc_i2c_read,
 .write =  mpc_i2c_write,
 .valid.max_access_size = 1,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };

 static const VMStateDescription mpc_i2c_vmstate = {
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
index 1ac2a6f..c92d3b1 100644
--- a/hw/i2c/versatile_i2c.c
+++ b/hw/i2c/versatile_i2c.c
@@ -77,7 +77,7 @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps versatile_i2c_ops = {
 .read = versatile_i2c_read,
 .write = versatile_i2c_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void versatile_i2c_init(Object *obj)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 15/42] hw/audio: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/audio/cs4231.c  | 2 +-
 hw/audio/marvell_88w8618.c | 2 +-
 hw/audio/milkymist-ac97.c  | 2 +-
 hw/audio/pl041.c   | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c
index 8372299..8946648 100644
--- a/hw/audio/cs4231.c
+++ b/hw/audio/cs4231.c
@@ -132,7 +132,7 @@ static void cs_mem_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps cs_mem_ops = {
 .read = cs_mem_read,
 .write = cs_mem_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };

 static const VMStateDescription vmstate_cs4231 = {
diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c
index ff1a0d0..a79e0b1 100644
--- a/hw/audio/marvell_88w8618.c
+++ b/hw/audio/marvell_88w8618.c
@@ -240,7 +240,7 @@ static void mv88w8618_audio_reset(DeviceState *d)
 static const MemoryRegionOps mv88w8618_audio_ops = {
 .read = mv88w8618_audio_read,
 .write = mv88w8618_audio_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void mv88w8618_audio_init(Object *obj)
diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c
index bf6a5a6..56feca2 100644
--- a/hw/audio/milkymist-ac97.c
+++ b/hw/audio/milkymist-ac97.c
@@ -176,7 +176,7 @@ static const MemoryRegionOps ac97_mmio_ops = {
 .min_access_size = 4,
 .max_access_size = 4,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_BIG_ENDIAN,
 };

 static void ac97_in_cb(void *opaque, int avail_b)
diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c
index 59c6ce1..b59a4f8 100644
--- a/hw/audio/pl041.c
+++ b/hw/audio/pl041.c
@@ -519,7 +519,7 @@ static void pl041_device_reset(DeviceState *d)
 static const MemoryRegionOps pl041_ops = {
 .read = pl041_read,
 .write = pl041_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl041_init(Object *obj)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 13/42] target/mips: Hard code size with MO_{8|16|32|64}

2019-08-16 Thread tony.nguyen
Temporarily no-op size_memop was introduced to aid the conversion of
memory_region_dispatch_{read|write} operand "unsigned size" into
"MemOp op".

Now size_memop is implemented, again hard coded size but with
MO_{8|16|32|64}. This is more expressive and avoids size_memop calls.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 target/mips/op_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 1c72a00..e79f99d 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -4741,11 +4741,11 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 if (op == 9) {
 /* Index Store Tag */
 memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
- size_memop(8), MEMTXATTRS_UNSPECIFIED);
+ MO_64, MEMTXATTRS_UNSPECIFIED);
 } else if (op == 5) {
 /* Index Load Tag */
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
-size_memop(8), MEMTXATTRS_UNSPECIFIED);
+MO_64, MEMTXATTRS_UNSPECIFIED);
 }
 #endif
 }
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 27/42] hw/pci-host: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/pci-host/q35.c   | 2 +-
 hw/pci-host/versatile.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 0a010be..fd20f72 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -288,7 +288,7 @@ static void tseg_blackhole_write(void *opaque, hwaddr addr, 
uint64_t val,
 static const MemoryRegionOps tseg_blackhole_ops = {
 .read = tseg_blackhole_read,
 .write = tseg_blackhole_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid.min_access_size = 1,
 .valid.max_access_size = 4,
 .impl.min_access_size = 4,
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 791b321..e7017f3 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -240,7 +240,7 @@ static uint64_t pci_vpb_reg_read(void *opaque, hwaddr addr,
 static const MemoryRegionOps pci_vpb_reg_ops = {
 .read = pci_vpb_reg_read,
 .write = pci_vpb_reg_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 4,
 .max_access_size = 4,
@@ -306,7 +306,7 @@ static uint64_t pci_vpb_config_read(void *opaque, hwaddr 
addr,
 static const MemoryRegionOps pci_vpb_config_ops = {
 .read = pci_vpb_config_read,
 .write = pci_vpb_config_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 12/42] hw/s390x: Hard code size with MO_{8|16|32|64}

2019-08-16 Thread tony.nguyen
Temporarily no-op size_memop was introduced to aid the conversion of
memory_region_dispatch_{read|write} operand "unsigned size" into
"MemOp op".

Now size_memop is implemented, again hard coded size but with
MO_{8|16|32|64}. This is more expressive and avoids size_memop calls.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/s390-pci-inst.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 0c958fc..0e92a37 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -782,8 +782,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 for (i = 0; i < len / 8; i++) {
 result = memory_region_dispatch_write(mr, offset + i * 8,
   ldq_p(buffer + i * 8),
-  size_memop(8),
-  MEMTXATTRS_UNSPECIFIED);
+  MO_64, MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 s390_program_interrupt(env, PGM_OPERAND, 6, ra);
 return 0;
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 18/42] hw/display: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/display/pl110.c| 2 +-
 hw/display/tc6393xb.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index 2bdfc3c..d0c6317 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -471,7 +471,7 @@ static void pl110_write(void *opaque, hwaddr offset,
 static const MemoryRegionOps pl110_ops = {
 .read = pl110_read,
 .write = pl110_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl110_mux_ctrl_set(void *opaque, int line, int level)
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 0b7c59c..6bc3360 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -547,7 +547,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t 
base, qemu_irq irq)
 static const MemoryRegionOps tc6393xb_ops = {
 .read = tc6393xb_readb,
 .write = tc6393xb_writeb,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 .impl = {
 .min_access_size = 1,
 .max_access_size = 1,
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 11/42] memory: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
Convert memory_region_dispatch_{read|write} operand "unsigned size"
into a "MemOp op".

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/memop.h  | 20 ++--
 include/exec/memory.h |  9 +
 memory.c  |  7 +--
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index dfd76a1..0a610b7 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -12,6 +12,8 @@
 #ifndef MEMOP_H
 #define MEMOP_H

+#include "qemu/host-utils.h"
+
 typedef enum MemOp {
 MO_8 = 0,
 MO_16= 1,
@@ -107,14 +109,20 @@ typedef enum MemOp {
 MO_SSIZE = MO_SIZE | MO_SIGN,
 } MemOp;

+/* MemOp to size in bytes.  */
+static inline unsigned memop_size(MemOp op)
+{
+return 1 << (op & MO_SIZE);
+}
+
 /* Size in bytes to MemOp.  */
-static inline unsigned size_memop(unsigned size)
+static inline MemOp size_memop(unsigned size)
 {
-/*
- * FIXME: No-op to aid conversion of memory_region_dispatch_{read|write}
- * "unsigned size" operand into a "MemOp op".
- */
-return size;
+#ifdef CONFIG_DEBUG_TCG
+/* Power of 2 up to 8.  */
+assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);
+#endif
+return ctz32(size);
 }

 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bb0961d..975b86a 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -19,6 +19,7 @@
 #include "exec/cpu-common.h"
 #include "exec/hwaddr.h"
 #include "exec/memattrs.h"
+#include "exec/memop.h"
 #include "exec/ramlist.h"
 #include "qemu/queue.h"
 #include "qemu/int128.h"
@@ -1731,13 +1732,13 @@ void mtree_info(bool flatview, bool dispatch_tree, bool 
owner);
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @pval: pointer to uint64_t which the data is written to
- * @size: size of the access in bytes
+ * @op: size, sign, and endianness of the memory operation
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 hwaddr addr,
 uint64_t *pval,
-unsigned size,
+MemOp op,
 MemTxAttrs attrs);
 /**
  * memory_region_dispatch_write: perform a write directly to the specified
@@ -1746,13 +1747,13 @@ MemTxResult memory_region_dispatch_read(MemoryRegion 
*mr,
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @data: data to write
- * @size: size of the access in bytes
+ * @op: size, sign, and endianness of the memory operation
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
  hwaddr addr,
  uint64_t data,
- unsigned size,
+ MemOp op,
  MemTxAttrs attrs);

 /**
diff --git a/memory.c b/memory.c
index 5d8c9a9..89ea4fb 100644
--- a/memory.c
+++ b/memory.c
@@ -1439,9 +1439,10 @@ static MemTxResult 
memory_region_dispatch_read1(MemoryRegion *mr,
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 hwaddr addr,
 uint64_t *pval,
-unsigned size,
+MemOp op,
 MemTxAttrs attrs)
 {
+unsigned size = memop_size(op);
 MemTxResult r;

 if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
@@ -1483,9 +1484,11 @@ static bool 
memory_region_dispatch_write_eventfds(MemoryRegion *mr,
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
  hwaddr addr,
  uint64_t data,
- unsigned size,
+ MemOp op,
  MemTxAttrs attrs)
 {
+unsigned size = memop_size(op);
+
 if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
 unassigned_mem_write(mr, addr, data, size);
 return MEMTX_DECODE_ERROR;
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 08/42] hw/vfio: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Reviewed-by: Cornelia Huck 
---
 hw/vfio/pci-quirks.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index b35a640..fb3cc33 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -11,6 +11,7 @@
  */

 #include "qemu/osdep.h"
+#include "exec/memop.h"
 #include "qemu/units.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
@@ -1071,7 +1072,7 @@ static void vfio_rtl8168_quirk_address_write(void 
*opaque, hwaddr addr,

 /* Write to the proper guest MSI-X table instead */
 memory_region_dispatch_write(>pdev.msix_table_mmio,
- offset, val, size,
+ offset, val, size_memop(size),
  MEMTXATTRS_UNSPECIFIED);
 }
 return; /* Do not write guest MSI-X data to hardware */
@@ -1102,7 +1103,8 @@ static uint64_t vfio_rtl8168_quirk_data_read(void *opaque,
 if (rtl->enabled && (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX)) {
 hwaddr offset = rtl->addr & 0xfff;
 memory_region_dispatch_read(>pdev.msix_table_mmio, offset,
-, size, MEMTXATTRS_UNSPECIFIED);
+, size_memop(size),
+MEMTXATTRS_UNSPECIFIED);
 trace_vfio_quirk_rtl8168_msix_read(vdev->vbasedev.name, offset, data);
 }

--
1.8.3.1

?



[Qemu-devel] [PATCH v7 14/42] exec: Hard code size with MO_{8|16|32|64}

2019-08-16 Thread tony.nguyen
Temporarily no-op size_memop was introduced to aid the conversion of
memory_region_dispatch_{read|write} operand "unsigned size" into
"MemOp op".

Now size_memop is implemented, again hard coded size but with
MO_{8|16|32|64}. This is more expressive and avoids size_memop calls.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 memory_ldst.inc.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index 1e8a2fc..de658c4 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -38,7 +38,7 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(4), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_32, attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap32(val);
@@ -114,7 +114,7 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(8), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_64, attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap64(val);
@@ -188,7 +188,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(1), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_8, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -224,7 +224,7 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(2), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_16, attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap16(val);
@@ -300,7 +300,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);

-r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_32, attrs);
 } else {
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
 stl_p(ptr, val);
@@ -346,7 +346,7 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap32(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_32, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -408,7 +408,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (!memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(1), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_8, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -451,7 +451,7 @@ static inline void glue(address_space_stw_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap16(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(2), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_16, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -524,7 +524,7 @@ static void glue(address_space_stq_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap64(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(8), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_64, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 20/42] hw/gpio: Declare device little or big endian

2019-08-16 Thread tony.nguyen
For each device declared with DEVICE_NATIVE_ENDIAN, find the set of
targets from the set of target/hw/*/device.o.

If the set of targets are all little or all big endian, re-declare
the device endianness as DEVICE_LITTLE_ENDIAN or DEVICE_BIG_ENDIAN
respectively.

This *naive* deduction may result in genuinely native endian devices
being incorrectly declared as little or big endian, but should not
introduce regressions for current targets.

These devices should be re-declared as DEVICE_NATIVE_ENDIAN if 1) it
has a new target with an opposite endian or 2) someone informed knows
better =)

Signed-off-by: Tony Nguyen 
---
 hw/gpio/pl061.c  | 2 +-
 hw/gpio/zaurus.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
index 02c01fd..da6ff6a 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -339,7 +339,7 @@ static void pl061_set_irq(void * opaque, int irq, int level)
 static const MemoryRegionOps pl061_ops = {
 .read = pl061_read,
 .write = pl061_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void pl061_luminary_init(Object *obj)
diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c
index f2f1f67..599d862 100644
--- a/hw/gpio/zaurus.c
+++ b/hw/gpio/zaurus.c
@@ -156,7 +156,7 @@ static void scoop_write(void *opaque, hwaddr addr,
 static const MemoryRegionOps scoop_ops = {
 .read = scoop_read,
 .write = scoop_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
+.endianness = DEVICE_LITTLE_ENDIAN,
 };

 static void scoop_gpio_set(void *opaque, int line, int level)
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 10/42] cputlb: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 accel/tcg/cputlb.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 523be4c..6c83878 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -906,8 +906,8 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_read(mr, mr_offset,
-, size, iotlbentry->attrs);
+r = memory_region_dispatch_read(mr, mr_offset, , size_memop(size),
+iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
@@ -947,8 +947,8 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_write(mr, mr_offset,
- val, size, iotlbentry->attrs);
+r = memory_region_dispatch_write(mr, mr_offset, val, size_memop(size),
+ iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 07/42] hw/virtio: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Reviewed-by: Cornelia Huck 
---
 hw/virtio/virtio-pci.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f6d2223..25875c8 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -17,6 +17,7 @@

 #include "qemu/osdep.h"

+#include "exec/memop.h"
 #include "standard-headers/linux/virtio_pci.h"
 #include "hw/virtio/virtio.h"
 #include "hw/pci/pci.h"
@@ -550,7 +551,8 @@ void virtio_address_space_write(VirtIOPCIProxy *proxy, 
hwaddr addr,
 /* As length is under guest control, handle illegal values. */
 return;
 }
-memory_region_dispatch_write(mr, addr, val, len, MEMTXATTRS_UNSPECIFIED);
+memory_region_dispatch_write(mr, addr, val, size_memop(len),
+ MEMTXATTRS_UNSPECIFIED);
 }

 static void
@@ -573,7 +575,8 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));

-memory_region_dispatch_read(mr, addr, , len, MEMTXATTRS_UNSPECIFIED);
+memory_region_dispatch_read(mr, addr, , size_memop(len),
+MEMTXATTRS_UNSPECIFIED);
 switch (len) {
 case 1:
 pci_set_byte(buf, val);
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 06/42] hw/intc/armv7m_nic: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 hw/intc/armv7m_nvic.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 9f8f0d3..237ccef 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -18,6 +18,7 @@
 #include "hw/intc/armv7m_nvic.h"
 #include "target/arm/cpu.h"
 #include "exec/exec-all.h"
+#include "exec/memop.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "trace.h"
@@ -2345,7 +2346,8 @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_write(mr, addr, value, size, attrs);
+return memory_region_dispatch_write(mr, addr, value, size_memop(size),
+attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2364,7 +2366,8 @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_read(mr, addr, data, size, attrs);
+return memory_region_dispatch_read(mr, addr, data, size_memop(size),
+   attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2390,7 +2393,8 @@ static MemTxResult nvic_systick_write(void *opaque, 
hwaddr addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_write(mr, addr, value, size, attrs);
+return memory_region_dispatch_write(mr, addr, value, size_memop(size),
+attrs);
 }

 static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
@@ -2402,7 +2406,7 @@ static MemTxResult nvic_systick_read(void *opaque, hwaddr 
addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_read(mr, addr, data, size, attrs);
+return memory_region_dispatch_read(mr, addr, data, size_memop(size), 
attrs);
 }

 static const MemoryRegionOps nvic_systick_ops = {
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 09/42] exec: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 exec.c|  6 --
 memory_ldst.inc.c | 18 +-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/exec.c b/exec.c
index 3e78de3..9f69197 100644
--- a/exec.c
+++ b/exec.c
@@ -3334,7 +3334,8 @@ static MemTxResult flatview_write_continue(FlatView *fv, 
hwaddr addr,
 /* XXX: could force current_cpu to NULL to avoid
potential bugs */
 val = ldn_p(buf, l);
-result |= memory_region_dispatch_write(mr, addr1, val, l, attrs);
+result |= memory_region_dispatch_write(mr, addr1, val,
+   size_memop(l), attrs);
 } else {
 /* RAM case */
 ptr = qemu_ram_ptr_length(mr->ram_block, addr1, , false);
@@ -3395,7 +3396,8 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr 
addr,
 /* I/O case */
 release_lock |= prepare_mmio_access(mr);
 l = memory_access_size(mr, l, addr1);
-result |= memory_region_dispatch_read(mr, addr1, , l, attrs);
+result |= memory_region_dispatch_read(mr, addr1, ,
+  size_memop(l), attrs);
 stn_p(buf, l, val);
 } else {
 /* RAM case */
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index acf865b..1e8a2fc 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -38,7 +38,7 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 4, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(4), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap32(val);
@@ -114,7 +114,7 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 8, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(8), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap64(val);
@@ -188,7 +188,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 1, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(1), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -224,7 +224,7 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 2, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(2), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap16(val);
@@ -300,7 +300,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);

-r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
 } else {
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
 stl_p(ptr, val);
@@ -346,7 +346,7 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap32(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -408,7 +408,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (!memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, size_memop(1), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -451,7 +451,7 @@ static inline void glue(address_space_stw_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap16(val);
 }
 #endif
-

[Qemu-devel] [PATCH v7 05/42] hw/s390x: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
Reviewed-by: Cornelia Huck 
---
 hw/s390x/s390-pci-inst.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 0023514..0c958fc 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -15,6 +15,7 @@
 #include "cpu.h"
 #include "s390-pci-inst.h"
 #include "s390-pci-bus.h"
+#include "exec/memop.h"
 #include "exec/memory-internal.h"
 #include "qemu/error-report.h"
 #include "sysemu/hw_accel.h"
@@ -372,7 +373,7 @@ static MemTxResult zpci_read_bar(S390PCIBusDevice *pbdev, 
uint8_t pcias,
 mr = pbdev->pdev->io_regions[pcias].memory;
 mr = s390_get_subregion(mr, offset, len);
 offset -= mr->addr;
-return memory_region_dispatch_read(mr, offset, data, len,
+return memory_region_dispatch_read(mr, offset, data, size_memop(len),
MEMTXATTRS_UNSPECIFIED);
 }

@@ -471,7 +472,7 @@ static MemTxResult zpci_write_bar(S390PCIBusDevice *pbdev, 
uint8_t pcias,
 mr = pbdev->pdev->io_regions[pcias].memory;
 mr = s390_get_subregion(mr, offset, len);
 offset -= mr->addr;
-return memory_region_dispatch_write(mr, offset, data, len,
+return memory_region_dispatch_write(mr, offset, data, size_memop(len),
 MEMTXATTRS_UNSPECIFIED);
 }

@@ -780,7 +781,8 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,

 for (i = 0; i < len / 8; i++) {
 result = memory_region_dispatch_write(mr, offset + i * 8,
-  ldq_p(buffer + i * 8), 8,
+  ldq_p(buffer + i * 8),
+  size_memop(8),
   MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 s390_program_interrupt(env, PGM_OPERAND, 6, ra);
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 02/42] tcg: TCGMemOp is now accelerator independent MemOp

2019-08-16 Thread tony.nguyen
Preparation for collapsing the two byte swaps, adjust_endianness and
handle_bswap, along the I/O path.

Target dependant attributes are conditionalized upon NEED_CPU_H.

Signed-off-by: Tony Nguyen 
Acked-by: David Gibson 
Reviewed-by: Richard Henderson 
Acked-by: Cornelia Huck 
---
 MAINTAINERS |   1 +
 accel/tcg/cputlb.c  |   2 +-
 include/exec/memop.h| 110 ++
 target/alpha/translate.c|   2 +-
 target/arm/translate-a64.c  |  48 ++--
 target/arm/translate-a64.h  |   2 +-
 target/arm/translate-sve.c  |   2 +-
 target/arm/translate.c  |  32 
 target/arm/translate.h  |   2 +-
 target/hppa/translate.c |  14 ++--
 target/i386/translate.c | 132 
 target/m68k/translate.c |   2 +-
 target/microblaze/translate.c   |   4 +-
 target/mips/translate.c |   8 +-
 target/openrisc/translate.c |   4 +-
 target/ppc/translate.c  |  12 +--
 target/riscv/insn_trans/trans_rva.inc.c |   8 +-
 target/riscv/insn_trans/trans_rvi.inc.c |   4 +-
 target/s390x/translate.c|   6 +-
 target/s390x/translate_vx.inc.c |  10 +--
 target/sparc/translate.c|  14 ++--
 target/tilegx/translate.c   |  10 +--
 target/tricore/translate.c  |   8 +-
 tcg/README  |   2 +-
 tcg/aarch64/tcg-target.inc.c|  26 +++
 tcg/arm/tcg-target.inc.c|  26 +++
 tcg/i386/tcg-target.inc.c   |  24 +++---
 tcg/mips/tcg-target.inc.c   |  16 ++--
 tcg/optimize.c  |   2 +-
 tcg/ppc/tcg-target.inc.c|  12 +--
 tcg/riscv/tcg-target.inc.c  |  20 ++---
 tcg/s390/tcg-target.inc.c   |  14 ++--
 tcg/sparc/tcg-target.inc.c  |   6 +-
 tcg/tcg-op.c|  38 -
 tcg/tcg-op.h|  86 ++---
 tcg/tcg.c   |   2 +-
 tcg/tcg.h   | 101 ++--
 trace/mem-internal.h|   4 +-
 trace/mem.h |   4 +-
 39 files changed, 421 insertions(+), 399 deletions(-)
 create mode 100644 include/exec/memop.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d6de200..c7cf84a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1889,6 +1889,7 @@ M: Paolo Bonzini 
 S: Supported
 F: include/exec/ioport.h
 F: ioport.c
+F: include/exec/memop.h
 F: include/exec/memory.h
 F: include/exec/ram_addr.h
 F: memory.c
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index bb9897b..523be4c 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1133,7 +1133,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 uintptr_t index = tlb_index(env, mmu_idx, addr);
 CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
 target_ulong tlb_addr = tlb_addr_write(tlbe);
-TCGMemOp mop = get_memop(oi);
+MemOp mop = get_memop(oi);
 int a_bits = get_alignment_bits(mop);
 int s_bits = mop & MO_SIZE;
 void *hostaddr;
diff --git a/include/exec/memop.h b/include/exec/memop.h
new file mode 100644
index 000..7262ca3
--- /dev/null
+++ b/include/exec/memop.h
@@ -0,0 +1,110 @@
+/*
+ * Constants for memory operations
+ *
+ * Authors:
+ *  Richard Henderson 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MEMOP_H
+#define MEMOP_H
+
+typedef enum MemOp {
+MO_8 = 0,
+MO_16= 1,
+MO_32= 2,
+MO_64= 3,
+MO_SIZE  = 3,   /* Mask for the above.  */
+
+MO_SIGN  = 4,   /* Sign-extended, otherwise zero-extended.  */
+
+MO_BSWAP = 8,   /* Host reverse endian.  */
+#ifdef HOST_WORDS_BIGENDIAN
+MO_LE= MO_BSWAP,
+MO_BE= 0,
+#else
+MO_LE= 0,
+MO_BE= MO_BSWAP,
+#endif
+#ifdef NEED_CPU_H
+#ifdef TARGET_WORDS_BIGENDIAN
+MO_TE= MO_BE,
+#else
+MO_TE= MO_LE,
+#endif
+#endif
+
+/*
+ * MO_UNALN accesses are never checked for alignment.
+ * MO_ALIGN accesses will result in a call to the CPU's
+ * do_unaligned_access hook if the guest address is not aligned.
+ * The default depends on whether the target CPU defines
+ * TARGET_ALIGNED_ONLY.
+ *
+ * Some architectures (e.g. ARMv8) need the address which is aligned
+ * to a size more than the size of the memory access.
+ * Some architectures (e.g. SPARCv9) need an address which is aligned,
+ * but less strictly than the natural alignment.
+ *
+ * MO_ALIGN supposes the alignment size is the size of a memory access.
+ *
+ * There are three options:
+ * - unaligned access permitted (MO_UNALN).
+  

[Qemu-devel] [PATCH v7 04/42] target/mips: Access MemoryRegion with MemOp

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 target/mips/op_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 9e2e02f..1c72a00 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -24,6 +24,7 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "exec/memop.h"
 #include "sysemu/kvm.h"

 /*/
@@ -4740,11 +4741,11 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 if (op == 9) {
 /* Index Store Tag */
 memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
- 8, MEMTXATTRS_UNSPECIFIED);
+ size_memop(8), MEMTXATTRS_UNSPECIFIED);
 } else if (op == 5) {
 /* Index Load Tag */
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
-8, MEMTXATTRS_UNSPECIFIED);
+size_memop(8), MEMTXATTRS_UNSPECIFIED);
 }
 #endif
 }
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 03/42] memory: Introduce size_memop

2019-08-16 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Introduce no-op size_memop to aid preparatory conversion of
interfaces.

Once interfaces are converted, size_memop will be implemented to
return a MemOp from size in bytes.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/memop.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index 7262ca3..dfd76a1 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -107,4 +107,14 @@ typedef enum MemOp {
 MO_SSIZE = MO_SIZE | MO_SIGN,
 } MemOp;

+/* Size in bytes to MemOp.  */
+static inline unsigned size_memop(unsigned size)
+{
+/*
+ * FIXME: No-op to aid conversion of memory_region_dispatch_{read|write}
+ * "unsigned size" operand into a "MemOp op".
+ */
+return size;
+}
+
 #endif
--
1.8.3.1

?



[Qemu-devel] [PATCH v7 01/42] configure: Define TARGET_ALIGNED_ONLY

2019-08-16 Thread tony.nguyen
Rename ALIGNED_ONLY to TARGET_ALIGNED_ONLY for clarity and move
defines out of target/foo/cpu.h into configure, as we do with
TARGET_WORDS_BIGENDIAN, so that it is always defined early.

Poisoned TARGET_ALIGNED_ONLY to prevent use in common code.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Aleksandar Markovic 
Reviewed-by: Cornelia Huck 
---
 configure | 10 +-
 include/exec/poison.h |  1 +
 include/qom/cpu.h |  2 +-
 target/alpha/cpu.h|  2 --
 target/hppa/cpu.h |  1 -
 target/mips/cpu.h |  2 --
 target/sh4/cpu.h  |  2 --
 target/sparc/cpu.h|  2 --
 target/xtensa/cpu.h   |  2 --
 tcg/tcg.c |  2 +-
 tcg/tcg.h |  8 +---
 11 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/configure b/configure
index 714e7fb..482ba0b 100755
--- a/configure
+++ b/configure
@@ -7431,8 +7431,13 @@ for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
 target_name=$(echo $target | cut -d '-' -f 1)
+target_aligned_only="no"
+case "$target_name" in
+  
alpha|hppa|mips64el|mips64|mipsel|mips|mipsn32|mipsn32el|sh4|sh4eb|sparc|sparc64|sparc32plus|xtensa|xtensaeb)
+  target_aligned_only="yes"
+  ;;
+esac
 target_bigendian="no"
-
 case "$target_name" in
   
armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
@@ -7717,6 +7722,9 @@ fi
 if supported_whpx_target $target; then
 echo "CONFIG_WHPX=y" >> $config_target_mak
 fi
+if test "$target_aligned_only" = "yes" ; then
+  echo "TARGET_ALIGNED_ONLY=y" >> $config_target_mak
+fi
 if test "$target_bigendian" = "yes" ; then
   echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
 fi
diff --git a/include/exec/poison.h b/include/exec/poison.h
index b862320..955eb86 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -35,6 +35,7 @@
 #pragma GCC poison TARGET_UNICORE32
 #pragma GCC poison TARGET_XTENSA

+#pragma GCC poison TARGET_ALIGNED_ONLY
 #pragma GCC poison TARGET_HAS_BFLT
 #pragma GCC poison TARGET_NAME
 #pragma GCC poison TARGET_SUPPORTS_MTTCG
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 5ee0046..9b50b73 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -89,7 +89,7 @@ struct TranslationBlock;
  * @do_unassigned_access: Callback for unassigned access handling.
  * (this is deprecated: new targets should use do_transaction_failed instead)
  * @do_unaligned_access: Callback for unaligned access handling, if
- * the target defines #ALIGNED_ONLY.
+ * the target defines #TARGET_ALIGNED_ONLY.
  * @do_transaction_failed: Callback for handling failed memory transactions
  * (ie bus faults or external aborts; not MMU faults)
  * @virtio_is_big_endian: Callback to return %true if a CPU which supports
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index b3e8a82..16eb804 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"

-#define ALIGNED_ONLY
-
 /* Alpha processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index aab251b..2be67c2 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -30,7 +30,6 @@
basis.  It's probably easier to fall back to a strong memory model.  */
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL

-#define ALIGNED_ONLY
 #define MMU_KERNEL_IDX   0
 #define MMU_USER_IDX 3
 #define MMU_PHYS_IDX 4
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 21c0615..c13cd4e 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1,8 +1,6 @@
 #ifndef MIPS_CPU_H
 #define MIPS_CPU_H

-#define ALIGNED_ONLY
-
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index aee733e..ecaa7a1 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"

-#define ALIGNED_ONLY
-
 /* CPU Subtypes */
 #define SH_CPU_SH7750  (1 << 0)
 #define SH_CPU_SH7750S (1 << 1)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ed2250..1406f0b 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -5,8 +5,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"

-#define ALIGNED_ONLY
-
 #if !defined(TARGET_SPARC64)
 #define TARGET_DPREGS 16
 #else
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 2c27713..0459243 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -32,8 +32,6 @@
 #include "exec/cpu-defs.h"
 #include "xtensa-isa.h"

-#define ALIGNED_ONLY
-
 /* Xtensa processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index be2c33c..8d23fb0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1926,7 +1926,7 @@ static const char * const ldst_name[] =
 };

 static const char * const 

[Qemu-devel] [PATCH v7 00/42] Invert Endian bit in SPARCv9 MMU TTE

2019-08-16 Thread tony.nguyen
This patchset implements the IE (Invert Endian) bit in SPARCv9 MMU TTE.

It is an attempt of the instructions outlined by Richard Henderson to Mark
Cave-Ayland.

Tested with OpenBSD on sun4u. Solaris 10 is my actual goal, but unfortunately a
separate keyboard issue remains in the way.

On 01/11/17 19:15, Mark Cave-Ayland wrote:

>On 15/08/17 19:10, Richard Henderson wrote:
>
>> [CC Peter re MemTxAttrs below]
>>
>> On 08/15/2017 09:38 AM, Mark Cave-Ayland wrote:
>>> Working through an incorrect endian issue on qemu-system-sparc64, it has
>>> become apparent that at least one OS makes use of the IE (Invert Endian)
>>> bit in the SPARCv9 MMU TTE to map PCI memory space without the
>>> programmer having to manually endian-swap accesses.
>>>
>>> In other words, to quote the UltraSPARC specification: "if this bit is
>>> set, accesses to the associated page are processed with inverse
>>> endianness from what is specified by the instruction (big-for-little and
>>> little-for-big)".

A good explanation by Mark why the IE bit is required.

>>>
>>> Looking through various bits of code, I'm trying to get a feel for the
>>> best way to implement this in an efficient manner. From what I can see
>>> this could be solved using an additional MMU index, however I'm not
>>> overly familiar with the memory and softmmu subsystems.
>>
>> No, it can't be solved with an MMU index.
>>
>>> Can anyone point me in the right direction as to what would be the best
>>> way to implement this feature within QEMU?
>>
>> It's definitely tricky.
>>
>> We definitely need some TLB_FLAGS_MASK bit set so that we're forced through
>> the
>> memory slow path.  There is no other way to bypass the endianness that we've
>> already encoded from the target instruction.
>>
>> Given the tlb_set_page_with_attrs interface, I would think that we need a new
>> bit in MemTxAttrs, so that the target/sparc tlb_fill (and subroutines) can
>> pass
>> along the TTE bit for the given page.
>>
>> We have an existing problem in softmmu_template.h,
>>
>> /* ??? Note that the io helpers always read data in the target
>>byte ordering.  We should push the LE/BE request down into io.  */
>> res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
>> res = TGT_BE(res);
>>
>> We do not want to add a third(!) byte swap along the i/o path.  We need to
>> collapse the two that we have already before considering this one.
>>
>> This probably takes the form of:
>>
>> (1) Replacing the "int size" argument with "TCGMemOp memop" for
>>   a) io_{read,write}x in accel/tcg/cputlb.c,
>>   b) memory_region_dispatch_{read,write} in memory.c,
>>   c) adjust_endianness in memory.c.
>> This carries size+sign+endianness down to the next level.
>>
>> (2) In memory.c, adjust_endianness,
>>
>>  if (memory_region_wrong_endianness(mr)) {
>> -switch (size) {
>> +memop ^= MO_BSWAP;
>> +}
>> +if (memop & MO_BSWAP) {
>>
>> For extra credit, re-arrange memory_region_wrong_endianness
>> to something more explicit -- "wrong" isn't helpful.
>
>Finally I've had a bit of spare time to experiment with this approach,
>and from what I can see there are currently 2 issues:
>
>
>1) Using TCGMemOp in memory.c means it is no longer accelerator agnostic
>
>For the moment I've defined a separate MemOp in memory.h and provided a
>mapping function in io_{read,write}x to map from TCGMemOp to MemOp and
>then pass that into memory_region_dispatch_{read,write}.
>
>Other than not referencing TCGMemOp in the memory API, another reason
>for doing this was that I wasn't convinced that all the MO_ attributes
>were valid outside of TCG. I do, of course, strongly defer to other
>people's knowledge in this area though.
>
>
>2) The above changes to adjust_endianness() fail when
>memory_region_dispatch_{read,write} are called recursively
>
>Whilst booting qemu-system-sparc64 I see that
>memory_region_dispatch_{read,write} get called recursively - once via
>io_{read,write}x and then again via flatview_read_continue() in exec.c.
>
>The net effect of this is that we perform the bswap correctly at the
>tail of the recursion, but then as we travel back up the stack we hit
>memory_region_dispatch_{read,write} once again causing a second bswap
>which means the value is returned with the incorrect endian again.
>
>
>My understanding from your softmmu_template.h comment above is that the
>memory API should do the endian swapping internally allowing the removal
>of the final TGT_BE/TGT_LE applied to the result, or did I get this wrong?
>
>> (3) In tlb_set_page_with_attrs, notice attrs.byte_swap and set
>> a new TLB_FORCE_SLOW bit within TLB_FLAGS_MASK.
>>
>> (4) In io_{read,write}x, if iotlbentry->attrs.byte_swap is set,
>> then memop ^= MO_BSWAP.

Thanks all for the feedback. Learnt a lot =)

v2:
- Moved size+sign+endianness attributes from TCGMemOp into MemOp.
  In v1 TCGMemOp was re-purposed entirely into MemOp.
- Replaced MemOp MO_{8|16|32|64} with 

Re: [Qemu-devel] [PATCH v6 26/26] target/sparc: sun4u Invert Endian TTE bit

2019-08-07 Thread tony.nguyen
Sorry, I missed a tag.?


Tested-by: Mark Cave-Ayland 


Re: [Qemu-devel] [PATCH v6 09/26] exec: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
Sorry, I missed a tag.


Reviewed-by: Philippe Mathieu-Daudé ?



Re: [Qemu-devel] [PATCH v6 06/26] hw/intc/armv7m_nic: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
Sorry, I missed a tag.


Reviewed-by: Philippe Mathieu-Daudé ?



Re: [Qemu-devel] [PATCH v6 04/26] target/mips: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
Sorry, I missed a tag.


Reviewed-by: Philippe Mathieu-Daudé ?



Re: [Qemu-devel] [PATCH v6 10/26] cputlb: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
Sorry, I missed a tag.


Reviewed-by: Philippe Mathieu-Daudé 


Re: [Qemu-devel] [PATCH v6 00/26] Invert Endian bit in SPARCv9 MMU TTE

2019-08-07 Thread tony.nguyen
On 8/7/19 8:37 PM, Philippe Mathieu-Daudé wrote:

> I'm confused I think I already reviewed various patches of your previous
?> series but don't see my Reviewed-by tags.?


Apologies Philippe! I am the confused one here =/


Will append.


Thank you very much for the reviews and qemu-devel newbie tips so far. I have 
felt very welcome.


Tony


[Qemu-devel] [PATCH v6 21/26] cputlb: Replace size and endian operands for MemOp

2019-08-07 Thread tony.nguyen
Preparation for collapsing the two byte swaps adjust_endianness and
handle_bswap into the former.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c   | 170 +--
 include/exec/memop.h |   6 ++
 memory.c |  11 +---
 3 files changed, 90 insertions(+), 97 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 6c83878..86d85cc 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -881,7 +881,7 @@ static void tlb_fill(CPUState *cpu, target_ulong addr, int 
size,

 static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
  int mmu_idx, target_ulong addr, uintptr_t retaddr,
- MMUAccessType access_type, int size)
+ MMUAccessType access_type, MemOp op)
 {
 CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
@@ -906,14 +906,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_read(mr, mr_offset, , size_memop(size),
-iotlbentry->attrs);
+r = memory_region_dispatch_read(mr, mr_offset, , op, 
iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
 section->offset_within_region;

-cpu_transaction_failed(cpu, physaddr, addr, size, access_type,
+cpu_transaction_failed(cpu, physaddr, addr, memop_size(op), 
access_type,
mmu_idx, iotlbentry->attrs, r, retaddr);
 }
 if (locked) {
@@ -925,7 +924,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,

 static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
   int mmu_idx, uint64_t val, target_ulong addr,
-  uintptr_t retaddr, int size)
+  uintptr_t retaddr, MemOp op)
 {
 CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
@@ -947,15 +946,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_write(mr, mr_offset, val, size_memop(size),
- iotlbentry->attrs);
+r = memory_region_dispatch_write(mr, mr_offset, val, op, 
iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
 section->offset_within_region;

-cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
-   mmu_idx, iotlbentry->attrs, r, retaddr);
+cpu_transaction_failed(cpu, physaddr, addr, memop_size(op),
+   MMU_DATA_STORE, mmu_idx, iotlbentry->attrs, r,
+   retaddr);
 }
 if (locked) {
 qemu_mutex_unlock_iothread();
@@ -1216,14 +1215,15 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
  * access type.
  */

-static inline uint64_t handle_bswap(uint64_t val, int size, bool big_endian)
+static inline uint64_t handle_bswap(uint64_t val, MemOp op)
 {
-if ((big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP)) {
-switch (size) {
-case 1: return val;
-case 2: return bswap16(val);
-case 4: return bswap32(val);
-case 8: return bswap64(val);
+if ((memop_big_endian(op) && NEED_BE_BSWAP) ||
+(!memop_big_endian(op) && NEED_LE_BSWAP)) {
+switch (op & MO_SIZE) {
+case MO_8: return val;
+case MO_16: return bswap16(val);
+case MO_32: return bswap32(val);
+case MO_64: return bswap64(val);
 default:
 g_assert_not_reached();
 }
@@ -1246,7 +1246,7 @@ typedef uint64_t FullLoadHelper(CPUArchState *env, 
target_ulong addr,

 static inline uint64_t __attribute__((always_inline))
 load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
-uintptr_t retaddr, size_t size, bool big_endian, bool code_read,
+uintptr_t retaddr, MemOp op, bool code_read,
 FullLoadHelper *full_load)
 {
 uintptr_t mmu_idx = get_mmuidx(oi);
@@ -1260,6 +1260,7 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 unsigned a_bits = get_alignment_bits(get_memop(oi));
 void *haddr;
 uint64_t res;
+size_t size = memop_size(op);

 /* Handle CPU specific unaligned behaviour */
 if (addr & ((1 << a_bits) - 1)) {
@@ -1305,9 +1306,10 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 }
 }

+/* FIXME: io_readx ignores MO_BSWAP.  */
 res = io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
-   mmu_idx, addr, retaddr, access_type, size);
-return handle_bswap(res, size, big_endian);
+   

[Qemu-devel] [PATCH v6 15/26] build: Correct non-common common-obj-* to obj-*

2019-08-07 Thread tony.nguyen
Preparation for replacing device_endian with MemOp.

Device realizing code with MemorRegionOps endianness as
DEVICE_NATIVE_ENDIAN is not common code.

Corrected devices were identified by making the declaration of
DEVICE_NATIVE_ENDIAN conditional upon NEED_CPU_H and then listing
what failed to compile.

Signed-off-by: Tony Nguyen 
---
 hw/audio/Makefile.objs| 11 ++-
 hw/block/Makefile.objs|  8 
 hw/char/Makefile.objs | 22 +++---
 hw/core/Makefile.objs |  2 +-
 hw/display/Makefile.objs  | 10 +-
 hw/dma/Makefile.objs  | 18 +-
 hw/gpio/Makefile.objs |  6 +++---
 hw/i2c/Makefile.objs  |  8 
 hw/input/Makefile.objs|  4 ++--
 hw/intc/Makefile.objs | 19 ++-
 hw/ipack/Makefile.objs|  2 +-
 hw/isa/Makefile.objs  |  2 +-
 hw/misc/Makefile.objs | 18 +-
 hw/net/Makefile.objs  | 14 +++---
 hw/pci-host/Makefile.objs |  6 +++---
 hw/scsi/Makefile.objs |  2 +-
 hw/sd/Makefile.objs   |  2 +-
 hw/ssi/Makefile.objs  | 10 +-
 hw/timer/Makefile.objs| 39 ---
 hw/virtio/Makefile.objs   |  2 +-
 20 files changed, 104 insertions(+), 101 deletions(-)

diff --git a/hw/audio/Makefile.objs b/hw/audio/Makefile.objs
index 63db383..40b26c6 100644
--- a/hw/audio/Makefile.objs
+++ b/hw/audio/Makefile.objs
@@ -5,14 +5,15 @@ common-obj-$(CONFIG_AC97) += ac97.o
 common-obj-$(CONFIG_ADLIB) += fmopl.o adlib.o
 common-obj-$(CONFIG_GUS) += gus.o gusemu_hal.o gusemu_mixer.o
 common-obj-$(CONFIG_CS4231A) += cs4231a.o
-common-obj-$(CONFIG_HDA) += intel-hda.o hda-codec.o
+common-obj-$(CONFIG_HDA) += hda-codec.o
+obj-$(CONFIG_HDA) += intel-hda.o

 common-obj-$(CONFIG_PCSPK) += pcspk.o
 common-obj-$(CONFIG_WM8750) += wm8750.o
-common-obj-$(CONFIG_PL041) += pl041.o lm4549.o
+obj-$(CONFIG_PL041) += pl041.o lm4549.o

-common-obj-$(CONFIG_CS4231) += cs4231.o
-common-obj-$(CONFIG_MARVELL_88W8618) += marvell_88w8618.o
-common-obj-$(CONFIG_MILKYMIST) += milkymist-ac97.o
+obj-$(CONFIG_CS4231) += cs4231.o
+obj-$(CONFIG_MARVELL_88W8618) += marvell_88w8618.o
+obj-$(CONFIG_MILKYMIST) += milkymist-ac97.o

 common-obj-y += soundhw.o
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index f5f643f..9098cda 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -1,12 +1,12 @@
 common-obj-y += block.o cdrom.o hd-geometry.o
-common-obj-$(CONFIG_FDC) += fdc.o
+obj-$(CONFIG_FDC) += fdc.o
 common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
 common-obj-$(CONFIG_NAND) += nand.o
-common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
-common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
+obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
+obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 common-obj-$(CONFIG_XEN) += xen-block.o
 common-obj-$(CONFIG_ECC) += ecc.o
-common-obj-$(CONFIG_ONENAND) += onenand.o
+obj-$(CONFIG_ONENAND) += onenand.o
 common-obj-$(CONFIG_NVME_PCI) += nvme.o

 obj-$(CONFIG_SH4) += tc58128.o
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 02d8a66..af3e76a 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -1,17 +1,17 @@
 common-obj-$(CONFIG_IPACK) += ipoctal232.o
-common-obj-$(CONFIG_ESCC) += escc.o
+obj-$(CONFIG_ESCC) += escc.o
 common-obj-$(CONFIG_NRF51_SOC) += nrf51_uart.o
-common-obj-$(CONFIG_PARALLEL) += parallel.o
+obj-$(CONFIG_PARALLEL) += parallel.o
 common-obj-$(CONFIG_ISA_BUS) += parallel-isa.o
-common-obj-$(CONFIG_PL011) += pl011.o
-common-obj-$(CONFIG_SERIAL) += serial.o
+obj-$(CONFIG_PL011) += pl011.o
+obj-$(CONFIG_SERIAL) += serial.o
 common-obj-$(CONFIG_SERIAL_ISA) += serial-isa.o
 common-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
 common-obj-$(CONFIG_SERIAL_PCI_MULTI) += serial-pci-multi.o
 common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
-common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
+obj-$(CONFIG_XILINX) += xilinx_uartlite.o
 common-obj-$(CONFIG_XEN) += xen_console.o
-common-obj-$(CONFIG_CADENCE) += cadence_uart.o
+obj-$(CONFIG_CADENCE) += cadence_uart.o

 obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
 obj-$(CONFIG_COLDFIRE) += mcf_uart.o
@@ -23,13 +23,13 @@ obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 obj-$(CONFIG_RASPI) += bcm2835_aux.o

 common-obj-$(CONFIG_CMSDK_APB_UART) += cmsdk-apb-uart.o
-common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
+obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
-common-obj-$(CONFIG_GRLIB) += grlib_apbuart.o
-common-obj-$(CONFIG_IMX) += imx_serial.o
+obj-$(CONFIG_GRLIB) += grlib_apbuart.o
+obj-$(CONFIG_IMX) += imx_serial.o
 common-obj-$(CONFIG_LM32) += lm32_juart.o
-common-obj-$(CONFIG_LM32) += lm32_uart.o
-common-obj-$(CONFIG_MILKYMIST) += milkymist-uart.o
+obj-$(CONFIG_LM32) += lm32_uart.o
+obj-$(CONFIG_MILKYMIST) += milkymist-uart.o
 common-obj-$(CONFIG_SCLPCONSOLE) += sclpconsole.o sclpconsole-lm.o

 obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 

[Qemu-devel] [PATCH v6 22/26] memory: Single byte swap along the I/O path

2019-08-07 Thread tony.nguyen
Now that MemOp has been pushed down into the memory API, and
callers are encoding endianness, we can collapse byte swaps
along the I/O path into the accelerator and target independent
adjust_endianness.

Collapsing byte swaps along the I/O path enables additional endian
inversion logic, e.g. SPARC64 Invert Endian TTE bit, with redundant
byte swaps cancelling out.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c | 42 +++--
 hw/virtio/virtio-pci.c | 10 
 memory.c   | 33 ++
 memory_ldst.inc.c  | 64 --
 4 files changed, 19 insertions(+), 130 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 86d85cc..473b8e6 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1200,38 +1200,6 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 cpu_loop_exit_atomic(env_cpu(env), retaddr);
 }

-#ifdef TARGET_WORDS_BIGENDIAN
-#define NEED_BE_BSWAP 0
-#define NEED_LE_BSWAP 1
-#else
-#define NEED_BE_BSWAP 1
-#define NEED_LE_BSWAP 0
-#endif
-
-/*
- * Byte Swap Helper
- *
- * This should all dead code away depending on the build host and
- * access type.
- */
-
-static inline uint64_t handle_bswap(uint64_t val, MemOp op)
-{
-if ((memop_big_endian(op) && NEED_BE_BSWAP) ||
-(!memop_big_endian(op) && NEED_LE_BSWAP)) {
-switch (op & MO_SIZE) {
-case MO_8: return val;
-case MO_16: return bswap16(val);
-case MO_32: return bswap32(val);
-case MO_64: return bswap64(val);
-default:
-g_assert_not_reached();
-}
-} else {
-return val;
-}
-}
-
 /*
  * Load Helpers
  *
@@ -1306,10 +1274,8 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 }
 }

-/* FIXME: io_readx ignores MO_BSWAP.  */
-res = io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
-   mmu_idx, addr, retaddr, access_type, op);
-return handle_bswap(res, op);
+return io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
+mmu_idx, addr, retaddr, access_type, op);
 }

 /* Handle slow unaligned access (it spans two pages or IO).  */
@@ -1552,10 +1518,8 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,
 }
 }

-/* FIXME: io_writex ignores MO_BSWAP.  */
 io_writex(env, _tlb(env)->d[mmu_idx].iotlb[index], mmu_idx,
-  handle_bswap(val, op),
-  addr, retaddr, op);
+  val, addr, retaddr, op);
 return;
 }

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 70eb161..f3fe6ca 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -542,16 +542,15 @@ void virtio_address_space_write(VirtIOPCIProxy *proxy, 
hwaddr addr,
 val = pci_get_byte(buf);
 break;
 case 2:
-val = cpu_to_le16(pci_get_word(buf));
+val = pci_get_word(buf);
 break;
 case 4:
-val = cpu_to_le32(pci_get_long(buf));
+val = pci_get_long(buf);
 break;
 default:
 /* As length is under guest control, handle illegal values. */
 return;
 }
-/* FIXME: memory_region_dispatch_write ignores MO_BSWAP.  */
 memory_region_dispatch_write(mr, addr, val, size_memop(len),
  MEMTXATTRS_UNSPECIFIED);
 }
@@ -576,7 +575,6 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));

-/* FIXME: memory_region_dispatch_read ignores MO_BSWAP.  */
 memory_region_dispatch_read(mr, addr, , size_memop(len),
 MEMTXATTRS_UNSPECIFIED);
 switch (len) {
@@ -584,10 +582,10 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 pci_set_byte(buf, val);
 break;
 case 2:
-pci_set_word(buf, le16_to_cpu(val));
+pci_set_word(buf, val);
 break;
 case 4:
-pci_set_long(buf, le32_to_cpu(val));
+pci_set_long(buf, val);
 break;
 default:
 /* As length is under guest control, handle illegal values. */
diff --git a/memory.c b/memory.c
index 264c624..9d3c3a6 100644
--- a/memory.c
+++ b/memory.c
@@ -343,32 +343,23 @@ static void flatview_simplify(FlatView *view)
 }
 }

-static bool memory_region_wrong_endianness(MemoryRegion *mr)
+static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
 {
-#ifdef TARGET_WORDS_BIGENDIAN
-return mr->ops->endianness == MO_LE;
-#else
-return mr->ops->endianness == MO_BE;
-#endif
-}
-
-static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
-{
-if (memory_region_wrong_endianness(mr)) {
-switch (size) {
-case 1:
+if ((op & MO_BSWAP) != 

[Qemu-devel] [PATCH v6 26/26] target/sparc: sun4u Invert Endian TTE bit

2019-08-07 Thread tony.nguyen
This bit configures endianness of PCI MMIO devices. It is used by
Solaris and OpenBSD sunhme drivers.

Tested working on OpenBSD.

Unfortunately Solaris 10 had a unrelated keyboard issue blocking
testing... another inch towards Solaris 10 on SPARC64 =)

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 target/sparc/cpu.h| 2 ++
 target/sparc/mmu_helper.c | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 1406f0b..c6bafa8 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -275,6 +275,7 @@ enum {

 #define TTE_VALID_BIT   (1ULL << 63)
 #define TTE_NFO_BIT (1ULL << 60)
+#define TTE_IE_BIT  (1ULL << 59)
 #define TTE_USED_BIT(1ULL << 41)
 #define TTE_LOCKED_BIT  (1ULL <<  6)
 #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
@@ -291,6 +292,7 @@ enum {

 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
 #define TTE_IS_NFO(tte) ((tte) & TTE_NFO_BIT)
+#define TTE_IS_IE(tte)  ((tte) & TTE_IE_BIT)
 #define TTE_IS_USED(tte)((tte) & TTE_USED_BIT)
 #define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
 #define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index 826e14b..77dc86a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -537,6 +537,10 @@ static int get_physical_address_data(CPUSPARCState *env, 
hwaddr *physical,
 if (ultrasparc_tag_match(>dtlb[i], address, context, physical)) {
 int do_fault = 0;

+if (TTE_IS_IE(env->dtlb[i].tte)) {
+attrs->byte_swap = true;
+}
+
 /* access ok? */
 /* multiple bits in SFSR.FT may be set on TT_DFAULT */
 if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
@@ -792,7 +796,7 @@ void dump_mmu(CPUSPARCState *env)
 }
 if (TTE_IS_VALID(env->dtlb[i].tte)) {
 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
-", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
+", %s, %s, %s, %s, ie %s, ctx %" PRId64 " %s\n",
 i,
 env->dtlb[i].tag & (uint64_t)~0x1fffULL,
 TTE_PA(env->dtlb[i].tte),
@@ -801,6 +805,8 @@ void dump_mmu(CPUSPARCState *env)
 TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
 TTE_IS_LOCKED(env->dtlb[i].tte) ?
 "locked" : "unlocked",
+TTE_IS_IE(env->dtlb[i].tte) ?
+"yes" : "no",
 env->dtlb[i].tag & (uint64_t)0x1fffULL,
 TTE_IS_GLOBAL(env->dtlb[i].tte) ?
 "global" : "local");
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 18/26] exec: Delete device_endian

2019-08-07 Thread tony.nguyen
device_endian has been made redundant by MemOp.

Signed-off-by: Tony Nguyen 
---
 include/exec/cpu-common.h | 8 
 1 file changed, 8 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 01a29ba..7eeb78c 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -18,14 +18,6 @@ void tcg_flush_softmmu_tlb(CPUState *cs);

 #include "exec/memop.h"

-enum device_endian {
-#ifdef NEED_CPU_H
-DEVICE_NATIVE_ENDIAN = MO_TE,
-#endif
-DEVICE_BIG_ENDIAN = MO_BE,
-DEVICE_LITTLE_ENDIAN = MO_LE,
-};
-
 #if defined(HOST_WORDS_BIGENDIAN)
 #define DEVICE_HOST_ENDIAN MO_BE
 #else
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 23/26] cpu: TLB_FLAGS_MASK bit to force memory slow path

2019-08-07 Thread tony.nguyen
The fast path is taken when TLB_FLAGS_MASK is all zero.

TLB_FORCE_SLOW is simply a TLB_FLAGS_MASK bit to force the slow path,
there are no other side effects.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 include/exec/cpu-all.h | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 536ea58..e496f99 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -331,12 +331,18 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #define TLB_MMIO(1 << (TARGET_PAGE_BITS - 3))
 /* Set if TLB entry must have MMU lookup repeated for every access */
 #define TLB_RECHECK (1 << (TARGET_PAGE_BITS - 4))
+/* Set if TLB entry must take the slow path.  */
+#define TLB_FORCE_SLOW  (1 << (TARGET_PAGE_BITS - 5))

 /* Use this mask to check interception with an alignment mask
  * in a TCG backend.
  */
-#define TLB_FLAGS_MASK  (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
- | TLB_RECHECK)
+#define TLB_FLAGS_MASK \
+(TLB_INVALID_MASK  \
+ | TLB_NOTDIRTY\
+ | TLB_MMIO\
+ | TLB_RECHECK \
+ | TLB_FORCE_SLOW)

 /**
  * tlb_hit_page: return true if page aligned @addr is a hit against the
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 24/26] cputlb: Byte swap memory transaction attribute

2019-08-07 Thread tony.nguyen
Notice new attribute, byte swap, and force the transaction through the
memory slow path.

Required by architectures that can invert endianness of memory
transaction, e.g. SPARC64 has the Invert Endian TTE bit.

Suggested-by: Richard Henderson 
Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 accel/tcg/cputlb.c  | 11 +++
 include/exec/memattrs.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 473b8e6..f6f4dd5 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -738,6 +738,9 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong 
vaddr,
  */
 address |= TLB_RECHECK;
 }
+if (attrs.byte_swap) {
+address |= TLB_FORCE_SLOW;
+}
 if (!memory_region_is_ram(section->mr) &&
 !memory_region_is_romd(section->mr)) {
 /* IO memory case */
@@ -891,6 +894,10 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -933,6 +940,10 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index d4a3477..95f2d20 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
 unsigned int user:1;
 /* Requester ID (for MSI for example) */
 unsigned int requester_id:16;
+/* Invert endianness for this page */
+unsigned int byte_swap:1;
 /*
  * The following are target-specific page-table bits.  These are not
  * related to actual memory transactions at all.  However, this structure
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 25/26] target/sparc: Add TLB entry with attributes

2019-08-07 Thread tony.nguyen
Append MemTxAttrs to interfaces so we can pass along up coming Invert
Endian TTE bit on SPARC64.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 target/sparc/mmu_helper.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index cbd1e91..826e14b 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -88,7 +88,7 @@ static const int perm_table[2][8] = {
 };

 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -219,6 +219,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 target_ulong page_size;
 int error_code = 0, prot, access_index;
+MemTxAttrs attrs = {};

 /*
  * TODO: If we ever need tlb_vaddr_to_host for this target,
@@ -229,7 +230,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 assert(!probe);

 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 vaddr = address;
@@ -490,8 +491,8 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 return 0;
 }

-static int get_physical_address_data(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int rw, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -608,8 +609,8 @@ static int get_physical_address_data(CPUSPARCState *env,
 return 1;
 }

-static int get_physical_address_code(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_code(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -686,7 +687,7 @@ static int get_physical_address_code(CPUSPARCState *env,
 }

 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -716,11 +717,11 @@ static int get_physical_address(CPUSPARCState *env, 
hwaddr *physical,
 }

 if (rw == 2) {
-return get_physical_address_code(env, physical, prot, address,
+return get_physical_address_code(env, physical, prot, attrs, address,
  mmu_idx);
 } else {
-return get_physical_address_data(env, physical, prot, address, rw,
- mmu_idx);
+return get_physical_address_data(env, physical, prot, attrs, address,
+ rw, mmu_idx);
 }
 }

@@ -734,10 +735,11 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 hwaddr paddr;
 target_ulong page_size;
+MemTxAttrs attrs = {};
 int error_code = 0, prot, access_index;

 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 if (likely(error_code == 0)) {
@@ -747,7 +749,8 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
env->dmmu.mmu_primary_context,
env->dmmu.mmu_secondary_context);

-tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
+tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx,
+page_size);
 return true;
 }
 if (probe) {
@@ -849,9 +852,10 @@ static int cpu_sparc_get_phys_page(CPUSPARCState *env, 
hwaddr *phys,
 {
 target_ulong page_size;
 int prot, access_index;
+MemTxAttrs attrs = {};

-return get_physical_address(env, phys, , _index, addr, rw,
-mmu_idx, _size);
+return get_physical_address(env, phys, , _index, , addr,
+rw, mmu_idx, _size);
 }

 #if defined(TARGET_SPARC64)
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 14/26] exec: Hard code size with MO_{8|16|32|64}

2019-08-07 Thread tony.nguyen
Temporarily no-op size_memop was introduced to aid the conversion of
memory_region_dispatch_{read|write} operand "unsigned size" into
"MemOp op".

Now size_memop is implemented, again hard coded size but with
MO_{8|16|32|64}. This is more expressive and avoid size_memop calls.

Signed-off-by: Tony Nguyen 
---
 memory_ldst.inc.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index 1e8a2fc..de658c4 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -38,7 +38,7 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(4), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_32, attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap32(val);
@@ -114,7 +114,7 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(8), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_64, attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap64(val);
@@ -188,7 +188,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(1), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_8, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -224,7 +224,7 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , size_memop(2), attrs);
+r = memory_region_dispatch_read(mr, addr1, , MO_16, attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap16(val);
@@ -300,7 +300,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);

-r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_32, attrs);
 } else {
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
 stl_p(ptr, val);
@@ -346,7 +346,7 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap32(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_32, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -408,7 +408,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (!memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(1), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_8, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -451,7 +451,7 @@ static inline void glue(address_space_stw_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap16(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(2), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_16, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -524,7 +524,7 @@ static void glue(address_space_stq_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap64(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, size_memop(8), attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_64, attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 20/26] memory: Access MemoryRegion with endianness

2019-08-07 Thread tony.nguyen
Preparation for collapsing the two byte swaps adjust_endianness and
handle_bswap into the former.

Call memory_region_dispatch_{read|write} with endianness encoded into
the "MemOp op" operand.

This patch does not change any behaviour as
memory_region_dispatch_{read|write} is yet to handle the endianness.

Once it does handle endianness, callers with byte swaps need to
collapse them into adjust_endianness.

Signed-off-by: Tony Nguyen 
---
 hw/s390x/s390-pci-inst.c |  3 ++-
 hw/virtio/virtio-pci.c   |  2 ++
 include/exec/memop.h |  4 
 memory_ldst.inc.c| 20 +---
 target/mips/op_helper.c  |  4 ++--
 5 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 0e92a37..d322b86 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -782,7 +782,8 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 for (i = 0; i < len / 8; i++) {
 result = memory_region_dispatch_write(mr, offset + i * 8,
   ldq_p(buffer + i * 8),
-  MO_64, MEMTXATTRS_UNSPECIFIED);
+  MO_64 | MO_TE,
+  MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 s390_program_interrupt(env, PGM_OPERAND, 6, ra);
 return 0;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index b929e44..70eb161 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -551,6 +551,7 @@ void virtio_address_space_write(VirtIOPCIProxy *proxy, 
hwaddr addr,
 /* As length is under guest control, handle illegal values. */
 return;
 }
+/* FIXME: memory_region_dispatch_write ignores MO_BSWAP.  */
 memory_region_dispatch_write(mr, addr, val, size_memop(len),
  MEMTXATTRS_UNSPECIFIED);
 }
@@ -575,6 +576,7 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));

+/* FIXME: memory_region_dispatch_read ignores MO_BSWAP.  */
 memory_region_dispatch_read(mr, addr, , size_memop(len),
 MEMTXATTRS_UNSPECIFIED);
 switch (len) {
diff --git a/include/exec/memop.h b/include/exec/memop.h
index 4a4212d..47a5500 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -122,7 +122,11 @@ static inline MemOp size_memop(unsigned size)
 /* Power of 2 up to 8.  */
 assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);
 #endif
+#ifdef NEED_CPU_H
+return ctz32(size) | MO_TE;
+#else
 return ctz32(size);
+#endif
 }

 #endif
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index d7e28d0..ff28b30 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -37,7 +37,8 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , MO_32, attrs);
+/* FIXME: memory_region_dispatch_read ignores MO_BSWAP.  */
+r = memory_region_dispatch_read(mr, addr1, , MO_32 | endian, 
attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == MO_LE) {
 val = bswap32(val);
@@ -112,7 +113,8 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , MO_64, attrs);
+/* FIXME: memory_region_dispatch_read ignores MO_BSWAP.  */
+r = memory_region_dispatch_read(mr, addr1, , MO_64 | endian, 
attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == MO_LE) {
 val = bswap64(val);
@@ -221,7 +223,8 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , MO_16, attrs);
+/* FIXME: memory_region_dispatch_read ignores MO_BSWAP.  */
+r = memory_region_dispatch_read(mr, addr1, , MO_16 | endian, 
attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == MO_LE) {
 val = bswap16(val);
@@ -297,7 +300,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);

-r = memory_region_dispatch_write(mr, addr1, val, MO_32, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, MO_32 | MO_TE, attrs);
 } else {
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
 stl_p(ptr, val);
@@ -343,7 +346,8 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap32(val);
 }
 #endif
-r = 

[Qemu-devel] [PATCH v6 16/26] exec: Map device_endian onto MemOp

2019-08-07 Thread tony.nguyen
Preparation to replace device_endian with MemOp.

Mapping device_endian onto MemOp limits behaviour changes to this
relatively smaller patch.

The next patch will replace all device_endian usages with the
equivalent MemOp. That patch will be large but have no behaviour
changes.

A subsequent patch will then delete unused device_endian.

Signed-off-by: Tony Nguyen 
---
 hw/char/serial.c  | 18 ++
 include/exec/cpu-common.h | 10 +++---
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 7c42a2a..7345f69 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -1012,22 +1012,15 @@ static void serial_mm_write(void *opaque, hwaddr addr,
 serial_ioport_write(s, addr >> s->it_shift, value, 1);
 }

-static const MemoryRegionOps serial_mm_ops[3] = {
-[DEVICE_NATIVE_ENDIAN] = {
-.read = serial_mm_read,
-.write = serial_mm_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
-.valid.max_access_size = 8,
-.impl.max_access_size = 8,
-},
-[DEVICE_LITTLE_ENDIAN] = {
+static const MemoryRegionOps serial_mm_ops[2] = {
+[0] = {
 .read = serial_mm_read,
 .write = serial_mm_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid.max_access_size = 8,
 .impl.max_access_size = 8,
 },
-[DEVICE_BIG_ENDIAN] = {
+[1] = {
 .read = serial_mm_read,
 .write = serial_mm_write,
 .endianness = DEVICE_BIG_ENDIAN,
@@ -1053,8 +1046,9 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
 serial_realize_core(s, _fatal);
 vmstate_register(NULL, base, _serial, s);

-memory_region_init_io(>io, NULL, _mm_ops[end], s,
-  "serial", 8 << it_shift);
+memory_region_init_io(>io, NULL,
+  _mm_ops[end == DEVICE_LITTLE_ENDIAN ? 0 : 1],
+  s, "serial", 8 << it_shift);
 memory_region_add_subregion(address_space, base, >io);
 return s;
 }
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index f7dbe75..c388453 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -16,10 +16,14 @@ void tcg_flush_softmmu_tlb(CPUState *cs);

 #if !defined(CONFIG_USER_ONLY)

+#include "exec/memop.h"
+
 enum device_endian {
-DEVICE_NATIVE_ENDIAN,
-DEVICE_BIG_ENDIAN,
-DEVICE_LITTLE_ENDIAN,
+#ifdef NEED_CPU_H
+DEVICE_NATIVE_ENDIAN = MO_TE,
+#endif
+DEVICE_BIG_ENDIAN = MO_BE,
+DEVICE_LITTLE_ENDIAN = MO_LE,
 };

 #if defined(HOST_WORDS_BIGENDIAN)
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 13/26] target/mips: Hard code size with MO_{8|16|32|64}

2019-08-07 Thread tony.nguyen
Temporarily no-op size_memop was introduced to aid the conversion of
memory_region_dispatch_{read|write} operand "unsigned size" into
"MemOp op".

Now size_memop is implemented, again hard coded size but with
MO_{8|16|32|64}. This is more expressive and avoid size_memop calls.

Signed-off-by: Tony Nguyen 
---
 target/mips/op_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 1c72a00..e79f99d 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -4741,11 +4741,11 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 if (op == 9) {
 /* Index Store Tag */
 memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
- size_memop(8), MEMTXATTRS_UNSPECIFIED);
+ MO_64, MEMTXATTRS_UNSPECIFIED);
 } else if (op == 5) {
 /* Index Load Tag */
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
-size_memop(8), MEMTXATTRS_UNSPECIFIED);
+MO_64, MEMTXATTRS_UNSPECIFIED);
 }
 #endif
 }
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 19/26] exec: Delete DEVICE_HOST_ENDIAN

2019-08-07 Thread tony.nguyen
DEVICE_HOST_ENDIAN is conditional upon HOST_WORDS_BIGENDIAN.

Code is cleaner if the single use of DEVICE_HOST_ENDIAN is instead
directly conditional upon HOST_WORDS_BIGENDIAN.

Signed-off-by: Tony Nguyen 
---
 include/exec/cpu-common.h | 8 
 memory.c  | 6 +-
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 7eeb78c..b33dc0c 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -16,14 +16,6 @@ void tcg_flush_softmmu_tlb(CPUState *cs);

 #if !defined(CONFIG_USER_ONLY)

-#include "exec/memop.h"
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define DEVICE_HOST_ENDIAN MO_BE
-#else
-#define DEVICE_HOST_ENDIAN MO_LE
-#endif
-
 /* address in the RAM (different from a physical address) */
 #if defined(CONFIG_XEN_BACKEND)
 typedef uint64_t ram_addr_t;
diff --git a/memory.c b/memory.c
index 3cabb52..11db6ec 100644
--- a/memory.c
+++ b/memory.c
@@ -1362,7 +1362,11 @@ static void memory_region_ram_device_write(void *opaque, 
hwaddr addr,
 static const MemoryRegionOps ram_device_mem_ops = {
 .read = memory_region_ram_device_read,
 .write = memory_region_ram_device_write,
-.endianness = DEVICE_HOST_ENDIAN,
+#if defined(HOST_WORDS_BIGENDIAN)
+.endianness = MO_BE,
+#else
+.endianness = MO_LE,
+#endif
 .valid = {
 .min_access_size = 1,
 .max_access_size = 8,
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 09/26] exec: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 exec.c|  6 --
 memory_ldst.inc.c | 18 +-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/exec.c b/exec.c
index 3e78de3..9f69197 100644
--- a/exec.c
+++ b/exec.c
@@ -3334,7 +3334,8 @@ static MemTxResult flatview_write_continue(FlatView *fv, 
hwaddr addr,
 /* XXX: could force current_cpu to NULL to avoid
potential bugs */
 val = ldn_p(buf, l);
-result |= memory_region_dispatch_write(mr, addr1, val, l, attrs);
+result |= memory_region_dispatch_write(mr, addr1, val,
+   size_memop(l), attrs);
 } else {
 /* RAM case */
 ptr = qemu_ram_ptr_length(mr->ram_block, addr1, , false);
@@ -3395,7 +3396,8 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr 
addr,
 /* I/O case */
 release_lock |= prepare_mmio_access(mr);
 l = memory_access_size(mr, l, addr1);
-result |= memory_region_dispatch_read(mr, addr1, , l, attrs);
+result |= memory_region_dispatch_read(mr, addr1, ,
+  size_memop(l), attrs);
 stn_p(buf, l, val);
 } else {
 /* RAM case */
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index acf865b..1e8a2fc 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -38,7 +38,7 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 4, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(4), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap32(val);
@@ -114,7 +114,7 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 8, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(8), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap64(val);
@@ -188,7 +188,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 1, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(1), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -224,7 +224,7 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 2, attrs);
+r = memory_region_dispatch_read(mr, addr1, , size_memop(2), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap16(val);
@@ -300,7 +300,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);

-r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
 } else {
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
 stl_p(ptr, val);
@@ -346,7 +346,7 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap32(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, size_memop(4), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -408,7 +408,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (!memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, size_memop(1), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -451,7 +451,7 @@ static inline void glue(address_space_stw_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap16(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, 

[Qemu-devel] [PATCH v6 08/26] hw/vfio: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 hw/vfio/pci-quirks.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index b35a640..fb3cc33 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -11,6 +11,7 @@
  */

 #include "qemu/osdep.h"
+#include "exec/memop.h"
 #include "qemu/units.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
@@ -1071,7 +1072,7 @@ static void vfio_rtl8168_quirk_address_write(void 
*opaque, hwaddr addr,

 /* Write to the proper guest MSI-X table instead */
 memory_region_dispatch_write(>pdev.msix_table_mmio,
- offset, val, size,
+ offset, val, size_memop(size),
  MEMTXATTRS_UNSPECIFIED);
 }
 return; /* Do not write guest MSI-X data to hardware */
@@ -1102,7 +1103,8 @@ static uint64_t vfio_rtl8168_quirk_data_read(void *opaque,
 if (rtl->enabled && (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX)) {
 hwaddr offset = rtl->addr & 0xfff;
 memory_region_dispatch_read(>pdev.msix_table_mmio, offset,
-, size, MEMTXATTRS_UNSPECIFIED);
+, size_memop(size),
+MEMTXATTRS_UNSPECIFIED);
 trace_vfio_quirk_rtl8168_msix_read(vdev->vbasedev.name, offset, data);
 }

--
1.8.3.1

?



[Qemu-devel] [PATCH v6 10/26] cputlb: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 523be4c..6c83878 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -906,8 +906,8 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_read(mr, mr_offset,
-, size, iotlbentry->attrs);
+r = memory_region_dispatch_read(mr, mr_offset, , size_memop(size),
+iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
@@ -947,8 +947,8 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_write(mr, mr_offset,
- val, size, iotlbentry->attrs);
+r = memory_region_dispatch_write(mr, mr_offset, val, size_memop(size),
+ iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 12/26] hw/s390x: Hard code size with MO_{8|16|32|64}

2019-08-07 Thread tony.nguyen
Temporarily no-op size_memop was introduced to aid the conversion of
memory_region_dispatch_{read|write} operand "unsigned size" into
"MemOp op".

Now size_memop is implemented, again hard coded size but with
MO_{8|16|32|64}. This is more expressive and avoid size_memop calls.

Signed-off-by: Tony Nguyen 
---
 hw/s390x/s390-pci-inst.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 0c958fc..0e92a37 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -782,8 +782,7 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,
 for (i = 0; i < len / 8; i++) {
 result = memory_region_dispatch_write(mr, offset + i * 8,
   ldq_p(buffer + i * 8),
-  size_memop(8),
-  MEMTXATTRS_UNSPECIFIED);
+  MO_64, MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 s390_program_interrupt(env, PGM_OPERAND, 6, ra);
 return 0;
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 11/26] memory: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
Convert memory_region_dispatch_{read|write} operand "unsigned size"
into a "MemOp op".

Signed-off-by: Tony Nguyen 
---
 include/exec/memop.h  | 18 +-
 include/exec/memory.h |  9 +
 memory.c  |  7 +--
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index 5c5769e..4a4212d 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -12,6 +12,8 @@
 #ifndef MEMOP_H
 #define MEMOP_H

+#include "qemu/host-utils.h"
+
 typedef enum MemOp {
 MO_8 = 0,
 MO_16= 1,
@@ -107,14 +109,20 @@ typedef enum MemOp {
 MO_SSIZE = MO_SIZE | MO_SIGN,
 } MemOp;

+/* MemOp to size in bytes.  */
+static inline unsigned memop_size(MemOp op)
+{
+return 1 << ((op) & MO_SIZE);
+}
+
 /* Size in bytes to MemOp.  */
 static inline MemOp size_memop(unsigned size)
 {
-/*
- * FIXME: No-op to aid conversion of memory_region_dispatch_{read|write}
- * "unsigned size" operand into a "MemOp op".
- */
-return size;
+#ifdef CONFIG_DEBUG_TCG
+/* Power of 2 up to 8.  */
+assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);
+#endif
+return ctz32(size);
 }

 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bb0961d..975b86a 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -19,6 +19,7 @@
 #include "exec/cpu-common.h"
 #include "exec/hwaddr.h"
 #include "exec/memattrs.h"
+#include "exec/memop.h"
 #include "exec/ramlist.h"
 #include "qemu/queue.h"
 #include "qemu/int128.h"
@@ -1731,13 +1732,13 @@ void mtree_info(bool flatview, bool dispatch_tree, bool 
owner);
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @pval: pointer to uint64_t which the data is written to
- * @size: size of the access in bytes
+ * @op: size, sign, and endianness of the memory operation
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 hwaddr addr,
 uint64_t *pval,
-unsigned size,
+MemOp op,
 MemTxAttrs attrs);
 /**
  * memory_region_dispatch_write: perform a write directly to the specified
@@ -1746,13 +1747,13 @@ MemTxResult memory_region_dispatch_read(MemoryRegion 
*mr,
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @data: data to write
- * @size: size of the access in bytes
+ * @op: size, sign, and endianness of the memory operation
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
  hwaddr addr,
  uint64_t data,
- unsigned size,
+ MemOp op,
  MemTxAttrs attrs);

 /**
diff --git a/memory.c b/memory.c
index 5d8c9a9..89ea4fb 100644
--- a/memory.c
+++ b/memory.c
@@ -1439,9 +1439,10 @@ static MemTxResult 
memory_region_dispatch_read1(MemoryRegion *mr,
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 hwaddr addr,
 uint64_t *pval,
-unsigned size,
+MemOp op,
 MemTxAttrs attrs)
 {
+unsigned size = memop_size(op);
 MemTxResult r;

 if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
@@ -1483,9 +1484,11 @@ static bool 
memory_region_dispatch_write_eventfds(MemoryRegion *mr,
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
  hwaddr addr,
  uint64_t data,
- unsigned size,
+ MemOp op,
  MemTxAttrs attrs)
 {
+unsigned size = memop_size(op);
+
 if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
 unassigned_mem_write(mr, addr, data, size);
 return MEMTX_DECODE_ERROR;
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 05/26] hw/s390x: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 hw/s390x/s390-pci-inst.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 0023514..0c958fc 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -15,6 +15,7 @@
 #include "cpu.h"
 #include "s390-pci-inst.h"
 #include "s390-pci-bus.h"
+#include "exec/memop.h"
 #include "exec/memory-internal.h"
 #include "qemu/error-report.h"
 #include "sysemu/hw_accel.h"
@@ -372,7 +373,7 @@ static MemTxResult zpci_read_bar(S390PCIBusDevice *pbdev, 
uint8_t pcias,
 mr = pbdev->pdev->io_regions[pcias].memory;
 mr = s390_get_subregion(mr, offset, len);
 offset -= mr->addr;
-return memory_region_dispatch_read(mr, offset, data, len,
+return memory_region_dispatch_read(mr, offset, data, size_memop(len),
MEMTXATTRS_UNSPECIFIED);
 }

@@ -471,7 +472,7 @@ static MemTxResult zpci_write_bar(S390PCIBusDevice *pbdev, 
uint8_t pcias,
 mr = pbdev->pdev->io_regions[pcias].memory;
 mr = s390_get_subregion(mr, offset, len);
 offset -= mr->addr;
-return memory_region_dispatch_write(mr, offset, data, len,
+return memory_region_dispatch_write(mr, offset, data, size_memop(len),
 MEMTXATTRS_UNSPECIFIED);
 }

@@ -780,7 +781,8 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,

 for (i = 0; i < len / 8; i++) {
 result = memory_region_dispatch_write(mr, offset + i * 8,
-  ldq_p(buffer + i * 8), 8,
+  ldq_p(buffer + i * 8),
+  size_memop(8),
   MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 s390_program_interrupt(env, PGM_OPERAND, 6, ra);
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 07/26] hw/virtio: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 hw/virtio/virtio-pci.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f6d2223..25875c8 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -17,6 +17,7 @@

 #include "qemu/osdep.h"

+#include "exec/memop.h"
 #include "standard-headers/linux/virtio_pci.h"
 #include "hw/virtio/virtio.h"
 #include "hw/pci/pci.h"
@@ -550,7 +551,8 @@ void virtio_address_space_write(VirtIOPCIProxy *proxy, 
hwaddr addr,
 /* As length is under guest control, handle illegal values. */
 return;
 }
-memory_region_dispatch_write(mr, addr, val, len, MEMTXATTRS_UNSPECIFIED);
+memory_region_dispatch_write(mr, addr, val, size_memop(len),
+ MEMTXATTRS_UNSPECIFIED);
 }

 static void
@@ -573,7 +575,8 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));

-memory_region_dispatch_read(mr, addr, , len, MEMTXATTRS_UNSPECIFIED);
+memory_region_dispatch_read(mr, addr, , size_memop(len),
+MEMTXATTRS_UNSPECIFIED);
 switch (len) {
 case 1:
 pci_set_byte(buf, val);
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 06/26] hw/intc/armv7m_nic: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 hw/intc/armv7m_nvic.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 9f8f0d3..237ccef 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -18,6 +18,7 @@
 #include "hw/intc/armv7m_nvic.h"
 #include "target/arm/cpu.h"
 #include "exec/exec-all.h"
+#include "exec/memop.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "trace.h"
@@ -2345,7 +2346,8 @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_write(mr, addr, value, size, attrs);
+return memory_region_dispatch_write(mr, addr, value, size_memop(size),
+attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2364,7 +2366,8 @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_read(mr, addr, data, size, attrs);
+return memory_region_dispatch_read(mr, addr, data, size_memop(size),
+   attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2390,7 +2393,8 @@ static MemTxResult nvic_systick_write(void *opaque, 
hwaddr addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_write(mr, addr, value, size, attrs);
+return memory_region_dispatch_write(mr, addr, value, size_memop(size),
+attrs);
 }

 static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
@@ -2402,7 +2406,7 @@ static MemTxResult nvic_systick_read(void *opaque, hwaddr 
addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_read(mr, addr, data, size, attrs);
+return memory_region_dispatch_read(mr, addr, data, size_memop(size), 
attrs);
 }

 static const MemoryRegionOps nvic_systick_ops = {
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 04/26] target/mips: Access MemoryRegion with MemOp

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Convert interfaces by using no-op size_memop.

After all interfaces are converted, size_memop will be implemented
and the memory_region_dispatch_{read|write} operand "unsigned size"
will be converted into a "MemOp op".

As size_memop is a no-op, this patch does not change any behaviour.

Signed-off-by: Tony Nguyen 
Reviewed-by: Richard Henderson 
---
 target/mips/op_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 9e2e02f..1c72a00 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -24,6 +24,7 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "exec/memop.h"
 #include "sysemu/kvm.h"

 /*/
@@ -4740,11 +4741,11 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 if (op == 9) {
 /* Index Store Tag */
 memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
- 8, MEMTXATTRS_UNSPECIFIED);
+ size_memop(8), MEMTXATTRS_UNSPECIFIED);
 } else if (op == 5) {
 /* Index Load Tag */
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
-8, MEMTXATTRS_UNSPECIFIED);
+size_memop(8), MEMTXATTRS_UNSPECIFIED);
 }
 #endif
 }
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 02/26] tcg: TCGMemOp is now accelerator independent MemOp

2019-08-07 Thread tony.nguyen
Preparation for collapsing the two byte swaps, adjust_endianness and
handle_bswap, along the I/O path.

Target dependant attributes are conditionalize upon NEED_CPU_H.

Signed-off-by: Tony Nguyen 
Acked-by: David Gibson 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |   1 +
 accel/tcg/cputlb.c  |   2 +-
 include/exec/memop.h| 110 ++
 target/alpha/translate.c|   2 +-
 target/arm/translate-a64.c  |  48 ++--
 target/arm/translate-a64.h  |   2 +-
 target/arm/translate-sve.c  |   2 +-
 target/arm/translate.c  |  32 
 target/arm/translate.h  |   2 +-
 target/hppa/translate.c |  14 ++--
 target/i386/translate.c | 132 
 target/m68k/translate.c |   2 +-
 target/microblaze/translate.c   |   4 +-
 target/mips/translate.c |   8 +-
 target/openrisc/translate.c |   4 +-
 target/ppc/translate.c  |  12 +--
 target/riscv/insn_trans/trans_rva.inc.c |   8 +-
 target/riscv/insn_trans/trans_rvi.inc.c |   4 +-
 target/s390x/translate.c|   6 +-
 target/s390x/translate_vx.inc.c |  10 +--
 target/sparc/translate.c|  14 ++--
 target/tilegx/translate.c   |  10 +--
 target/tricore/translate.c  |   8 +-
 tcg/README  |   2 +-
 tcg/aarch64/tcg-target.inc.c|  26 +++
 tcg/arm/tcg-target.inc.c|  26 +++
 tcg/i386/tcg-target.inc.c   |  24 +++---
 tcg/mips/tcg-target.inc.c   |  16 ++--
 tcg/optimize.c  |   2 +-
 tcg/ppc/tcg-target.inc.c|  12 +--
 tcg/riscv/tcg-target.inc.c  |  20 ++---
 tcg/s390/tcg-target.inc.c   |  14 ++--
 tcg/sparc/tcg-target.inc.c  |   6 +-
 tcg/tcg-op.c|  38 -
 tcg/tcg-op.h|  86 ++---
 tcg/tcg.c   |   2 +-
 tcg/tcg.h   | 101 ++--
 trace/mem-internal.h|   4 +-
 trace/mem.h |   4 +-
 39 files changed, 421 insertions(+), 399 deletions(-)
 create mode 100644 include/exec/memop.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d6de200..c7cf84a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1889,6 +1889,7 @@ M: Paolo Bonzini 
 S: Supported
 F: include/exec/ioport.h
 F: ioport.c
+F: include/exec/memop.h
 F: include/exec/memory.h
 F: include/exec/ram_addr.h
 F: memory.c
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index bb9897b..523be4c 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1133,7 +1133,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 uintptr_t index = tlb_index(env, mmu_idx, addr);
 CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
 target_ulong tlb_addr = tlb_addr_write(tlbe);
-TCGMemOp mop = get_memop(oi);
+MemOp mop = get_memop(oi);
 int a_bits = get_alignment_bits(mop);
 int s_bits = mop & MO_SIZE;
 void *hostaddr;
diff --git a/include/exec/memop.h b/include/exec/memop.h
new file mode 100644
index 000..7262ca3
--- /dev/null
+++ b/include/exec/memop.h
@@ -0,0 +1,110 @@
+/*
+ * Constants for memory operations
+ *
+ * Authors:
+ *  Richard Henderson 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MEMOP_H
+#define MEMOP_H
+
+typedef enum MemOp {
+MO_8 = 0,
+MO_16= 1,
+MO_32= 2,
+MO_64= 3,
+MO_SIZE  = 3,   /* Mask for the above.  */
+
+MO_SIGN  = 4,   /* Sign-extended, otherwise zero-extended.  */
+
+MO_BSWAP = 8,   /* Host reverse endian.  */
+#ifdef HOST_WORDS_BIGENDIAN
+MO_LE= MO_BSWAP,
+MO_BE= 0,
+#else
+MO_LE= 0,
+MO_BE= MO_BSWAP,
+#endif
+#ifdef NEED_CPU_H
+#ifdef TARGET_WORDS_BIGENDIAN
+MO_TE= MO_BE,
+#else
+MO_TE= MO_LE,
+#endif
+#endif
+
+/*
+ * MO_UNALN accesses are never checked for alignment.
+ * MO_ALIGN accesses will result in a call to the CPU's
+ * do_unaligned_access hook if the guest address is not aligned.
+ * The default depends on whether the target CPU defines
+ * TARGET_ALIGNED_ONLY.
+ *
+ * Some architectures (e.g. ARMv8) need the address which is aligned
+ * to a size more than the size of the memory access.
+ * Some architectures (e.g. SPARCv9) need an address which is aligned,
+ * but less strictly than the natural alignment.
+ *
+ * MO_ALIGN supposes the alignment size is the size of a memory access.
+ *
+ * There are three options:
+ * - unaligned access permitted (MO_UNALN).
+ * - an alignment to 

[Qemu-devel] [PATCH v6 03/26] memory: Introduce size_memop

2019-08-07 Thread tony.nguyen
The memory_region_dispatch_{read|write} operand "unsigned size" is
being converted into a "MemOp op".

Introduce no-op size_memop to aid preparatory conversion of
interfaces.

Once interfaces are converted, size_memop will be implemented to
return a MemOp from size in bytes.

Signed-off-by: Tony Nguyen 
---
 include/exec/memop.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index 7262ca3..5c5769e 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -107,4 +107,14 @@ typedef enum MemOp {
 MO_SSIZE = MO_SIZE | MO_SIGN,
 } MemOp;

+/* Size in bytes to MemOp.  */
+static inline MemOp size_memop(unsigned size)
+{
+/*
+ * FIXME: No-op to aid conversion of memory_region_dispatch_{read|write}
+ * "unsigned size" operand into a "MemOp op".
+ */
+return size;
+}
+
 #endif
--
1.8.3.1

?



[Qemu-devel] [PATCH v6 01/26] configure: Define TARGET_ALIGNED_ONLY

2019-08-07 Thread tony.nguyen
Rename ALIGNED_ONLY to TARGET_ALIGNED_ONLY for clarity and move
defines out of target/foo/cpu.h into configure, as we do with
TARGET_WORDS_BIGENDIAN, so that it is always defined early.

Poisoned TARGET_ALIGNED_ONLY to prevent use in common code.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Reviewed-by: Aleksandar Markovic 
---
 configure | 10 +-
 include/exec/poison.h |  1 +
 include/qom/cpu.h |  2 +-
 target/alpha/cpu.h|  2 --
 target/hppa/cpu.h |  1 -
 target/mips/cpu.h |  2 --
 target/sh4/cpu.h  |  2 --
 target/sparc/cpu.h|  2 --
 target/xtensa/cpu.h   |  2 --
 tcg/tcg.c |  2 +-
 tcg/tcg.h |  8 +---
 11 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/configure b/configure
index 714e7fb..482ba0b 100755
--- a/configure
+++ b/configure
@@ -7431,8 +7431,13 @@ for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
 target_name=$(echo $target | cut -d '-' -f 1)
+target_aligned_only="no"
+case "$target_name" in
+  
alpha|hppa|mips64el|mips64|mipsel|mips|mipsn32|mipsn32el|sh4|sh4eb|sparc|sparc64|sparc32plus|xtensa|xtensaeb)
+  target_aligned_only="yes"
+  ;;
+esac
 target_bigendian="no"
-
 case "$target_name" in
   
armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
@@ -7717,6 +7722,9 @@ fi
 if supported_whpx_target $target; then
 echo "CONFIG_WHPX=y" >> $config_target_mak
 fi
+if test "$target_aligned_only" = "yes" ; then
+  echo "TARGET_ALIGNED_ONLY=y" >> $config_target_mak
+fi
 if test "$target_bigendian" = "yes" ; then
   echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
 fi
diff --git a/include/exec/poison.h b/include/exec/poison.h
index b862320..955eb86 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -35,6 +35,7 @@
 #pragma GCC poison TARGET_UNICORE32
 #pragma GCC poison TARGET_XTENSA

+#pragma GCC poison TARGET_ALIGNED_ONLY
 #pragma GCC poison TARGET_HAS_BFLT
 #pragma GCC poison TARGET_NAME
 #pragma GCC poison TARGET_SUPPORTS_MTTCG
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 5ee0046..9b50b73 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -89,7 +89,7 @@ struct TranslationBlock;
  * @do_unassigned_access: Callback for unassigned access handling.
  * (this is deprecated: new targets should use do_transaction_failed instead)
  * @do_unaligned_access: Callback for unaligned access handling, if
- * the target defines #ALIGNED_ONLY.
+ * the target defines #TARGET_ALIGNED_ONLY.
  * @do_transaction_failed: Callback for handling failed memory transactions
  * (ie bus faults or external aborts; not MMU faults)
  * @virtio_is_big_endian: Callback to return %true if a CPU which supports
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index b3e8a82..16eb804 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"

-#define ALIGNED_ONLY
-
 /* Alpha processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)

diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index aab251b..2be67c2 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -30,7 +30,6 @@
basis.  It's probably easier to fall back to a strong memory model.  */
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL

-#define ALIGNED_ONLY
 #define MMU_KERNEL_IDX   0
 #define MMU_USER_IDX 3
 #define MMU_PHYS_IDX 4
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 21c0615..c13cd4e 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1,8 +1,6 @@
 #ifndef MIPS_CPU_H
 #define MIPS_CPU_H

-#define ALIGNED_ONLY
-
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index aee733e..ecaa7a1 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"

-#define ALIGNED_ONLY
-
 /* CPU Subtypes */
 #define SH_CPU_SH7750  (1 << 0)
 #define SH_CPU_SH7750S (1 << 1)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ed2250..1406f0b 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -5,8 +5,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"

-#define ALIGNED_ONLY
-
 #if !defined(TARGET_SPARC64)
 #define TARGET_DPREGS 16
 #else
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 2c27713..0459243 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -32,8 +32,6 @@
 #include "exec/cpu-defs.h"
 #include "xtensa-isa.h"

-#define ALIGNED_ONLY
-
 /* Xtensa processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index be2c33c..8d23fb0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1926,7 +1926,7 @@ static const char * const ldst_name[] =
 };

 static const char * const alignment_name[(MO_AMASK >> 

[Qemu-devel] [PATCH v6 00/26] Invert Endian bit in SPARCv9 MMU TTE

2019-08-07 Thread tony.nguyen
This patchset implements the IE (Invert Endian) bit in SPARCv9 MMU TTE.

It is an attempt of the instructions outlined by Richard Henderson to Mark
Cave-Ayland.

Tested with OpenBSD on sun4u. Solaris 10 is my actual goal, but unfortunately a
separate keyboard issue remains in the way.

On 01/11/17 19:15, Mark Cave-Ayland wrote:

>On 15/08/17 19:10, Richard Henderson wrote:
>
>> [CC Peter re MemTxAttrs below]
>>
>> On 08/15/2017 09:38 AM, Mark Cave-Ayland wrote:
>>> Working through an incorrect endian issue on qemu-system-sparc64, it has
>>> become apparent that at least one OS makes use of the IE (Invert Endian)
>>> bit in the SPARCv9 MMU TTE to map PCI memory space without the
>>> programmer having to manually endian-swap accesses.
>>>
>>> In other words, to quote the UltraSPARC specification: "if this bit is
>>> set, accesses to the associated page are processed with inverse
>>> endianness from what is specified by the instruction (big-for-little and
>>> little-for-big)".

A good explanation by Mark why the IE bit is required.

>>>
>>> Looking through various bits of code, I'm trying to get a feel for the
>>> best way to implement this in an efficient manner. From what I can see
>>> this could be solved using an additional MMU index, however I'm not
>>> overly familiar with the memory and softmmu subsystems.
>>
>> No, it can't be solved with an MMU index.
>>
>>> Can anyone point me in the right direction as to what would be the best
>>> way to implement this feature within QEMU?
>>
>> It's definitely tricky.
>>
>> We definitely need some TLB_FLAGS_MASK bit set so that we're forced through
>> the
>> memory slow path.  There is no other way to bypass the endianness that we've
>> already encoded from the target instruction.
>>
>> Given the tlb_set_page_with_attrs interface, I would think that we need a new
>> bit in MemTxAttrs, so that the target/sparc tlb_fill (and subroutines) can
>> pass
>> along the TTE bit for the given page.
>>
>> We have an existing problem in softmmu_template.h,
>>
>> /* ??? Note that the io helpers always read data in the target
>>byte ordering.  We should push the LE/BE request down into io.  */
>> res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
>> res = TGT_BE(res);
>>
>> We do not want to add a third(!) byte swap along the i/o path.  We need to
>> collapse the two that we have already before considering this one.
>>
>> This probably takes the form of:
>>
>> (1) Replacing the "int size" argument with "TCGMemOp memop" for
>>   a) io_{read,write}x in accel/tcg/cputlb.c,
>>   b) memory_region_dispatch_{read,write} in memory.c,
>>   c) adjust_endianness in memory.c.
>> This carries size+sign+endianness down to the next level.
>>
>> (2) In memory.c, adjust_endianness,
>>
>>  if (memory_region_wrong_endianness(mr)) {
>> -switch (size) {
>> +memop ^= MO_BSWAP;
>> +}
>> +if (memop & MO_BSWAP) {
>>
>> For extra credit, re-arrange memory_region_wrong_endianness
>> to something more explicit -- "wrong" isn't helpful.
>
>Finally I've had a bit of spare time to experiment with this approach,
>and from what I can see there are currently 2 issues:
>
>
>1) Using TCGMemOp in memory.c means it is no longer accelerator agnostic
>
>For the moment I've defined a separate MemOp in memory.h and provided a
>mapping function in io_{read,write}x to map from TCGMemOp to MemOp and
>then pass that into memory_region_dispatch_{read,write}.
>
>Other than not referencing TCGMemOp in the memory API, another reason
>for doing this was that I wasn't convinced that all the MO_ attributes
>were valid outside of TCG. I do, of course, strongly defer to other
>people's knowledge in this area though.
>
>
>2) The above changes to adjust_endianness() fail when
>memory_region_dispatch_{read,write} are called recursively
>
>Whilst booting qemu-system-sparc64 I see that
>memory_region_dispatch_{read,write} get called recursively - once via
>io_{read,write}x and then again via flatview_read_continue() in exec.c.
>
>The net effect of this is that we perform the bswap correctly at the
>tail of the recursion, but then as we travel back up the stack we hit
>memory_region_dispatch_{read,write} once again causing a second bswap
>which means the value is returned with the incorrect endian again.
>
>
>My understanding from your softmmu_template.h comment above is that the
>memory API should do the endian swapping internally allowing the removal
>of the final TGT_BE/TGT_LE applied to the result, or did I get this wrong?
>
>> (3) In tlb_set_page_with_attrs, notice attrs.byte_swap and set
>> a new TLB_FORCE_SLOW bit within TLB_FLAGS_MASK.
>>
>> (4) In io_{read,write}x, if iotlbentry->attrs.byte_swap is set,
>> then memop ^= MO_BSWAP.

Thanks all for the feedback. Learnt a lot =)

v2:
- Moved size+sign+endianness attributes from TCGMemOp into MemOp.
  In v1 TCGMemOp was re-purposed entirely into MemOp.
- Replaced MemOp MO_{8|16|32|64} with 

[Qemu-devel] [PATCH v4 1/1] configure: Define target access alignment in configure

2019-07-31 Thread tony.nguyen
Rename ALIGNED_ONLY to TARGET_ALIGNED_ONLY for clarity and move
defines out of target/foo/cpu.h into configure, as we do with
TARGET_WORDS_BIGENDIAN, so that it is always defined early.

Poison TARGET_ALIGNED_ONLY to prevent use in common code.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 configure | 10 +-
 include/exec/poison.h |  1 +
 include/qom/cpu.h |  2 +-
 target/alpha/cpu.h|  2 --
 target/hppa/cpu.h |  1 -
 target/mips/cpu.h |  2 --
 target/sh4/cpu.h  |  2 --
 target/sparc/cpu.h|  2 --
 target/xtensa/cpu.h   |  2 --
 tcg/tcg.c |  2 +-
 tcg/tcg.h |  8 +---
 11 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/configure b/configure
index 714e7fb6a1..482ba0b240 100755
--- a/configure
+++ b/configure
@@ -7431,8 +7431,13 @@ for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
 target_name=$(echo $target | cut -d '-' -f 1)
+target_aligned_only="no"
+case "$target_name" in
+  
alpha|hppa|mips64el|mips64|mipsel|mips|mipsn32|mipsn32el|sh4|sh4eb|sparc|sparc64|sparc32plus|xtensa|xtensaeb)
+  target_aligned_only="yes"
+  ;;
+esac
 target_bigendian="no"
-
 case "$target_name" in
   
armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
@@ -7717,6 +7722,9 @@ fi
 if supported_whpx_target $target; then
 echo "CONFIG_WHPX=y" >> $config_target_mak
 fi
+if test "$target_aligned_only" = "yes" ; then
+  echo "TARGET_ALIGNED_ONLY=y" >> $config_target_mak
+fi
 if test "$target_bigendian" = "yes" ; then
   echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
 fi
diff --git a/include/exec/poison.h b/include/exec/poison.h
index b862320fa6..955eb863ab 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -35,6 +35,7 @@
 #pragma GCC poison TARGET_UNICORE32
 #pragma GCC poison TARGET_XTENSA
 
+#pragma GCC poison TARGET_ALIGNED_ONLY
 #pragma GCC poison TARGET_HAS_BFLT
 #pragma GCC poison TARGET_NAME
 #pragma GCC poison TARGET_SUPPORTS_MTTCG
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 5ee0046b62..9b50b73339 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -89,7 +89,7 @@ struct TranslationBlock;
  * @do_unassigned_access: Callback for unassigned access handling.
  * (this is deprecated: new targets should use do_transaction_failed instead)
  * @do_unaligned_access: Callback for unaligned access handling, if
- * the target defines #ALIGNED_ONLY.
+ * the target defines #TARGET_ALIGNED_ONLY.
  * @do_transaction_failed: Callback for handling failed memory transactions
  * (ie bus faults or external aborts; not MMU faults)
  * @virtio_is_big_endian: Callback to return %true if a CPU which supports
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index b3e8a823e1..16eb8047cf 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
-#define ALIGNED_ONLY
-
 /* Alpha processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)
 
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index aab251bc4b..2be67c289a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -30,7 +30,6 @@
basis.  It's probably easier to fall back to a strong memory model.  */
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL
 
-#define ALIGNED_ONLY
 #define MMU_KERNEL_IDX   0
 #define MMU_USER_IDX 3
 #define MMU_PHYS_IDX 4
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 21c0615e02..c13cd4eb31 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1,8 +1,6 @@
 #ifndef MIPS_CPU_H
 #define MIPS_CPU_H
 
-#define ALIGNED_ONLY
-
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index aee733eaaa..ecaa7a18a9 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
-#define ALIGNED_ONLY
-
 /* CPU Subtypes */
 #define SH_CPU_SH7750  (1 << 0)
 #define SH_CPU_SH7750S (1 << 1)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ed2250cd0..1406f0ba2e 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -5,8 +5,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
-#define ALIGNED_ONLY
-
 #if !defined(TARGET_SPARC64)
 #define TARGET_DPREGS 16
 #else
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 2c277134f1..0459243e6b 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -32,8 +32,6 @@
 #include "exec/cpu-defs.h"
 #include "xtensa-isa.h"
 
-#define ALIGNED_ONLY
-
 /* Xtensa processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index be2c33c400..8d23fb0592 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1926,7 +1926,7 @@ static const char * const ldst_name[] =
 };
 
 static const char * const 

[Qemu-devel] [PATCH v4 1/1] configure: Define target access alignment in configure

2019-07-31 Thread tony.nguyen
Rename ALIGNED_ONLY to TARGET_ALIGNED_ONLY for clarity and move
defines out of target/foo/cpu.h into configure, as we do with
TARGET_WORDS_BIGENDIAN, so that it is always defined early.

Poison TARGET_ALIGNED_ONLY to prevent use in common code.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
---
 configure | 10 +-
 include/exec/poison.h |  1 +
 include/qom/cpu.h |  2 +-
 target/alpha/cpu.h|  2 --
 target/hppa/cpu.h |  1 -
 target/mips/cpu.h |  2 --
 target/sh4/cpu.h  |  2 --
 target/sparc/cpu.h|  2 --
 target/xtensa/cpu.h   |  2 --
 tcg/tcg.c |  2 +-
 tcg/tcg.h |  8 +---
 11 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/configure b/configure
index 714e7fb6a1..482ba0b240 100755
--- a/configure
+++ b/configure
@@ -7431,8 +7431,13 @@ for target in $target_list; do
 target_dir="$target"
 config_target_mak=$target_dir/config-target.mak
 target_name=$(echo $target | cut -d '-' -f 1)
+target_aligned_only="no"
+case "$target_name" in
+  
alpha|hppa|mips64el|mips64|mipsel|mips|mipsn32|mipsn32el|sh4|sh4eb|sparc|sparc64|sparc32plus|xtensa|xtensaeb)
+  target_aligned_only="yes"
+  ;;
+esac
 target_bigendian="no"
-
 case "$target_name" in
   
armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
@@ -7717,6 +7722,9 @@ fi
 if supported_whpx_target $target; then
 echo "CONFIG_WHPX=y" >> $config_target_mak
 fi
+if test "$target_aligned_only" = "yes" ; then
+  echo "TARGET_ALIGNED_ONLY=y" >> $config_target_mak
+fi
 if test "$target_bigendian" = "yes" ; then
   echo "TARGET_WORDS_BIGENDIAN=y" >> $config_target_mak
 fi
diff --git a/include/exec/poison.h b/include/exec/poison.h
index b862320fa6..955eb863ab 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -35,6 +35,7 @@
 #pragma GCC poison TARGET_UNICORE32
 #pragma GCC poison TARGET_XTENSA
 
+#pragma GCC poison TARGET_ALIGNED_ONLY
 #pragma GCC poison TARGET_HAS_BFLT
 #pragma GCC poison TARGET_NAME
 #pragma GCC poison TARGET_SUPPORTS_MTTCG
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 5ee0046b62..9b50b73339 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -89,7 +89,7 @@ struct TranslationBlock;
  * @do_unassigned_access: Callback for unassigned access handling.
  * (this is deprecated: new targets should use do_transaction_failed instead)
  * @do_unaligned_access: Callback for unaligned access handling, if
- * the target defines #ALIGNED_ONLY.
+ * the target defines #TARGET_ALIGNED_ONLY.
  * @do_transaction_failed: Callback for handling failed memory transactions
  * (ie bus faults or external aborts; not MMU faults)
  * @virtio_is_big_endian: Callback to return %true if a CPU which supports
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index b3e8a823e1..16eb8047cf 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
-#define ALIGNED_ONLY
-
 /* Alpha processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)
 
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index aab251bc4b..2be67c289a 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -30,7 +30,6 @@
basis.  It's probably easier to fall back to a strong memory model.  */
 #define TCG_GUEST_DEFAULT_MOTCG_MO_ALL
 
-#define ALIGNED_ONLY
 #define MMU_KERNEL_IDX   0
 #define MMU_USER_IDX 3
 #define MMU_PHYS_IDX 4
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 21c0615e02..c13cd4eb31 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1,8 +1,6 @@
 #ifndef MIPS_CPU_H
 #define MIPS_CPU_H
 
-#define ALIGNED_ONLY
-
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat.h"
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index aee733eaaa..ecaa7a18a9 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -23,8 +23,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
-#define ALIGNED_ONLY
-
 /* CPU Subtypes */
 #define SH_CPU_SH7750  (1 << 0)
 #define SH_CPU_SH7750S (1 << 1)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ed2250cd0..1406f0ba2e 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -5,8 +5,6 @@
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
 
-#define ALIGNED_ONLY
-
 #if !defined(TARGET_SPARC64)
 #define TARGET_DPREGS 16
 #else
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 2c277134f1..0459243e6b 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -32,8 +32,6 @@
 #include "exec/cpu-defs.h"
 #include "xtensa-isa.h"
 
-#define ALIGNED_ONLY
-
 /* Xtensa processors have a weak memory model */
 #define TCG_GUEST_DEFAULT_MO  (0)
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index be2c33c400..8d23fb0592 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1926,7 +1926,7 @@ static const char * const ldst_name[] =
 };
 
 static const char * const 

[Qemu-devel] [PATCH v4 0/1] configure: Define target access alignment in configure

2019-07-31 Thread tony.nguyen
Move the define of target access alignment earlier from
target/foo/cpu.h to configure.

Suggested in Richard Henderson's reply to "[PATCH 1/4] tcg: TCGMemOp
is now accelerator independent MemOp"

Analysed target/foo/cpu.h for more candidates to define earlier but
did not spot any other straight forward predicates.

Possible future clean ups:
- TCG_GUEST_DEFAULT_MO and TCG_TARGET_DEFAULT_MO seems like duplicates
- TARGET_INSN_START_EXTRA_WORDS 1 seems redundant as ifndef value is 1

v2:
- split cosmetic changes into separate patch
- cc corresponding maintainers

v3:
- dropped cosmetic changes
- improved commit message

v4:
- further improved commit message

Tony Nguyen (1):
  configure: Define TARGET_ALIGNED_ONLY in configure

 configure | 10 +-
 include/exec/poison.h |  1 +
 include/qom/cpu.h |  2 +-
 target/alpha/cpu.h|  2 --
 target/hppa/cpu.h |  1 -
 target/mips/cpu.h |  2 --
 target/sh4/cpu.h  |  2 --
 target/sparc/cpu.h|  2 --
 target/xtensa/cpu.h   |  2 --
 tcg/tcg.c |  2 +-
 tcg/tcg.h |  8 +---
 11 files changed, 17 insertions(+), 17 deletions(-)

-- 
2.22.0



[Qemu-devel] [PATCH v4 0/1] configure: Define target access alignment in configure

2019-07-30 Thread tony.nguyen
Move the define of target access alignment earlier from
target/foo/cpu.h to configure.

Suggested in Richard Henderson's reply to "[PATCH 1/4] tcg: TCGMemOp
is now accelerator independent MemOp"

Analysed target/foo/cpu.h for more candidates to define earlier but
did not spot any other straight forward predicates.

Possible future clean ups:
- TCG_GUEST_DEFAULT_MO and TCG_TARGET_DEFAULT_MO seems like duplicates
- TARGET_INSN_START_EXTRA_WORDS 1 seems redundant as ifndef value is 1

v2:
- split cosmetic changes into separate patch
- cc corresponding maintainers

v3:
- dropped cosmetic changes
- improved commit message

v4:
- further improved commit message

Tony Nguyen (1):
  configure: Define TARGET_ALIGNED_ONLY in configure

 configure | 10 +-
 include/exec/poison.h |  1 +
 include/qom/cpu.h |  2 +-
 target/alpha/cpu.h|  2 --
 target/hppa/cpu.h |  1 -
 target/mips/cpu.h |  2 --
 target/sh4/cpu.h  |  2 --
 target/sparc/cpu.h|  2 --
 target/xtensa/cpu.h   |  2 --
 tcg/tcg.c |  2 +-
 tcg/tcg.h |  8 +---
 11 files changed, 17 insertions(+), 17 deletions(-)

-- 
2.22.0



[Qemu-devel] [PATCH v5 15/15] target/sparc: sun4u Invert Endian TTE bit

2019-07-26 Thread tony.nguyen
This bit configures endianness of PCI MMIO devices. It is used by
Solaris and OpenBSD sunhme drivers.

Tested working on OpenBSD.

Unfortunately Solaris 10 had a unrelated keyboard issue blocking
testing... another inch towards Solaris 10 on SPARC64 =)

Signed-off-by: Tony Nguyen 
---
 target/sparc/cpu.h| 2 ++
 target/sparc/mmu_helper.c | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ed2250..77e8e07 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -277,6 +277,7 @@ enum {

 #define TTE_VALID_BIT   (1ULL << 63)
 #define TTE_NFO_BIT (1ULL << 60)
+#define TTE_IE_BIT  (1ULL << 59)
 #define TTE_USED_BIT(1ULL << 41)
 #define TTE_LOCKED_BIT  (1ULL <<  6)
 #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
@@ -293,6 +294,7 @@ enum {

 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
 #define TTE_IS_NFO(tte) ((tte) & TTE_NFO_BIT)
+#define TTE_IS_IE(tte)  ((tte) & TTE_IE_BIT)
 #define TTE_IS_USED(tte)((tte) & TTE_USED_BIT)
 #define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
 #define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index 826e14b..77dc86a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -537,6 +537,10 @@ static int get_physical_address_data(CPUSPARCState *env, 
hwaddr *physical,
 if (ultrasparc_tag_match(>dtlb[i], address, context, physical)) {
 int do_fault = 0;

+if (TTE_IS_IE(env->dtlb[i].tte)) {
+attrs->byte_swap = true;
+}
+
 /* access ok? */
 /* multiple bits in SFSR.FT may be set on TT_DFAULT */
 if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
@@ -792,7 +796,7 @@ void dump_mmu(CPUSPARCState *env)
 }
 if (TTE_IS_VALID(env->dtlb[i].tte)) {
 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
-", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
+", %s, %s, %s, %s, ie %s, ctx %" PRId64 " %s\n",
 i,
 env->dtlb[i].tag & (uint64_t)~0x1fffULL,
 TTE_PA(env->dtlb[i].tte),
@@ -801,6 +805,8 @@ void dump_mmu(CPUSPARCState *env)
 TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
 TTE_IS_LOCKED(env->dtlb[i].tte) ?
 "locked" : "unlocked",
+TTE_IS_IE(env->dtlb[i].tte) ?
+"yes" : "no",
 env->dtlb[i].tag & (uint64_t)0x1fffULL,
 TTE_IS_GLOBAL(env->dtlb[i].tte) ?
 "global" : "local");
--
1.8.3.1





[Qemu-devel] [PATCH v5 13/15] cputlb: Byte swap memory transaction attribute

2019-07-26 Thread tony.nguyen
Notice new attribute, byte swap, and force the transaction through the
memory slow path.

Required by architectures that can invert endianness of memory
transaction, e.g. SPARC64 has the Invert Endian TTE bit.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c  | 11 +++
 include/exec/memattrs.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index e61b1eb..f292a87 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -738,6 +738,9 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong 
vaddr,
  */
 address |= TLB_RECHECK;
 }
+if (attrs.byte_swap) {
+address |= TLB_FORCE_SLOW;
+}
 if (!memory_region_is_ram(section->mr) &&
 !memory_region_is_romd(section->mr)) {
 /* IO memory case */
@@ -891,6 +894,10 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -933,6 +940,10 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index d4a3477..a0644eb 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
 unsigned int user:1;
 /* Requester ID (for MSI for example) */
 unsigned int requester_id:16;
+/* SPARC64: TTE invert endianness */
+unsigned int byte_swap:1;
 /*
  * The following are target-specific page-table bits.  These are not
  * related to actual memory transactions at all.  However, this structure
--
1.8.3.1





[Qemu-devel] [PATCH v5 14/15] target/sparc: Add TLB entry with attributes

2019-07-26 Thread tony.nguyen
Append MemTxAttrs to interfaces so we can pass along up coming Invert
Endian TTE bit on SPARC64.

Signed-off-by: Tony Nguyen 
---
 target/sparc/mmu_helper.c | 32 ++--
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index cbd1e91..826e14b 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -88,7 +88,7 @@ static const int perm_table[2][8] = {
 };

 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -219,6 +219,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 target_ulong page_size;
 int error_code = 0, prot, access_index;
+MemTxAttrs attrs = {};

 /*
  * TODO: If we ever need tlb_vaddr_to_host for this target,
@@ -229,7 +230,7 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 assert(!probe);

 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 vaddr = address;
@@ -490,8 +491,8 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb,
 return 0;
 }

-static int get_physical_address_data(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_data(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int rw, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -608,8 +609,8 @@ static int get_physical_address_data(CPUSPARCState *env,
 return 1;
 }

-static int get_physical_address_code(CPUSPARCState *env,
- hwaddr *physical, int *prot,
+static int get_physical_address_code(CPUSPARCState *env, hwaddr *physical,
+ int *prot, MemTxAttrs *attrs,
  target_ulong address, int mmu_idx)
 {
 CPUState *cs = env_cpu(env);
@@ -686,7 +687,7 @@ static int get_physical_address_code(CPUSPARCState *env,
 }

 static int get_physical_address(CPUSPARCState *env, hwaddr *physical,
-int *prot, int *access_index,
+int *prot, int *access_index, MemTxAttrs 
*attrs,
 target_ulong address, int rw, int mmu_idx,
 target_ulong *page_size)
 {
@@ -716,11 +717,11 @@ static int get_physical_address(CPUSPARCState *env, 
hwaddr *physical,
 }

 if (rw == 2) {
-return get_physical_address_code(env, physical, prot, address,
+return get_physical_address_code(env, physical, prot, attrs, address,
  mmu_idx);
 } else {
-return get_physical_address_data(env, physical, prot, address, rw,
- mmu_idx);
+return get_physical_address_data(env, physical, prot, attrs, address,
+ rw, mmu_idx);
 }
 }

@@ -734,10 +735,11 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 target_ulong vaddr;
 hwaddr paddr;
 target_ulong page_size;
+MemTxAttrs attrs = {};
 int error_code = 0, prot, access_index;

 address &= TARGET_PAGE_MASK;
-error_code = get_physical_address(env, , , _index,
+error_code = get_physical_address(env, , , _index, 
,
   address, access_type,
   mmu_idx, _size);
 if (likely(error_code == 0)) {
@@ -747,7 +749,8 @@ bool sparc_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
env->dmmu.mmu_primary_context,
env->dmmu.mmu_secondary_context);

-tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
+tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx,
+page_size);
 return true;
 }
 if (probe) {
@@ -849,9 +852,10 @@ static int cpu_sparc_get_phys_page(CPUSPARCState *env, 
hwaddr *phys,
 {
 target_ulong page_size;
 int prot, access_index;
+MemTxAttrs attrs = {};

-return get_physical_address(env, phys, , _index, addr, rw,
-mmu_idx, _size);
+return get_physical_address(env, phys, , _index, , addr,
+rw, mmu_idx, _size);
 }

 #if defined(TARGET_SPARC64)
--
1.8.3.1





[Qemu-devel] [PATCH v5 12/15] cpu: TLB_FLAGS_MASK bit to force memory slow path

2019-07-26 Thread tony.nguyen
The fast path is taken when TLB_FLAGS_MASK is all zero.

TLB_FORCE_SLOW is simply a TLB_FLAGS_MASK bit to force the slow path,
there are no other side effects.

Signed-off-by: Tony Nguyen 
---
 include/exec/cpu-all.h | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 536ea58..e496f99 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -331,12 +331,18 @@ CPUArchState *cpu_copy(CPUArchState *env);
 #define TLB_MMIO(1 << (TARGET_PAGE_BITS - 3))
 /* Set if TLB entry must have MMU lookup repeated for every access */
 #define TLB_RECHECK (1 << (TARGET_PAGE_BITS - 4))
+/* Set if TLB entry must take the slow path.  */
+#define TLB_FORCE_SLOW  (1 << (TARGET_PAGE_BITS - 5))

 /* Use this mask to check interception with an alignment mask
  * in a TCG backend.
  */
-#define TLB_FLAGS_MASK  (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
- | TLB_RECHECK)
+#define TLB_FLAGS_MASK \
+(TLB_INVALID_MASK  \
+ | TLB_NOTDIRTY\
+ | TLB_MMIO\
+ | TLB_RECHECK \
+ | TLB_FORCE_SLOW)

 /**
  * tlb_hit_page: return true if page aligned @addr is a hit against the
--
1.8.3.1





[Qemu-devel] [PATCH v5 11/15] memory: Single byte swap along the I/O path

2019-07-26 Thread tony.nguyen
Now that MemOp has been pushed down into the memory API, we can
collapse the two byte swaps adjust_endianness and handle_bswap into
the former.

Collapsing byte swaps along the I/O path enables additional endian
inversion logic, e.g. SPARC64 Invert Endian TTE bit, with redundant
byte swaps cancelling out.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c | 41 +++--
 memory.c   | 30 +-
 2 files changed, 36 insertions(+), 35 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 5d88cec..e61b1eb 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1209,26 +1209,13 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 #endif

 /*
- * Byte Swap Helper
+ * Byte Swap Checker
  *
- * This should all dead code away depending on the build host and
- * access type.
+ * Dead code should all go away depending on the build host and access type.
  */
-
-static inline uint64_t handle_bswap(uint64_t val, int size, bool big_endian)
+static inline bool need_bswap(bool big_endian)
 {
-if ((big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP)) {
-switch (size) {
-case 1: return val;
-case 2: return bswap16(val);
-case 4: return bswap32(val);
-case 8: return bswap64(val);
-default:
-g_assert_not_reached();
-}
-} else {
-return val;
-}
+return (big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP);
 }

 /*
@@ -1259,6 +1246,7 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 unsigned a_bits = get_alignment_bits(get_memop(oi));
 void *haddr;
 uint64_t res;
+MemOp op;

 /* Handle CPU specific unaligned behaviour */
 if (addr & ((1 << a_bits) - 1)) {
@@ -1304,9 +1292,13 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 }
 }

-res = io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
-   mmu_idx, addr, retaddr, access_type, SIZE_MEMOP(size));
-return handle_bswap(res, size, big_endian);
+op = SIZE_MEMOP(size);
+if (need_bswap(big_endian)) {
+op ^= MO_BSWAP;
+}
+
+return io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
+   mmu_idx, addr, retaddr, access_type, op);
 }

 /* Handle slow unaligned access (it spans two pages or IO).  */
@@ -1507,6 +1499,7 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,
 const size_t tlb_off = offsetof(CPUTLBEntry, addr_write);
 unsigned a_bits = get_alignment_bits(get_memop(oi));
 void *haddr;
+MemOp op;

 /* Handle CPU specific unaligned behaviour */
 if (addr & ((1 << a_bits) - 1)) {
@@ -1552,9 +1545,13 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,
 }
 }

+op = SIZE_MEMOP(size);
+if (need_bswap(big_endian)) {
+op ^= MO_BSWAP;
+}
+
 io_writex(env, _tlb(env)->d[mmu_idx].iotlb[index], mmu_idx,
-  handle_bswap(val, size, big_endian),
-  addr, retaddr, SIZE_MEMOP(size));
+  val, addr, retaddr, op);
 return;
 }

diff --git a/memory.c b/memory.c
index 6982e19..0277d3d 100644
--- a/memory.c
+++ b/memory.c
@@ -352,7 +352,7 @@ static bool memory_region_big_endian(MemoryRegion *mr)
 #endif
 }

-static bool memory_region_wrong_endianness(MemoryRegion *mr)
+static bool memory_region_endianness_inverted(MemoryRegion *mr)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
 return mr->ops->endianness == DEVICE_LITTLE_ENDIAN;
@@ -361,23 +361,27 @@ static bool memory_region_wrong_endianness(MemoryRegion 
*mr)
 #endif
 }

-static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
+static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
 {
-if (memory_region_wrong_endianness(mr)) {
-switch (size) {
-case 1:
+if (memory_region_endianness_inverted(mr)) {
+op ^= MO_BSWAP;
+}
+
+if (op & MO_BSWAP) {
+switch (op & MO_SIZE) {
+case MO_8:
 break;
-case 2:
+case MO_16:
 *data = bswap16(*data);
 break;
-case 4:
+case MO_32:
 *data = bswap32(*data);
 break;
-case 8:
+case MO_64:
 *data = bswap64(*data);
 break;
 default:
-abort();
+g_assert_not_reached();
 }
 }
 }
@@ -1451,7 +1455,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 }

 r = memory_region_dispatch_read1(mr, addr, pval, size, attrs);
-adjust_endianness(mr, pval, size);
+adjust_endianness(mr, pval, op);
 return r;
 }

@@ -1494,7 +1498,7 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
 return MEMTX_DECODE_ERROR;
 }

-adjust_endianness(mr, , size);
+   

[Qemu-devel] [PATCH v5 10/15] memory: Access MemoryRegion with MemOp semantics

2019-07-26 Thread tony.nguyen
To convert interfaces of MemoryRegion access, MEMOP_SIZE and
SIZE_MEMOP no-op stubs were introduced to change syntax while keeping
the existing semantics.

Now with interfaces converted, we fill the stubs and use MemOp
semantics.

Signed-off-by: Tony Nguyen 
---
 include/exec/memop.h  | 5 ++---
 include/exec/memory.h | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index 09c8d20..f2847e8 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -106,8 +106,7 @@ typedef enum MemOp {
 MO_SSIZE = MO_SIZE | MO_SIGN,
 } MemOp;

-/* No-op while memory_region_dispatch_[read|write] is converted to MemOp */
-#define MEMOP_SIZE(op)  (op)/* MemOp to size.  */
-#define SIZE_MEMOP(ul)  (ul)/* Size to MemOp.  */
+#define MEMOP_SIZE(op)  (1 << ((op) & MO_SIZE)) /* MemOp to size.  */
+#define SIZE_MEMOP(ul)  (ctzl(ul))  /* Size to MemOp.  */

 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 0ea4843..975b86a 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1732,7 +1732,7 @@ void mtree_info(bool flatview, bool dispatch_tree, bool 
owner);
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @pval: pointer to uint64_t which the data is written to
- * @op: size of the access in bytes
+ * @op: size, sign, and endianness of the memory operation
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
@@ -1747,7 +1747,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @data: data to write
- * @op: size of the access in bytes
+ * @op: size, sign, and endianness of the memory operation
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
--
1.8.3.1





[Qemu-devel] [PATCH v5 08/15] exec: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op SIZE_MEMOP macro allows us to later easily convert
memory_region_dispatch_{read|write} paramter "unsigned size" into a
size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
---
 exec.c|  6 --
 memory_ldst.inc.c | 18 +-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/exec.c b/exec.c
index 3e78de3..5013864 100644
--- a/exec.c
+++ b/exec.c
@@ -3334,7 +3334,8 @@ static MemTxResult flatview_write_continue(FlatView *fv, 
hwaddr addr,
 /* XXX: could force current_cpu to NULL to avoid
potential bugs */
 val = ldn_p(buf, l);
-result |= memory_region_dispatch_write(mr, addr1, val, l, attrs);
+result |= memory_region_dispatch_write(mr, addr1, val,
+   SIZE_MEMOP(l), attrs);
 } else {
 /* RAM case */
 ptr = qemu_ram_ptr_length(mr->ram_block, addr1, , false);
@@ -3395,7 +3396,8 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr 
addr,
 /* I/O case */
 release_lock |= prepare_mmio_access(mr);
 l = memory_access_size(mr, l, addr1);
-result |= memory_region_dispatch_read(mr, addr1, , l, attrs);
+result |= memory_region_dispatch_read(mr, addr1, ,
+  SIZE_MEMOP(l), attrs);
 stn_p(buf, l, val);
 } else {
 /* RAM case */
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
index acf865b..e073cf9 100644
--- a/memory_ldst.inc.c
+++ b/memory_ldst.inc.c
@@ -38,7 +38,7 @@ static inline uint32_t glue(address_space_ldl_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 4, attrs);
+r = memory_region_dispatch_read(mr, addr1, , SIZE_MEMOP(4), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap32(val);
@@ -114,7 +114,7 @@ static inline uint64_t glue(address_space_ldq_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 8, attrs);
+r = memory_region_dispatch_read(mr, addr1, , SIZE_MEMOP(8), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap64(val);
@@ -188,7 +188,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 1, attrs);
+r = memory_region_dispatch_read(mr, addr1, , SIZE_MEMOP(1), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -224,7 +224,7 @@ static inline uint32_t glue(address_space_lduw_internal, 
SUFFIX)(ARG1_DECL,
 release_lock |= prepare_mmio_access(mr);

 /* I/O case */
-r = memory_region_dispatch_read(mr, addr1, , 2, attrs);
+r = memory_region_dispatch_read(mr, addr1, , SIZE_MEMOP(2), attrs);
 #if defined(TARGET_WORDS_BIGENDIAN)
 if (endian == DEVICE_LITTLE_ENDIAN) {
 val = bswap16(val);
@@ -300,7 +300,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
 if (l < 4 || !memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);

-r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, SIZE_MEMOP(4), attrs);
 } else {
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
 stl_p(ptr, val);
@@ -346,7 +346,7 @@ static inline void glue(address_space_stl_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap32(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, SIZE_MEMOP(4), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -408,7 +408,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
 mr = TRANSLATE(addr, , , true, attrs);
 if (!memory_access_is_direct(mr, true)) {
 release_lock |= prepare_mmio_access(mr);
-r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, SIZE_MEMOP(1), attrs);
 } else {
 /* RAM case */
 ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
@@ -451,7 +451,7 @@ static inline void glue(address_space_stw_internal, 
SUFFIX)(ARG1_DECL,
 val = bswap16(val);
 }
 #endif
-r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
+r = memory_region_dispatch_write(mr, addr1, val, SIZE_MEMOP(2), attrs);
 } else {
 /* RAM case */
  

[Qemu-devel] [PATCH v5 09/15] cputlb: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op MEMOP_SIZE and SIZE_MEMOP macros allows us to later easily
convert memory_region_dispatch_{read|write} paramter "unsigned size"
into a size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 523be4c..5d88cec 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -881,7 +881,7 @@ static void tlb_fill(CPUState *cpu, target_ulong addr, int 
size,

 static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
  int mmu_idx, target_ulong addr, uintptr_t retaddr,
- MMUAccessType access_type, int size)
+ MMUAccessType access_type, MemOp op)
 {
 CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
@@ -906,14 +906,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_read(mr, mr_offset,
-, size, iotlbentry->attrs);
+r = memory_region_dispatch_read(mr, mr_offset, , op, 
iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
 section->offset_within_region;

-cpu_transaction_failed(cpu, physaddr, addr, size, access_type,
+cpu_transaction_failed(cpu, physaddr, addr, MEMOP_SIZE(op), 
access_type,
mmu_idx, iotlbentry->attrs, r, retaddr);
 }
 if (locked) {
@@ -925,7 +924,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,

 static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
   int mmu_idx, uint64_t val, target_ulong addr,
-  uintptr_t retaddr, int size)
+  uintptr_t retaddr, MemOp op)
 {
 CPUState *cpu = env_cpu(env);
 hwaddr mr_offset;
@@ -947,15 +946,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 qemu_mutex_lock_iothread();
 locked = true;
 }
-r = memory_region_dispatch_write(mr, mr_offset,
- val, size, iotlbentry->attrs);
+r = memory_region_dispatch_write(mr, mr_offset, val, op, 
iotlbentry->attrs);
 if (r != MEMTX_OK) {
 hwaddr physaddr = mr_offset +
 section->offset_within_address_space -
 section->offset_within_region;

-cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
-   mmu_idx, iotlbentry->attrs, r, retaddr);
+cpu_transaction_failed(cpu, physaddr, addr, MEMOP_SIZE(op),
+   MMU_DATA_STORE, mmu_idx, iotlbentry->attrs, r,
+   retaddr);
 }
 if (locked) {
 qemu_mutex_unlock_iothread();
@@ -1306,7 +1305,7 @@ load_helper(CPUArchState *env, target_ulong addr, 
TCGMemOpIdx oi,
 }

 res = io_readx(env, _tlb(env)->d[mmu_idx].iotlb[index],
-   mmu_idx, addr, retaddr, access_type, size);
+   mmu_idx, addr, retaddr, access_type, SIZE_MEMOP(size));
 return handle_bswap(res, size, big_endian);
 }

@@ -1555,7 +1554,7 @@ store_helper(CPUArchState *env, target_ulong addr, 
uint64_t val,

 io_writex(env, _tlb(env)->d[mmu_idx].iotlb[index], mmu_idx,
   handle_bswap(val, size, big_endian),
-  addr, retaddr, size);
+  addr, retaddr, SIZE_MEMOP(size));
 return;
 }

--
1.8.3.1





[Qemu-devel] [PATCH v5 07/15] hw/vfio: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op SIZE_MEMOP macro allows us to later easily convert
memory_region_dispatch_{read|write} paramter "unsigned size" into a
size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
---
 hw/vfio/pci-quirks.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index b35a640..3240afa 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1071,7 +1071,7 @@ static void vfio_rtl8168_quirk_address_write(void 
*opaque, hwaddr addr,

 /* Write to the proper guest MSI-X table instead */
 memory_region_dispatch_write(>pdev.msix_table_mmio,
- offset, val, size,
+ offset, val, SIZE_MEMOP(size),
  MEMTXATTRS_UNSPECIFIED);
 }
 return; /* Do not write guest MSI-X data to hardware */
@@ -1102,7 +1102,8 @@ static uint64_t vfio_rtl8168_quirk_data_read(void *opaque,
 if (rtl->enabled && (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX)) {
 hwaddr offset = rtl->addr & 0xfff;
 memory_region_dispatch_read(>pdev.msix_table_mmio, offset,
-, size, MEMTXATTRS_UNSPECIFIED);
+, SIZE_MEMOP(size),
+MEMTXATTRS_UNSPECIFIED);
 trace_vfio_quirk_rtl8168_msix_read(vdev->vbasedev.name, offset, data);
 }

--
1.8.3.1





[Qemu-devel] [PATCH v5 06/15] hw/virtio: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op SIZE_MEMOP macro allows us to later easily convert
memory_region_dispatch_{read|write} paramter "unsigned size" into a
size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
---
 hw/virtio/virtio-pci.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index ce928f2..265f066 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -17,6 +17,7 @@

 #include "qemu/osdep.h"

+#include "exec/memop.h"
 #include "standard-headers/linux/virtio_pci.h"
 #include "hw/virtio/virtio.h"
 #include "hw/pci/pci.h"
@@ -550,7 +551,8 @@ void virtio_address_space_write(VirtIOPCIProxy *proxy, 
hwaddr addr,
 /* As length is under guest control, handle illegal values. */
 return;
 }
-memory_region_dispatch_write(mr, addr, val, len, MEMTXATTRS_UNSPECIFIED);
+memory_region_dispatch_write(mr, addr, val, SIZE_MEMOP(len),
+ MEMTXATTRS_UNSPECIFIED);
 }

 static void
@@ -573,7 +575,8 @@ virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr 
addr,
 /* Make sure caller aligned buf properly */
 assert(!(((uintptr_t)buf) & (len - 1)));

-memory_region_dispatch_read(mr, addr, , len, MEMTXATTRS_UNSPECIFIED);
+memory_region_dispatch_read(mr, addr, , SIZE_MEMOP(len),
+MEMTXATTRS_UNSPECIFIED);
 switch (len) {
 case 1:
 pci_set_byte(buf, val);
--
1.8.3.1





[Qemu-devel] [PATCH v5 05/15] hw/intc/armv7m_nic: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op SIZE_MEMOP macro allows us to later easily convert
memory_region_dispatch_{read|write} paramter "unsigned size" into a
size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/intc/armv7m_nvic.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 9f8f0d3..25bb88a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -18,6 +18,7 @@
 #include "hw/intc/armv7m_nvic.h"
 #include "target/arm/cpu.h"
 #include "exec/exec-all.h"
+#include "exec/memop.h"
 #include "qemu/log.h"
 #include "qemu/module.h"
 #include "trace.h"
@@ -2345,7 +2346,8 @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_write(mr, addr, value, size, attrs);
+return memory_region_dispatch_write(mr, addr, value, SIZE_MEMOP(size),
+attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2364,7 +2366,8 @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, 
hwaddr addr,
 if (attrs.secure) {
 /* S accesses to the alias act like NS accesses to the real region */
 attrs.secure = 0;
-return memory_region_dispatch_read(mr, addr, data, size, attrs);
+return memory_region_dispatch_read(mr, addr, data, SIZE_MEMOP(size),
+   attrs);
 } else {
 /* NS attrs are RAZ/WI for privileged, and BusFault for user */
 if (attrs.user) {
@@ -2390,7 +2393,8 @@ static MemTxResult nvic_systick_write(void *opaque, 
hwaddr addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_write(mr, addr, value, size, attrs);
+return memory_region_dispatch_write(mr, addr, value, SIZE_MEMOP(size),
+attrs);
 }

 static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
@@ -2402,7 +2406,7 @@ static MemTxResult nvic_systick_read(void *opaque, hwaddr 
addr,

 /* Direct the access to the correct systick */
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>systick[attrs.secure]), 0);
-return memory_region_dispatch_read(mr, addr, data, size, attrs);
+return memory_region_dispatch_read(mr, addr, data, SIZE_MEMOP(size), 
attrs);
 }

 static const MemoryRegionOps nvic_systick_ops = {
--
1.8.3.1





[Qemu-devel] [PATCH v5 01/15] tcg: TCGMemOp is now accelerator independent MemOp

2019-07-26 Thread tony.nguyen
Preparation for collapsing the two byte swaps, adjust_endianness and
handle_bswap, along the I/O path.

Target dependant attributes are conditionalize upon NEED_CPU_H.

Signed-off-by: Tony Nguyen 
---
 MAINTAINERS |   1 +
 accel/tcg/cputlb.c  |   2 +-
 include/exec/memop.h| 109 ++
 target/alpha/translate.c|   2 +-
 target/arm/translate-a64.c  |  48 ++--
 target/arm/translate-a64.h  |   2 +-
 target/arm/translate-sve.c  |   2 +-
 target/arm/translate.c  |  32 
 target/arm/translate.h  |   2 +-
 target/hppa/translate.c |  14 ++--
 target/i386/translate.c | 132 
 target/m68k/translate.c |   2 +-
 target/microblaze/translate.c   |   4 +-
 target/mips/translate.c |   8 +-
 target/openrisc/translate.c |   4 +-
 target/ppc/translate.c  |  12 +--
 target/riscv/insn_trans/trans_rva.inc.c |   8 +-
 target/riscv/insn_trans/trans_rvi.inc.c |   4 +-
 target/s390x/translate.c|   6 +-
 target/s390x/translate_vx.inc.c |  10 +--
 target/sparc/translate.c|  14 ++--
 target/tilegx/translate.c   |  10 +--
 target/tricore/translate.c  |   8 +-
 tcg/README  |   2 +-
 tcg/aarch64/tcg-target.inc.c|  26 +++
 tcg/arm/tcg-target.inc.c|  26 +++
 tcg/i386/tcg-target.inc.c   |  24 +++---
 tcg/mips/tcg-target.inc.c   |  16 ++--
 tcg/optimize.c  |   2 +-
 tcg/ppc/tcg-target.inc.c|  12 +--
 tcg/riscv/tcg-target.inc.c  |  20 ++---
 tcg/s390/tcg-target.inc.c   |  14 ++--
 tcg/sparc/tcg-target.inc.c  |   6 +-
 tcg/tcg-op.c|  38 -
 tcg/tcg-op.h|  86 ++---
 tcg/tcg.c   |   2 +-
 tcg/tcg.h   |  99 ++--
 trace/mem-internal.h|   4 +-
 trace/mem.h |   4 +-
 39 files changed, 420 insertions(+), 397 deletions(-)
 create mode 100644 include/exec/memop.h

diff --git a/MAINTAINERS b/MAINTAINERS
index cc9636b..3f148cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1890,6 +1890,7 @@ M: Paolo Bonzini 
 S: Supported
 F: include/exec/ioport.h
 F: ioport.c
+F: include/exec/memop.h
 F: include/exec/memory.h
 F: include/exec/ram_addr.h
 F: memory.c
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index bb9897b..523be4c 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1133,7 +1133,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 uintptr_t index = tlb_index(env, mmu_idx, addr);
 CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
 target_ulong tlb_addr = tlb_addr_write(tlbe);
-TCGMemOp mop = get_memop(oi);
+MemOp mop = get_memop(oi);
 int a_bits = get_alignment_bits(mop);
 int s_bits = mop & MO_SIZE;
 void *hostaddr;
diff --git a/include/exec/memop.h b/include/exec/memop.h
new file mode 100644
index 000..ac58066
--- /dev/null
+++ b/include/exec/memop.h
@@ -0,0 +1,109 @@
+/*
+ * Constants for memory operations
+ *
+ * Authors:
+ *  Richard Henderson 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MEMOP_H
+#define MEMOP_H
+
+typedef enum MemOp {
+MO_8 = 0,
+MO_16= 1,
+MO_32= 2,
+MO_64= 3,
+MO_SIZE  = 3,   /* Mask for the above.  */
+
+MO_SIGN  = 4,   /* Sign-extended, otherwise zero-extended.  */
+
+MO_BSWAP = 8,   /* Host reverse endian.  */
+#ifdef HOST_WORDS_BIGENDIAN
+MO_LE= MO_BSWAP,
+MO_BE= 0,
+#else
+MO_LE= 0,
+MO_BE= MO_BSWAP,
+#endif
+#ifdef NEED_CPU_H
+#ifdef TARGET_WORDS_BIGENDIAN
+MO_TE= MO_BE,
+#else
+MO_TE= MO_LE,
+#endif
+#endif
+
+/*
+ * MO_UNALN accesses are never checked for alignment.
+ * MO_ALIGN accesses will result in a call to the CPU's
+ * do_unaligned_access hook if the guest address is not aligned.
+ * The default depends on whether the target CPU defines ALIGNED_ONLY.
+ *
+ * Some architectures (e.g. ARMv8) need the address which is aligned
+ * to a size more than the size of the memory access.
+ * Some architectures (e.g. SPARCv9) need an address which is aligned,
+ * but less strictly than the natural alignment.
+ *
+ * MO_ALIGN supposes the alignment size is the size of a memory access.
+ *
+ * There are three options:
+ * - unaligned access permitted (MO_UNALN).
+ * - an alignment to the size of an access (MO_ALIGN);
+ * - an alignment to a specified 

[Qemu-devel] [PATCH v5 04/15] hw/s390x: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op SIZE_MEMOP macro allows us to later easily convert
memory_region_dispatch_{read|write} paramter "unsigned size" into a
size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
---
 hw/s390x/s390-pci-inst.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 0023514..c126bcc 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -15,6 +15,7 @@
 #include "cpu.h"
 #include "s390-pci-inst.h"
 #include "s390-pci-bus.h"
+#include "exec/memop.h"
 #include "exec/memory-internal.h"
 #include "qemu/error-report.h"
 #include "sysemu/hw_accel.h"
@@ -372,7 +373,7 @@ static MemTxResult zpci_read_bar(S390PCIBusDevice *pbdev, 
uint8_t pcias,
 mr = pbdev->pdev->io_regions[pcias].memory;
 mr = s390_get_subregion(mr, offset, len);
 offset -= mr->addr;
-return memory_region_dispatch_read(mr, offset, data, len,
+return memory_region_dispatch_read(mr, offset, data, SIZE_MEMOP(len),
MEMTXATTRS_UNSPECIFIED);
 }

@@ -471,7 +472,7 @@ static MemTxResult zpci_write_bar(S390PCIBusDevice *pbdev, 
uint8_t pcias,
 mr = pbdev->pdev->io_regions[pcias].memory;
 mr = s390_get_subregion(mr, offset, len);
 offset -= mr->addr;
-return memory_region_dispatch_write(mr, offset, data, len,
+return memory_region_dispatch_write(mr, offset, data, SIZE_MEMOP(len),
 MEMTXATTRS_UNSPECIFIED);
 }

@@ -780,7 +781,8 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t 
r3, uint64_t gaddr,

 for (i = 0; i < len / 8; i++) {
 result = memory_region_dispatch_write(mr, offset + i * 8,
-  ldq_p(buffer + i * 8), 8,
+  ldq_p(buffer + i * 8),
+  SIZE_MEMOP(8),
   MEMTXATTRS_UNSPECIFIED);
 if (result != MEMTX_OK) {
 s390_program_interrupt(env, PGM_OPERAND, 6, ra);
--
1.8.3.1





[Qemu-devel] [PATCH v5 03/15] target/mips: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
No-op SIZE_MEMOP macro allows us to later easily convert
memory_region_dispatch_{read|write} paramter "unsigned size" into a
size+sign+endianness encoded "MemOp op".

Being a no-op macro, this patch does not introduce any logical change.

Signed-off-by: Tony Nguyen 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/mips/op_helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 9e2e02f..dccb8df 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -24,6 +24,7 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "exec/memop.h"
 #include "sysemu/kvm.h"

 /*/
@@ -4740,11 +4741,11 @@ void helper_cache(CPUMIPSState *env, target_ulong addr, 
uint32_t op)
 if (op == 9) {
 /* Index Store Tag */
 memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
- 8, MEMTXATTRS_UNSPECIFIED);
+ SIZE_MEMOP(8), MEMTXATTRS_UNSPECIFIED);
 } else if (op == 5) {
 /* Index Load Tag */
 memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
-8, MEMTXATTRS_UNSPECIFIED);
+SIZE_MEMOP(8), MEMTXATTRS_UNSPECIFIED);
 }
 #endif
 }
--
1.8.3.1





[Qemu-devel] [PATCH v5 02/15] memory: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
Change memory_region_dispatch_{read|write} parameter "unsigned size"
to "MemOp op".

The endianness encoded in MemOp will enable the collapse of two byte
swaps, adjust_endianness and handle_bswap, along the I/O path.

Interfaces will be converted in two steps: first syntactically then
semantically.

The syntax change is usage of no-op MEMOP_SIZE and SIZE_MEMOP macros.
Being no-op there are no logical change, and we rely on coercion
between unsigned and MemOp.

The semantic change is implementing MEMOP_SIZE and SIZE_MEMOP to
logically convert an unsigned size to and from a size+sign+endianness
encoded MemOp.

Signed-off-by: Tony Nguyen 
---
 include/exec/memop.h  | 4 
 include/exec/memory.h | 9 +
 memory.c  | 7 +--
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/include/exec/memop.h b/include/exec/memop.h
index ac58066..09c8d20 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -106,4 +106,8 @@ typedef enum MemOp {
 MO_SSIZE = MO_SIZE | MO_SIGN,
 } MemOp;

+/* No-op while memory_region_dispatch_[read|write] is converted to MemOp */
+#define MEMOP_SIZE(op)  (op)/* MemOp to size.  */
+#define SIZE_MEMOP(ul)  (ul)/* Size to MemOp.  */
+
 #endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index bb0961d..0ea4843 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -19,6 +19,7 @@
 #include "exec/cpu-common.h"
 #include "exec/hwaddr.h"
 #include "exec/memattrs.h"
+#include "exec/memop.h"
 #include "exec/ramlist.h"
 #include "qemu/queue.h"
 #include "qemu/int128.h"
@@ -1731,13 +1732,13 @@ void mtree_info(bool flatview, bool dispatch_tree, bool 
owner);
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @pval: pointer to uint64_t which the data is written to
- * @size: size of the access in bytes
+ * @op: size of the access in bytes
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 hwaddr addr,
 uint64_t *pval,
-unsigned size,
+MemOp op,
 MemTxAttrs attrs);
 /**
  * memory_region_dispatch_write: perform a write directly to the specified
@@ -1746,13 +1747,13 @@ MemTxResult memory_region_dispatch_read(MemoryRegion 
*mr,
  * @mr: #MemoryRegion to access
  * @addr: address within that region
  * @data: data to write
- * @size: size of the access in bytes
+ * @op: size of the access in bytes
  * @attrs: memory transaction attributes to use for the access
  */
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
  hwaddr addr,
  uint64_t data,
- unsigned size,
+ MemOp op,
  MemTxAttrs attrs);

 /**
diff --git a/memory.c b/memory.c
index 5d8c9a9..6982e19 100644
--- a/memory.c
+++ b/memory.c
@@ -1439,10 +1439,11 @@ static MemTxResult 
memory_region_dispatch_read1(MemoryRegion *mr,
 MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
 hwaddr addr,
 uint64_t *pval,
-unsigned size,
+MemOp op,
 MemTxAttrs attrs)
 {
 MemTxResult r;
+unsigned size = MEMOP_SIZE(op);

 if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
 *pval = unassigned_mem_read(mr, addr, size);
@@ -1483,9 +1484,11 @@ static bool 
memory_region_dispatch_write_eventfds(MemoryRegion *mr,
 MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
  hwaddr addr,
  uint64_t data,
- unsigned size,
+ MemOp op,
  MemTxAttrs attrs)
 {
+unsigned size = MEMOP_SIZE(op);
+
 if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
 unassigned_mem_write(mr, addr, data, size);
 return MEMTX_DECODE_ERROR;
--
1.8.3.1





[Qemu-devel] [PATCH v5 00/15] Invert Endian bit in SPARCv9 MMU TTE

2019-07-26 Thread tony.nguyen
This patchset implements the IE (Invert Endian) bit in SPARCv9 MMU TTE.

It is an attempt of the instructions outlined by Richard Henderson to Mark
Cave-Ayland.

Tested with OpenBSD on sun4u. Solaris 10 is my actual goal, but unfortunately a
separate keyboard issue remains in the way.

On 01/11/17 19:15, Mark Cave-Ayland wrote:

>On 15/08/17 19:10, Richard Henderson wrote:
>
>> [CC Peter re MemTxAttrs below]
>>
>> On 08/15/2017 09:38 AM, Mark Cave-Ayland wrote:
>>> Working through an incorrect endian issue on qemu-system-sparc64, it has
>>> become apparent that at least one OS makes use of the IE (Invert Endian)
>>> bit in the SPARCv9 MMU TTE to map PCI memory space without the
>>> programmer having to manually endian-swap accesses.
>>>
>>> In other words, to quote the UltraSPARC specification: "if this bit is
>>> set, accesses to the associated page are processed with inverse
>>> endianness from what is specified by the instruction (big-for-little and
>>> little-for-big)".

A good explanation by Mark why the IE bit is required.

>>>
>>> Looking through various bits of code, I'm trying to get a feel for the
>>> best way to implement this in an efficient manner. From what I can see
>>> this could be solved using an additional MMU index, however I'm not
>>> overly familiar with the memory and softmmu subsystems.
>>
>> No, it can't be solved with an MMU index.
>>
>>> Can anyone point me in the right direction as to what would be the best
>>> way to implement this feature within QEMU?
>>
>> It's definitely tricky.
>>
>> We definitely need some TLB_FLAGS_MASK bit set so that we're forced through
>> the
>> memory slow path.  There is no other way to bypass the endianness that we've
>> already encoded from the target instruction.
>>
>> Given the tlb_set_page_with_attrs interface, I would think that we need a new
>> bit in MemTxAttrs, so that the target/sparc tlb_fill (and subroutines) can
>> pass
>> along the TTE bit for the given page.
>>
>> We have an existing problem in softmmu_template.h,
>>
>> /* ??? Note that the io helpers always read data in the target
>>byte ordering.  We should push the LE/BE request down into io.  */
>> res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
>> res = TGT_BE(res);
>>
>> We do not want to add a third(!) byte swap along the i/o path.  We need to
>> collapse the two that we have already before considering this one.
>>
>> This probably takes the form of:
>>
>> (1) Replacing the "int size" argument with "TCGMemOp memop" for
>>   a) io_{read,write}x in accel/tcg/cputlb.c,
>>   b) memory_region_dispatch_{read,write} in memory.c,
>>   c) adjust_endianness in memory.c.
>> This carries size+sign+endianness down to the next level.
>>
>> (2) In memory.c, adjust_endianness,
>>
>>  if (memory_region_wrong_endianness(mr)) {
>> -switch (size) {
>> +memop ^= MO_BSWAP;
>> +}
>> +if (memop & MO_BSWAP) {
>>
>> For extra credit, re-arrange memory_region_wrong_endianness
>> to something more explicit -- "wrong" isn't helpful.
>
>Finally I've had a bit of spare time to experiment with this approach,
>and from what I can see there are currently 2 issues:
>
>
>1) Using TCGMemOp in memory.c means it is no longer accelerator agnostic
>
>For the moment I've defined a separate MemOp in memory.h and provided a
>mapping function in io_{read,write}x to map from TCGMemOp to MemOp and
>then pass that into memory_region_dispatch_{read,write}.
>
>Other than not referencing TCGMemOp in the memory API, another reason
>for doing this was that I wasn't convinced that all the MO_ attributes
>were valid outside of TCG. I do, of course, strongly defer to other
>people's knowledge in this area though.
>
>
>2) The above changes to adjust_endianness() fail when
>memory_region_dispatch_{read,write} are called recursively
>
>Whilst booting qemu-system-sparc64 I see that
>memory_region_dispatch_{read,write} get called recursively - once via
>io_{read,write}x and then again via flatview_read_continue() in exec.c.
>
>The net effect of this is that we perform the bswap correctly at the
>tail of the recursion, but then as we travel back up the stack we hit
>memory_region_dispatch_{read,write} once again causing a second bswap
>which means the value is returned with the incorrect endian again.
>
>
>My understanding from your softmmu_template.h comment above is that the
>memory API should do the endian swapping internally allowing the removal
>of the final TGT_BE/TGT_LE applied to the result, or did I get this wrong?
>
>> (3) In tlb_set_page_with_attrs, notice attrs.byte_swap and set
>> a new TLB_FORCE_SLOW bit within TLB_FLAGS_MASK.
>>
>> (4) In io_{read,write}x, if iotlbentry->attrs.byte_swap is set,
>> then memop ^= MO_BSWAP.

Thanks all for the feedback. Learnt a lot =)

v2:
- Moved size+sign+endianness attributes from TCGMemOp into MemOp.
  In v1 TCGMemOp was re-purposed entirely into MemOp.
- Replaced MemOp MO_{8|16|32|64} with 

Re: [Qemu-devel] [PATCH v4 02/15] memory: Access MemoryRegion with MemOp

2019-07-26 Thread tony.nguyen
On 7/25/19 9:45 PM, Philippe Mathieu-Daudé wrote:
>On 7/25/19 11:52 AM, tony.ngu...@bt.com wrote:
>> Replacing size with size+sign+endianness (MemOp) will enable us to
>> collapse the two byte swaps, adjust_endianness and handle_bswap, along
>> the I/O path.
>>
>> While interfaces are converted, callers will have existing unsigned
>> size coerced into a MemOp, and the callee will use this MemOp as an
>> unsigned size.
>>
>> Signed-off-by: Tony Nguyen 
>> ---
>>  include/exec/memop.h  | 4 
>>  include/exec/memory.h | 9 +
>>  memory.c  | 7 +--
>>  3 files changed, 14 insertions(+), 6 deletions(-)
>>
>> diff --git a/include/exec/memop.h b/include/exec/memop.h
>> index ac58066..09c8d20 100644
>> --- a/include/exec/memop.h
>> +++ b/include/exec/memop.h
>> @@ -106,4 +106,8 @@ typedef enum MemOp {
>>  MO_SSIZE = MO_SIZE | MO_SIGN,
>>  } MemOp;
>>
>> +/* No-op while memory_region_dispatch_[read|write] is converted to MemOp */
>> +#define MEMOP_SIZE(op)  (op)/* MemOp to size.  */
>> +#define SIZE_MEMOP(ul)  (ul)/* Size to MemOp.  */
>
>SIZE_MEMOP() is never used until patch #10 "memory: Access MemoryRegion
>with MemOp semantics", it would be clearer to only introduce the
>MEMOP_SIZE() no-op here, and directly introduce the correct SIZE_MEMOP()
>macro in patch #10.

SIZE_MEMOP() is used, and is the main change, in patches #3 to #10. Perhaps you
meant MEMOP_SIZE()?

Either way, you have raised an issue :)

There is a lack of clarity in how the two macros are used to update the
interfaces.?



[Qemu-devel] [PATCH v4 15/15] target/sparc: sun4u Invert Endian TTE bit

2019-07-25 Thread tony.nguyen
This bit configures endianness of PCI MMIO devices. It is used by
Solaris and OpenBSD sunhme drivers.

Tested working on OpenBSD.

Unfortunately Solaris 10 had a unrelated keyboard issue blocking
testing... another inch towards Solaris 10 on SPARC64 =)

Signed-off-by: Tony Nguyen 
---
 target/sparc/cpu.h| 2 ++
 target/sparc/mmu_helper.c | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index 8ed2250..77e8e07 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -277,6 +277,7 @@ enum {

 #define TTE_VALID_BIT   (1ULL << 63)
 #define TTE_NFO_BIT (1ULL << 60)
+#define TTE_IE_BIT  (1ULL << 59)
 #define TTE_USED_BIT(1ULL << 41)
 #define TTE_LOCKED_BIT  (1ULL <<  6)
 #define TTE_SIDEEFFECT_BIT  (1ULL <<  3)
@@ -293,6 +294,7 @@ enum {

 #define TTE_IS_VALID(tte)   ((tte) & TTE_VALID_BIT)
 #define TTE_IS_NFO(tte) ((tte) & TTE_NFO_BIT)
+#define TTE_IS_IE(tte)  ((tte) & TTE_IE_BIT)
 #define TTE_IS_USED(tte)((tte) & TTE_USED_BIT)
 #define TTE_IS_LOCKED(tte)  ((tte) & TTE_LOCKED_BIT)
 #define TTE_IS_SIDEEFFECT(tte) ((tte) & TTE_SIDEEFFECT_BIT)
diff --git a/target/sparc/mmu_helper.c b/target/sparc/mmu_helper.c
index 826e14b..77dc86a 100644
--- a/target/sparc/mmu_helper.c
+++ b/target/sparc/mmu_helper.c
@@ -537,6 +537,10 @@ static int get_physical_address_data(CPUSPARCState *env, 
hwaddr *physical,
 if (ultrasparc_tag_match(>dtlb[i], address, context, physical)) {
 int do_fault = 0;

+if (TTE_IS_IE(env->dtlb[i].tte)) {
+attrs->byte_swap = true;
+}
+
 /* access ok? */
 /* multiple bits in SFSR.FT may be set on TT_DFAULT */
 if (TTE_IS_PRIV(env->dtlb[i].tte) && is_user) {
@@ -792,7 +796,7 @@ void dump_mmu(CPUSPARCState *env)
 }
 if (TTE_IS_VALID(env->dtlb[i].tte)) {
 qemu_printf("[%02u] VA: %" PRIx64 ", PA: %llx"
-", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
+", %s, %s, %s, %s, ie %s, ctx %" PRId64 " %s\n",
 i,
 env->dtlb[i].tag & (uint64_t)~0x1fffULL,
 TTE_PA(env->dtlb[i].tte),
@@ -801,6 +805,8 @@ void dump_mmu(CPUSPARCState *env)
 TTE_IS_W_OK(env->dtlb[i].tte) ? "RW" : "RO",
 TTE_IS_LOCKED(env->dtlb[i].tte) ?
 "locked" : "unlocked",
+TTE_IS_IE(env->dtlb[i].tte) ?
+"yes" : "no",
 env->dtlb[i].tag & (uint64_t)0x1fffULL,
 TTE_IS_GLOBAL(env->dtlb[i].tte) ?
 "global" : "local");
--
1.8.3.1





[Qemu-devel] [PATCH v4 13/15] cputlb: Byte swap memory transaction attribute

2019-07-25 Thread tony.nguyen
Notice new attribute, byte swap, and force the transaction through the
memory slow path.

Required by architectures that can invert endianness of memory
transaction, e.g. SPARC64 has the Invert Endian TTE bit.

Signed-off-by: Tony Nguyen 
---
 accel/tcg/cputlb.c  | 11 +++
 include/exec/memattrs.h |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index e61b1eb..f292a87 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -738,6 +738,9 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong 
vaddr,
  */
 address |= TLB_RECHECK;
 }
+if (attrs.byte_swap) {
+address |= TLB_FORCE_SLOW;
+}
 if (!memory_region_is_ram(section->mr) &&
 !memory_region_is_romd(section->mr)) {
 /* IO memory case */
@@ -891,6 +894,10 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
@@ -933,6 +940,10 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry 
*iotlbentry,
 bool locked = false;
 MemTxResult r;

+if (iotlbentry->attrs.byte_swap) {
+op ^= MO_BSWAP;
+}
+
 section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
 mr = section->mr;
 mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index d4a3477..a0644eb 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -37,6 +37,8 @@ typedef struct MemTxAttrs {
 unsigned int user:1;
 /* Requester ID (for MSI for example) */
 unsigned int requester_id:16;
+/* SPARC64: TTE invert endianness */
+unsigned int byte_swap:1;
 /*
  * The following are target-specific page-table bits.  These are not
  * related to actual memory transactions at all.  However, this structure
--
1.8.3.1





  1   2   >