mirror of https://github.com/xqemu/xqemu.git
target-arm queue:
* target/arm: Honour FPCR.FZ in FRECPX * MAINTAINERS: Add entries for newer MPS2 boards and devices * hw/intc/arm_gicv3: Fix APxR<n> register dispatching * arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel GIC state * tcg: Fix helper function vs host abi for float16 * arm: fix qemu crash on startup with -bios option * arm: fix malloc type mismatch * xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors * Correct CPACR reset value for v7 cores * memory.h: Improve IOMMU related documentation * exec: Plumb transaction attributes through various functions in preparation for allowing IOMMUs to see them * vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY * ARM: ACPI: Fix use-after-free due to memory realloc * KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJbEBrAAAoJEDwlJe0UNgzedCwP/3cVeJxrncXDGRwpc3LOJahy AzB8eq4u4mIBehzRzTqU5vQTREEKL9ivDzfGGZo5FkUh0ss8MkAj5xXVcbrlo0wC dvHXRiDtM64ZHNANhc9iMWoI9RTIUFtGnbpqc1JeYiXCyzxj7Y5R79d0dBerFzCK wpqbJjV4gyDVrc4Ah3OK0eISZOve7sbdA05BDvb5eEtmtilIb0QeQ5uZlFlrh3sl gzyj9skaVRTFflGyXBM2AZEwhwRxm/T+K9U36VCdr7AU81xpfHpJoolWc4SLtDL4 8sHwtII0zbwkfKIo9GIalRMYlu9cyo2wkvARcLdon1qH5SYV1JnASKCo2+l7wSbs bRJoX4TjJLAmkOF1Od88hNT5KMU6fIRfEQlFfdL9b3YkilSy9i5x2Pw6LBDMb9cA UoeCZsrCiBWGZ1FQGcwjENSzwA+LhHLzXdOKwNUw/HvimvFC/27WfPJyOhbTyeVA QHwGvjjFozQZrTbgKG+GoUd2U7YyNyuWEcbbybNsMrY4FHMqSSxVHGpBdP1Bbhaf 6d27wWxjlzFGmwwjGG/a6bt4a7qWUKTU08aHeB8XcF/6hjrFqyA8QBg2POnDsC45 BmeJPVZTNY14h+McS1Yc6T+rbq3Db+c2GJtBlbHNNrfSq05NxD+5/vbFK8EnjwFo ZmyGvvfsemf6OsdX1k2i =3O2B -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180531-1' into staging target-arm queue: * target/arm: Honour FPCR.FZ in FRECPX * MAINTAINERS: Add entries for newer MPS2 boards and devices * hw/intc/arm_gicv3: Fix APxR<n> register dispatching * arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel GIC state * tcg: Fix helper function vs host abi for float16 * arm: fix qemu crash on startup with -bios option * arm: fix malloc type mismatch * xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors * Correct CPACR reset value for v7 cores * memory.h: Improve IOMMU related documentation * exec: Plumb transaction attributes through various functions in preparation for allowing IOMMUs to see them * vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY * ARM: ACPI: Fix use-after-free due to memory realloc * KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice # gpg: Signature made Thu 31 May 2018 16:54:40 BST # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180531-1: (25 commits) KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice ARM: ACPI: Fix use-after-free due to memory realloc vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY Make address_space_translate_iommu take a MemTxAttrs argument Make flatview_do_translate() take a MemTxAttrs argument Make address_space_get_iotlb_entry() take a MemTxAttrs argument Make flatview_translate() take a MemTxAttrs argument Make flatview_access_valid() take a MemTxAttrs argument Make MemoryRegion valid.accepts callback take a MemTxAttrs argument Make memory_region_access_valid() take a MemTxAttrs argument Make flatview_extend_translation() take a MemTxAttrs argument Make address_space_access_valid() take a MemTxAttrs argument Make address_space_map() take a MemTxAttrs argument Make address_space_translate{, _cached}() take a MemTxAttrs argument Make tb_invalidate_phys_addr() take a MemTxAttrs argument memory.h: Improve IOMMU related documentation Correct CPACR reset value for v7 cores xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors arm: fix malloc type mismatch arm: fix qemu crash on startup with -bios option ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
c181ddaa17
|
@ -447,6 +447,8 @@ F: hw/timer/cmsdk-apb-timer.c
|
|||
F: include/hw/timer/cmsdk-apb-timer.h
|
||||
F: hw/char/cmsdk-apb-uart.c
|
||||
F: include/hw/char/cmsdk-apb-uart.h
|
||||
F: hw/misc/tz-ppc.c
|
||||
F: include/hw/misc/tz-ppc.h
|
||||
|
||||
ARM cores
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
|
@ -515,8 +517,11 @@ M: Peter Maydell <peter.maydell@linaro.org>
|
|||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/mps2.c
|
||||
F: hw/misc/mps2-scc.c
|
||||
F: include/hw/misc/mps2-scc.h
|
||||
F: hw/arm/mps2-tz.c
|
||||
F: hw/misc/mps2-*.c
|
||||
F: include/hw/misc/mps2-*.h
|
||||
F: hw/arm/iotkit.c
|
||||
F: include/hw/arm/iotkit.h
|
||||
|
||||
Musicpal
|
||||
M: Jan Kiszka <jan.kiszka@web.de>
|
||||
|
|
|
@ -1669,14 +1669,14 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
|||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
|
||||
{
|
||||
ram_addr_t ram_addr;
|
||||
MemoryRegion *mr;
|
||||
hwaddr l = 1;
|
||||
|
||||
rcu_read_lock();
|
||||
mr = address_space_translate(as, addr, &addr, &l, false);
|
||||
mr = address_space_translate(as, addr, &addr, &l, false, attrs);
|
||||
if (!(memory_region_is_ram(mr)
|
||||
|| memory_region_is_romd(mr))) {
|
||||
rcu_read_unlock();
|
||||
|
|
95
exec.c
95
exec.c
|
@ -478,6 +478,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
|
|||
* @is_write: whether the translation operation is for write
|
||||
* @is_mmio: whether this can be MMIO, set true if it can
|
||||
* @target_as: the address space targeted by the IOMMU
|
||||
* @attrs: transaction attributes
|
||||
*
|
||||
* This function is called from RCU critical section. It is the common
|
||||
* part of flatview_do_translate and address_space_translate_cached.
|
||||
|
@ -488,7 +489,8 @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
|
|||
hwaddr *page_mask_out,
|
||||
bool is_write,
|
||||
bool is_mmio,
|
||||
AddressSpace **target_as)
|
||||
AddressSpace **target_as,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection *section;
|
||||
hwaddr page_mask = (hwaddr)-1;
|
||||
|
@ -541,6 +543,7 @@ unassigned:
|
|||
* @is_write: whether the translation operation is for write
|
||||
* @is_mmio: whether this can be MMIO, set true if it can
|
||||
* @target_as: the address space targeted by the IOMMU
|
||||
* @attrs: memory transaction attributes
|
||||
*
|
||||
* This function is called from RCU critical section
|
||||
*/
|
||||
|
@ -551,7 +554,8 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
|||
hwaddr *page_mask_out,
|
||||
bool is_write,
|
||||
bool is_mmio,
|
||||
AddressSpace **target_as)
|
||||
AddressSpace **target_as,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection *section;
|
||||
IOMMUMemoryRegion *iommu_mr;
|
||||
|
@ -570,7 +574,7 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
|||
return address_space_translate_iommu(iommu_mr, xlat,
|
||||
plen_out, page_mask_out,
|
||||
is_write, is_mmio,
|
||||
target_as);
|
||||
target_as, attrs);
|
||||
}
|
||||
if (page_mask_out) {
|
||||
/* Not behind an IOMMU, use default page size. */
|
||||
|
@ -582,7 +586,7 @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
|
|||
|
||||
/* Called from RCU critical section */
|
||||
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
bool is_write)
|
||||
bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection section;
|
||||
hwaddr xlat, page_mask;
|
||||
|
@ -592,7 +596,8 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
|||
* but page mask.
|
||||
*/
|
||||
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
|
||||
NULL, &page_mask, is_write, false, &as);
|
||||
NULL, &page_mask, is_write, false, &as,
|
||||
attrs);
|
||||
|
||||
/* Illegal translation */
|
||||
if (section.mr == &io_mem_unassigned) {
|
||||
|
@ -618,7 +623,8 @@ iotlb_fail:
|
|||
|
||||
/* Called from RCU critical section */
|
||||
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *plen, bool is_write)
|
||||
hwaddr *plen, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
MemoryRegionSection section;
|
||||
|
@ -626,7 +632,7 @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
|
|||
|
||||
/* This can be MMIO, so setup MMIO bit. */
|
||||
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
|
||||
is_write, true, &as);
|
||||
is_write, true, &as, attrs);
|
||||
mr = section.mr;
|
||||
|
||||
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||
|
@ -898,7 +904,7 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
|||
if (phys != -1) {
|
||||
/* Locks grabbed by tb_invalidate_phys_addr */
|
||||
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
|
||||
phys | (pc & ~TARGET_PAGE_MASK));
|
||||
phys | (pc & ~TARGET_PAGE_MASK), attrs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2539,7 +2545,8 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
|
|||
}
|
||||
|
||||
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return is_write;
|
||||
}
|
||||
|
@ -2696,7 +2703,7 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
|||
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||
const uint8_t *buf, int len);
|
||||
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
bool is_write);
|
||||
bool is_write, MemTxAttrs attrs);
|
||||
|
||||
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
|
||||
unsigned len, MemTxAttrs attrs)
|
||||
|
@ -2762,7 +2769,8 @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool subpage_accepts(void *opaque, hwaddr addr,
|
||||
unsigned len, bool is_write)
|
||||
unsigned len, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
subpage_t *subpage = opaque;
|
||||
#if defined(DEBUG_SUBPAGE)
|
||||
|
@ -2771,7 +2779,7 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
|
|||
#endif
|
||||
|
||||
return flatview_access_valid(subpage->fv, addr + subpage->base,
|
||||
len, is_write);
|
||||
len, is_write, attrs);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps subpage_ops = {
|
||||
|
@ -2845,7 +2853,8 @@ static void readonly_mem_write(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return is_write;
|
||||
}
|
||||
|
@ -3149,7 +3158,7 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
|
|||
}
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -3165,7 +3174,7 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
|||
MemTxResult result = MEMTX_OK;
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
|
||||
result = flatview_write_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
|
||||
|
@ -3236,7 +3245,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
|
|||
}
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -3251,7 +3260,7 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
|||
MemoryRegion *mr;
|
||||
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
|
||||
return flatview_read_continue(fv, addr, attrs, buf, len,
|
||||
addr1, l, mr);
|
||||
}
|
||||
|
@ -3322,7 +3331,8 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
|
|||
rcu_read_lock();
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||
mr = address_space_translate(as, addr, &addr1, &l, true,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
|
||||
if (!(memory_region_is_ram(mr) ||
|
||||
memory_region_is_romd(mr))) {
|
||||
|
@ -3457,17 +3467,17 @@ static void cpu_notify_map_clients(void)
|
|||
}
|
||||
|
||||
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
||||
bool is_write)
|
||||
bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
hwaddr l, xlat;
|
||||
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
|
||||
if (!memory_access_is_direct(mr, is_write)) {
|
||||
l = memory_access_size(mr, l, addr);
|
||||
if (!memory_region_access_valid(mr, xlat, l, is_write)) {
|
||||
if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3479,23 +3489,24 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
|
|||
}
|
||||
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
|
||||
int len, bool is_write)
|
||||
int len, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
FlatView *fv;
|
||||
bool result;
|
||||
|
||||
rcu_read_lock();
|
||||
fv = address_space_to_flatview(as);
|
||||
result = flatview_access_valid(fv, addr, len, is_write);
|
||||
result = flatview_access_valid(fv, addr, len, is_write, attrs);
|
||||
rcu_read_unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
static hwaddr
|
||||
flatview_extend_translation(FlatView *fv, hwaddr addr,
|
||||
hwaddr target_len,
|
||||
MemoryRegion *mr, hwaddr base, hwaddr len,
|
||||
bool is_write)
|
||||
hwaddr target_len,
|
||||
MemoryRegion *mr, hwaddr base, hwaddr len,
|
||||
bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
hwaddr done = 0;
|
||||
hwaddr xlat;
|
||||
|
@ -3511,7 +3522,7 @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
|
|||
|
||||
len = target_len;
|
||||
this_mr = flatview_translate(fv, addr, &xlat,
|
||||
&len, is_write);
|
||||
&len, is_write, attrs);
|
||||
if (this_mr != mr || xlat != base + done) {
|
||||
return done;
|
||||
}
|
||||
|
@ -3528,7 +3539,8 @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
|
|||
void *address_space_map(AddressSpace *as,
|
||||
hwaddr addr,
|
||||
hwaddr *plen,
|
||||
bool is_write)
|
||||
bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
hwaddr len = *plen;
|
||||
hwaddr l, xlat;
|
||||
|
@ -3543,7 +3555,7 @@ void *address_space_map(AddressSpace *as,
|
|||
l = len;
|
||||
rcu_read_lock();
|
||||
fv = address_space_to_flatview(as);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
|
||||
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
|
||||
|
||||
if (!memory_access_is_direct(mr, is_write)) {
|
||||
if (atomic_xchg(&bounce.in_use, true)) {
|
||||
|
@ -3571,7 +3583,7 @@ void *address_space_map(AddressSpace *as,
|
|||
|
||||
memory_region_ref(mr);
|
||||
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
|
||||
l, is_write);
|
||||
l, is_write, attrs);
|
||||
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
|
||||
rcu_read_unlock();
|
||||
|
||||
|
@ -3615,7 +3627,8 @@ void *cpu_physical_memory_map(hwaddr addr,
|
|||
hwaddr *plen,
|
||||
int is_write)
|
||||
{
|
||||
return address_space_map(&address_space_memory, addr, plen, is_write);
|
||||
return address_space_map(&address_space_memory, addr, plen, is_write,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
}
|
||||
|
||||
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
|
||||
|
@ -3655,8 +3668,13 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
|
|||
mr = cache->mrs.mr;
|
||||
memory_region_ref(mr);
|
||||
if (memory_access_is_direct(mr, is_write)) {
|
||||
/* We don't care about the memory attributes here as we're only
|
||||
* doing this if we found actual RAM, which behaves the same
|
||||
* regardless of attributes; so UNSPECIFIED is fine.
|
||||
*/
|
||||
l = flatview_extend_translation(cache->fv, addr, len, mr,
|
||||
cache->xlat, l, is_write);
|
||||
cache->xlat, l, is_write,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
|
||||
} else {
|
||||
cache->ptr = NULL;
|
||||
|
@ -3699,7 +3717,7 @@ void address_space_cache_destroy(MemoryRegionCache *cache)
|
|||
*/
|
||||
static inline MemoryRegion *address_space_translate_cached(
|
||||
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *plen, bool is_write)
|
||||
hwaddr *plen, bool is_write, MemTxAttrs attrs)
|
||||
{
|
||||
MemoryRegionSection section;
|
||||
MemoryRegion *mr;
|
||||
|
@ -3718,7 +3736,7 @@ static inline MemoryRegion *address_space_translate_cached(
|
|||
|
||||
section = address_space_translate_iommu(iommu_mr, xlat, plen,
|
||||
NULL, is_write, true,
|
||||
&target_as);
|
||||
&target_as, attrs);
|
||||
return section.mr;
|
||||
}
|
||||
|
||||
|
@ -3733,7 +3751,8 @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
|
|||
MemoryRegion *mr;
|
||||
|
||||
l = len;
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
flatview_read_continue(cache->fv,
|
||||
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
|
||||
addr1, l, mr);
|
||||
|
@ -3750,7 +3769,8 @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
|
|||
MemoryRegion *mr;
|
||||
|
||||
l = len;
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
|
||||
mr = address_space_translate_cached(cache, addr, &addr1, &l, true,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
flatview_write_continue(cache->fv,
|
||||
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
|
||||
addr1, l, mr);
|
||||
|
@ -3848,7 +3868,8 @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
|
|||
|
||||
rcu_read_lock();
|
||||
mr = address_space_translate(&address_space_memory,
|
||||
phys_addr, &phys_addr, &l, false);
|
||||
phys_addr, &phys_addr, &l, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
|
||||
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -926,6 +926,15 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
|||
static const ARMInsnFixup *primary_loader;
|
||||
AddressSpace *as = arm_boot_address_space(cpu, info);
|
||||
|
||||
/* CPU objects (unlike devices) are not automatically reset on system
|
||||
* reset, so we must always register a handler to do so. If we're
|
||||
* actually loading a kernel, the handler is also responsible for
|
||||
* arranging that we start it correctly.
|
||||
*/
|
||||
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
|
||||
qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
|
||||
}
|
||||
|
||||
/* The board code is not supposed to set secure_board_setup unless
|
||||
* running its code in secure mode is actually possible, and KVM
|
||||
* doesn't support secure.
|
||||
|
@ -1143,15 +1152,6 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
|
|||
ARM_CPU(cs)->env.boot_info = info;
|
||||
}
|
||||
|
||||
/* CPU objects (unlike devices) are not automatically reset on system
|
||||
* reset, so we must always register a handler to do so. If we're
|
||||
* actually loading a kernel, the handler is also responsible for
|
||||
* arranging that we start it correctly.
|
||||
*/
|
||||
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
|
||||
qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
|
||||
}
|
||||
|
||||
if (!info->skip_dtb_autoload && have_dtb(info)) {
|
||||
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
|
||||
exit(1);
|
||||
|
|
|
@ -400,7 +400,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
AcpiIortItsGroup *its;
|
||||
AcpiIortTable *iort;
|
||||
AcpiIortSmmu3 *smmu;
|
||||
size_t node_size, iort_length, smmu_offset = 0;
|
||||
size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
|
||||
AcpiIortRC *rc;
|
||||
|
||||
iort = acpi_data_push(table_data, sizeof(*iort));
|
||||
|
@ -413,7 +413,12 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
|
||||
iort_length = sizeof(*iort);
|
||||
iort->node_count = cpu_to_le32(nb_nodes);
|
||||
iort->node_offset = cpu_to_le32(sizeof(*iort));
|
||||
/*
|
||||
* Use a copy in case table_data->data moves during acpi_data_push
|
||||
* operations.
|
||||
*/
|
||||
iort_node_offset = sizeof(*iort);
|
||||
iort->node_offset = cpu_to_le32(iort_node_offset);
|
||||
|
||||
/* ITS group node */
|
||||
node_size = sizeof(*its) + sizeof(uint32_t);
|
||||
|
@ -429,7 +434,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
int irq = vms->irqmap[VIRT_SMMU];
|
||||
|
||||
/* SMMUv3 node */
|
||||
smmu_offset = iort->node_offset + node_size;
|
||||
smmu_offset = iort_node_offset + node_size;
|
||||
node_size = sizeof(*smmu) + sizeof(*idmap);
|
||||
iort_length += node_size;
|
||||
smmu = acpi_data_push(table_data, node_size);
|
||||
|
@ -450,7 +455,7 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
idmap->id_count = cpu_to_le32(0xFFFF);
|
||||
idmap->output_base = 0;
|
||||
/* output IORT node is the ITS group node (the first node) */
|
||||
idmap->output_reference = cpu_to_le32(iort->node_offset);
|
||||
idmap->output_reference = cpu_to_le32(iort_node_offset);
|
||||
}
|
||||
|
||||
/* Root Complex Node */
|
||||
|
@ -479,9 +484,14 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
|||
idmap->output_reference = cpu_to_le32(smmu_offset);
|
||||
} else {
|
||||
/* output IORT node is the ITS group node (the first node) */
|
||||
idmap->output_reference = cpu_to_le32(iort->node_offset);
|
||||
idmap->output_reference = cpu_to_le32(iort_node_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the pointer address in case table_data->data moves during above
|
||||
* acpi_data_push operations.
|
||||
*/
|
||||
iort = (AcpiIortTable *)(table_data->data + iort_start);
|
||||
iort->length = cpu_to_le32(iort_length);
|
||||
|
||||
build_header(linker, table_data, (void *)(table_data->data + iort_start),
|
||||
|
|
|
@ -302,7 +302,7 @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
|
|||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"zdma: unaligned descriptor at %" PRIx64,
|
||||
addr);
|
||||
memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
|
||||
memset(buf, 0x0, sizeof(XlnxZDMADescr));
|
||||
s->error = true;
|
||||
return false;
|
||||
}
|
||||
|
@ -707,9 +707,11 @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
|
|||
RegisterInfo *r = &s->regs_info[addr / 4];
|
||||
|
||||
if (!r->data) {
|
||||
gchar *path = object_get_canonical_path(OBJECT(s));
|
||||
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
|
||||
object_get_canonical_path(OBJECT(s)),
|
||||
path,
|
||||
addr);
|
||||
g_free(path);
|
||||
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
|
||||
zdma_ch_imr_update_irq(s);
|
||||
return 0;
|
||||
|
@ -724,9 +726,11 @@ static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
|
|||
RegisterInfo *r = &s->regs_info[addr / 4];
|
||||
|
||||
if (!r->data) {
|
||||
gchar *path = object_get_canonical_path(OBJECT(s));
|
||||
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
|
||||
object_get_canonical_path(OBJECT(s)),
|
||||
path,
|
||||
addr, value);
|
||||
g_free(path);
|
||||
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
|
||||
zdma_ch_imr_update_irq(s);
|
||||
return;
|
||||
|
|
|
@ -137,7 +137,8 @@ static void gsc_to_pci_forwarding(DinoState *s)
|
|||
}
|
||||
|
||||
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
switch (addr) {
|
||||
case DINO_IAR0:
|
||||
|
|
|
@ -572,7 +572,6 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
if (kvm_has_gsi_routing()) {
|
||||
/* set up irq routing */
|
||||
kvm_init_irq_routing(kvm_state);
|
||||
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
|
||||
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
|
||||
}
|
||||
|
|
|
@ -427,7 +427,7 @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
uint64_t value = cs->ich_apr[grp][regno];
|
||||
|
||||
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
|
||||
|
@ -439,7 +439,7 @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
|
||||
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
|
||||
|
||||
|
@ -1461,7 +1461,7 @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|||
uint64_t value;
|
||||
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
|
||||
|
||||
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
|
||||
return icv_ap_read(env, ri);
|
||||
|
@ -1483,7 +1483,7 @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
|
||||
|
||||
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
|
||||
icv_ap_write(env, ri, value);
|
||||
|
@ -2292,7 +2292,7 @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
|||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
uint64_t value;
|
||||
|
||||
value = cs->ich_apr[grp][regno];
|
||||
|
@ -2305,7 +2305,7 @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
{
|
||||
GICv3CPUState *cs = icc_cs_from_env(env);
|
||||
int regno = ri->opc2 & 3;
|
||||
int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
|
||||
int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
|
||||
|
||||
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
|
||||
|
||||
|
|
|
@ -243,6 +243,7 @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
|
|||
if (clroffset != 0) {
|
||||
reg = 0;
|
||||
kvm_gicd_access(s, clroffset, ®, true);
|
||||
clroffset += 4;
|
||||
}
|
||||
reg = *gic_bmp_ptr32(bmp, irq);
|
||||
kvm_gicd_access(s, offset, ®, true);
|
||||
|
@ -760,7 +761,6 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
if (kvm_has_gsi_routing()) {
|
||||
/* set up irq routing */
|
||||
kvm_init_irq_routing(kvm_state);
|
||||
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
|
||||
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
|
||||
}
|
||||
|
|
|
@ -420,14 +420,16 @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
|
||||
(size == 8 && addr == 0));
|
||||
}
|
||||
|
||||
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return addr == 0;
|
||||
}
|
||||
|
@ -439,7 +441,8 @@ static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return is_write && size == 2;
|
||||
}
|
||||
|
@ -458,7 +461,8 @@ static void fw_cfg_comb_write(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return (size == 1) || (is_write && size == 2);
|
||||
}
|
||||
|
|
|
@ -762,7 +762,8 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
|
|||
mr = s390_get_subregion(mr, offset, len);
|
||||
offset -= mr->addr;
|
||||
|
||||
if (!memory_region_access_valid(mr, offset, len, true)) {
|
||||
if (!memory_region_access_valid(mr, offset, len, true,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -564,7 +564,8 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
|
|||
}
|
||||
|
||||
static bool esp_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return (size == 1) || (is_write && size == 4);
|
||||
}
|
||||
|
|
|
@ -324,7 +324,8 @@ static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
|
|||
*/
|
||||
mr = address_space_translate(&address_space_memory,
|
||||
iotlb->translated_addr,
|
||||
&xlat, &len, writable);
|
||||
&xlat, &len, writable,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (!memory_region_is_ram(mr)) {
|
||||
error_report("iommu map to non memory area %"HWADDR_PRIx"",
|
||||
xlat);
|
||||
|
|
|
@ -897,7 +897,8 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
|
|||
trace_vhost_iotlb_miss(dev, 1);
|
||||
|
||||
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
|
||||
iova, write);
|
||||
iova, write,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (iotlb.target_as != NULL) {
|
||||
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
|
||||
&uaddr, &len);
|
||||
|
|
|
@ -498,7 +498,8 @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool pci_msix_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return !(addr & (size - 1));
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
|
|||
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||
hwaddr paddr, int prot,
|
||||
int mmu_idx, target_ulong size);
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
|
||||
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
|
||||
uintptr_t retaddr);
|
||||
#else
|
||||
|
@ -303,7 +303,8 @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
|
|||
uint16_t idxmap)
|
||||
{
|
||||
}
|
||||
static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
|
||||
static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#define dh_ctype_int int
|
||||
#define dh_ctype_i64 uint64_t
|
||||
#define dh_ctype_s64 int64_t
|
||||
#define dh_ctype_f16 float16
|
||||
#define dh_ctype_f16 uint32_t
|
||||
#define dh_ctype_f32 float32
|
||||
#define dh_ctype_f64 float64
|
||||
#define dh_ctype_ptr void *
|
||||
|
|
|
@ -37,7 +37,8 @@ void flatview_unref(FlatView *view);
|
|||
extern const MemoryRegionOps unassigned_mem_ops;
|
||||
|
||||
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
|
||||
unsigned size, bool is_write);
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs);
|
||||
|
||||
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
|
||||
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
|
||||
|
|
|
@ -166,7 +166,8 @@ struct MemoryRegionOps {
|
|||
* as a machine check exception).
|
||||
*/
|
||||
bool (*accepts)(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write);
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs);
|
||||
} valid;
|
||||
/* Internal implementation constraints: */
|
||||
struct {
|
||||
|
@ -194,29 +195,100 @@ enum IOMMUMemoryRegionAttr {
|
|||
IOMMU_ATTR_SPAPR_TCE_FD
|
||||
};
|
||||
|
||||
/**
|
||||
* IOMMUMemoryRegionClass:
|
||||
*
|
||||
* All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
|
||||
* and provide an implementation of at least the @translate method here
|
||||
* to handle requests to the memory region. Other methods are optional.
|
||||
*
|
||||
* The IOMMU implementation must use the IOMMU notifier infrastructure
|
||||
* to report whenever mappings are changed, by calling
|
||||
* memory_region_notify_iommu() (or, if necessary, by calling
|
||||
* memory_region_notify_one() for each registered notifier).
|
||||
*/
|
||||
typedef struct IOMMUMemoryRegionClass {
|
||||
/* private */
|
||||
struct DeviceClass parent_class;
|
||||
|
||||
/*
|
||||
* Return a TLB entry that contains a given address. Flag should
|
||||
* be the access permission of this translation operation. We can
|
||||
* set flag to IOMMU_NONE to mean that we don't need any
|
||||
* read/write permission checks, like, when for region replay.
|
||||
* Return a TLB entry that contains a given address.
|
||||
*
|
||||
* The IOMMUAccessFlags indicated via @flag are optional and may
|
||||
* be specified as IOMMU_NONE to indicate that the caller needs
|
||||
* the full translation information for both reads and writes. If
|
||||
* the access flags are specified then the IOMMU implementation
|
||||
* may use this as an optimization, to stop doing a page table
|
||||
* walk as soon as it knows that the requested permissions are not
|
||||
* allowed. If IOMMU_NONE is passed then the IOMMU must do the
|
||||
* full page table walk and report the permissions in the returned
|
||||
* IOMMUTLBEntry. (Note that this implies that an IOMMU may not
|
||||
* return different mappings for reads and writes.)
|
||||
*
|
||||
* The returned information remains valid while the caller is
|
||||
* holding the big QEMU lock or is inside an RCU critical section;
|
||||
* if the caller wishes to cache the mapping beyond that it must
|
||||
* register an IOMMU notifier so it can invalidate its cached
|
||||
* information when the IOMMU mapping changes.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
* @hwaddr: address to be translated within the memory region
|
||||
* @flag: requested access permissions
|
||||
*/
|
||||
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
|
||||
IOMMUAccessFlags flag);
|
||||
/* Returns minimum supported page size */
|
||||
/* Returns minimum supported page size in bytes.
|
||||
* If this method is not provided then the minimum is assumed to
|
||||
* be TARGET_PAGE_SIZE.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
*/
|
||||
uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu);
|
||||
/* Called when IOMMU Notifier flag changed */
|
||||
/* Called when IOMMU Notifier flag changes (ie when the set of
|
||||
* events which IOMMU users are requesting notification for changes).
|
||||
* Optional method -- need not be provided if the IOMMU does not
|
||||
* need to know exactly which events must be notified.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
* @old_flags: events which previously needed to be notified
|
||||
* @new_flags: events which now need to be notified
|
||||
*/
|
||||
void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
|
||||
IOMMUNotifierFlag old_flags,
|
||||
IOMMUNotifierFlag new_flags);
|
||||
/* Set this up to provide customized IOMMU replay function */
|
||||
/* Called to handle memory_region_iommu_replay().
|
||||
*
|
||||
* The default implementation of memory_region_iommu_replay() is to
|
||||
* call the IOMMU translate method for every page in the address space
|
||||
* with flag == IOMMU_NONE and then call the notifier if translate
|
||||
* returns a valid mapping. If this method is implemented then it
|
||||
* overrides the default behaviour, and must provide the full semantics
|
||||
* of memory_region_iommu_replay(), by calling @notifier for every
|
||||
* translation present in the IOMMU.
|
||||
*
|
||||
* Optional method -- an IOMMU only needs to provide this method
|
||||
* if the default is inefficient or produces undesirable side effects.
|
||||
*
|
||||
* Note: this is not related to record-and-replay functionality.
|
||||
*/
|
||||
void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier);
|
||||
|
||||
/* Get IOMMU misc attributes */
|
||||
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr,
|
||||
/* Get IOMMU misc attributes. This is an optional method that
|
||||
* can be used to allow users of the IOMMU to get implementation-specific
|
||||
* information. The IOMMU implements this method to handle calls
|
||||
* by IOMMU users to memory_region_iommu_get_attr() by filling in
|
||||
* the arbitrary data pointer for any IOMMUMemoryRegionAttr values that
|
||||
* the IOMMU supports. If the method is unimplemented then
|
||||
* memory_region_iommu_get_attr() will always return -EINVAL.
|
||||
*
|
||||
* @iommu: the IOMMUMemoryRegion
|
||||
* @attr: attribute being queried
|
||||
* @data: memory to fill in with the attribute data
|
||||
*
|
||||
* Returns 0 on success, or a negative errno; in particular
|
||||
* returns -EINVAL for unrecognized or unimplemented attribute types.
|
||||
*/
|
||||
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
|
||||
void *data);
|
||||
} IOMMUMemoryRegionClass;
|
||||
|
||||
|
@ -705,6 +777,14 @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
|
|||
* An IOMMU region translates addresses and forwards accesses to a target
|
||||
* memory region.
|
||||
*
|
||||
* The IOMMU implementation must define a subclass of TYPE_IOMMU_MEMORY_REGION.
|
||||
* @_iommu_mr should be a pointer to enough memory for an instance of
|
||||
* that subclass, @instance_size is the size of that subclass, and
|
||||
* @mrtypename is its name. This function will initialize @_iommu_mr as an
|
||||
* instance of the subclass, and its methods will then be called to handle
|
||||
* accesses to the memory region. See the documentation of
|
||||
* #IOMMUMemoryRegionClass for further details.
|
||||
*
|
||||
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
|
||||
* @instance_size: the IOMMUMemoryRegion subclass instance size
|
||||
* @mrtypename: the type name of the #IOMMUMemoryRegion
|
||||
|
@ -953,6 +1033,8 @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
|
|||
* a notifier with the minimum page granularity returned by
|
||||
* mr->iommu_ops->get_page_size().
|
||||
*
|
||||
* Note: this is not related to record-and-replay functionality.
|
||||
*
|
||||
* @iommu_mr: the memory region to observe
|
||||
* @n: the notifier to which to replay iommu mappings
|
||||
*/
|
||||
|
@ -962,6 +1044,8 @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
|
|||
* memory_region_iommu_replay_all: replay existing IOMMU translations
|
||||
* to all the notifiers registered.
|
||||
*
|
||||
* Note: this is not related to record-and-replay functionality.
|
||||
*
|
||||
* @iommu_mr: the memory region to observe
|
||||
*/
|
||||
void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
|
||||
|
@ -981,7 +1065,9 @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
|
|||
* memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
|
||||
* defined on the IOMMU.
|
||||
*
|
||||
* Returns 0 if succeded, error code otherwise.
|
||||
* Returns 0 on success, or a negative errno otherwise. In particular,
|
||||
* -EINVAL indicates that the IOMMU does not support the requested
|
||||
* attribute.
|
||||
*
|
||||
* @iommu_mr: the memory region
|
||||
* @attr: the requested attribute
|
||||
|
@ -1810,7 +1896,7 @@ void address_space_cache_destroy(MemoryRegionCache *cache);
|
|||
* entry. Should be called from an RCU critical section.
|
||||
*/
|
||||
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
||||
bool is_write);
|
||||
bool is_write, MemTxAttrs attrs);
|
||||
|
||||
/* address_space_translate: translate an address range into an address space
|
||||
* into a MemoryRegion and an address range into that section. Should be
|
||||
|
@ -1823,17 +1909,20 @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
|
|||
* #MemoryRegion.
|
||||
* @len: pointer to length
|
||||
* @is_write: indicates the transfer direction
|
||||
* @attrs: memory attributes
|
||||
*/
|
||||
MemoryRegion *flatview_translate(FlatView *fv,
|
||||
hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *len, bool is_write);
|
||||
hwaddr *len, bool is_write,
|
||||
MemTxAttrs attrs);
|
||||
|
||||
static inline MemoryRegion *address_space_translate(AddressSpace *as,
|
||||
hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *len, bool is_write)
|
||||
hwaddr *len, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return flatview_translate(address_space_to_flatview(as),
|
||||
addr, xlat, len, is_write);
|
||||
addr, xlat, len, is_write, attrs);
|
||||
}
|
||||
|
||||
/* address_space_access_valid: check for validity of accessing an address
|
||||
|
@ -1850,8 +1939,10 @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
|
|||
* @addr: address within that address space
|
||||
* @len: length of the area to be checked
|
||||
* @is_write: indicates the transfer direction
|
||||
* @attrs: memory attributes
|
||||
*/
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
|
||||
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
|
||||
bool is_write, MemTxAttrs attrs);
|
||||
|
||||
/* address_space_map: map a physical memory region into a host virtual address
|
||||
*
|
||||
|
@ -1865,9 +1956,10 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
|
|||
* @addr: address within that address space
|
||||
* @plen: pointer to length of buffer; updated on return
|
||||
* @is_write: indicates the transfer direction
|
||||
* @attrs: memory attributes
|
||||
*/
|
||||
void *address_space_map(AddressSpace *as, hwaddr addr,
|
||||
hwaddr *plen, bool is_write);
|
||||
hwaddr *plen, bool is_write, MemTxAttrs attrs);
|
||||
|
||||
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
|
||||
*
|
||||
|
@ -1939,7 +2031,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
|
|||
rcu_read_lock();
|
||||
fv = address_space_to_flatview(as);
|
||||
l = len;
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false);
|
||||
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
|
||||
if (len == l && memory_access_is_direct(mr, false)) {
|
||||
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||
memcpy(buf, ptr, len);
|
||||
|
|
|
@ -870,6 +870,9 @@ extern const VMStateInfo vmstate_info_qtailq;
|
|||
#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
|
||||
VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
|
||||
|
||||
#define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \
|
||||
VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool)
|
||||
|
||||
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
|
||||
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
|
||||
|
||||
|
|
|
@ -77,7 +77,8 @@ static inline bool dma_memory_valid(AddressSpace *as,
|
|||
DMADirection dir)
|
||||
{
|
||||
return address_space_access_valid(as, addr, len,
|
||||
dir == DMA_DIRECTION_FROM_DEVICE);
|
||||
dir == DMA_DIRECTION_FROM_DEVICE,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
|
||||
|
@ -132,7 +133,8 @@ static inline void *dma_memory_map(AddressSpace *as,
|
|||
hwaddr xlen = *len;
|
||||
void *p;
|
||||
|
||||
p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
|
||||
p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
*len = xlen;
|
||||
return p;
|
||||
}
|
||||
|
|
12
memory.c
12
memory.c
|
@ -1269,7 +1269,8 @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
|
|||
}
|
||||
|
||||
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
|
||||
unsigned size, bool is_write)
|
||||
unsigned size, bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1347,7 +1348,8 @@ static const MemoryRegionOps ram_device_mem_ops = {
|
|||
bool memory_region_access_valid(MemoryRegion *mr,
|
||||
hwaddr addr,
|
||||
unsigned size,
|
||||
bool is_write)
|
||||
bool is_write,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
int access_size_min, access_size_max;
|
||||
int access_size, i;
|
||||
|
@ -1373,7 +1375,7 @@ bool memory_region_access_valid(MemoryRegion *mr,
|
|||
access_size = MAX(MIN(size, access_size_max), access_size_min);
|
||||
for (i = 0; i < size; i += access_size) {
|
||||
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
|
||||
is_write)) {
|
||||
is_write, attrs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1416,7 +1418,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
|
|||
{
|
||||
MemTxResult r;
|
||||
|
||||
if (!memory_region_access_valid(mr, addr, size, false)) {
|
||||
if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
|
||||
*pval = unassigned_mem_read(mr, addr, size);
|
||||
return MEMTX_DECODE_ERROR;
|
||||
}
|
||||
|
@ -1458,7 +1460,7 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
|
|||
unsigned size,
|
||||
MemTxAttrs attrs)
|
||||
{
|
||||
if (!memory_region_access_valid(mr, addr, size, true)) {
|
||||
if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
|
||||
unassigned_mem_write(mr, addr, data, size);
|
||||
return MEMTX_DECODE_ERROR;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, false);
|
||||
mr = TRANSLATE(addr, &addr1, &l, false, attrs);
|
||||
if (l < 4 || !IS_DIRECT(mr, false)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -109,7 +109,7 @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, false);
|
||||
mr = TRANSLATE(addr, &addr1, &l, false, attrs);
|
||||
if (l < 8 || !IS_DIRECT(mr, false)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -183,7 +183,7 @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, false);
|
||||
mr = TRANSLATE(addr, &addr1, &l, false, attrs);
|
||||
if (!IS_DIRECT(mr, false)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -219,7 +219,7 @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, false);
|
||||
mr = TRANSLATE(addr, &addr1, &l, false, attrs);
|
||||
if (l < 2 || !IS_DIRECT(mr, false)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -296,7 +296,7 @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, true);
|
||||
mr = TRANSLATE(addr, &addr1, &l, true, attrs);
|
||||
if (l < 4 || !IS_DIRECT(mr, true)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -333,7 +333,7 @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, true);
|
||||
mr = TRANSLATE(addr, &addr1, &l, true, attrs);
|
||||
if (l < 4 || !IS_DIRECT(mr, true)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -405,7 +405,7 @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, true);
|
||||
mr = TRANSLATE(addr, &addr1, &l, true, attrs);
|
||||
if (!IS_DIRECT(mr, true)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
|
||||
|
@ -438,7 +438,7 @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, true);
|
||||
mr = TRANSLATE(addr, &addr1, &l, true, attrs);
|
||||
if (l < 2 || !IS_DIRECT(mr, true)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
@ -511,7 +511,7 @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
|
|||
bool release_lock = false;
|
||||
|
||||
RCU_READ_LOCK();
|
||||
mr = TRANSLATE(addr, &addr1, &l, true);
|
||||
mr = TRANSLATE(addr, &addr1, &l, true, attrs);
|
||||
if (l < 8 || !IS_DIRECT(mr, true)) {
|
||||
release_lock |= prepare_mmio_access(mr);
|
||||
|
||||
|
|
|
@ -157,8 +157,7 @@ int arm_gen_dynamic_xml(CPUState *cs)
|
|||
RegisterSysregXmlParam param = {cs, s};
|
||||
|
||||
cpu->dyn_xml.num_cpregs = 0;
|
||||
cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(uint32_t *) *
|
||||
g_hash_table_size(cpu->cp_regs));
|
||||
cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
|
||||
g_string_printf(s, "<?xml version=\"1.0\"?>");
|
||||
g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
|
||||
g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
|
||||
|
|
|
@ -85,12 +85,12 @@ static inline uint32_t float_rel_to_flags(int res)
|
|||
return flags;
|
||||
}
|
||||
|
||||
uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
|
||||
uint64_t HELPER(vfp_cmph_a64)(uint32_t x, uint32_t y, void *fp_status)
|
||||
{
|
||||
return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
|
||||
}
|
||||
|
||||
uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
|
||||
uint64_t HELPER(vfp_cmpeh_a64)(uint32_t x, uint32_t y, void *fp_status)
|
||||
{
|
||||
return float_rel_to_flags(float16_compare(x, y, fp_status));
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
|
|||
#define float64_three make_float64(0x4008000000000000ULL)
|
||||
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
|
||||
|
||||
float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(recpsf_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
|
@ -259,7 +259,7 @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
|
|||
return float64_muladd(a, b, float64_two, 0, fpst);
|
||||
}
|
||||
|
||||
float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
|
@ -366,7 +366,7 @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
|
|||
}
|
||||
|
||||
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
|
||||
float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
|
||||
uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
uint16_t val16, sbit;
|
||||
|
@ -384,6 +384,8 @@ float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
|
|||
return nan;
|
||||
}
|
||||
|
||||
a = float16_squash_input_denormal(a, fpst);
|
||||
|
||||
val16 = float16_val(a);
|
||||
sbit = 0x8000 & val16;
|
||||
exp = extract32(val16, 10, 5);
|
||||
|
@ -413,6 +415,8 @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
|
|||
return nan;
|
||||
}
|
||||
|
||||
a = float32_squash_input_denormal(a, fpst);
|
||||
|
||||
val32 = float32_val(a);
|
||||
sbit = 0x80000000ULL & val32;
|
||||
exp = extract32(val32, 23, 8);
|
||||
|
@ -442,6 +446,8 @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
|
|||
return nan;
|
||||
}
|
||||
|
||||
a = float64_squash_input_denormal(a, fpst);
|
||||
|
||||
val64 = float64_val(a);
|
||||
sbit = 0x8000000000000000ULL & val64;
|
||||
exp = extract64(float64_val(a), 52, 11);
|
||||
|
@ -695,7 +701,7 @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
|
|||
#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
|
||||
|
||||
#define ADVSIMD_HALFOP(name) \
|
||||
float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
|
||||
uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
return float16_ ## name(a, b, fpst); \
|
||||
|
@ -755,7 +761,8 @@ ADVSIMD_HALFOP(mulx)
|
|||
ADVSIMD_TWOHALFOP(mulx)
|
||||
|
||||
/* fused multiply-accumulate */
|
||||
float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
|
||||
uint32_t HELPER(advsimd_muladdh)(uint32_t a, uint32_t b, uint32_t c,
|
||||
void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
return float16_muladd(a, b, c, 0, fpst);
|
||||
|
@ -786,14 +793,14 @@ uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
|
|||
|
||||
#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
|
||||
|
||||
uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(advsimd_ceq_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
int compare = float16_compare_quiet(a, b, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_equal);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(advsimd_cge_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
int compare = float16_compare(a, b, fpst);
|
||||
|
@ -801,14 +808,14 @@ uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
|
|||
compare == float_relation_equal);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(advsimd_cgt_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
int compare = float16_compare(a, b, fpst);
|
||||
return ADVSIMD_CMPRES(compare == float_relation_greater);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(advsimd_acge_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
float16 f0 = float16_abs(a);
|
||||
|
@ -818,7 +825,7 @@ uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
|
|||
compare == float_relation_equal);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
|
||||
uint32_t HELPER(advsimd_acgt_f16)(uint32_t a, uint32_t b, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
float16 f0 = float16_abs(a);
|
||||
|
@ -828,12 +835,12 @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
|
|||
}
|
||||
|
||||
/* round to integral */
|
||||
float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
|
||||
uint32_t HELPER(advsimd_rinth_exact)(uint32_t x, void *fp_status)
|
||||
{
|
||||
return float16_round_to_int(x, fp_status);
|
||||
}
|
||||
|
||||
float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
|
||||
uint32_t HELPER(advsimd_rinth)(uint32_t x, void *fp_status)
|
||||
{
|
||||
int old_flags = get_float_exception_flags(fp_status), new_flags;
|
||||
float16 ret;
|
||||
|
@ -857,7 +864,7 @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
|
|||
* setting the mode appropriately before calling the helper.
|
||||
*/
|
||||
|
||||
uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
|
||||
uint32_t HELPER(advsimd_f16tosinth)(uint32_t a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
|
@ -869,7 +876,7 @@ uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
|
|||
return float16_to_int16(a, fpst);
|
||||
}
|
||||
|
||||
uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
|
||||
uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
|
||||
|
@ -885,7 +892,7 @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
|
|||
* Square Root and Reciprocal square root
|
||||
*/
|
||||
|
||||
float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
|
||||
uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
|
||||
{
|
||||
float_status *s = fpstp;
|
||||
|
||||
|
|
|
@ -863,6 +863,14 @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
env->cp15.cpacr_el1 = value;
|
||||
}
|
||||
|
||||
static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
/* Call cpacr_write() so that we reset with the correct RAO bits set
|
||||
* for our CPU features.
|
||||
*/
|
||||
cpacr_write(env, ri, 0);
|
||||
}
|
||||
|
||||
static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
bool isread)
|
||||
{
|
||||
|
@ -920,7 +928,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
|
|||
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
|
||||
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
|
||||
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
|
||||
.resetvalue = 0, .writefn = cpacr_write },
|
||||
.resetfn = cpacr_reset, .writefn = cpacr_write },
|
||||
REGINFO_SENTINEL
|
||||
};
|
||||
|
||||
|
@ -11344,35 +11352,35 @@ DO_VFP_cmp(d, float64)
|
|||
|
||||
/* Integer to float and float to integer conversions */
|
||||
|
||||
#define CONV_ITOF(name, fsz, sign) \
|
||||
float##fsz HELPER(name)(uint32_t x, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
|
||||
#define CONV_ITOF(name, ftype, fsz, sign) \
|
||||
ftype HELPER(name)(uint32_t x, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
|
||||
}
|
||||
|
||||
#define CONV_FTOI(name, fsz, sign, round) \
|
||||
uint32_t HELPER(name)(float##fsz x, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
if (float##fsz##_is_any_nan(x)) { \
|
||||
float_raise(float_flag_invalid, fpst); \
|
||||
return 0; \
|
||||
} \
|
||||
return float##fsz##_to_##sign##int32##round(x, fpst); \
|
||||
#define CONV_FTOI(name, ftype, fsz, sign, round) \
|
||||
uint32_t HELPER(name)(ftype x, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
if (float##fsz##_is_any_nan(x)) { \
|
||||
float_raise(float_flag_invalid, fpst); \
|
||||
return 0; \
|
||||
} \
|
||||
return float##fsz##_to_##sign##int32##round(x, fpst); \
|
||||
}
|
||||
|
||||
#define FLOAT_CONVS(name, p, fsz, sign) \
|
||||
CONV_ITOF(vfp_##name##to##p, fsz, sign) \
|
||||
CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
|
||||
CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
|
||||
#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
|
||||
CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
|
||||
CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
|
||||
CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
|
||||
|
||||
FLOAT_CONVS(si, h, 16, )
|
||||
FLOAT_CONVS(si, s, 32, )
|
||||
FLOAT_CONVS(si, d, 64, )
|
||||
FLOAT_CONVS(ui, h, 16, u)
|
||||
FLOAT_CONVS(ui, s, 32, u)
|
||||
FLOAT_CONVS(ui, d, 64, u)
|
||||
FLOAT_CONVS(si, h, uint32_t, 16, )
|
||||
FLOAT_CONVS(si, s, float32, 32, )
|
||||
FLOAT_CONVS(si, d, float64, 64, )
|
||||
FLOAT_CONVS(ui, h, uint32_t, 16, u)
|
||||
FLOAT_CONVS(ui, s, float32, 32, u)
|
||||
FLOAT_CONVS(ui, d, float64, 64, u)
|
||||
|
||||
#undef CONV_ITOF
|
||||
#undef CONV_FTOI
|
||||
|
@ -11465,22 +11473,22 @@ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
|
|||
return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
|
||||
}
|
||||
|
||||
float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
|
||||
}
|
||||
|
||||
float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
|
||||
}
|
||||
|
||||
float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
|
||||
}
|
||||
|
||||
float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
|
||||
}
|
||||
|
@ -11504,32 +11512,32 @@ static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
|
||||
}
|
||||
|
||||
uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
|
||||
}
|
||||
|
||||
uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
|
||||
}
|
||||
|
||||
uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
|
||||
uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
|
||||
}
|
||||
|
||||
uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
|
||||
uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
|
||||
}
|
||||
|
||||
uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
|
||||
uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
|
||||
{
|
||||
return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
|
||||
}
|
||||
|
@ -11565,7 +11573,7 @@ uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
|
|||
}
|
||||
|
||||
/* Half precision conversions. */
|
||||
float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
|
||||
float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
|
||||
{
|
||||
/* Squash FZ16 to 0 for the duration of conversion. In this case,
|
||||
* it would affect flushing input denormals.
|
||||
|
@ -11578,7 +11586,7 @@ float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
|
|||
return r;
|
||||
}
|
||||
|
||||
float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
|
||||
uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
|
||||
{
|
||||
/* Squash FZ16 to 0 for the duration of conversion. In this case,
|
||||
* it would affect flushing output denormals.
|
||||
|
@ -11591,7 +11599,7 @@ float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
|
|||
return r;
|
||||
}
|
||||
|
||||
float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
|
||||
float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
|
||||
{
|
||||
/* Squash FZ16 to 0 for the duration of conversion. In this case,
|
||||
* it would affect flushing input denormals.
|
||||
|
@ -11604,7 +11612,7 @@ float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
|
|||
return r;
|
||||
}
|
||||
|
||||
float16 HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
|
||||
uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
|
||||
{
|
||||
/* Squash FZ16 to 0 for the duration of conversion. In this case,
|
||||
* it would affect flushing output denormals.
|
||||
|
@ -11742,7 +11750,7 @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
|
|||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
float16 HELPER(recpe_f16)(float16 input, void *fpstp)
|
||||
uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
|
||||
{
|
||||
float_status *fpst = fpstp;
|
||||
float16 f16 = float16_squash_input_denormal(input, fpst);
|
||||
|
@ -11937,7 +11945,7 @@ static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
|
|||
return extract64(estimate, 0, 8) << 44;
|
||||
}
|
||||
|
||||
float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
|
||||
uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
|
||||
{
|
||||
float_status *s = fpstp;
|
||||
float16 f16 = float16_squash_input_denormal(input, s);
|
||||
|
|
|
@ -664,7 +664,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
|
|||
/* MSI doorbell address is translated by an IOMMU */
|
||||
|
||||
rcu_read_lock();
|
||||
mr = address_space_translate(as, address, &xlat, &len, true);
|
||||
mr = address_space_translate(as, address, &xlat, &len, true,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (!mr) {
|
||||
goto unlock;
|
||||
}
|
||||
|
|
|
@ -431,7 +431,8 @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false);
|
||||
hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (plen < (n * HASH_PTE_SIZE_64)) {
|
||||
hw_error("%s: Unable to map all requested HPTEs\n", __func__);
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ restart:
|
|||
MemoryRegion *mr;
|
||||
hwaddr l = sizeof(target_ulong), addr1;
|
||||
mr = address_space_translate(cs->as, pte_addr,
|
||||
&addr1, &l, false);
|
||||
&addr1, &l, false, MEMTXATTRS_UNSPECIFIED);
|
||||
if (memory_access_is_direct(mr, true)) {
|
||||
target_ulong *pte_pa =
|
||||
qemu_map_ram_ptr(mr->ram_block, addr1);
|
||||
|
|
|
@ -87,7 +87,8 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
|
|||
return;
|
||||
}
|
||||
if (!address_space_access_valid(&address_space_memory, addr,
|
||||
sizeof(IplParameterBlock), false)) {
|
||||
sizeof(IplParameterBlock), false,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
|
||||
return;
|
||||
}
|
||||
|
@ -116,7 +117,8 @@ out:
|
|||
return;
|
||||
}
|
||||
if (!address_space_access_valid(&address_space_memory, addr,
|
||||
sizeof(IplParameterBlock), true)) {
|
||||
sizeof(IplParameterBlock), true,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,8 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, int size,
|
|||
|
||||
/* check out of RAM access */
|
||||
if (!address_space_access_valid(&address_space_memory, raddr,
|
||||
TARGET_PAGE_SIZE, rw)) {
|
||||
TARGET_PAGE_SIZE, rw,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
|
||||
(uint64_t)raddr, (uint64_t)ram_size);
|
||||
trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
|
||||
|
|
|
@ -461,7 +461,8 @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
|
|||
return ret;
|
||||
}
|
||||
if (!address_space_access_valid(&address_space_memory, pages[i],
|
||||
TARGET_PAGE_SIZE, is_write)) {
|
||||
TARGET_PAGE_SIZE, is_write,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
|
@ -280,7 +280,8 @@ static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
|
|||
cpu_synchronize_state(cs);
|
||||
|
||||
if (!address_space_access_valid(&address_space_memory, addr,
|
||||
sizeof(struct LowCore), false)) {
|
||||
sizeof(struct LowCore), false,
|
||||
MEMTXATTRS_UNSPECIFIED)) {
|
||||
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,8 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
|
|||
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
|
||||
&paddr, &page_size, &access);
|
||||
if (ret == 0) {
|
||||
tb_invalidate_phys_addr(&address_space_memory, paddr);
|
||||
tb_invalidate_phys_addr(&address_space_memory, paddr,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue