1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 /******************************* DisplayPort *******************************\ 25 * * 26 * Module: dp_address.h * 27 * Basic class for AUX Address * 28 * * 29 \***************************************************************************/ 30 31 #ifndef INCLUDED_DP_ADDRESS_H 32 #define INCLUDED_DP_ADDRESS_H 33 34 #include "dp_internal.h" 35 36 namespace DisplayPort 37 { 38 class Address 39 { 40 public: 41 enum 42 { 43 maxHops = 15, // update DP_MAX_ADDRESS_HOPS when changed (in displayportCommon.h) 44 maxHopsHDCP = 7, 45 maxPortCount = 15 46 }; 47 Address()48 Address() 49 { 50 clear(); 51 } 52 Address(unsigned hop0)53 Address(unsigned hop0) 54 { 55 clear(); 56 hop[hops++] = hop0; 57 } 58 Address(unsigned hop0,unsigned hop1)59 Address(unsigned hop0, unsigned hop1) 60 { 61 clear(); 62 hop[hops++] = hop0; 63 hop[hops++] = hop1; 64 } 65 Address(const Address & other)66 Address(const Address & other) 67 { 68 clear(); 69 for(unsigned i = 0; i < other.size(); i++) 70 { 71 append(other[i]); 72 } 73 } 74 clear()75 void clear() 76 { 77 hops = 0; 78 for (unsigned i = 0; i < maxHops; i++) 79 { 80 hop[i] = 0; 81 } 82 } 83 parent()84 Address parent() const 85 { 86 if (hops == 0) 87 { 88 DP_ASSERT(hops != 0); 89 return 0; 90 } 91 Address addr = *this; 92 addr.hops --; 93 return addr; 94 } 95 tail()96 unsigned tail() const 97 { 98 if (hops == 0) 99 { 100 DP_ASSERT(hops != 0); 101 return 0; 102 } 103 return hop[hops-1]; 104 } 105 append(unsigned port)106 void append(unsigned port) 107 { 108 if (hops >= maxHops) 109 { 110 DP_ASSERT(0); 111 return; 112 } 113 hop[hops++] = port; 114 } 115 prepend(unsigned port)116 void prepend(unsigned port) 117 { 118 if (hops >= maxHops) 119 { 120 DP_ASSERT(0); 121 return; 122 } 123 hops++; 124 for (unsigned i = hops - 1; i > 0; i--) 125 hop[i] = hop[i-1]; 126 hop[0] = port; 127 } 128 pop()129 void pop() 130 { 131 if (hops == 0) 132 { 133 DP_ASSERT(0); 134 return; 135 } 136 hops--; 137 } 138 139 // Just to keep clear copy 140 Address & operator = (const Address & other) 141 { 142 clear(); 143 for(unsigned i = 0; i < other.size(); i++) 144 { 145 append(other[i]); 146 } 147 148 return *this; 149 } 150 151 bool operator == (const Address & other) const 152 { 153 if (other.size() != size()) 154 return false; 155 156 for (unsigned i = 0; i < hops; i++) 157 if (other[i] != (*this)[i]) 158 return false; 159 160 return true; 161 } 162 163 // 164 // Sort by size first, then "alphabetically" (lexicographical see wikipedia) 165 // 166 bool operator > (const Address & other) const 167 { 168 if (size() > other.size()) 169 return true; 170 else if (size() < other.size()) 171 return false; 172 173 for (unsigned i = 0; i < hops; i++) 174 { 175 if ((*this)[i] > other[i]) 176 return true; 177 else if ((*this)[i] < other[i]) 178 return false; 179 } 180 181 return false; 182 } 183 184 // 185 // Sort by size first, then "alphabetically" (lexicographical see wikipedia) 186 // 187 bool operator < (const Address & other) const 188 { 189 if (size() < other.size()) 190 return true; 191 else if (size() > other.size()) 192 return false; 193 194 for (unsigned i = 0; i < hops; i++) 195 { 196 if ((*this)[i] < other[i]) 197 return true; 198 else if ((*this)[i] > other[i]) 199 return false; 200 } 201 202 return false; 203 } 204 205 bool operator >= (const Address & other) const 206 { 207 return !((*this) < other); 208 } 209 210 bool operator <= (const Address & other) const 211 { 212 return !((*this) > other); 213 } 214 215 bool operator != (const Address & other) const 216 { 217 return !((*this) == other); 218 } 219 size()220 unsigned size() const 221 { 222 return hops; 223 } 224 225 unsigned & operator [](unsigned index) 226 { 227 DP_ASSERT(index < hops); 228 return hop[index]; 229 } 230 231 const unsigned & operator [](unsigned index) const 232 { 233 DP_ASSERT(index < hops); 234 return hop[index]; 235 } 236 under(const Address & root)237 bool under(const Address & root) const 238 { 239 if (size() < root.size()) 240 return false; 241 242 for (unsigned i = 0; i < root.size(); i++) 243 if ((*this)[i] != root[i]) 244 return false; 245 246 return true; 247 } 248 249 typedef char StringBuffer[maxHops*3+1]; 250 char * toString(StringBuffer & buffer, bool removeLeadingZero = false) const 251 { 252 char * p = &buffer[0]; 253 int hopsWritten = 0; 254 for (unsigned i = 0; i < hops; i++) 255 { 256 if (i == 0 && hop[0] == 0 && removeLeadingZero) 257 continue; 258 if (hopsWritten > 0) 259 *p++ = '.'; 260 if (hop[i] >= 10) 261 *p++ = (char)(hop[i] / 10 +'0'); 262 *p++ = (char)(hop[i] % 10 + '0'); 263 hopsWritten++; 264 } 265 266 *p++= 0; 267 return (char *)&buffer[0]; 268 } 269 270 // Large enough to fit 4 hops into every NvU32 271 typedef NvU32 NvU32Buffer[(maxHops-1)/4+1 < 4 ? 4 : (maxHops-1)/4+1]; toNvU32Buffer(NvU32Buffer & buffer)272 NvU32 * toNvU32Buffer(NvU32Buffer & buffer) const 273 { 274 for (unsigned i = 0; i < hops; i++) 275 { 276 buffer[i/4] |= ((NvU8) hop[i]) << (i % 4) * 8; 277 } 278 279 return (NvU32 *)&buffer[0]; 280 } 281 282 private: 283 unsigned hop[maxHops]; 284 unsigned hops; 285 }; 286 } 287 288 #endif //INCLUDED_DP_ADDRESS_H 289