mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Don't silently truncate extremely long words in the command line * dtc configure fixes * MemoryRegionCache second try * Deprecated option removal * add support for Hyper-V reenlightenment MSRs # gpg: Signature made Fri 11 May 2018 13:33:46 BST # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (29 commits) rename included C files to foo.inc.c, remove osdep.h pc-dimm: fix error messages if no slots were defined build: Silence dtc directory creation shippable: Remove Debian 8 libfdt kludge configure: Display if libfdt is from system or git configure: Really use local libfdt if the system one is too old i386/kvm: add support for Hyper-V reenlightenment MSRs qemu-doc: provide details of supported build platforms qemu-options: Remove deprecated -no-kvm-irqchip qemu-options: Remove deprecated -no-kvm-pit-reinjection qemu-options: Bail out on unsupported options instead of silently ignoring them qemu-options: Remove remainders of the -tdf option qemu-options: Mark -virtioconsole as deprecated target/i386: sev: fix memory leaks opts: don't silently truncate long option values opts: don't silently truncate long parameter keys accel: use g_strsplit for parsing accelerator names update-linux-headers: drop hyperv.h qemu-thread: always keep the posix wrapper layer exec: reintroduce MemoryRegion caching ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+31
-42
@@ -168,51 +168,40 @@ extern unsigned long reserved_va;
|
||||
#else
|
||||
|
||||
#include "exec/hwaddr.h"
|
||||
uint32_t lduw_phys(AddressSpace *as, hwaddr addr);
|
||||
uint32_t ldl_phys(AddressSpace *as, hwaddr addr);
|
||||
uint64_t ldq_phys(AddressSpace *as, hwaddr addr);
|
||||
void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val);
|
||||
|
||||
uint32_t address_space_lduw(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_ldl(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint64_t address_space_ldq(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
#define SUFFIX
|
||||
#define ARG1 as
|
||||
#define ARG1_DECL AddressSpace *as
|
||||
#define TARGET_ENDIANNESS
|
||||
#include "exec/memory_ldst.inc.h"
|
||||
|
||||
uint32_t lduw_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint32_t ldl_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint64_t ldq_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
void stl_phys_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stw_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stl_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stq_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
|
||||
#define SUFFIX _cached_slow
|
||||
#define ARG1 cache
|
||||
#define ARG1_DECL MemoryRegionCache *cache
|
||||
#define TARGET_ENDIANNESS
|
||||
#include "exec/memory_ldst.inc.h"
|
||||
|
||||
uint32_t address_space_lduw_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_ldl_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint64_t address_space_ldq_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_notdirty_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stw_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stq_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
|
||||
{
|
||||
address_space_stl_notdirty(as, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
#define SUFFIX
|
||||
#define ARG1 as
|
||||
#define ARG1_DECL AddressSpace *as
|
||||
#define TARGET_ENDIANNESS
|
||||
#include "exec/memory_ldst_phys.inc.h"
|
||||
|
||||
/* Inline fast path for direct RAM access. */
|
||||
#define ENDIANNESS
|
||||
#include "exec/memory_ldst_cached.inc.h"
|
||||
|
||||
#define SUFFIX _cached
|
||||
#define ARG1 cache
|
||||
#define ARG1_DECL MemoryRegionCache *cache
|
||||
#define TARGET_ENDIANNESS
|
||||
#include "exec/memory_ldst_phys.inc.h"
|
||||
#endif
|
||||
|
||||
/* page related stuff */
|
||||
|
||||
@@ -31,6 +31,9 @@ static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
|
||||
return flatview_to_dispatch(address_space_to_flatview(as));
|
||||
}
|
||||
|
||||
FlatView *address_space_get_flatview(AddressSpace *as);
|
||||
void flatview_unref(FlatView *view);
|
||||
|
||||
extern const MemoryRegionOps unassigned_mem_ops;
|
||||
|
||||
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
||||
|
||||
+95
-112
@@ -1676,57 +1676,91 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
|
||||
* @result: location to write the success/failure of the transaction;
|
||||
* if NULL, this information is discarded
|
||||
*/
|
||||
uint32_t address_space_ldub(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_lduw_le(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_lduw_be(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_ldl_le(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_ldl_be(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint64_t address_space_ldq_le(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint64_t address_space_ldq_be(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stb(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stw_le(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stw_be(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_le(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_be(AddressSpace *as, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
|
||||
uint32_t ldub_phys(AddressSpace *as, hwaddr addr);
|
||||
uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr);
|
||||
uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr);
|
||||
uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr);
|
||||
uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr);
|
||||
uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr);
|
||||
uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr);
|
||||
void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val);
|
||||
void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val);
|
||||
void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val);
|
||||
#define SUFFIX
|
||||
#define ARG1 as
|
||||
#define ARG1_DECL AddressSpace *as
|
||||
#include "exec/memory_ldst.inc.h"
|
||||
|
||||
#define SUFFIX
|
||||
#define ARG1 as
|
||||
#define ARG1_DECL AddressSpace *as
|
||||
#include "exec/memory_ldst_phys.inc.h"
|
||||
|
||||
struct MemoryRegionCache {
|
||||
void *ptr;
|
||||
hwaddr xlat;
|
||||
hwaddr len;
|
||||
AddressSpace *as;
|
||||
FlatView *fv;
|
||||
MemoryRegionSection mrs;
|
||||
bool is_write;
|
||||
};
|
||||
|
||||
#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .as = NULL })
|
||||
#define MEMORY_REGION_CACHE_INVALID ((MemoryRegionCache) { .mrs.mr = NULL })
|
||||
|
||||
|
||||
/* address_space_ld*_cached: load from a cached #MemoryRegion
|
||||
* address_space_st*_cached: store into a cached #MemoryRegion
|
||||
*
|
||||
* These functions perform a load or store of the byte, word,
|
||||
* longword or quad to the specified address. The address is
|
||||
* a physical address in the AddressSpace, but it must lie within
|
||||
* a #MemoryRegion that was mapped with address_space_cache_init.
|
||||
*
|
||||
* The _le suffixed functions treat the data as little endian;
|
||||
* _be indicates big endian; no suffix indicates "same endianness
|
||||
* as guest CPU".
|
||||
*
|
||||
* The "guest CPU endianness" accessors are deprecated for use outside
|
||||
* target-* code; devices should be CPU-agnostic and use either the LE
|
||||
* or the BE accessors.
|
||||
*
|
||||
* @cache: previously initialized #MemoryRegionCache to be accessed
|
||||
* @addr: address within the address space
|
||||
* @val: data value, for stores
|
||||
* @attrs: memory transaction attributes
|
||||
* @result: location to write the success/failure of the transaction;
|
||||
* if NULL, this information is discarded
|
||||
*/
|
||||
|
||||
#define SUFFIX _cached_slow
|
||||
#define ARG1 cache
|
||||
#define ARG1_DECL MemoryRegionCache *cache
|
||||
#include "exec/memory_ldst.inc.h"
|
||||
|
||||
/* Inline fast path for direct RAM access. */
|
||||
static inline uint8_t address_space_ldub_cached(MemoryRegionCache *cache,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len);
|
||||
if (likely(cache->ptr)) {
|
||||
return ldub_p(cache->ptr + addr);
|
||||
} else {
|
||||
return address_space_ldub_cached_slow(cache, addr, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void address_space_stb_cached(MemoryRegionCache *cache,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len);
|
||||
if (likely(cache->ptr)) {
|
||||
stb_p(cache->ptr + addr, val);
|
||||
} else {
|
||||
address_space_stb_cached_slow(cache, addr, val, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
#define ENDIANNESS _le
|
||||
#include "exec/memory_ldst_cached.inc.h"
|
||||
|
||||
#define ENDIANNESS _be
|
||||
#include "exec/memory_ldst_cached.inc.h"
|
||||
|
||||
#define SUFFIX _cached
|
||||
#define ARG1 cache
|
||||
#define ARG1_DECL MemoryRegionCache *cache
|
||||
#include "exec/memory_ldst_phys.inc.h"
|
||||
|
||||
/* address_space_cache_init: prepare for repeated access to a physical
|
||||
* memory region
|
||||
@@ -1772,72 +1806,6 @@ void address_space_cache_invalidate(MemoryRegionCache *cache,
|
||||
*/
|
||||
void address_space_cache_destroy(MemoryRegionCache *cache);
|
||||
|
||||
/* address_space_ld*_cached: load from a cached #MemoryRegion
|
||||
* address_space_st*_cached: store into a cached #MemoryRegion
|
||||
*
|
||||
* These functions perform a load or store of the byte, word,
|
||||
* longword or quad to the specified address. The address is
|
||||
* a physical address in the AddressSpace, but it must lie within
|
||||
* a #MemoryRegion that was mapped with address_space_cache_init.
|
||||
*
|
||||
* The _le suffixed functions treat the data as little endian;
|
||||
* _be indicates big endian; no suffix indicates "same endianness
|
||||
* as guest CPU".
|
||||
*
|
||||
* The "guest CPU endianness" accessors are deprecated for use outside
|
||||
* target-* code; devices should be CPU-agnostic and use either the LE
|
||||
* or the BE accessors.
|
||||
*
|
||||
* @cache: previously initialized #MemoryRegionCache to be accessed
|
||||
* @addr: address within the address space
|
||||
* @val: data value, for stores
|
||||
* @attrs: memory transaction attributes
|
||||
* @result: location to write the success/failure of the transaction;
|
||||
* if NULL, this information is discarded
|
||||
*/
|
||||
uint32_t address_space_ldub_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_lduw_le_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_lduw_be_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_ldl_le_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint32_t address_space_ldl_be_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint64_t address_space_ldq_le_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
uint64_t address_space_ldq_be_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stb_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stw_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stw_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stl_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stq_le_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
void address_space_stq_be_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val,
|
||||
MemTxAttrs attrs, MemTxResult *result);
|
||||
|
||||
uint32_t ldub_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint32_t lduw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint32_t lduw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint32_t ldl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint32_t ldl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint64_t ldq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
uint64_t ldq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr);
|
||||
void stb_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val);
|
||||
void stq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
|
||||
void stq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val);
|
||||
/* address_space_get_iotlb_entry: translate an address into an IOTLB
|
||||
* entry. Should be called from an RCU critical section.
|
||||
*/
|
||||
@@ -1925,6 +1893,13 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
||||
MemoryRegion *mr);
|
||||
void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
|
||||
|
||||
/* Internal functions, part of the implementation of address_space_read_cached
|
||||
* and address_space_write_cached. */
|
||||
void address_space_read_cached_slow(MemoryRegionCache *cache,
|
||||
hwaddr addr, void *buf, int len);
|
||||
void address_space_write_cached_slow(MemoryRegionCache *cache,
|
||||
hwaddr addr, const void *buf, int len);
|
||||
|
||||
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
|
||||
{
|
||||
if (is_write) {
|
||||
@@ -1993,7 +1968,11 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
void *buf, int len)
|
||||
{
|
||||
assert(addr < cache->len && len <= cache->len - addr);
|
||||
address_space_read(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
|
||||
if (likely(cache->ptr)) {
|
||||
memcpy(buf, cache->ptr + addr, len);
|
||||
} else {
|
||||
address_space_read_cached_slow(cache, addr, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2009,7 +1988,11 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
|
||||
void *buf, int len)
|
||||
{
|
||||
assert(addr < cache->len && len <= cache->len - addr);
|
||||
address_space_write(cache->as, cache->xlat + addr, MEMTXATTRS_UNSPECIFIED, buf, len);
|
||||
if (likely(cache->ptr)) {
|
||||
memcpy(cache->ptr + addr, buf, len);
|
||||
} else {
|
||||
address_space_write_cached_slow(cache, addr, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Physical memory access templates
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2015 Linaro, Inc.
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_ENDIANNESS
|
||||
extern uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stw, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stl, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stq, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
#else
|
||||
extern uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stb, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stw_le, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stl_le, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stl_be, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stq_le, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
extern void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
|
||||
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
|
||||
#endif
|
||||
|
||||
#undef ARG1_DECL
|
||||
#undef ARG1
|
||||
#undef SUFFIX
|
||||
#undef TARGET_ENDIANNESS
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Memory access templates for MemoryRegionCache
|
||||
*
|
||||
* Copyright (c) 2018 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define ADDRESS_SPACE_LD_CACHED(size) \
|
||||
glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached))
|
||||
#define ADDRESS_SPACE_LD_CACHED_SLOW(size) \
|
||||
glue(glue(address_space_ld, size), glue(ENDIANNESS, _cached_slow))
|
||||
#define LD_P(size) \
|
||||
glue(glue(ld, size), glue(ENDIANNESS, _p))
|
||||
|
||||
static inline uint32_t ADDRESS_SPACE_LD_CACHED(l)(MemoryRegionCache *cache,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len && 4 <= cache->len - addr);
|
||||
if (likely(cache->ptr)) {
|
||||
return LD_P(l)(cache->ptr + addr);
|
||||
} else {
|
||||
return ADDRESS_SPACE_LD_CACHED_SLOW(l)(cache, addr, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t ADDRESS_SPACE_LD_CACHED(q)(MemoryRegionCache *cache,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len && 8 <= cache->len - addr);
|
||||
if (likely(cache->ptr)) {
|
||||
return LD_P(q)(cache->ptr + addr);
|
||||
} else {
|
||||
return ADDRESS_SPACE_LD_CACHED_SLOW(q)(cache, addr, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t ADDRESS_SPACE_LD_CACHED(uw)(MemoryRegionCache *cache,
|
||||
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len && 2 <= cache->len - addr);
|
||||
if (likely(cache->ptr)) {
|
||||
return LD_P(uw)(cache->ptr + addr);
|
||||
} else {
|
||||
return ADDRESS_SPACE_LD_CACHED_SLOW(uw)(cache, addr, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
#undef ADDRESS_SPACE_LD_CACHED
|
||||
#undef ADDRESS_SPACE_LD_CACHED_SLOW
|
||||
#undef LD_P
|
||||
|
||||
#define ADDRESS_SPACE_ST_CACHED(size) \
|
||||
glue(glue(address_space_st, size), glue(ENDIANNESS, _cached))
|
||||
#define ADDRESS_SPACE_ST_CACHED_SLOW(size) \
|
||||
glue(glue(address_space_st, size), glue(ENDIANNESS, _cached_slow))
|
||||
#define ST_P(size) \
|
||||
glue(glue(st, size), glue(ENDIANNESS, _p))
|
||||
|
||||
static inline void ADDRESS_SPACE_ST_CACHED(l)(MemoryRegionCache *cache,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len && 4 <= cache->len - addr);
|
||||
if (likely(cache->ptr)) {
|
||||
ST_P(l)(cache->ptr + addr, val);
|
||||
} else {
|
||||
ADDRESS_SPACE_ST_CACHED_SLOW(l)(cache, addr, val, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ADDRESS_SPACE_ST_CACHED(w)(MemoryRegionCache *cache,
|
||||
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len && 2 <= cache->len - addr);
|
||||
if (likely(cache->ptr)) {
|
||||
ST_P(w)(cache->ptr + addr, val);
|
||||
} else {
|
||||
ADDRESS_SPACE_ST_CACHED_SLOW(w)(cache, addr, val, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ADDRESS_SPACE_ST_CACHED(q)(MemoryRegionCache *cache,
|
||||
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
|
||||
{
|
||||
assert(addr < cache->len && 8 <= cache->len - addr);
|
||||
if (likely(cache->ptr)) {
|
||||
ST_P(q)(cache->ptr + addr, val);
|
||||
} else {
|
||||
ADDRESS_SPACE_ST_CACHED_SLOW(q)(cache, addr, val, attrs, result);
|
||||
}
|
||||
}
|
||||
|
||||
#undef ADDRESS_SPACE_ST_CACHED
|
||||
#undef ADDRESS_SPACE_ST_CACHED_SLOW
|
||||
#undef ST_P
|
||||
|
||||
#undef ENDIANNESS
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Physical memory access templates
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2015 Linaro, Inc.
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_ENDIANNESS
|
||||
static inline uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldl, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldq, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_lduw, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stl, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stw, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
|
||||
{
|
||||
glue(address_space_stq, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
#else
|
||||
static inline uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldl_le, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldl_be, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldq_le, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldq_be, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_ldub, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_lduw_le, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
|
||||
{
|
||||
return glue(address_space_lduw_be, SUFFIX)(ARG1, addr,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stl_le, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stl_be, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stb, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stw_le, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
|
||||
{
|
||||
glue(address_space_stw_be, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
|
||||
{
|
||||
glue(address_space_stq_le, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static inline void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
|
||||
{
|
||||
glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
|
||||
MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef ARG1_DECL
|
||||
#undef ARG1
|
||||
#undef SUFFIX
|
||||
#undef TARGET_ENDIANNESS
|
||||
Reference in New Issue
Block a user