1 // 2 // Copyright (c) 2010-2023 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using Antmicro.Renode.Utilities.Packets; 8 9 namespace Antmicro.Renode.Peripherals.Storage 10 { 11 public enum UPIUTransactionCodeInitiatorToTarget : byte 12 { 13 NopOut = 0b000000, 14 Command = 0b000001, 15 DataOut = 0b000010, 16 TaskManagementRequest = 0b000100, 17 QueryRequest = 0b010110, 18 } 19 20 public enum UPIUTransactionCodeTargetToInitiator : byte 21 { 22 NopIn = 0b100000, 23 Response = 0b100001, 24 DataIn = 0b100010, 25 TaskManagementResponse = 0b100100, 26 ReadyToTransfer = 0b110001, 27 QueryResponse = 0b110110, 28 RejectUPIU = 0b111111, 29 } 30 31 public enum TaskAttribute 32 { 33 Simple = 0b00, 34 Ordered = 0b01, 35 HeadOfQueue = 0b10, 36 ACA = 0b11 37 } 38 39 public enum QueryFunction : byte 40 { 41 StandardReadRequest = 0x01, 42 StandardWriteRequest = 0x81, 43 } 44 45 public enum QueryFunctionOpcode : byte 46 { 47 Nop = 0x00, 48 ReadDescriptor = 0x01, 49 WriteDescriptor = 0x02, 50 ReadAttribute = 0x03, 51 WriteAttribute = 0x04, 52 ReadFlag = 0x05, 53 SetFlag = 0x06, 54 ClearFlag = 0x07, 55 ToggleFlag = 0x08 56 } 57 58 public enum QueryResponseCode : byte 59 { 60 Success = 0x0, 61 ParameterNotReadable = 0xf6, 62 ParameterNotWriteable = 0xf7, 63 ParameterAlreadyWritten = 0xf8, 64 InvalidLength = 0xf9, 65 InvalidValue = 0xfa, 66 InvalidSelector = 0xfb, 67 InvalidIndex = 0xfc, 68 InvalidIdn = 0xfd, 69 InvalidOpcode = 0xfe, 70 GeneralFailure = 0xff 71 } 72 73 #pragma warning disable 649, 169 74 public struct BasicUPIUHeader 75 { 76 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 77 public byte TransactionCode; 78 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 79 public bool DataSegmentsCRC; 80 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 81 public bool HeaderSegmentsCRC; 82 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 83 public byte Flags; 84 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 85 public byte LogicalUnitNumber; 86 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 87 public byte TaskTag; 88 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 89 public byte InitiatorID; 90 [PacketField, Offset(doubleWords: 1, bits: 4), Width(4)] 91 public byte CommandSetType; 92 [PacketField, Offset(doubleWords: 1, bits: 8), Width(8)] 93 public byte Function; 94 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 95 public byte Response; 96 [PacketField, Offset(doubleWords: 1, bits: 24), Width(8)] 97 public byte Status; 98 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 99 public byte TotalEHSLength; 100 [PacketField, Offset(doubleWords: 2, bits: 8), Width(8)] 101 public byte DeviceInformation; 102 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 103 public ushort DataSegmentLength; 104 } 105 106 public struct CommandUPIU 107 { 108 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 109 public byte TransactionCode; 110 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 111 public bool DataSegmentsCRC; 112 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 113 public bool HeaderSegmentsCRC; 114 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 115 public byte Flags; 116 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 117 public byte LogicalUnitNumber; 118 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 119 public byte TaskTag; 120 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 121 public byte InitiatorID; 122 [PacketField, Offset(doubleWords: 1, bits: 4), Width(4)] 123 public byte CommandSetType; 124 [PacketField, Offset(doubleWords: 1, bits: 24), Width(4)] 125 public byte NexusInitiatorID; 126 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 127 public byte TotalEHSLength; 128 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 129 public ushort DataSegmentLength; 130 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 131 public uint ExpectedDataTransferLength; 132 [PacketField, Width(16)] 133 public byte[] CommandDescriptorBlock; 134 } 135 136 public struct CommandUPIUFlags 137 { 138 [PacketField, Offset(bytes: 0, bits: 0), Width(2)] 139 public TaskAttribute TaskAttribute; 140 [PacketField, Offset(bytes: 0, bits: 2), Width(1)] 141 public bool CommandPriority; 142 [PacketField, Offset(bytes: 0, bits: 5), Width(1)] 143 public bool Write; 144 [PacketField, Offset(bytes: 0, bits: 6), Width(1)] 145 public bool Read; 146 } 147 public struct DataInUPIU 148 { 149 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 150 public byte TransactionCode; 151 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 152 public bool DataSegmentsCRC; 153 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 154 public bool HeaderSegmentsCRC; 155 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 156 public byte Flags; 157 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 158 public byte LogicalUnitNumber; 159 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 160 public byte TaskTag; 161 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 162 public byte InitiatorID; 163 [PacketField, Offset(doubleWords: 1, bits: 8), Width(4)] 164 public byte NexusInitiatorID; 165 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 166 public byte TotalEHSLength; 167 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 168 public ushort DataSegmentLength; 169 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 170 public uint DataBufferOffset; 171 [PacketField, Offset(doubleWords: 4, bits: 0), Width(32)] 172 public uint DataTransferCount; 173 [PacketField, Offset(doubleWords: 5, bits: 4), Width(4)] 174 public byte HintControl; 175 [PacketField, Offset(doubleWords: 5, bits: 8), Width(4)] 176 public byte HintNexusInitiatorID; 177 [PacketField, Offset(doubleWords: 5, bits: 12), Width(4)] 178 public byte HintInitiatorID; 179 [PacketField, Offset(doubleWords: 5, bits: 16), Width(8)] 180 public byte HintLogicalUnitNumber; 181 [PacketField, Offset(doubleWords: 5, bits: 24), Width(8)] 182 public byte HintTaskTag; 183 [PacketField, Offset(doubleWords: 6, bits: 0), Width(32)] 184 public uint HintDataBufferOffset; 185 [PacketField, Offset(doubleWords: 7, bits: 0), Width(32)] 186 public uint HintDataCount; 187 } 188 189 public struct DataOutUPIU 190 { 191 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 192 public byte TransactionCode; 193 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 194 public bool DataSegmentsCRC; 195 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 196 public bool HeaderSegmentsCRC; 197 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 198 public byte Flags; 199 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 200 public byte LogicalUnitNumber; 201 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 202 public byte TaskTag; 203 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 204 public byte InitiatorID; 205 [PacketField, Offset(doubleWords: 1, bits: 24), Width(4)] 206 public byte NexusInitiatorID; 207 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 208 public byte TotalEHSLength; 209 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 210 public ushort DataSegmentLength; 211 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 212 public uint DataBufferOffset; 213 [PacketField, Offset(doubleWords: 4, bits: 0), Width(32)] 214 public uint DataTransferCount; 215 } 216 217 public struct NopInUPIU 218 { 219 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 220 public byte TransactionCode; 221 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 222 public bool DataSegmentsCRC; 223 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 224 public bool HeaderSegmentsCRC; 225 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 226 public byte Flags; 227 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 228 public byte TaskTag; 229 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 230 public byte Response; 231 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 232 public byte TotalEHSLength; 233 [PacketField, Offset(doubleWords: 2, bits: 8), Width(8)] 234 public byte DeviceInformation; 235 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 236 public ushort DataSegmentLength; 237 } 238 239 public struct NopOutUPIU 240 { 241 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 242 public byte TransactionCode; 243 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 244 public bool DataSegmentsCRC; 245 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 246 public bool HeaderSegmentsCRC; 247 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 248 public byte Flags; 249 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 250 public byte TaskTag; 251 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 252 public byte TotalEHSLength; 253 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 254 public ushort DataSegmentLength; 255 } 256 257 public struct QueryRequestUPIU 258 { 259 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 260 public byte TransactionCode; 261 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 262 public bool DataSegmentsCRC; 263 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 264 public bool HeaderSegmentsCRC; 265 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 266 public byte Flags; 267 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 268 public byte TaskTag; 269 [PacketField, Offset(doubleWords: 1, bits: 8), Width(8)] 270 public QueryFunction QueryFunction; 271 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 272 public byte TotalEHSLength; 273 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 274 public ushort DataSegmentLength; 275 [PacketField, Width(16)] 276 public byte[] TransactionSpecificFields; 277 } 278 279 public struct QueryResponseUPIU 280 { 281 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 282 public byte TransactionCode; 283 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 284 public bool DataSegmentsCRC; 285 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 286 public bool HeaderSegmentsCRC; 287 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 288 public byte Flags; 289 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 290 public byte TaskTag; 291 [PacketField, Offset(doubleWords: 1, bits: 8), Width(8)] 292 public QueryFunction QueryFunction; 293 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 294 public QueryResponseCode QueryResponse; 295 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 296 public byte TotalEHSLength; 297 [PacketField, Offset(doubleWords: 2, bits: 8), Width(8)] 298 public byte DeviceInformation; 299 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 300 public ushort DataSegmentLength; 301 [PacketField, Width(16)] 302 public byte[] TransactionSpecficFields; 303 } 304 305 public struct ReadyToTransferUPIU 306 { 307 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 308 public byte TransactionCode; 309 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 310 public bool DataSegmentsCRC; 311 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 312 public bool HeaderSegmentsCRC; 313 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 314 public byte Flags; 315 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 316 public byte LogicalUnitNumber; 317 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 318 public byte TaskTag; 319 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 320 public byte InitiatorID; 321 [PacketField, Offset(doubleWords: 1, bits: 8), Width(4)] 322 public byte NexusInitiatorID; 323 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 324 public byte TotalEHSLength; 325 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 326 public ushort DataSegmentLength; 327 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 328 public uint DataBufferOffset; 329 [PacketField, Offset(doubleWords: 4, bits: 0), Width(32)] 330 public uint DataTransferCount; 331 [PacketField, Offset(doubleWords: 5, bits: 4), Width(4)] 332 public byte HintControl; 333 [PacketField, Offset(doubleWords: 5, bits: 8), Width(4)] 334 public byte HintNexusInitiatorID; 335 [PacketField, Offset(doubleWords: 5, bits: 12), Width(4)] 336 public byte HintInitiatorID; 337 [PacketField, Offset(doubleWords: 5, bits: 16), Width(8)] 338 public byte HintLogicalUnitNumber; 339 [PacketField, Offset(doubleWords: 5, bits: 24), Width(8)] 340 public byte HintTaskTag; 341 [PacketField, Offset(doubleWords: 6, bits: 0), Width(32)] 342 public uint HintDataBufferOffset; 343 [PacketField, Offset(doubleWords: 7, bits: 0), Width(32)] 344 public uint HintDataCount; 345 } 346 347 public struct RejectUPIU 348 { 349 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 350 public byte TransactionCode; 351 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 352 public bool DataSegmentsCRC; 353 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 354 public bool HeaderSegmentsCRC; 355 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 356 public byte Flags; 357 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 358 public byte LogicalUnitNumber; 359 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 360 public byte TaskTag; 361 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 362 public byte InitiatorID; 363 [PacketField, Offset(doubleWords: 1, bits: 8), Width(4)] 364 public byte NexusInitiatorID; 365 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 366 public byte Response; 367 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 368 public byte TotalEHSLength; 369 [PacketField, Offset(doubleWords: 2, bits: 8), Width(8)] 370 public byte DeviceInformation; 371 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 372 public ushort DataSegmentLength; 373 [PacketField, Offset(doubleWords: 3, bits: 0), Width(8)] 374 public byte BasicHeaderStatus; 375 [PacketField, Offset(doubleWords: 3, bits: 16), Width(8)] 376 public byte E2EStatus; 377 } 378 379 public struct ResponseUPIU 380 { 381 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 382 public byte TransactionCode; 383 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 384 public bool DataSegmentsCRC; 385 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 386 public bool HeaderSegmentsCRC; 387 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 388 public byte Flags; 389 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 390 public byte LogicalUnitNumber; 391 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 392 public byte TaskTag; 393 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 394 public byte InitiatorID; 395 [PacketField, Offset(doubleWords: 1, bits: 4), Width(4)] 396 public byte CommandSetType; 397 [PacketField, Offset(doubleWords: 1, bits: 8), Width(4)] 398 public byte NexusInitiatorID; 399 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 400 public byte Response; 401 [PacketField, Offset(doubleWords: 1, bits: 24), Width(8)] 402 public byte Status; 403 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 404 public byte TotalEHSLength; 405 [PacketField, Offset(doubleWords: 2, bits: 8), Width(8)] 406 public byte DeviceInformation; 407 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 408 public ushort DataSegmentLength; 409 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 410 public uint ResidualTransferCount; 411 } 412 413 public struct ResponseUPIUFlags 414 { 415 [PacketField, Offset(bytes: 0, bits: 4), Width(1)] 416 public bool DataOutMismatch; 417 [PacketField, Offset(bytes: 0, bits: 5), Width(1)] 418 public bool DataUnderflow; 419 [PacketField, Offset(bytes: 0, bits: 6), Width(1)] 420 public bool DataOverflow; 421 } 422 423 public struct TaskManagementRequestUPIU 424 { 425 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 426 public byte TransactionCode; 427 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 428 public bool DataSegmentsCRC; 429 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 430 public bool HeaderSegmentsCRC; 431 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 432 public byte Flags; 433 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 434 public byte LogicalUnitNumber; 435 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 436 public byte TaskTag; 437 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 438 public byte InitiatorID; 439 [PacketField, Offset(doubleWords: 1, bits: 8), Width(8)] 440 public byte TaskManagementFunction; 441 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 442 public byte Response; 443 [PacketField, Offset(doubleWords: 1, bits: 24), Width(4)] 444 public byte NexusInitiatorID; 445 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 446 public byte TotalEHSLength; 447 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 448 public ushort DataSegmentLength; 449 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 450 public uint InputParameter1; 451 [PacketField, Offset(doubleWords: 4, bits: 0), Width(32)] 452 public uint InputParameter2; 453 [PacketField, Offset(doubleWords: 5, bits: 0), Width(32)] 454 public uint InputParameter3; 455 } 456 457 public struct TaskManagementResponseUPIU 458 { 459 [PacketField, Offset(doubleWords: 0, bits: 0), Width(6)] 460 public byte TransactionCode; 461 [PacketField, Offset(doubleWords: 0, bits: 6), Width(1)] 462 public bool DataSegmentsCRC; 463 [PacketField, Offset(doubleWords: 0, bits: 7), Width(1)] 464 public bool HeaderSegmentsCRC; 465 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 466 public byte Flags; 467 [PacketField, Offset(doubleWords: 0, bits: 16), Width(8)] 468 public byte LogicalUnitNumber; 469 [PacketField, Offset(doubleWords: 0, bits: 24), Width(8)] 470 public byte TaskTag; 471 [PacketField, Offset(doubleWords: 1, bits: 0), Width(4)] 472 public byte InitiatorID; 473 [PacketField, Offset(doubleWords: 1, bits: 8), Width(4)] 474 public byte NexusInitiatorID; 475 [PacketField, Offset(doubleWords: 1, bits: 16), Width(8)] 476 public byte Response; 477 [PacketField, Offset(doubleWords: 2, bits: 0), Width(8)] 478 public byte TotalEHSLength; 479 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] 480 public ushort DataSegmentLength; 481 [PacketField, Offset(doubleWords: 3, bits: 0), Width(32)] 482 public uint OutputParameter1; 483 [PacketField, Offset(doubleWords: 4, bits: 0), Width(32)] 484 public uint OutputParameter2; 485 } 486 487 public struct EHSEntry 488 { 489 [PacketField, Offset(doubleWords: 0, bits: 0), Width(8)] 490 public byte Length; 491 [PacketField, Offset(doubleWords: 0, bits: 8), Width(8)] 492 public byte EHSType; 493 [PacketField, Offset(doubleWords: 0, bits: 16), Width(16)] 494 public ushort EHSSubType; 495 // EHS data 496 } 497 #pragma warning restore 649, 169 498 }