/* * Copyright (c) 2019 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall * not be construed as granting a license to any other intellectual * property including but not limited to intellectual property relating * to a hardware implementation of the functionality of the software * licensed hereunder. You may use the software subject to the license * terms below provided that you ensure that this notice is replicated * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Andreas Sandberg */ #ifndef __BASE_CHANNEL_ADDR_HH__ #define __BASE_CHANNEL_ADDR_HH__ #include #include "base/addr_range.hh" /** * Class holding a guest address in a contiguous channel-local address * space. */ class ChannelAddr { public: using Type = Addr; /** Explicit constructor assigning a value. */ explicit constexpr ChannelAddr(Type _a) : a(_a) { } /** Converting back to the value type. */ explicit constexpr operator Type() const { return a; } /** Converting back to the value type. */ constexpr Type value() const { return a; } constexpr ChannelAddr() : a(0) { } ChannelAddr(const AddrRange &range, Addr _a) : a(range.removeIntlvBits(_a)) {} ChannelAddr(const ChannelAddr &) = default; ChannelAddr &operator=(const ChannelAddr &) = default; Addr getPA(const AddrRange &range) const { return range.addIntlvBits(a); } constexpr ChannelAddr operator|(const Type b) const { return ChannelAddr(a | b); } constexpr ChannelAddr operator&(const Type b) const { return ChannelAddr(a & b); } constexpr ChannelAddr operator>>(const int b) const { return ChannelAddr(a >> b); } constexpr ChannelAddr operator<<(const int b) const { return ChannelAddr(a << b); } constexpr ChannelAddr operator*(const Type &b) const { return ChannelAddr(a * b); } constexpr ChannelAddr operator/(const Type &b) const { return ChannelAddr(a / b); } constexpr ChannelAddr operator+(const Type &b) const { return ChannelAddr(a + b); } constexpr ChannelAddr operator-(const Type &b) const { return ChannelAddr(a - b); } constexpr ChannelAddr operator|(const ChannelAddr &b) const { return ChannelAddr(a | b.a); } constexpr ChannelAddr operator&(const ChannelAddr &b) const { return ChannelAddr(a & b.a); } constexpr ChannelAddr operator^(const ChannelAddr &b) const { return ChannelAddr(a ^ b.a); } constexpr ChannelAddr operator+(const ChannelAddr &b) const { return ChannelAddr(a + b.a); } constexpr ChannelAddr operator-(const ChannelAddr &b) const { return ChannelAddr(a - b.a); } constexpr bool operator>(const ChannelAddr &b) const { return a > b.a; } constexpr bool operator>=(const ChannelAddr &b) const { return a >= b.a; } constexpr bool operator<(const ChannelAddr &b) const { return a < b.a; } constexpr bool operator<=(const ChannelAddr &b) const { return a <= b.a; } constexpr bool operator==(const ChannelAddr &b) const { return a == b.a; } constexpr bool operator!=(const ChannelAddr &b) const { return a != b.a; } private: /** Member holding the actual value. */ Type a; }; /** * The ChanneelAddrRange class describes a contiguous range of * addresses in a contiguous channel-local address space. */ class ChannelAddrRange { public: constexpr ChannelAddrRange() : ChannelAddrRange(ChannelAddr(1), ChannelAddr(0)) {} constexpr ChannelAddrRange(ChannelAddr start, ChannelAddr end) : _start(start), _end(end) {} ChannelAddrRange(AddrRange ch_range, Addr start, Addr end); ChannelAddrRange(AddrRange ch_range, AddrRange range); constexpr ChannelAddrRange(const ChannelAddrRange &) = default; constexpr ChannelAddr size() const { return _end - _start + 1; } constexpr bool valid() const { return _start <= _end; } constexpr ChannelAddr start() const { return _start; } constexpr ChannelAddr end() const { return _end; } constexpr bool contains(ChannelAddr a) const { return a >= _start && a <= _end; } protected: ChannelAddr _start; ChannelAddr _end; }; namespace std { template<> struct hash { typedef ChannelAddr argument_type; typedef std::size_t result_type; result_type operator()(argument_type const &a) const noexcept { return std::hash{}( static_cast(a)); } }; } std::ostream &operator<<(std::ostream &out, const ChannelAddr &addr); #endif // __BASE_CHANNEL_ADDR_HH__