diff options
-rw-r--r-- | accel/tcg/cputlb.c | 12 | ||||
-rw-r--r-- | include/exec/memattrs.h | 2 |
2 files changed, 14 insertions, 0 deletions
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 3c9e634d99..d9787cc893 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -738,6 +738,10 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr, */ address |= TLB_RECHECK; } + if (attrs.byte_swap) { + /* Force the access through the I/O slow path. */ + address |= TLB_MMIO; + } if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) { /* IO memory case */ @@ -891,6 +895,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 +941,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 d4a3477d71..95f2d20d55 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 |