diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/block/qdict.h | 34 | ||||
-rw-r--r-- | include/exec/cpu-all.h | 4 | ||||
-rw-r--r-- | include/exec/cpu-defs.h | 9 | ||||
-rw-r--r-- | include/exec/exec-all.h | 16 | ||||
-rw-r--r-- | include/exec/memory.h | 65 | ||||
-rw-r--r-- | include/hw/arm/arm.h | 8 | ||||
-rw-r--r-- | include/hw/block/block.h | 1 | ||||
-rw-r--r-- | include/hw/or-irq.h | 5 | ||||
-rw-r--r-- | include/qapi/qmp/qdict.h | 17 | ||||
-rw-r--r-- | include/qemu/bswap.h | 52 | ||||
-rw-r--r-- | include/qom/cpu.h | 3 | ||||
-rw-r--r-- | include/sysemu/blockdev.h | 3 |
12 files changed, 184 insertions, 33 deletions
diff --git a/include/block/qdict.h b/include/block/qdict.h new file mode 100644 index 0000000000..d8cb502d7d --- /dev/null +++ b/include/block/qdict.h @@ -0,0 +1,34 @@ +/* + * Special QDict functions used by the block layer + * + * Copyright (c) 2013-2018 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#ifndef BLOCK_QDICT_H +#define BLOCK_QDICT_H + +#include "qapi/qmp/qdict.h" + +void qdict_copy_default(QDict *dst, QDict *src, const char *key); +void qdict_set_default_str(QDict *dst, const char *key, const char *val); + +void qdict_join(QDict *dest, QDict *src, bool overwrite); + +void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start); +void qdict_array_split(QDict *src, QList **dst); +int qdict_array_entries(QDict *src, const char *subqdict); +QObject *qdict_crumple(const QDict *src, Error **errp); +void qdict_flatten(QDict *qdict); + +typedef struct QDictRenames { + const char *from; + const char *to; +} QDictRenames; +bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp); + +Visitor *qobject_input_visitor_new_flat_confused(QDict *qdict, + Error **errp); +#endif diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index a635f532f9..7fa726b8e3 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -133,6 +133,8 @@ static inline void tswap64s(uint64_t *s) #define stq_p(p, v) stq_be_p(p, v) #define stfl_p(p, v) stfl_be_p(p, v) #define stfq_p(p, v) stfq_be_p(p, v) +#define ldn_p(p, sz) ldn_be_p(p, sz) +#define stn_p(p, sz, v) stn_be_p(p, sz, v) #else #define lduw_p(p) lduw_le_p(p) #define ldsw_p(p) ldsw_le_p(p) @@ -145,6 +147,8 @@ static inline void tswap64s(uint64_t *s) #define stq_p(p, v) stq_le_p(p, v) #define stfl_p(p, v) stfl_le_p(p, v) #define stfq_p(p, v) stfq_le_p(p, v) +#define ldn_p(p, sz) ldn_le_p(p, sz) +#define stn_p(p, sz, v) stn_le_p(p, sz, v) #endif /* MMU memory access macros */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index e43ff8346b..a171ffc1a4 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -127,6 +127,15 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS)); * structs into one.) */ typedef struct CPUIOTLBEntry { + /* + * @addr contains: + * - in the lower TARGET_PAGE_BITS, a physical section number + * - with the lower TARGET_PAGE_BITS masked off, an offset which + * must be added to the virtual address to obtain: + * + the ram_addr_t of the target RAM (if the physical section + * number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM) + * + the offset within the target MemoryRegion (otherwise) + */ hwaddr addr; MemTxAttrs attrs; } CPUIOTLBEntry; diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 4d09eaba72..8bbea787a9 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -437,8 +437,17 @@ void tb_lock_reset(void); #if !defined(CONFIG_USER_ONLY) -struct MemoryRegion *iotlb_to_region(CPUState *cpu, - hwaddr index, MemTxAttrs attrs); +/** + * iotlb_to_section: + * @cpu: CPU performing the access + * @index: TCG CPU IOTLB entry + * + * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that + * it refers to. @index will have been initially created and returned + * by memory_region_section_get_iotlb(). + */ +struct MemoryRegionSection *iotlb_to_section(CPUState *cpu, + hwaddr index, MemTxAttrs attrs); void tlb_fill(CPUState *cpu, target_ulong addr, int size, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); @@ -469,7 +478,8 @@ void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr); MemoryRegionSection * address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, - hwaddr *xlat, hwaddr *plen); + hwaddr *xlat, hwaddr *plen, + MemTxAttrs attrs, int *prot); hwaddr memory_region_section_get_iotlb(CPUState *cpu, MemoryRegionSection *section, target_ulong vaddr, diff --git a/include/exec/memory.h b/include/exec/memory.h index eb2ba06519..050323f532 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -98,18 +98,21 @@ struct IOMMUNotifier { /* Notify for address space range start <= addr <= end */ hwaddr start; hwaddr end; + int iommu_idx; QLIST_ENTRY(IOMMUNotifier) node; }; typedef struct IOMMUNotifier IOMMUNotifier; static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn, IOMMUNotifierFlag flags, - hwaddr start, hwaddr end) + hwaddr start, hwaddr end, + int iommu_idx) { n->notify = fn; n->notifier_flags = flags; n->start = start; n->end = end; + n->iommu_idx = iommu_idx; } /* @@ -206,6 +209,20 @@ enum IOMMUMemoryRegionAttr { * 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). + * + * Conceptually an IOMMU provides a mapping from input address + * to an output TLB entry. If the IOMMU is aware of memory transaction + * attributes and the output TLB entry depends on the transaction + * attributes, we represent this using IOMMU indexes. Each index + * selects a particular translation table that the IOMMU has: + * @attrs_to_index returns the IOMMU index for a set of transaction attributes + * @translate takes an input address and an IOMMU index + * and the mapping returned can only depend on the input address and the + * IOMMU index. + * + * Most IOMMUs don't care about the transaction attributes and support + * only a single IOMMU index. A more complex IOMMU might have one index + * for secure transactions and one for non-secure transactions. */ typedef struct IOMMUMemoryRegionClass { /* private */ @@ -234,9 +251,10 @@ typedef struct IOMMUMemoryRegionClass { * @iommu: the IOMMUMemoryRegion * @hwaddr: address to be translated within the memory region * @flag: requested access permissions + * @iommu_idx: IOMMU index for the translation */ IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr, - IOMMUAccessFlags flag); + IOMMUAccessFlags flag, int iommu_idx); /* Returns minimum supported page size in bytes. * If this method is not provided then the minimum is assumed to * be TARGET_PAGE_SIZE. @@ -290,6 +308,29 @@ typedef struct IOMMUMemoryRegionClass { */ int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr, void *data); + + /* Return the IOMMU index to use for a given set of transaction attributes. + * + * Optional method: if an IOMMU only supports a single IOMMU index then + * the default implementation of memory_region_iommu_attrs_to_index() + * will return 0. + * + * The indexes supported by an IOMMU must be contiguous, starting at 0. + * + * @iommu: the IOMMUMemoryRegion + * @attrs: memory transaction attributes + */ + int (*attrs_to_index)(IOMMUMemoryRegion *iommu, MemTxAttrs attrs); + + /* Return the number of IOMMU indexes this IOMMU supports. + * + * Optional method: if this method is not provided, then + * memory_region_iommu_num_indexes() will return 1, indicating that + * only a single IOMMU index is supported. + * + * @iommu: the IOMMUMemoryRegion + */ + int (*num_indexes)(IOMMUMemoryRegion *iommu); } IOMMUMemoryRegionClass; typedef struct CoalescedMemoryRange CoalescedMemoryRange; @@ -971,11 +1012,13 @@ uint64_t memory_region_iommu_get_min_page_size(IOMMUMemoryRegion *iommu_mr); * should be notified with an UNMAP followed by a MAP. * * @iommu_mr: the memory region that was changed + * @iommu_idx: the IOMMU index for the translation table which has changed * @entry: the new entry in the IOMMU translation table. The entry * replaces all old entries for the same virtual I/O address range. * Deleted entries have .@perm == 0. */ void memory_region_notify_iommu(IOMMUMemoryRegion *iommu_mr, + int iommu_idx, IOMMUTLBEntry entry); /** @@ -1055,6 +1098,24 @@ int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr, void *data); /** + * memory_region_iommu_attrs_to_index: return the IOMMU index to + * use for translations with the given memory transaction attributes. + * + * @iommu_mr: the memory region + * @attrs: the memory transaction attributes + */ +int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr, + MemTxAttrs attrs); + +/** + * memory_region_iommu_num_indexes: return the total number of IOMMU + * indexes that this IOMMU supports. + * + * @iommu_mr: the memory region + */ +int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr); + +/** * memory_region_name: get a memory region's name * * Returns the string that was used to initialize the memory region. diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index 70fa2287e2..ffed39252d 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -23,9 +23,6 @@ typedef enum { ARM_ENDIANNESS_BE32, } arm_endianness; -/* armv7m.c */ -DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq, - const char *kernel_filename, const char *cpu_type); /** * armv7m_load_kernel: * @cpu: CPU @@ -33,9 +30,8 @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq, * @mem_size: mem_size: maximum image size to load * * Load the guest image for an ARMv7M system. This must be called by - * any ARMv7M board, either directly or via armv7m_init(). (This is - * necessary to ensure that the CPU resets correctly on system reset, - * as well as for kernel loading.) + * any ARMv7M board. (This is necessary to ensure that the CPU resets + * correctly on system reset, as well as for kernel loading.) */ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size); diff --git a/include/hw/block/block.h b/include/hw/block/block.h index d4f4dfffab..e9f9e2223f 100644 --- a/include/hw/block/block.h +++ b/include/hw/block/block.h @@ -72,7 +72,6 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) /* Configuration helpers */ -void blkconf_serial(BlockConf *conf, char **serial); bool blkconf_geometry(BlockConf *conf, int *trans, unsigned cyls_max, unsigned heads_max, unsigned secs_max, Error **errp); diff --git a/include/hw/or-irq.h b/include/hw/or-irq.h index 3f6fc1b58a..5a31e5a188 100644 --- a/include/hw/or-irq.h +++ b/include/hw/or-irq.h @@ -31,7 +31,10 @@ #define TYPE_OR_IRQ "or-irq" -#define MAX_OR_LINES 16 +/* This can safely be increased if necessary without breaking + * migration compatibility (as long as it remains greater than 15). + */ +#define MAX_OR_LINES 32 typedef struct OrIRQState qemu_or_irq; diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 921a28d2d3..7f3ec10a10 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -67,23 +67,6 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key, bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value); const char *qdict_get_try_str(const QDict *qdict, const char *key); -void qdict_copy_default(QDict *dst, QDict *src, const char *key); -void qdict_set_default_str(QDict *dst, const char *key, const char *val); - QDict *qdict_clone_shallow(const QDict *src); -void qdict_flatten(QDict *qdict); - -void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start); -void qdict_array_split(QDict *src, QList **dst); -int qdict_array_entries(QDict *src, const char *subqdict); -QObject *qdict_crumple(const QDict *src, Error **errp); - -void qdict_join(QDict *dest, QDict *src, bool overwrite); - -typedef struct QDictRenames { - const char *from; - const char *to; -} QDictRenames; -bool qdict_rename_keys(QDict *qdict, const QDictRenames *renames, Error **errp); #endif /* QDICT_H */ diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h index 3f28f661b1..a684c1a7a2 100644 --- a/include/qemu/bswap.h +++ b/include/qemu/bswap.h @@ -290,6 +290,15 @@ typedef union { * For accessors that take a guest address rather than a * host address, see the cpu_{ld,st}_* accessors defined in * cpu_ldst.h. + * + * For cases where the size to be used is not fixed at compile time, + * there are + * stn{endian}_p(ptr, sz, val) + * which stores @val to @ptr as an @endian-order number @sz bytes in size + * and + * ldn{endian}_p(ptr, sz) + * which loads @sz bytes from @ptr as an unsigned @endian-order number + * and returns it in a uint64_t. */ static inline int ldub_p(const void *ptr) @@ -495,6 +504,49 @@ static inline unsigned long leul_to_cpu(unsigned long v) #endif } +/* Store v to p as a sz byte value in host order */ +#define DO_STN_LDN_P(END) \ + static inline void stn_## END ## _p(void *ptr, int sz, uint64_t v) \ + { \ + switch (sz) { \ + case 1: \ + stb_p(ptr, v); \ + break; \ + case 2: \ + stw_ ## END ## _p(ptr, v); \ + break; \ + case 4: \ + stl_ ## END ## _p(ptr, v); \ + break; \ + case 8: \ + stq_ ## END ## _p(ptr, v); \ + break; \ + default: \ + g_assert_not_reached(); \ + } \ + } \ + static inline uint64_t ldn_## END ## _p(const void *ptr, int sz) \ + { \ + switch (sz) { \ + case 1: \ + return ldub_p(ptr); \ + case 2: \ + return lduw_ ## END ## _p(ptr); \ + case 4: \ + return (uint32_t)ldl_ ## END ## _p(ptr); \ + case 8: \ + return ldq_ ## END ## _p(ptr); \ + default: \ + g_assert_not_reached(); \ + } \ + } + +DO_STN_LDN_P(he) +DO_STN_LDN_P(le) +DO_STN_LDN_P(be) + +#undef DO_STN_LDN_P + #undef le_bswap #undef be_bswap #undef le_bswaps diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 9d3afc6c75..cce2fd6acc 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -429,6 +429,9 @@ struct CPUState { uint16_t pending_tlb_flush; int hvf_fd; + + /* track IOMMUs whose translations we've cached in the TCG TLB */ + GArray *iommu_notifiers; }; QTAILQ_HEAD(CPUTailQ, CPUState); diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index ac22f2ae1f..24954b94e0 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -28,16 +28,13 @@ typedef enum { } BlockInterfaceType; struct DriveInfo { - const char *devaddr; BlockInterfaceType type; int bus; int unit; int auto_del; /* see blockdev_mark_auto_del() */ bool is_default; /* Added by default_drive() ? */ int media_cd; - int cyls, heads, secs, trans; QemuOpts *opts; - char *serial; QTAILQ_ENTRY(DriveInfo) next; }; |