1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 9 using System; 10 using System.Runtime.InteropServices; 11 using Antmicro.Renode.Core.Extensions; 12 using Antmicro.Renode.Peripherals.Bus; 13 using NUnit.Framework; 14 using Moq; 15 16 namespace Antmicro.Renode.UnitTests 17 { 18 [TestFixture] 19 public class WriteExtensionsTest 20 { 21 [SetUp] SetUp()22 public void SetUp() 23 { 24 bytePeriMock = new Mock<IBytePeripheral>(); 25 wordPeriMock = new Mock<IWordPeripheral>(); 26 dwordPeriMock = new Mock<IDoubleWordPeripheral>(); 27 qwordPeriMock = new Mock<IQuadWordPeripheral>(); 28 } 29 30 [Test] ShouldWriteWordUsingByte()31 public void ShouldWriteWordUsingByte() 32 { 33 var bytePeripheral = bytePeriMock.Object; 34 bytePeripheral.WriteWordUsingByte(0, 0x3412); 35 bytePeripheral.WriteWordUsingByte(2, 0x7856); 36 bytePeriMock.Verify(x => x.WriteByte(0, 0x12), Times.Once()); 37 bytePeriMock.Verify(x => x.WriteByte(1, 0x34), Times.Once()); 38 bytePeriMock.Verify(x => x.WriteByte(2, 0x56), Times.Once()); 39 bytePeriMock.Verify(x => x.WriteByte(3, 0x78), Times.Once()); 40 } 41 42 [Test] ShouldWriteWordUsingByteBigEndian()43 public void ShouldWriteWordUsingByteBigEndian() 44 { 45 var bytePeripheral = bytePeriMock.Object; 46 bytePeripheral.WriteWordUsingByteBigEndian(0, 0x3412); 47 bytePeripheral.WriteWordUsingByteBigEndian(2, 0x7856); 48 bytePeriMock.Verify(x => x.WriteByte(0, 0x34), Times.Once()); 49 bytePeriMock.Verify(x => x.WriteByte(1, 0x12), Times.Once()); 50 bytePeriMock.Verify(x => x.WriteByte(2, 0x78), Times.Once()); 51 bytePeriMock.Verify(x => x.WriteByte(3, 0x56), Times.Once()); 52 } 53 54 [Test] ShouldWriteDoubleWordUsingByte()55 public void ShouldWriteDoubleWordUsingByte() 56 { 57 var bytePeripheral = bytePeriMock.Object; 58 bytePeripheral.WriteDoubleWordUsingByte(0, 0x78563412); 59 bytePeriMock.Verify(x => x.WriteByte(0, 0x12), Times.Once()); 60 bytePeriMock.Verify(x => x.WriteByte(1, 0x34), Times.Once()); 61 bytePeriMock.Verify(x => x.WriteByte(2, 0x56), Times.Once()); 62 bytePeriMock.Verify(x => x.WriteByte(3, 0x78), Times.Once()); 63 } 64 65 [Test] ShouldWriteDoubleWordUsingByteBigEndian()66 public void ShouldWriteDoubleWordUsingByteBigEndian() 67 { 68 var bytePeripheral = bytePeriMock.Object; 69 bytePeripheral.WriteDoubleWordUsingByteBigEndian(0, 0x78563412); 70 bytePeriMock.Verify(x => x.WriteByte(0, 0x78), Times.Once()); 71 bytePeriMock.Verify(x => x.WriteByte(1, 0x56), Times.Once()); 72 bytePeriMock.Verify(x => x.WriteByte(2, 0x34), Times.Once()); 73 bytePeriMock.Verify(x => x.WriteByte(3, 0x12), Times.Once()); 74 } 75 76 [Test] ShouldWriteQuadWordUsingByte()77 public void ShouldWriteQuadWordUsingByte() 78 { 79 var bytePeripheral = bytePeriMock.Object; 80 bytePeripheral.WriteQuadWordUsingByte(0, 0x7856341221436587); 81 bytePeriMock.Verify(x => x.WriteByte(0, 0x87), Times.Once()); 82 bytePeriMock.Verify(x => x.WriteByte(1, 0x65), Times.Once()); 83 bytePeriMock.Verify(x => x.WriteByte(2, 0x43), Times.Once()); 84 bytePeriMock.Verify(x => x.WriteByte(3, 0x21), Times.Once()); 85 bytePeriMock.Verify(x => x.WriteByte(4, 0x12), Times.Once()); 86 bytePeriMock.Verify(x => x.WriteByte(5, 0x34), Times.Once()); 87 bytePeriMock.Verify(x => x.WriteByte(6, 0x56), Times.Once()); 88 bytePeriMock.Verify(x => x.WriteByte(7, 0x78), Times.Once()); 89 } 90 91 [Test] ShouldWriteQuadWordUsingByteBigEndian()92 public void ShouldWriteQuadWordUsingByteBigEndian() 93 { 94 var bytePeripheral = bytePeriMock.Object; 95 bytePeripheral.WriteQuadWordUsingByteBigEndian(0, 0x7856341221436587); 96 bytePeriMock.Verify(x => x.WriteByte(0, 0x78), Times.Once()); 97 bytePeriMock.Verify(x => x.WriteByte(1, 0x56), Times.Once()); 98 bytePeriMock.Verify(x => x.WriteByte(2, 0x34), Times.Once()); 99 bytePeriMock.Verify(x => x.WriteByte(3, 0x12), Times.Once()); 100 bytePeriMock.Verify(x => x.WriteByte(4, 0x21), Times.Once()); 101 bytePeriMock.Verify(x => x.WriteByte(5, 0x43), Times.Once()); 102 bytePeriMock.Verify(x => x.WriteByte(6, 0x65), Times.Once()); 103 bytePeriMock.Verify(x => x.WriteByte(7, 0x87), Times.Once()); 104 } 105 106 [Test] ShouldWriteByteUsingWord()107 public void ShouldWriteByteUsingWord() 108 { 109 var wordPeripheral = wordPeriMock.Object; 110 wordPeripheral.WriteByteUsingWord(0, 0x12); 111 wordPeriMock.Verify(x => x.WriteWord(0, 0x0012)); 112 wordPeriMock.Setup(x => x.ReadWord(0)).Returns(0x0012); 113 wordPeripheral.WriteByteUsingWord(1, 0x34); 114 wordPeriMock.Verify(x => x.WriteWord(0, 0x3412)); 115 wordPeripheral.WriteByteUsingWord(2, 0x56); 116 wordPeriMock.Verify(x => x.WriteWord(2, 0x0056)); 117 wordPeriMock.Setup(x => x.ReadWord(2)).Returns(0x0056); 118 wordPeripheral.WriteByteUsingWord(3, 0x78); 119 wordPeriMock.Verify(x => x.WriteWord(2, 0x7856)); 120 } 121 122 [Test] ShouldWriteByteUsingWordBigEndian()123 public void ShouldWriteByteUsingWordBigEndian() 124 { 125 var wordPeripheral = wordPeriMock.Object; 126 wordPeripheral.WriteByteUsingWordBigEndian(0, 0x12); 127 wordPeriMock.Verify(x => x.WriteWord(0, 0x1200)); 128 wordPeriMock.Setup(x => x.ReadWord(0)).Returns(0x1200); 129 wordPeripheral.WriteByteUsingWordBigEndian(1, 0x34); 130 wordPeriMock.Verify(x => x.WriteWord(0, 0x1234)); 131 wordPeripheral.WriteByteUsingWordBigEndian(2, 0x56); 132 wordPeriMock.Verify(x => x.WriteWord(2, 0x5600)); 133 wordPeriMock.Setup(x => x.ReadWord(2)).Returns(0x5600); 134 wordPeripheral.WriteByteUsingWordBigEndian(3, 0x78); 135 wordPeriMock.Verify(x => x.WriteWord(2, 0x5678)); 136 } 137 138 [Test] ShouldWriteDoubleWordUsingWord()139 public void ShouldWriteDoubleWordUsingWord() 140 { 141 var wordPeripheral = wordPeriMock.Object; 142 wordPeripheral.WriteDoubleWordUsingWord(0, 0x78563412); 143 wordPeriMock.Verify(x => x.WriteWord(0, 0x3412)); 144 wordPeriMock.Verify(x => x.WriteWord(2, 0x7856)); 145 } 146 147 [Test] ShouldWriteDoubleWordUsingWordBigEndian()148 public void ShouldWriteDoubleWordUsingWordBigEndian() 149 { 150 var wordPeripheral = wordPeriMock.Object; 151 wordPeripheral.WriteDoubleWordUsingWordBigEndian(0, 0x78563412); 152 wordPeriMock.Verify(x => x.WriteWord(0, 0x5678)); 153 wordPeriMock.Verify(x => x.WriteWord(2, 0x1234)); 154 } 155 156 [Test] ShouldWriteQuadWordUsingWord()157 public void ShouldWriteQuadWordUsingWord() 158 { 159 var wordPeripheral = wordPeriMock.Object; 160 wordPeripheral.WriteQuadWordUsingWord(0, 0x7856341221436587); 161 wordPeriMock.Verify(x => x.WriteWord(0, 0x6587)); 162 wordPeriMock.Verify(x => x.WriteWord(2, 0x2143)); 163 wordPeriMock.Verify(x => x.WriteWord(4, 0x3412)); 164 wordPeriMock.Verify(x => x.WriteWord(6, 0x7856)); 165 } 166 167 [Test] ShouldWriteQuadWordUsingWordBigEndian()168 public void ShouldWriteQuadWordUsingWordBigEndian() 169 { 170 var wordPeripheral = wordPeriMock.Object; 171 wordPeripheral.WriteQuadWordUsingWordBigEndian(0, 0x7856341221436587); 172 wordPeriMock.Verify(x => x.WriteWord(0, 0x5678)); 173 wordPeriMock.Verify(x => x.WriteWord(2, 0x1234)); 174 wordPeriMock.Verify(x => x.WriteWord(4, 0x4321)); 175 wordPeriMock.Verify(x => x.WriteWord(6, 0x8765)); 176 } 177 178 [Test] ShouldWriteByteUsingDoubleWord()179 public void ShouldWriteByteUsingDoubleWord() 180 { 181 var dwordPeripheral = dwordPeriMock.Object; 182 dwordPeripheral.WriteByteUsingDoubleWord(0, 0x12); 183 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12)); 184 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x12); 185 dwordPeripheral.WriteByteUsingDoubleWord(1, 0x34); 186 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x3412)); 187 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x3412); 188 dwordPeripheral.WriteByteUsingDoubleWord(2, 0x56); 189 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x563412)); 190 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x563412); 191 dwordPeripheral.WriteByteUsingDoubleWord(3, 0x78); 192 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x78563412)); 193 } 194 195 [Test] ShouldWriteByteUsingDoubleWordBigEndian()196 public void ShouldWriteByteUsingDoubleWordBigEndian() 197 { 198 var dwordPeripheral = dwordPeriMock.Object; 199 dwordPeripheral.WriteByteUsingDoubleWordBigEndian(0, 0x12); 200 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12000000)); 201 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x12000000); 202 dwordPeripheral.WriteByteUsingDoubleWordBigEndian(1, 0x34); 203 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12340000)); 204 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x12340000); 205 dwordPeripheral.WriteByteUsingDoubleWordBigEndian(2, 0x56); 206 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12345600)); 207 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x12345600); 208 dwordPeripheral.WriteByteUsingDoubleWordBigEndian(3, 0x78); 209 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12345678)); 210 } 211 212 [Test] ShouldWriteWordUsingDoubleWord()213 public void ShouldWriteWordUsingDoubleWord() 214 { 215 var dwordPeripheral = dwordPeriMock.Object; 216 dwordPeripheral.WriteWordUsingDoubleWord(0, 0x3412); 217 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x3412)); 218 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x3412); 219 dwordPeripheral.WriteWordUsingDoubleWord(2, 0x7856); 220 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x78563412)); 221 } 222 223 [Test] ShouldWriteWordUsingDoubleWordBigEndian()224 public void ShouldWriteWordUsingDoubleWordBigEndian() 225 { 226 var dwordPeripheral = dwordPeriMock.Object; 227 dwordPeripheral.WriteWordUsingDoubleWordBigEndian(0, 0x3412); 228 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12340000)); 229 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x12340000); 230 dwordPeripheral.WriteWordUsingDoubleWordBigEndian(2, 0x7856); 231 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12345678)); 232 } 233 234 [Test] ShouldWriteQuadWordUsingDoubleWord()235 public void ShouldWriteQuadWordUsingDoubleWord() 236 { 237 var dwordPeripheral = dwordPeriMock.Object; 238 dwordPeripheral.WriteQuadWordUsingDoubleWord(0, 0x7856341221436587); 239 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x21436587)); 240 dwordPeriMock.Verify(x => x.WriteDoubleWord(4, 0x78563412)); 241 } 242 243 [Test] ShouldWriteQuadWordUsingDoubleWordBigEndian()244 public void ShouldWriteQuadWordUsingDoubleWordBigEndian() 245 { 246 var dwordPeripheral = dwordPeriMock.Object; 247 dwordPeripheral.WriteQuadWordUsingDoubleWordBigEndian(0, 0x7856341221436587); 248 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x12345678)); 249 dwordPeriMock.Verify(x => x.WriteDoubleWord(4, 0x87654321)); 250 } 251 252 [Test] ShouldWriteWordUsingDoubleWordNotAligned1()253 public void ShouldWriteWordUsingDoubleWordNotAligned1() 254 { 255 var dwordPeripheral = dwordPeriMock.Object; 256 PrepareOldData(); 257 dwordPeripheral.WriteWordUsingDoubleWord(1, 0xDFEF); 258 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x78DFEF12), Times.Once()); 259 } 260 261 [Test] ShouldWriteWordUsingDoubleWordNotAligned1BigEndian()262 public void ShouldWriteWordUsingDoubleWordNotAligned1BigEndian() 263 { 264 var dwordPeripheral = dwordPeriMock.Object; 265 PrepareOldData(); 266 dwordPeripheral.WriteWordUsingDoubleWordBigEndian(1, 0xDFEF); 267 dwordPeriMock.Verify(x => x.WriteDoubleWord(0, 0x78EFDF12), Times.Once()); 268 } 269 270 [Test] ShouldWriteByteUsingQuadWord()271 public void ShouldWriteByteUsingQuadWord() 272 { 273 byte[] bytes = {0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21}; 274 var qwordPeripheral = qwordPeriMock.Object; 275 ulong act = 0; 276 for(var i = 0; i < 7; i++) 277 { 278 qwordPeripheral.WriteByteUsingQuadWord(i, bytes[i]); 279 act |= (ulong)bytes[i] << (8 * i); 280 qwordPeriMock.Verify(x => x.WriteQuadWord(0, act)); 281 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(act); 282 } 283 } 284 285 [Test] ShouldWriteByteUsingQuadWordBigEndian()286 public void ShouldWriteByteUsingQuadWordBigEndian() 287 { 288 byte[] bytes = {0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21}; 289 var qwordPeripheral = qwordPeriMock.Object; 290 ulong act = 0; 291 for(var i = 0; i < 7; i++) 292 { 293 qwordPeripheral.WriteByteUsingQuadWordBigEndian(i, bytes[i]); 294 act |= (ulong)bytes[i] << (7 - i) * 8; 295 qwordPeriMock.Verify(x => x.WriteQuadWord(0, act)); 296 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(act); 297 } 298 } 299 300 [Test] ShouldWriteWordUsingQuadWord()301 public void ShouldWriteWordUsingQuadWord() 302 { 303 var qwordPeripheral = qwordPeriMock.Object; 304 qwordPeripheral.WriteWordUsingQuadWord(0, 0x3412); 305 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x3412)); 306 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x3412); 307 qwordPeripheral.WriteWordUsingQuadWord(2, 0x7856); 308 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x78563412)); 309 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x78563412); 310 qwordPeripheral.WriteWordUsingQuadWord(4, 0x5678); 311 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x567878563412)); 312 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x567878563412); 313 qwordPeripheral.WriteWordUsingQuadWord(6, 0x1234); 314 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567878563412)); 315 } 316 317 [Test] ShouldWriteWordUsingQuadWordBigEndian()318 public void ShouldWriteWordUsingQuadWordBigEndian() 319 { 320 var qwordPeripheral = qwordPeriMock.Object; 321 qwordPeripheral.WriteWordUsingQuadWordBigEndian(0, 0x3412); 322 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234000000000000)); 323 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x1234000000000000); 324 qwordPeripheral.WriteWordUsingQuadWordBigEndian(2, 0x7856); 325 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567800000000)); 326 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x1234567800000000); 327 qwordPeripheral.WriteWordUsingQuadWordBigEndian(4, 0x6587); 328 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567887650000)); 329 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x1234567887650000); 330 qwordPeripheral.WriteWordUsingQuadWordBigEndian(6, 0x2143); 331 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567887654321)); 332 } 333 334 [Test] ShouldWriteDoubleWordUsingQuadWord()335 public void ShouldWriteDoubleWordUsingQuadWord() 336 { 337 var qwordPeripheral = qwordPeriMock.Object; 338 qwordPeripheral.WriteDoubleWordUsingQuadWord(0, 0x78563412); 339 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x78563412)); 340 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x78563412); 341 qwordPeripheral.WriteDoubleWordUsingQuadWord(4, 0x12345678); 342 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567878563412)); 343 } 344 345 [Test] ShouldWriteDoubleWordUsingQuadWordBigEndian()346 public void ShouldWriteDoubleWordUsingQuadWordBigEndian() 347 { 348 var qwordPeripheral = qwordPeriMock.Object; 349 qwordPeripheral.WriteDoubleWordUsingQuadWordBigEndian(0, 0x78563412); 350 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567800000000)); 351 qwordPeriMock.Setup(x => x.ReadQuadWord(0)).Returns(0x1234567800000000); 352 qwordPeripheral.WriteDoubleWordUsingQuadWordBigEndian(4, 0x21436587); 353 qwordPeriMock.Verify(x => x.WriteQuadWord(0, 0x1234567887654321)); 354 } 355 PrepareOldData()356 private void PrepareOldData() 357 { 358 dwordPeriMock.Setup(x => x.ReadDoubleWord(0)).Returns(0x78563412); 359 dwordPeriMock.Setup(x => x.ReadDoubleWord(4)).Returns(0xCCBBAA90); 360 wordPeriMock.Setup(x => x.ReadWord(0)).Returns(0x3412); 361 wordPeriMock.Setup(x => x.ReadWord(2)).Returns(0x7856); 362 wordPeriMock.Setup(x => x.ReadWord(4)).Returns(0xAA90); 363 wordPeriMock.Setup(x => x.ReadWord(6)).Returns(0xCCBB); 364 } 365 366 private Mock<IBytePeripheral> bytePeriMock; 367 private Mock<IWordPeripheral> wordPeriMock; 368 private Mock<IDoubleWordPeripheral> dwordPeriMock; 369 private Mock<IQuadWordPeripheral> qwordPeriMock; 370 } 371 } 372