diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-07-05 16:48:24 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-07-05 16:48:24 +0100 |
| commit | 791b7d2340cfafcac9af7864343cf23504d57804 (patch) | |
| tree | 5834c152f6881c3e907bfe64dd66bcfa83cf8369 /include/qemu/range.h | |
| parent | 60a0f1af07d685c88f4ffa09370da5bd7514823e (diff) | |
| parent | 269fe4c3ab0cf29329317eb868f8ec90ac761b41 (diff) | |
| download | focaccia-qemu-791b7d2340cfafcac9af7864343cf23504d57804.tar.gz focaccia-qemu-791b7d2340cfafcac9af7864343cf23504d57804.zip | |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc, pci, virtio: new features, cleanups, fixes iommus can not be added with -device. cleanups and fixes all over the place Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Tue 05 Jul 2016 11:18:32 BST # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * remotes/mst/tags/for_upstream: (30 commits) vmw_pvscsi: remove unnecessary internal msi state flag e1000e: remove unnecessary internal msi state flag vmxnet3: remove unnecessary internal msi state flag mptsas: remove unnecessary internal msi state flag megasas: remove unnecessary megasas_use_msi() pci: Convert msi_init() to Error and fix callers to check it pci bridge dev: change msi property type megasas: change msi/msix property type mptsas: change msi property type intel-hda: change msi property type usb xhci: change msi/msix property type change pvscsi_init_msi() type to void tests: add APIC.cphp and DSDT.cphp blobs tests: acpi: add CPU hotplug testcase log: Permit -dfilter 0..0xffffffffffffffff range: Replace internal representation of Range range: Eliminate direct Range member access log: Clean up misuse of Range for -dfilter pci_register_bar: cleanup Revert "virtio-net: unbreak self announcement and guest offloads after migration" ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include/qemu/range.h')
| -rw-r--r-- | include/qemu/range.h | 103 |
1 files changed, 91 insertions, 12 deletions
diff --git a/include/qemu/range.h b/include/qemu/range.h index 3970f00089..f28f0c1825 100644 --- a/include/qemu/range.h +++ b/include/qemu/range.h @@ -26,32 +26,111 @@ /* * Operations on 64 bit address ranges. * Notes: - * - ranges must not wrap around 0, but can include the last byte ~0x0LL. - * - this can not represent a full 0 to ~0x0LL range. + * - Ranges must not wrap around 0, but can include UINT64_MAX. */ -/* A structure representing a range of addresses. */ struct Range { - uint64_t begin; /* First byte of the range, or 0 if empty. */ - uint64_t end; /* 1 + the last byte. 0 if range empty or ends at ~0x0LL. */ + /* + * Do not access members directly, use the functions! + * A non-empty range has @lob <= @upb. + * An empty range has @lob == @upb + 1. + */ + uint64_t lob; /* inclusive lower bound */ + uint64_t upb; /* inclusive upper bound */ }; +static inline void range_invariant(Range *range) +{ + assert(range->lob <= range->upb || range->lob == range->upb + 1); +} + +/* Compound literal encoding the empty range */ +#define range_empty ((Range){ .lob = 1, .upb = 0 }) + +/* Is @range empty? */ +static inline bool range_is_empty(Range *range) +{ + range_invariant(range); + return range->lob > range->upb; +} + +/* Does @range contain @val? */ +static inline bool range_contains(Range *range, uint64_t val) +{ + return val >= range->lob && val <= range->upb; +} + +/* Initialize @range to the empty range */ +static inline void range_make_empty(Range *range) +{ + *range = range_empty; + assert(range_is_empty(range)); +} + +/* + * Initialize @range to span the interval [@lob,@upb]. + * Both bounds are inclusive. + * The interval must not be empty, i.e. @lob must be less than or + * equal @upb. + */ +static inline void range_set_bounds(Range *range, uint64_t lob, uint64_t upb) +{ + range->lob = lob; + range->upb = upb; + assert(!range_is_empty(range)); +} + +/* + * Initialize @range to span the interval [@lob,@upb_plus1). + * The lower bound is inclusive, the upper bound is exclusive. + * Zero @upb_plus1 is special: if @lob is also zero, set @range to the + * empty range. Else, set @range to [@lob,UINT64_MAX]. + */ +static inline void range_set_bounds1(Range *range, + uint64_t lob, uint64_t upb_plus1) +{ + if (!lob && !upb_plus1) { + *range = range_empty; + } else { + range->lob = lob; + range->upb = upb_plus1 - 1; + } + range_invariant(range); +} + +/* Return @range's lower bound. @range must not be empty. */ +static inline uint64_t range_lob(Range *range) +{ + assert(!range_is_empty(range)); + return range->lob; +} + +/* Return @range's upper bound. @range must not be empty. */ +static inline uint64_t range_upb(Range *range) +{ + assert(!range_is_empty(range)); + return range->upb; +} + +/* + * Extend @range to the smallest interval that includes @extend_by, too. + */ static inline void range_extend(Range *range, Range *extend_by) { - if (!extend_by->begin && !extend_by->end) { + if (range_is_empty(extend_by)) { return; } - if (!range->begin && !range->end) { + if (range_is_empty(range)) { *range = *extend_by; return; } - if (range->begin > extend_by->begin) { - range->begin = extend_by->begin; + if (range->lob > extend_by->lob) { + range->lob = extend_by->lob; } - /* Compare last byte in case region ends at ~0x0LL */ - if (range->end - 1 < extend_by->end - 1) { - range->end = extend_by->end; + if (range->upb < extend_by->upb) { + range->upb = extend_by->upb; } + range_invariant(range); } /* Get last byte of a range from offset + length. |