gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ufs_device.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2015 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
70 #include "dev/arm/ufs_device.hh"
71 
76  uint32_t lun_id, const Callback &transfer_cb,
77  const Callback &read_cb):
78  SimObject(p),
79  flashDisk(p.image[lun_id]),
80  flashDevice(p.internalflash[lun_id]),
81  blkSize(p.img_blk_size),
82  lunAvail(p.image.size()),
83  diskSize(flashDisk->size()),
84  capacityLower((diskSize - 1) & 0xffffffff),
85  capacityUpper((diskSize - SectorSize) >> 32),
86  lunID(lun_id),
87  transferCompleted(false),
88  readCompleted(false),
89  totalRead(0),
90  totalWrite(0),
91  amountOfWriteTransfers(0),
92  amountOfReadTransfers(0)
93 {
99  signalDone = transfer_cb;
100  memReadCallback = [this]() { readCallback(); };
101  deviceReadCallback = read_cb;
102  memWriteCallback = [this]() { SSDWriteDone(); };
103 
108  uint32_t temp_id = ((lun_id | 0x30) << 24) | 0x3A4449;
109  lunInfo.dWord0 = 0x02060000; //data
110  lunInfo.dWord1 = 0x0200001F;
111  lunInfo.vendor0 = 0x484D5241; //ARMH (HMRA)
112  lunInfo.vendor1 = 0x424D4143; //CAMB (BMAC)
113  lunInfo.product0 = 0x356D6567; //gem5 (5meg)
114  lunInfo.product1 = 0x4D534655; //UFSM (MSFU)
115  lunInfo.product2 = 0x4C45444F; //ODEL (LEDO)
116  lunInfo.product3 = temp_id; // ID:"lun_id" ("lun_id":DI)
117  lunInfo.productRevision = 0x01000000; //0x01
118 
119  DPRINTF(UFSHostDevice, "Logic unit %d assumes that %d logic units are"
120  " present in the system\n", lunID, lunAvail);
121  DPRINTF(UFSHostDevice,"The disksize of lun: %d should be %d blocks\n",
122  lunID, diskSize);
124 }
125 
126 
132 const unsigned int UFSHostDevice::UFSSCSIDevice::controlPage[3] =
133  {0x01400A0A, 0x00000000,
134  0x0000FFFF};
135 const unsigned int UFSHostDevice::UFSSCSIDevice::recoveryPage[3] =
136  {0x03800A01, 0x00000000,
137  0xFFFF0003};
138 const unsigned int UFSHostDevice::UFSSCSIDevice::cachingPage[5] =
139  {0x00011208, 0x00000000,
140  0x00000000, 0x00000020,
141  0x00000000};
142 
144 
158 {
159  struct SCSIReply scsi_out;
160  scsi_out.reset();
161 
166  scsi_out.message.header.dWord0 = UPIUHeaderDataIndWord0 |
167  lunID << 16;
168  scsi_out.message.header.dWord1 = UPIUHeaderDataIndWord1;
169  scsi_out.message.header.dWord2 = UPIUHeaderDataIndWord2;
170  statusCheck(SCSIGood, scsi_out.senseCode);
171  scsi_out.senseSize = scsi_out.senseCode[0];
172  scsi_out.LUN = lunID;
173  scsi_out.status = SCSIGood;
174 
175  DPRINTF(UFSHostDevice, "SCSI command:%2x\n", SCSI_msg[4]);
178  switch (SCSI_msg[4] & 0xFF) {
179 
180  case SCSIInquiry: {
184  scsi_out.msgSize = 36;
185  scsi_out.message.dataMsg.resize(9);
186 
187  for (uint8_t count = 0; count < 9; count++)
188  scsi_out.message.dataMsg[count] =
189  (reinterpret_cast<uint32_t*> (&lunInfo))[count];
190  } break;
191 
192  case SCSIRead6: {
196  scsi_out.expectMore = 0x02;
197  scsi_out.msgSize = 0;
198 
199  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
200 
205  uint32_t tmp = *reinterpret_cast<uint32_t*>(tempptr);
206  uint64_t read_offset = betoh(tmp) & 0x1FFFFF;
207 
208  uint32_t read_size = tempptr[4];
209 
210 
211  scsi_out.msgSize = read_size * blkSize;
212  scsi_out.offset = read_offset * blkSize;
213 
214  if ((read_offset + read_size) > diskSize)
215  scsi_out.status = SCSIIllegalRequest;
216 
217  DPRINTF(UFSHostDevice, "Read6 offset: 0x%8x, for %d blocks\n",
218  read_offset, read_size);
219 
223  statusCheck(scsi_out.status, scsi_out.senseCode);
224  scsi_out.senseSize = scsi_out.senseCode[0];
225  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
226  SCSICheckCondition;
227 
228  } break;
229 
230  case SCSIRead10: {
231  scsi_out.expectMore = 0x02;
232  scsi_out.msgSize = 0;
233 
234  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
235 
237  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
238  uint64_t read_offset = betoh(tmp);
239 
240  uint16_t tmpsize = *reinterpret_cast<uint16_t*>(&tempptr[7]);
241  uint32_t read_size = betoh(tmpsize);
242 
243  scsi_out.msgSize = read_size * blkSize;
244  scsi_out.offset = read_offset * blkSize;
245 
246  if ((read_offset + read_size) > diskSize)
247  scsi_out.status = SCSIIllegalRequest;
248 
249  DPRINTF(UFSHostDevice, "Read10 offset: 0x%8x, for %d blocks\n",
250  read_offset, read_size);
251 
255  statusCheck(scsi_out.status, scsi_out.senseCode);
256  scsi_out.senseSize = scsi_out.senseCode[0];
257  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
258  SCSICheckCondition;
259 
260  } break;
261 
262  case SCSIRead16: {
263  scsi_out.expectMore = 0x02;
264  scsi_out.msgSize = 0;
265 
266  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
267 
269  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
270  uint64_t read_offset = betoh(tmp);
271 
272  tmp = *reinterpret_cast<uint32_t*>(&tempptr[6]);
273  read_offset = (read_offset << 32) | betoh(tmp);
274 
275  tmp = *reinterpret_cast<uint32_t*>(&tempptr[10]);
276  uint32_t read_size = betoh(tmp);
277 
278  scsi_out.msgSize = read_size * blkSize;
279  scsi_out.offset = read_offset * blkSize;
280 
281  if ((read_offset + read_size) > diskSize)
282  scsi_out.status = SCSIIllegalRequest;
283 
284  DPRINTF(UFSHostDevice, "Read16 offset: 0x%8x, for %d blocks\n",
285  read_offset, read_size);
286 
290  statusCheck(scsi_out.status, scsi_out.senseCode);
291  scsi_out.senseSize = scsi_out.senseCode[0];
292  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
293  SCSICheckCondition;
294 
295  } break;
296 
297  case SCSIReadCapacity10: {
301  scsi_out.msgSize = 8;
302  scsi_out.message.dataMsg.resize(2);
303  scsi_out.message.dataMsg[0] =
304  betoh(capacityLower);//last block
305  scsi_out.message.dataMsg[1] = betoh(blkSize);//blocksize
306 
307  } break;
308  case SCSIReadCapacity16: {
309  scsi_out.msgSize = 32;
310  scsi_out.message.dataMsg.resize(8);
311  scsi_out.message.dataMsg[0] =
312  betoh(capacityUpper);//last block
313  scsi_out.message.dataMsg[1] =
314  betoh(capacityLower);//last block
315  scsi_out.message.dataMsg[2] = betoh(blkSize);//blocksize
316  scsi_out.message.dataMsg[3] = 0x00;//
317  scsi_out.message.dataMsg[4] = 0x00;//reserved
318  scsi_out.message.dataMsg[5] = 0x00;//reserved
319  scsi_out.message.dataMsg[6] = 0x00;//reserved
320  scsi_out.message.dataMsg[7] = 0x00;//reserved
321 
322  } break;
323 
324  case SCSIReportLUNs: {
328  scsi_out.msgSize = (lunAvail * 8) + 8;//list + overhead
329  scsi_out.message.dataMsg.resize(2 * lunAvail + 2);
330  scsi_out.message.dataMsg[0] = (lunAvail * 8) << 24;//LUN listlength
331  scsi_out.message.dataMsg[1] = 0x00;
332 
333  for (uint8_t count = 0; count < lunAvail; count++) {
334  //LUN "count"
335  scsi_out.message.dataMsg[2 + 2 * count] = (count & 0x7F) << 8;
336  scsi_out.message.dataMsg[3 + 2 * count] = 0x00;
337  }
338 
339  } break;
340 
341  case SCSIStartStop: {
342  //Just acknowledge; not deemed relevant ATM
343  scsi_out.msgSize = 0;
344 
345  } break;
346 
347  case SCSITestUnitReady: {
348  //Just acknowledge; not deemed relevant ATM
349  scsi_out.msgSize = 0;
350 
351  } break;
352 
353  case SCSIVerify10: {
358  scsi_out.msgSize = 0;
359 
360  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
361 
363  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
364  uint64_t read_offset = betoh(tmp);
365 
366  uint16_t tmpsize = *reinterpret_cast<uint16_t*>(&tempptr[7]);
367  uint32_t read_size = betoh(tmpsize);
368 
369  if ((read_offset + read_size) > diskSize)
370  scsi_out.status = SCSIIllegalRequest;
371 
375  statusCheck(scsi_out.status, scsi_out.senseCode);
376  scsi_out.senseSize = scsi_out.senseCode[0];
377  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
378  SCSICheckCondition;
379 
380  } break;
381 
382  case SCSIWrite6: {
387  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
388 
393  uint32_t tmp = *reinterpret_cast<uint32_t*>(tempptr);
394  uint64_t write_offset = betoh(tmp) & 0x1FFFFF;
395 
396  uint32_t write_size = tempptr[4];
397 
398  scsi_out.msgSize = write_size * blkSize;
399  scsi_out.offset = write_offset * blkSize;
400  scsi_out.expectMore = 0x01;
401 
402  if ((write_offset + write_size) > diskSize)
403  scsi_out.status = SCSIIllegalRequest;
404 
405  DPRINTF(UFSHostDevice, "Write6 offset: 0x%8x, for %d blocks\n",
406  write_offset, write_size);
407 
411  statusCheck(scsi_out.status, scsi_out.senseCode);
412  scsi_out.senseSize = scsi_out.senseCode[0];
413  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
414  SCSICheckCondition;
415 
416  } break;
417 
418  case SCSIWrite10: {
419  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
420 
422  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
423  uint64_t write_offset = betoh(tmp);
424 
425  uint16_t tmpsize = *reinterpret_cast<uint16_t*>(&tempptr[7]);
426  uint32_t write_size = betoh(tmpsize);
427 
428  scsi_out.msgSize = write_size * blkSize;
429  scsi_out.offset = write_offset * blkSize;
430  scsi_out.expectMore = 0x01;
431 
432  if ((write_offset + write_size) > diskSize)
433  scsi_out.status = SCSIIllegalRequest;
434 
435  DPRINTF(UFSHostDevice, "Write10 offset: 0x%8x, for %d blocks\n",
436  write_offset, write_size);
437 
441  statusCheck(scsi_out.status, scsi_out.senseCode);
442  scsi_out.senseSize = scsi_out.senseCode[0];
443  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
444  SCSICheckCondition;
445 
446  } break;
447 
448  case SCSIWrite16: {
449  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
450 
452  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
453  uint64_t write_offset = betoh(tmp);
454 
455  tmp = *reinterpret_cast<uint32_t*>(&tempptr[6]);
456  write_offset = (write_offset << 32) | betoh(tmp);
457 
458  tmp = *reinterpret_cast<uint32_t*>(&tempptr[10]);
459  uint32_t write_size = betoh(tmp);
460 
461  scsi_out.msgSize = write_size * blkSize;
462  scsi_out.offset = write_offset * blkSize;
463  scsi_out.expectMore = 0x01;
464 
465  if ((write_offset + write_size) > diskSize)
466  scsi_out.status = SCSIIllegalRequest;
467 
468  DPRINTF(UFSHostDevice, "Write16 offset: 0x%8x, for %d blocks\n",
469  write_offset, write_size);
470 
474  statusCheck(scsi_out.status, scsi_out.senseCode);
475  scsi_out.senseSize = scsi_out.senseCode[0];
476  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
477  SCSICheckCondition;
478 
479  } break;
480 
481  case SCSIFormatUnit: {//not yet verified
482  scsi_out.msgSize = 0;
483  scsi_out.expectMore = 0x01;
484 
485  } break;
486 
487  case SCSISendDiagnostic: {//not yet verified
488  scsi_out.msgSize = 0;
489 
490  } break;
491 
492  case SCSISynchronizeCache: {
493  //do we have cache (we don't have cache at this moment)
494  //TODO: here will synchronization happen when cache is modelled
495  scsi_out.msgSize = 0;
496 
497  } break;
498 
499  //UFS SCSI additional command set for full functionality
500  case SCSIModeSelect10:
501  //TODO:
502  //scsi_out.expectMore = 0x01;//not supported due to modepage support
503  //code isn't dead, code suggest what is to be done when implemented
504  break;
505 
506  case SCSIModeSense6: case SCSIModeSense10: {
511  if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x0A) {//control page
512  scsi_out.message.dataMsg.resize((sizeof(controlPage) >> 2) + 2);
513  scsi_out.message.dataMsg[0] = 0x00000A00;//control page code
514  scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8
515 
516  for (uint8_t count = 0; count < 3; count++)
517  scsi_out.message.dataMsg[2 + count] = controlPage[count];
518 
519  scsi_out.msgSize = 20;
520  DPRINTF(UFSHostDevice, "CONTROL page\n");
521 
522  } else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x01) {//recovery page
523  scsi_out.message.dataMsg.resize((sizeof(recoveryPage) >> 2)
524  + 2);
525 
526  scsi_out.message.dataMsg[0] = 0x00000100;//recovery page code
527  scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8
528 
529  for (uint8_t count = 0; count < 3; count++)
530  scsi_out.message.dataMsg[2 + count] = recoveryPage[count];
531 
532  scsi_out.msgSize = 20;
533  DPRINTF(UFSHostDevice, "RECOVERY page\n");
534 
535  } else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x08) {//caching page
536 
537  scsi_out.message.dataMsg.resize((sizeof(cachingPage) >> 2) + 2);
538  scsi_out.message.dataMsg[0] = 0x00001200;//caching page code
539  scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8
540 
541  for (uint8_t count = 0; count < 5; count++)
542  scsi_out.message.dataMsg[2 + count] = cachingPage[count];
543 
544  scsi_out.msgSize = 20;
545  DPRINTF(UFSHostDevice, "CACHE page\n");
546 
547  } else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x3F) {//ALL the pages!
548 
549  scsi_out.message.dataMsg.resize(((sizeof(controlPage) +
550  sizeof(recoveryPage) +
551  sizeof(cachingPage)) >> 2)
552  + 2);
553  scsi_out.message.dataMsg[0] = 0x00003200;//all page code
554  scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8
555 
556  for (uint8_t count = 0; count < 3; count++)
557  scsi_out.message.dataMsg[2 + count] = recoveryPage[count];
558 
559  for (uint8_t count = 0; count < 5; count++)
560  scsi_out.message.dataMsg[5 + count] = cachingPage[count];
561 
562  for (uint8_t count = 0; count < 3; count++)
563  scsi_out.message.dataMsg[10 + count] = controlPage[count];
564 
565  scsi_out.msgSize = 52;
566  DPRINTF(UFSHostDevice, "Return ALL the pages!!!\n");
567 
568  } else inform("Wrong mode page requested\n");
569 
570  scsi_out.message.dataCount = scsi_out.msgSize << 24;
571  } break;
572 
573  case SCSIRequestSense: {
574  scsi_out.msgSize = 0;
575 
576  } break;
577 
578  case SCSIUnmap:break;//not yet verified
579 
580  case SCSIWriteBuffer: {
581  scsi_out.expectMore = 0x01;
582 
583  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
584 
586  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
587  uint64_t write_offset = betoh(tmp) & 0xFFFFFF;
588 
589  tmp = *reinterpret_cast<uint32_t*>(&tempptr[5]);
590  uint32_t write_size = betoh(tmp) & 0xFFFFFF;
591 
592  scsi_out.msgSize = write_size;
593  scsi_out.offset = write_offset;
594 
595  } break;
596 
597  case SCSIReadBuffer: {
603  scsi_out.expectMore = 0x02;
604 
605  uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);
606 
608  uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
609  uint64_t read_offset = betoh(tmp) & 0xFFFFFF;
610 
611  tmp = *reinterpret_cast<uint32_t*>(&tempptr[5]);
612  uint32_t read_size = betoh(tmp) & 0xFFFFFF;
613 
614  scsi_out.msgSize = read_size;
615  scsi_out.offset = read_offset;
616 
617  if ((read_offset + read_size) > capacityLower * blkSize)
618  scsi_out.status = SCSIIllegalRequest;
619 
620  DPRINTF(UFSHostDevice, "Read buffer location: 0x%8x\n",
621  read_offset);
622  DPRINTF(UFSHostDevice, "Number of bytes: 0x%8x\n", read_size);
623 
624  statusCheck(scsi_out.status, scsi_out.senseCode);
625  scsi_out.senseSize = scsi_out.senseCode[0];
626  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
627  SCSICheckCondition;
628 
629  } break;
630 
631  case SCSIMaintenanceIn: {
638  DPRINTF(UFSHostDevice, "Ignoring Maintenance In command\n");
639  statusCheck(SCSIIllegalRequest, scsi_out.senseCode);
640  scsi_out.senseSize = scsi_out.senseCode[0];
641  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
642  SCSICheckCondition;
643  scsi_out.msgSize = 0;
644  } break;
645 
646  default: {
647  statusCheck(SCSIIllegalRequest, scsi_out.senseCode);
648  scsi_out.senseSize = scsi_out.senseCode[0];
649  scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
650  SCSICheckCondition;
651  scsi_out.msgSize = 0;
652  inform("Unsupported scsi message type: %2x\n", SCSI_msg[4] & 0xFF);
653  inform("0x%8x\n", SCSI_msg[0]);
654  inform("0x%8x\n", SCSI_msg[1]);
655  inform("0x%8x\n", SCSI_msg[2]);
656  inform("0x%8x\n", SCSI_msg[3]);
657  inform("0x%8x\n", SCSI_msg[4]);
658  } break;
659  }
660 
661  return scsi_out;
662 }
663 
670 void
672  uint8_t* sensecodelist)
673 {
674  for (uint8_t count = 0; count < 19; count++)
675  sensecodelist[count] = 0;
676 
677  sensecodelist[0] = 18; //sense length
678  sensecodelist[1] = 0x70; //we send a valid frame
679  sensecodelist[3] = status & 0xF; //mask to be sure + sensecode
680  sensecodelist[8] = 0x1F; //data length
681 }
682 
687 void
689  uint32_t size)
690 {
692  for (int count = 0; count < (size / SectorSize); count++)
693  flashDisk->read(&(readaddr[SectorSize*count]), (offset /
694  SectorSize) + count);
695 }
696 
701 void
703  uint32_t size)
704 {
706  for (int count = 0; count < (size / SectorSize); count++)
707  flashDisk->write(&(writeaddr[SectorSize * count]),
708  (offset / SectorSize) + count);
709 }
710 
715 UFSHostDevice::UFSHostDevice(const UFSHostDeviceParams &p) :
716  DmaDevice(p),
717  pioAddr(p.pio_addr),
718  pioSize(0x0FFF),
719  pioDelay(p.pio_latency),
720  intNum(p.int_num),
721  gic(p.gic),
722  lunAvail(p.image.size()),
723  UFSSlots(p.ufs_slots - 1),
724  readPendingNum(0),
725  writePendingNum(0),
726  activeDoorbells(0),
727  pendingDoorbells(0),
728  countInt(0),
729  transferTrack(0),
730  taskCommandTrack(0),
731  idlePhaseStart(0),
732  stats(this),
733  SCSIResumeEvent([this]{ SCSIStart(); }, name()),
734  UTPEvent([this]{ finalUTP(); }, name())
735 {
736  DPRINTF(UFSHostDevice, "The hostcontroller hosts %d Logic units\n",
737  lunAvail);
738  UFSDevice.resize(lunAvail);
739 
740  for (int count = 0; count < lunAvail; count++) {
741  UFSDevice[count] = new UFSSCSIDevice(p, count,
742  [this]() { LUNSignal(); },
743  [this]() { readCallback(); });
744  }
745 
746  if (UFSSlots > 31)
747  warn("UFSSlots = %d, this will results in %d command slots",
748  UFSSlots, (UFSSlots & 0x1F));
749 
750  if ((UFSSlots & 0x1F) == 0)
751  fatal("Number of UFS command slots should be between 1 and 32.");
752 
753  setValues();
754 }
755 
758  : Stats::Group(parent, "UFSDiskHost"),
759  ADD_STAT(currentSCSIQueue, UNIT_COUNT,
760  "Most up to date length of the command queue"),
761  ADD_STAT(currentReadSSDQueue, UNIT_COUNT,
762  "Most up to date length of the read SSD queue"),
763  ADD_STAT(currentWriteSSDQueue, UNIT_COUNT,
764  "Most up to date length of the write SSD queue"),
766  ADD_STAT(totalReadSSD, UNIT_BYTE,
767  "Number of bytes read from SSD"),
768  ADD_STAT(totalWrittenSSD, UNIT_BYTE,
769  "Number of bytes written to SSD"),
770  ADD_STAT(totalReadDiskTransactions, UNIT_COUNT,
771  "Number of transactions from disk"),
772  ADD_STAT(totalWriteDiskTransactions, UNIT_COUNT,
773  "Number of transactions to disk"),
774  ADD_STAT(totalReadUFSTransactions, UNIT_COUNT,
775  "Number of transactions from device"),
776  ADD_STAT(totalWriteUFSTransactions, UNIT_COUNT,
777  "Number of transactions to device"),
779  ADD_STAT(averageReadSSDBW,
780  UNIT_RATE(Stats::Units::Byte, Stats::Units::Second),
781  "Average read bandwidth",
782  totalReadSSD / simSeconds),
783  ADD_STAT(averageWriteSSDBW,
784  UNIT_RATE(Stats::Units::Byte, Stats::Units::Second),
785  "Average write bandwidth",
786  totalWrittenSSD / simSeconds),
787  ADD_STAT(averageSCSIQueue,
788  UNIT_RATE(Stats::Units::Count, Stats::Units::Tick),
789  "Average command queue length"),
790  ADD_STAT(averageReadSSDQueue,
791  UNIT_RATE(Stats::Units::Count, Stats::Units::Tick),
792  "Average read queue length"),
793  ADD_STAT(averageWriteSSDQueue,
794  UNIT_RATE(Stats::Units::Count, Stats::Units::Tick),
795  "Average write queue length"),
797  ADD_STAT(curDoorbell, UNIT_COUNT,
798  "Most up to date number of doorbells used",
799  parent->activeDoorbells),
800  ADD_STAT(maxDoorbell, UNIT_COUNT,
801  "Maximum number of doorbells utilized"),
802  ADD_STAT(averageDoorbell,
803  UNIT_RATE(Stats::Units::Count, Stats::Units::Tick),
804  "Average number of Doorbells used"),
806  ADD_STAT(transactionLatency, UNIT_TICK,
807  "Histogram of transaction times"),
808  ADD_STAT(idleTimes, UNIT_TICK, "Histogram of idle times")
809 {
810  using namespace Stats;
811 
812  // Register the stats
815  .flags(none);
817  .flags(none);
819  .flags(none);
820 
823  .flags(none);
824 
826  .flags(none);
827 
829  .flags(none);
831  .flags(none);
833  .flags(none);
835  .flags(none);
836 
839  .flags(nozero);
840 
842  .flags(nozero);
843 
845  .flags(nozero);
847  .flags(nozero);
849  .flags(nozero);
850 
853  .flags(none);
854 
856  .flags(none);
858  .flags(nozero);
859 
862  .init(100)
863  .flags(pdf);
864 
865  idleTimes
866  .init(100)
867  .flags(pdf);
868 }
869 
874 {
880  UFSHCIMem.HCCAP = 0x06070000 | (UFSSlots & 0x1F);
881  UFSHCIMem.HCversion = 0x00010000; //version is 1.0
882  UFSHCIMem.HCHCDDID = 0xAA003C3C;// Arbitrary number
883  UFSHCIMem.HCHCPMID = 0x41524D48; //ARMH (not an official MIPI number)
884  UFSHCIMem.TRUTRLDBR = 0x00;
885  UFSHCIMem.TMUTMRLDBR = 0x00;
886  UFSHCIMem.CMDUICCMDR = 0x00;
887  // We can process CMD, TM, TR, device present
889  UFSHCIMem.TRUTRLBA = 0x00;
890  UFSHCIMem.TRUTRLBAU = 0x00;
891  UFSHCIMem.TMUTMRLBA = 0x00;
892  UFSHCIMem.TMUTMRLBAU = 0x00;
893 }
894 
901 {
902  AddrRangeList ranges;
903  ranges.push_back(RangeSize(pioAddr, pioSize));
904  return ranges;
905 }
906 
912 Tick
914 {
915  uint32_t data = 0;
916 
917  switch (pkt->getAddr() & 0xFF)
918  {
919 
921  data = UFSHCIMem.HCCAP;
922  break;
923 
924  case regUFSVersion:
926  break;
927 
928  case regControllerDEVID:
930  break;
931 
932  case regControllerPRODID:
934  break;
935 
936  case regInterruptStatus:
939  //TODO: Revise and extend
940  clearInterrupt();
941  break;
942 
943  case regInterruptEnable:
945  break;
946 
947  case regControllerStatus:
949  break;
950 
951  case regControllerEnable:
953  break;
954 
957  break;
958 
961  break;
962 
965  break;
966 
969  break;
970 
971  case regUICErrorCodeDME:
973  break;
974 
977  break;
978 
981  break;
982 
985  break;
986 
989  break;
990 
993  break;
994 
997  break;
998 
1001  break;
1002 
1005  break;
1006 
1007  case regUTPTaskREQDoorbell:
1009  break;
1010 
1013  break;
1014 
1017  break;
1018 
1019  case regUICCommand:
1021  break;
1022 
1023  case regUICCommandArg1:
1025  break;
1026 
1027  case regUICCommandArg2:
1029  break;
1030 
1031  case regUICCommandArg3:
1033  break;
1034 
1035  default:
1036  data = 0x00;
1037  break;
1038  }
1039 
1040  pkt->setLE<uint32_t>(data);
1041  pkt->makeResponse();
1042  return pioDelay;
1043 }
1044 
1050 Tick
1052 {
1053  assert(pkt->getSize() <= 4);
1054 
1055  const uint32_t data = pkt->getUintX(ByteOrder::little);
1056 
1057  switch (pkt->getAddr() & 0xFF)
1058  {
1059  case regControllerCapabilities://you shall not write to this
1060  break;
1061 
1062  case regUFSVersion://you shall not write to this
1063  break;
1064 
1065  case regControllerDEVID://you shall not write to this
1066  break;
1067 
1068  case regControllerPRODID://you shall not write to this
1069  break;
1070 
1071  case regInterruptStatus://you shall not write to this
1072  break;
1073 
1074  case regInterruptEnable:
1076  break;
1077 
1078  case regControllerStatus:
1080  break;
1081 
1082  case regControllerEnable:
1084  break;
1085 
1088  break;
1089 
1092  break;
1093 
1095  UFSHCIMem.ORUECN = data;
1096  break;
1097 
1099  UFSHCIMem.ORUECT = data;
1100  break;
1101 
1102  case regUICErrorCodeDME:
1104  break;
1105 
1108  break;
1109 
1112  if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
1113  ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU)!= 0x00))
1115  break;
1116 
1119  if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
1120  ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU) != 0x00))
1122  break;
1123 
1125  if (!(UFSHCIMem.TRUTRLDBR) && data)
1126  stats.idleTimes.sample(curTick() - idlePhaseStart);
1128  requestHandler();
1129  break;
1130 
1133  break;
1134 
1137  break;
1138 
1141  if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
1142  ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU) != 0x00))
1144  break;
1145 
1148  if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
1149  ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU) != 0x00))
1151  break;
1152 
1153  case regUTPTaskREQDoorbell:
1155  requestHandler();
1156  break;
1157 
1160  break;
1161 
1164  break;
1165 
1166  case regUICCommand:
1168  requestHandler();
1169  break;
1170 
1171  case regUICCommandArg1:
1173  break;
1174 
1175  case regUICCommandArg2:
1177  break;
1178 
1179  case regUICCommandArg3:
1181  break;
1182 
1183  default:break;//nothing happens, you try to access a register that
1184  //does not exist
1185 
1186  }
1187 
1188  pkt->makeResponse();
1189  return pioDelay;
1190 }
1191 
1197 void
1199 {
1200  Addr address = 0x00;
1201  int mask = 0x01;
1202  int size;
1203  int count = 0;
1204  struct taskStart task_info;
1205  struct transferStart transferstart_info;
1206  transferstart_info.done = 0;
1207 
1213  while (((UFSHCIMem.CMDUICCMDR > 0x00) |
1214  ((UFSHCIMem.TMUTMRLDBR ^ taskCommandTrack) > 0x00) |
1215  ((UFSHCIMem.TRUTRLDBR ^ transferTrack) > 0x00)) ) {
1216 
1217  if (UFSHCIMem.CMDUICCMDR > 0x00) {
1222  commandHandler();
1225  UFSHCIMem.CMDUICCMDR = 0x00;
1226  return; //command, nothing more we can do
1227 
1228  } else if ((UFSHCIMem.TMUTMRLDBR ^ taskCommandTrack) > 0x00) {
1233  size = sizeof(UTPUPIUTaskReq);
1236  address = UFSHCIMem.TMUTMRLBAU;
1237  //<-64 bit
1238  address = (count * size) + (address << 32) +
1240  taskCommandTrack |= mask << count;
1241 
1242  inform("UFSmodel received a task from the system; this might"
1243  " lead to untested behaviour.\n");
1244 
1245  task_info.mask = mask << count;
1246  task_info.address = address;
1247  task_info.size = size;
1248  task_info.done = UFSHCIMem.TMUTMRLDBR;
1249  taskInfo.push_back(task_info);
1250  taskEventQueue.push_back(
1251  EventFunctionWrapper([this]{ taskStart(); }, name()));
1252  writeDevice(&taskEventQueue.back(), false, address, size,
1253  reinterpret_cast<uint8_t*>
1254  (&taskInfo.back().destination), 0, 0);
1255 
1256  } else if ((UFSHCIMem.TRUTRLDBR ^ transferTrack) > 0x00) {
1262  size = sizeof(UTPTransferReqDesc);
1265  address = UFSHCIMem.TRUTRLBAU;
1266  //<-64 bit
1267  address = (count * size) + (address << 32) + UFSHCIMem.TRUTRLBA;
1268 
1269  transferTrack |= mask << count;
1270  DPRINTF(UFSHostDevice, "Doorbell register: 0x%8x select #:"
1271  " 0x%8x completion info: 0x%8x\n", UFSHCIMem.TRUTRLDBR,
1272  count, transferstart_info.done);
1273 
1274  transferstart_info.done = UFSHCIMem.TRUTRLDBR;
1275 
1277  transactionStart[count] = curTick(); //note the start time
1278  ++activeDoorbells;
1279  stats.maxDoorbell = (stats.maxDoorbell.value() < activeDoorbells)
1280  ? activeDoorbells : stats.maxDoorbell.value();
1281  stats.averageDoorbell = stats.maxDoorbell.value();
1282 
1288  transferstart_info.mask = mask << count;
1289  transferstart_info.address = address;
1290  transferstart_info.size = size;
1291  transferstart_info.done = UFSHCIMem.TRUTRLDBR;
1292  transferStartInfo.push_back(transferstart_info);
1293 
1295  transferStartInfo.back().destination = new struct
1297  DPRINTF(UFSHostDevice, "Initial transfer start: 0x%8x\n",
1298  transferstart_info.done);
1299  transferEventQueue.push_back(
1300  EventFunctionWrapper([this]{ transferStart(); }, name()));
1301 
1302  if (transferEventQueue.size() < 2) {
1303  writeDevice(&transferEventQueue.front(), false,
1304  address, size, reinterpret_cast<uint8_t*>
1305  (transferStartInfo.front().destination),0, 0);
1306  DPRINTF(UFSHostDevice, "Transfer scheduled\n");
1307  }
1308  }
1309  }
1310 }
1311 
1316 void
1318 {
1319  DPRINTF(UFSHostDevice, "Task start");
1320  taskHandler(&taskInfo.front().destination, taskInfo.front().mask,
1321  taskInfo.front().address, taskInfo.front().size);
1322  taskInfo.pop_front();
1323  taskEventQueue.pop_front();
1324 }
1325 
1330 void
1332 {
1333  DPRINTF(UFSHostDevice, "Enter transfer event\n");
1334  transferHandler(transferStartInfo.front().destination,
1335  transferStartInfo.front().mask,
1336  transferStartInfo.front().address,
1337  transferStartInfo.front().size,
1338  transferStartInfo.front().done);
1339 
1340  transferStartInfo.pop_front();
1341  DPRINTF(UFSHostDevice, "Transfer queue size at end of event: "
1342  "0x%8x\n", transferEventQueue.size());
1343 }
1344 
1350 void
1352 {
1353  if (UFSHCIMem.CMDUICCMDR == 0x16) {
1354  UFSHCIMem.ORHostControllerStatus |= 0x0F;//link startup
1355  }
1356 
1357 }
1358 
1364 void
1366  uint32_t req_pos, Addr finaladdress, uint32_t
1367  finalsize)
1368 {
1373  inform("taskHandler\n");
1374  inform("%8x\n", request_in->header.dWord0);
1375  inform("%8x\n", request_in->header.dWord1);
1376  inform("%8x\n", request_in->header.dWord2);
1377 
1378  request_in->header.dWord2 &= 0xffffff00;
1379 
1380  UFSHCIMem.TMUTMRLDBR &= ~(req_pos);
1381  taskCommandTrack &= ~(req_pos);
1383 
1384  readDevice(true, finaladdress, finalsize, reinterpret_cast<uint8_t*>
1385  (request_in), true, NULL);
1386 
1387 }
1388 
1400 void
1402  int req_pos, Addr finaladdress, uint32_t
1403  finalsize, uint32_t done)
1404 {
1405 
1406  Addr cmd_desc_addr = 0x00;
1407 
1408 
1409  //acknowledge handling of the message
1410  DPRINTF(UFSHostDevice, "SCSI message detected\n");
1411  request_in->header.dWord2 &= 0xffffff00;
1412  SCSIInfo.RequestIn = request_in;
1413  SCSIInfo.reqPos = req_pos;
1414  SCSIInfo.finalAddress = finaladdress;
1415  SCSIInfo.finalSize = finalsize;
1416  SCSIInfo.destination.resize(request_in->PRDTableOffset * 4
1417  + request_in->PRDTableLength * sizeof(UFSHCDSGEntry));
1418  SCSIInfo.done = done;
1419 
1420  assert(!SCSIResumeEvent.scheduled());
1424  cmd_desc_addr = request_in->commandDescBaseAddrHi;
1425  cmd_desc_addr = (cmd_desc_addr << 32) |
1426  (request_in->commandDescBaseAddrLo & 0xffffffff);
1427 
1428  writeDevice(&SCSIResumeEvent, false, cmd_desc_addr,
1429  SCSIInfo.destination.size(), &SCSIInfo.destination[0],0, 0);
1430 
1431  DPRINTF(UFSHostDevice, "SCSI scheduled\n");
1432 
1433  transferEventQueue.pop_front();
1434 }
1435 
1443 void
1445 {
1446  DPRINTF(UFSHostDevice, "SCSI message on hold until ready\n");
1447  uint32_t LUN = SCSIInfo.destination[2];
1448  UFSDevice[LUN]->SCSIInfoQueue.push_back(SCSIInfo);
1449 
1450  DPRINTF(UFSHostDevice, "SCSI queue %d has %d elements\n", LUN,
1451  UFSDevice[LUN]->SCSIInfoQueue.size());
1452 
1454  if (UFSDevice[LUN]->SCSIInfoQueue.size() < 2) //LUN is available
1455  SCSIResume(LUN);
1456 
1457  else if (UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
1458  panic("SCSI queue is getting too big %d\n", UFSDevice[LUN]->
1459  SCSIInfoQueue.size());
1460 
1465  if (!transferEventQueue.empty()) {
1466 
1471  writeDevice(&transferEventQueue.front(), false,
1472  transferStartInfo.front().address,
1473  transferStartInfo.front().size, reinterpret_cast<uint8_t*>
1474  (transferStartInfo.front().destination), 0, 0);
1475 
1476  DPRINTF(UFSHostDevice, "Transfer scheduled");
1477  }
1478 }
1479 
1488 void
1490 {
1491  DPRINTF(UFSHostDevice, "SCSIresume\n");
1492  if (UFSDevice[lun_id]->SCSIInfoQueue.empty())
1493  panic("No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1495 
1497  struct UTPTransferReqDesc* request_in = UFSDevice[lun_id]->
1498  SCSIInfoQueue.front().RequestIn;
1499 
1500  uint32_t req_pos = UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;
1501 
1502  Addr finaladdress = UFSDevice[lun_id]->SCSIInfoQueue.front().
1503  finalAddress;
1504 
1505  uint32_t finalsize = UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;
1506 
1507  uint32_t* transfercommand = reinterpret_cast<uint32_t*>
1508  (&(UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));
1509 
1510  DPRINTF(UFSHostDevice, "Task tag: 0x%8x\n", transfercommand[0]>>24);
1512  request_out_datain = UFSDevice[(transfercommand[0] & 0xFF0000) >> 16]->
1513  SCSICMDHandle(transfercommand);
1514 
1516 
1521  request_in->header.dWord0 = ((request_in->header.dWord0 >> 24) == 0x21)
1522  ? 0x36 : 0x21;
1523  UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
1524  request_in->header.dWord0 | (request_out_datain.LUN << 8)
1525  | (transfercommand[0] & 0xFF000000);
1527  UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
1528  (request_out_datain.status << 24);
1530  UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
1531  ((request_out_datain.senseSize + 2) << 24) | 0x05;
1533  UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
1535 
1536  //data
1537  for (uint8_t count = 0; count<request_out_datain.senseSize; count++) {
1538  UFSDevice[lun_id]->transferInfo.requestOut.senseData[count] =
1540  }
1541 
1542  /*
1543  * At position defined by "request_in->PRDTableOffset" (counting 32 bit
1544  * words) in array "transfercommand" we have a scatter gather list, which
1545  * is usefull to us if we interpreted it as a UFSHCDSGEntry structure.
1546  */
1547  struct UFSHCDSGEntry* sglist = reinterpret_cast<UFSHCDSGEntry*>
1548  (&(transfercommand[(request_in->PRDTableOffset)]));
1549 
1550  uint32_t length = request_in->PRDTableLength;
1551  DPRINTF(UFSHostDevice, "# PRDT entries: %d\n", length);
1552 
1553  Addr response_addr = request_in->commandDescBaseAddrHi;
1554  response_addr = (response_addr << 32) |
1555  ((request_in->commandDescBaseAddrLo +
1556  (request_in->responseUPIULength << 2)) & 0xffffffff);
1557 
1559  UFSDevice[lun_id]->transferInfo.responseStartAddr = response_addr;
1560  UFSDevice[lun_id]->transferInfo.reqPos = req_pos;
1561  UFSDevice[lun_id]->transferInfo.size = finalsize;
1562  UFSDevice[lun_id]->transferInfo.address = finaladdress;
1563  UFSDevice[lun_id]->transferInfo.destination = reinterpret_cast<uint8_t*>
1564  (UFSDevice[lun_id]->SCSIInfoQueue.front().RequestIn);
1565  UFSDevice[lun_id]->transferInfo.finished = true;
1566  UFSDevice[lun_id]->transferInfo.lunID = request_out_datain.LUN;
1567 
1573  if (request_out_datain.expectMore == 0x01) {
1576  length, sglist);
1577 
1578  } else if (request_out_datain.expectMore == 0x02) {
1581  request_out_datain.offset, length, sglist);
1582 
1583  } else {
1585  uint32_t count = 0;
1586  uint32_t size_accum = 0;
1587  DPRINTF(UFSHostDevice, "Data DMA size: 0x%8x\n",
1589 
1591  while ((length > count) && size_accum
1592  < (request_out_datain.msgSize - 1) &&
1593  (request_out_datain.msgSize != 0x00)) {
1594  Addr SCSI_start = sglist[count].upperAddr;
1595  SCSI_start = (SCSI_start << 32) |
1596  (sglist[count].baseAddr & 0xFFFFFFFF);
1597  DPRINTF(UFSHostDevice, "Data DMA start: 0x%8x\n", SCSI_start);
1598  DPRINTF(UFSHostDevice, "Data DMA size: 0x%8x\n",
1599  (sglist[count].size + 1));
1607  uint32_t size_to_send = sglist[count].size + 1;
1608 
1609  if (request_out_datain.msgSize < (size_to_send + size_accum))
1610  size_to_send = request_out_datain.msgSize - size_accum;
1611 
1612  readDevice(false, SCSI_start, size_to_send,
1613  reinterpret_cast<uint8_t*>
1614  (&(request_out_datain.message.dataMsg[size_accum])),
1615  false, NULL);
1616 
1617  size_accum += size_to_send;
1618  DPRINTF(UFSHostDevice, "Total remaining: 0x%8x,accumulated so far"
1619  " : 0x%8x\n", (request_out_datain.msgSize - size_accum),
1620  size_accum);
1621 
1622  ++count;
1623  DPRINTF(UFSHostDevice, "Transfer #: %d\n", count);
1624  }
1625 
1627  transferDone(response_addr, req_pos, UFSDevice[lun_id]->
1628  transferInfo.requestOut, finalsize, finaladdress,
1629  reinterpret_cast<uint8_t*>(request_in), true, lun_id);
1630  }
1631 
1632  DPRINTF(UFSHostDevice, "SCSI resume done\n");
1633 }
1634 
1640 void
1642 {
1643  uint8_t this_lun = 0;
1644 
1645  //while we haven't found the right lun, keep searching
1646  while ((this_lun < lunAvail) && !UFSDevice[this_lun]->finishedCommand())
1647  ++this_lun;
1648 
1649  if (this_lun < lunAvail) {
1650  //Clear signal.
1651  UFSDevice[this_lun]->clearSignal();
1652  //found it; call transferDone
1653  transferDone(UFSDevice[this_lun]->transferInfo.responseStartAddr,
1654  UFSDevice[this_lun]->transferInfo.reqPos,
1655  UFSDevice[this_lun]->transferInfo.requestOut,
1656  UFSDevice[this_lun]->transferInfo.size,
1657  UFSDevice[this_lun]->transferInfo.address,
1658  UFSDevice[this_lun]->transferInfo.destination,
1659  UFSDevice[this_lun]->transferInfo.finished,
1660  UFSDevice[this_lun]->transferInfo.lunID);
1661  }
1662 
1663  else
1664  panic("no LUN finished in tick %d\n", curTick());
1665 }
1666 
1672 void
1673 UFSHostDevice::transferDone(Addr responseStartAddr, uint32_t req_pos,
1674  struct UTPUPIURSP request_out, uint32_t size,
1675  Addr address, uint8_t* destination,
1676  bool finished, uint32_t lun_id)
1677 {
1679  if (UFSDevice[lun_id]->SCSIInfoQueue.empty())
1680  panic("No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1682 
1683  DPRINTF(UFSHostDevice, "DMA start: 0x%8x; DMA size: 0x%8x\n",
1684  responseStartAddr, sizeof(request_out));
1685 
1686  struct transferStart lastinfo;
1687  lastinfo.mask = req_pos;
1688  lastinfo.done = finished;
1689  lastinfo.address = address;
1690  lastinfo.size = size;
1691  lastinfo.destination = reinterpret_cast<UTPTransferReqDesc*>
1692  (destination);
1693  lastinfo.lun_id = lun_id;
1694 
1695  transferEnd.push_back(lastinfo);
1696 
1697  DPRINTF(UFSHostDevice, "Transfer done start\n");
1698 
1699  readDevice(false, responseStartAddr, sizeof(request_out),
1700  reinterpret_cast<uint8_t*>
1701  (&(UFSDevice[lun_id]->transferInfo.requestOut)),
1702  true, &UTPEvent);
1703 }
1704 
1711 void
1713 {
1714  uint32_t lun_id = transferEnd.front().lun_id;
1715 
1716  UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
1717  DPRINTF(UFSHostDevice, "SCSIInfoQueue size: %d, lun: %d\n",
1718  UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);
1719 
1721  if (UFSHCIMem.TRUTRLDBR & transferEnd.front().mask) {
1722  uint8_t count = 0;
1723  while (!(transferEnd.front().mask & (0x1 << count)))
1724  ++count;
1725  stats.transactionLatency.sample(curTick() -
1727  }
1728 
1730  readDevice(true, transferEnd.front().address,
1731  transferEnd.front().size, reinterpret_cast<uint8_t*>
1732  (transferEnd.front().destination), true, NULL);
1733 
1735  transferTrack &= ~(transferEnd.front().mask);
1736  --activeDoorbells;
1737  ++pendingDoorbells;
1738  garbage.push_back(transferEnd.front().destination);
1739  transferEnd.pop_front();
1740  DPRINTF(UFSHostDevice, "UTP handled\n");
1741 
1743  stats.averageDoorbell = stats.maxDoorbell.value();
1744 
1745  DPRINTF(UFSHostDevice, "activeDoorbells: %d, pendingDoorbells: %d,"
1746  " garbage: %d, TransferEvent: %d\n", activeDoorbells,
1747  pendingDoorbells, garbage.size(), transferEventQueue.size());
1748 
1750  if (!UFSDevice[lun_id]->SCSIInfoQueue.empty())
1751  SCSIResume(lun_id);
1752 }
1753 
1757 void
1759 {
1760  DPRINTF(UFSHostDevice, "Read done start\n");
1761  --readPendingNum;
1762 
1764  if (garbage.size() > 0) {
1765  delete garbage.front();
1766  garbage.pop_front();
1767  }
1768 
1770  if (!(UFSHCIMem.ORInterruptStatus & 0x01)) {
1773  }
1774 
1775 
1776  if (!readDoneEvent.empty()) {
1777  readDoneEvent.pop_front();
1778  }
1779 }
1780 
1785 void
1787 {
1789  countInt++;
1790 
1793  pendingDoorbells = 0;
1794  DPRINTF(UFSHostDevice, "Clear doorbell %X\n", UFSHCIMem.TRUTRLDBR);
1795 
1796  checkDrain();
1797 
1799  gic->sendInt(intNum);
1800  DPRINTF(UFSHostDevice, "Send interrupt @ transaction: 0x%8x!\n",
1801  countInt);
1802 }
1803 
1808 void
1810 {
1811  gic->clearInt(intNum);
1812  DPRINTF(UFSHostDevice, "Clear interrupt: 0x%8x!\n", countInt);
1813 
1814  checkDrain();
1815 
1816  if (!(UFSHCIMem.TRUTRLDBR)) {
1817  idlePhaseStart = curTick();
1818  }
1820 }
1821 
1846 void
1847 UFSHostDevice::writeDevice(Event* additional_action, bool toDisk, Addr
1848  start, int size, uint8_t* destination, uint64_t
1849  SCSIDiskOffset, uint32_t lun_id)
1850 {
1851  DPRINTF(UFSHostDevice, "Write transaction Start: 0x%8x; Size: %d\n",
1852  start, size);
1853 
1855  if (toDisk) {
1856  ++writePendingNum;
1857 
1858  while (!writeDoneEvent.empty() && (writeDoneEvent.front().when()
1859  < curTick()))
1860  writeDoneEvent.pop_front();
1861 
1862  writeDoneEvent.push_back(
1863  EventFunctionWrapper([this]{ writeDone(); },
1864  name()));
1865  assert(!writeDoneEvent.back().scheduled());
1866 
1868  struct transferInfo new_transfer;
1869  new_transfer.offset = SCSIDiskOffset;
1870  new_transfer.size = size;
1871  new_transfer.lunID = lun_id;
1872  new_transfer.filePointer = 0;
1873  SSDWriteinfo.push_back(new_transfer);
1874 
1876  SSDWriteinfo.back().buffer.resize(size);
1877 
1879  dmaPort.dmaAction(MemCmd::ReadReq, start, size,
1880  &writeDoneEvent.back(),
1881  &SSDWriteinfo.back().buffer[0], 0);
1882  //yes, a readreq at a write device function is correct.
1883  DPRINTF(UFSHostDevice, "Write to disk scheduled\n");
1884 
1885  } else {
1886  assert(!additional_action->scheduled());
1887  dmaPort.dmaAction(MemCmd::ReadReq, start, size,
1888  additional_action, destination, 0);
1889  DPRINTF(UFSHostDevice, "Write scheduled\n");
1890  }
1891 }
1892 
1898 void
1899 UFSHostDevice::manageWriteTransfer(uint8_t LUN, uint64_t offset, uint32_t
1900  sg_table_length, struct UFSHCDSGEntry*
1901  sglist)
1902 {
1903  struct writeToDiskBurst next_packet;
1904 
1905  next_packet.SCSIDiskOffset = offset;
1906 
1907  UFSDevice[LUN]->setTotalWrite(sg_table_length);
1908 
1913  for (uint32_t count = 0; count < sg_table_length; count++) {
1914  next_packet.start = sglist[count].upperAddr;
1915  next_packet.start = (next_packet.start << 32) |
1916  (sglist[count].baseAddr & 0xFFFFFFFF);
1917  next_packet.LUN = LUN;
1918  DPRINTF(UFSHostDevice, "Write data DMA start: 0x%8x\n",
1919  next_packet.start);
1920  DPRINTF(UFSHostDevice, "Write data DMA size: 0x%8x\n",
1921  (sglist[count].size + 1));
1922  assert(sglist[count].size > 0);
1923 
1924  if (count != 0)
1925  next_packet.SCSIDiskOffset = next_packet.SCSIDiskOffset +
1926  (sglist[count - 1].size + 1);
1927 
1928  next_packet.size = sglist[count].size + 1;
1929 
1931  if (dmaWriteInfo.empty())
1932  writeDevice(NULL, true, next_packet.start, next_packet.size,
1933  NULL, next_packet.SCSIDiskOffset, next_packet.LUN);
1934  else
1935  DPRINTF(UFSHostDevice, "Write not initiated queue: %d\n",
1936  dmaWriteInfo.size());
1937 
1938  dmaWriteInfo.push_back(next_packet);
1939  DPRINTF(UFSHostDevice, "Write Location: 0x%8x\n",
1940  next_packet.SCSIDiskOffset);
1941 
1942  DPRINTF(UFSHostDevice, "Write transfer #: 0x%8x\n", count + 1);
1943 
1945  stats.totalWrittenSSD += (sglist[count].size + 1);
1946  }
1947 
1949  ++stats.totalWriteUFSTransactions;
1950 }
1951 
1957 void
1959 {
1961  assert(dmaWriteInfo.size() > 0);
1962  dmaWriteInfo.pop_front();
1963  assert(SSDWriteinfo.size() > 0);
1964  uint32_t lun = SSDWriteinfo.front().lunID;
1965 
1967  DPRINTF(UFSHostDevice, "Write done entered, queue: %d\n",
1968  UFSDevice[lun]->SSDWriteDoneInfo.size());
1970  UFSDevice[lun]->writeFlash(&SSDWriteinfo.front().buffer[0],
1971  SSDWriteinfo.front().offset,
1972  SSDWriteinfo.front().size);
1973 
1979  UFSDevice[lun]->SSDWriteDoneInfo.push_back(SSDWriteinfo.front());
1980  SSDWriteinfo.pop_front();
1981 
1982  --writePendingNum;
1984  UFSDevice[lun]->SSDWriteStart();
1985 
1987  stats.currentWriteSSDQueue = UFSDevice[lun]->SSDWriteDoneInfo.size();
1988  stats.averageWriteSSDQueue = UFSDevice[lun]->SSDWriteDoneInfo.size();
1989  ++stats.totalWriteDiskTransactions;
1990 
1992  if (!dmaWriteInfo.empty())
1993  writeDevice(NULL, true, dmaWriteInfo.front().start,
1994  dmaWriteInfo.front().size, NULL,
1995  dmaWriteInfo.front().SCSIDiskOffset,
1996  dmaWriteInfo.front().LUN);
1997  DPRINTF(UFSHostDevice, "Write done end\n");
1998 }
1999 
2003 void
2005 {
2006  assert(SSDWriteDoneInfo.size() > 0);
2007  flashDevice->writeMemory(
2008  SSDWriteDoneInfo.front().offset,
2009  SSDWriteDoneInfo.front().size, memWriteCallback);
2010 
2011  SSDWriteDoneInfo.pop_front();
2012 
2013  DPRINTF(UFSHostDevice, "Write is started; left in queue: %d\n",
2014  SSDWriteDoneInfo.size());
2015 }
2016 
2017 
2022 void
2024 {
2025  DPRINTF(UFSHostDevice, "Write disk, aiming for %d messages, %d so far\n",
2026  totalWrite, amountOfWriteTransfers);
2027 
2028  //we have done one extra transfer
2029  ++amountOfWriteTransfers;
2030 
2032  assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);
2033 
2035  if (totalWrite == amountOfWriteTransfers) {
2036  DPRINTF(UFSHostDevice, "Write transactions finished\n");
2037  totalWrite = 0;
2038  amountOfWriteTransfers = 0;
2039 
2040  //Callback UFS Host
2041  setSignal();
2042  signalDone();
2043  }
2044 
2045 }
2046 
2052 void
2053 UFSHostDevice::readDevice(bool lastTransfer, Addr start, uint32_t size,
2054  uint8_t* destination, bool no_cache, Event*
2055  additional_action)
2056 {
2057  DPRINTF(UFSHostDevice, "Read start: 0x%8x; Size: %d, data[0]: 0x%8x\n",
2058  start, size, (reinterpret_cast<uint32_t *>(destination))[0]);
2059 
2061  if (lastTransfer) {
2062  ++readPendingNum;
2063  readDoneEvent.push_back(
2064  EventFunctionWrapper([this]{ readDone(); },
2065  name()));
2066  assert(!readDoneEvent.back().scheduled());
2067  dmaPort.dmaAction(MemCmd::WriteReq, start, size,
2068  &readDoneEvent.back(), destination, 0);
2069  //yes, a writereq at a read device function is correct.
2070 
2071  } else {
2072  if (additional_action != NULL)
2073  assert(!additional_action->scheduled());
2074 
2075  dmaPort.dmaAction(MemCmd::WriteReq, start, size,
2076  additional_action, destination, 0);
2077 
2078  }
2079 
2080 }
2081 
2087 void
2088 UFSHostDevice::manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t
2089  offset, uint32_t sg_table_length,
2090  struct UFSHCDSGEntry* sglist)
2091 {
2092  uint32_t size_accum = 0;
2093 
2094  DPRINTF(UFSHostDevice, "Data READ size: %d\n", size);
2095 
2100  for (uint32_t count = 0; count < sg_table_length; count++) {
2101  struct transferInfo new_transfer;
2102  new_transfer.offset = sglist[count].upperAddr;
2103  new_transfer.offset = (new_transfer.offset << 32) |
2104  (sglist[count].baseAddr & 0xFFFFFFFF);
2105  new_transfer.filePointer = offset + size_accum;
2106  new_transfer.size = (sglist[count].size + 1);
2107  new_transfer.lunID = LUN;
2108 
2109  DPRINTF(UFSHostDevice, "Data READ start: 0x%8x; size: %d\n",
2110  new_transfer.offset, new_transfer.size);
2111 
2112  UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
2113  UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[count].size
2114  + 1);
2115 
2121  UFSDevice[LUN]->readFlash(&UFSDevice[LUN]->
2122  SSDReadInfo.back().buffer[0],
2123  offset + size_accum,
2124  sglist[count].size + 1);
2125 
2126  size_accum += (sglist[count].size + 1);
2127 
2128  DPRINTF(UFSHostDevice, "Transfer %d; Remaining: 0x%8x, Accumulated:"
2129  " 0x%8x\n", (count + 1), (size-size_accum), size_accum);
2130 
2132  stats.totalReadSSD += (sglist[count].size + 1);
2133  stats.currentReadSSDQueue = UFSDevice[LUN]->SSDReadInfo.size();
2134  stats.averageReadSSDQueue = UFSDevice[LUN]->SSDReadInfo.size();
2135  }
2136 
2137  UFSDevice[LUN]->SSDReadStart(sg_table_length);
2138 
2140  ++stats.totalReadUFSTransactions;
2141 
2142 }
2143 
2144 
2145 
2152 void
2154 {
2155  totalRead = total_read;
2156  for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
2157  number_handled++) {
2162  flashDevice->readMemory(SSDReadInfo.front().filePointer,
2163  SSDReadInfo.front().size, memReadCallback);
2164  }
2165 
2166 }
2167 
2168 
2173 void
2175 {
2176  DPRINTF(UFSHostDevice, "SSD read done at lun %d, Aiming for %d messages,"
2177  " %d so far\n", lunID, totalRead, amountOfReadTransfers);
2178 
2179  if (totalRead == amountOfReadTransfers) {
2180  totalRead = 0;
2181  amountOfReadTransfers = 0;
2182 
2184  setSignal();
2185  signalDone();
2186  }
2187 
2188 }
2189 
2194 void
2196 {
2197  ++amountOfReadTransfers;
2198 
2202  setReadSignal();
2203  deviceReadCallback();
2204 
2205  //Are we done yet?
2206  SSDReadDone();
2207 }
2208 
2214 void
2216 {
2217  DPRINTF(UFSHostDevice, "Read Callback\n");
2218  uint8_t this_lun = 0;
2219 
2220  //while we haven't found the right lun, keep searching
2221  while ((this_lun < lunAvail) && !UFSDevice[this_lun]->finishedRead())
2222  ++this_lun;
2223 
2224  DPRINTF(UFSHostDevice, "Found LUN %d messages pending for clean: %d\n",
2225  this_lun, SSDReadPending.size());
2226 
2227  if (this_lun < lunAvail) {
2228  //Clear signal.
2229  UFSDevice[this_lun]->clearReadSignal();
2230  SSDReadPending.push_back(UFSDevice[this_lun]->SSDReadInfo.front());
2231  UFSDevice[this_lun]->SSDReadInfo.pop_front();
2232  readGarbageEventQueue.push_back(
2233  EventFunctionWrapper([this]{ readGarbage(); }, name()));
2234 
2235  //make sure the queue is popped a the end of the dma transaction
2236  readDevice(false, SSDReadPending.front().offset,
2237  SSDReadPending.front().size,
2238  &SSDReadPending.front().buffer[0], false,
2239  &readGarbageEventQueue.back());
2240 
2242  ++stats.totalReadDiskTransactions;
2243  }
2244  else
2245  panic("no read finished in tick %d\n", curTick());
2246 }
2247 
2252 void
2254 {
2255  DPRINTF(UFSHostDevice, "Clean read data, %d\n", SSDReadPending.size());
2256  SSDReadPending.pop_front();
2257  readGarbageEventQueue.pop_front();
2258 }
2259 
2264 void
2266 {
2268 
2269  const uint8_t* temp_HCI_mem = reinterpret_cast<const uint8_t*>(&UFSHCIMem);
2270  SERIALIZE_ARRAY(temp_HCI_mem, sizeof(HCIMem));
2271 
2272  uint32_t lun_avail = lunAvail;
2273  SERIALIZE_SCALAR(lun_avail);
2274 }
2275 
2276 
2281 void
2283 {
2285  uint8_t* temp_HCI_mem = reinterpret_cast<uint8_t*>(&UFSHCIMem);
2286  UNSERIALIZE_ARRAY(temp_HCI_mem, sizeof(HCIMem));
2287 
2288  uint32_t lun_avail;
2289  UNSERIALIZE_SCALAR(lun_avail);
2290  assert(lunAvail == lun_avail);
2291 }
2292 
2293 
2298 DrainState
2300 {
2301  if (UFSHCIMem.TRUTRLDBR) {
2302  DPRINTF(UFSHostDevice, "UFSDevice is draining...\n");
2303  return DrainState::Draining;
2304  } else {
2305  DPRINTF(UFSHostDevice, "UFSDevice drained\n");
2306  return DrainState::Drained;
2307  }
2308 }
2309 
2314 void
2316 {
2318  return;
2319 
2320  if (UFSHCIMem.TRUTRLDBR) {
2321  DPRINTF(UFSHostDevice, "UFSDevice is still draining; with %d active"
2322  " doorbells\n", activeDoorbells);
2323  } else {
2324  DPRINTF(UFSHostDevice, "UFSDevice is done draining\n");
2325  signalDrainDone();
2326  }
2327 }
UFSHostDevice::setValues
void setValues()
Initialization function.
Definition: ufs_device.cc:873
UFSHostDevice::UFSHostDeviceStats::totalWriteUFSTransactions
Stats::Scalar totalWriteUFSTransactions
Definition: ufs_device.hh:513
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
UFSHostDevice::HCIMem::TRUTRLDBR
uint32_t TRUTRLDBR
Definition: ufs_device.hh:221
UFSHostDevice::readDevice
void readDevice(bool lastTransfer, Addr SCSIStart, uint32_t SCSISize, uint8_t *SCSIDestination, bool no_cache, Event *additional_action)
Dma transaction function: read device.
Definition: ufs_device.cc:2053
UFSHostDevice::transferStart::size
uint32_t size
Definition: ufs_device.hh:455
ArmISA::status
Bitfield< 5, 0 > status
Definition: miscregs_types.hh:417
UFSHostDevice::LUNInfo::vendor0
uint32_t vendor0
Definition: ufs_device.hh:397
UFSHostDevice::HCIMem
Host Controller Interface This is a set of registers that allow the driver to control the transaction...
Definition: ufs_device.hh:188
UFSHostDevice::UFSSCSIDevice::SCSICMDHandle
struct SCSIReply SCSICMDHandle(uint32_t *SCSI_msg)
SCSI command handle function; determines what the command is and returns a reply structure that allow...
Definition: ufs_device.cc:157
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:462
UFSHostDevice::regControllerCapabilities
@ regControllerCapabilities
Definition: ufs_device.hh:1184
UFSHostDevice::transferStart::destination
struct UTPTransferReqDesc * destination
Definition: ufs_device.hh:452
UFSHostDevice::writeToDiskBurst
Disk transfer burst information.
Definition: ufs_device.hh:488
UFSHostDevice::gic
BaseGic * gic
Definition: ufs_device.hh:1005
UNIT_BYTE
#define UNIT_BYTE
Definition: units.hh:43
warn
#define warn(...)
Definition: logging.hh:239
UFSHostDevice::regUTPTaskREQListClear
@ regUTPTaskREQListClear
Definition: ufs_device.hh:1206
UFSHostDevice::commandHandler
void commandHandler()
Command handler function.
Definition: ufs_device.cc:1351
UFSHostDevice::SSDReadPending
std::deque< struct transferInfo > SSDReadPending
Information from the Disk, waiting to be pushed to the DMA.
Definition: ufs_device.hh:1116
UFSHostDevice::transferInfo
Different events, and scenarios require different types of information.
Definition: ufs_device.hh:425
data
const char data[]
Definition: circlebuf.test.cc:47
UFSHostDevice::LUNInfo::dWord1
uint32_t dWord1
Definition: ufs_device.hh:396
UFSHostDevice::transferStart
void transferStart()
Transfer Start function.
Definition: ufs_device.cc:1331
UFSHostDevice::SCSIResumeInfo::finalSize
uint32_t finalSize
Definition: ufs_device.hh:479
UFSHostDevice::intNum
const int intNum
Definition: ufs_device.hh:1004
UFSHostDevice::UTPUPIUHeader::dWord0
uint32_t dWord0
Definition: ufs_device.hh:257
UFSHostDevice::UFSSCSIDevice::readFlash
void readFlash(uint8_t *readaddr, uint64_t offset, uint32_t size)
Disk access functions.
Definition: ufs_device.cc:688
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:591
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:755
UFSHostDevice::UFSHCDSGEntry
struct UFSHCDSGEntry - UFSHCI PRD Entry baseAddr: Lower 32bit physical address DW-0 upperAddr: Upper ...
Definition: ufs_device.hh:301
UFSHostDevice::regUICCommand
@ regUICCommand
Definition: ufs_device.hh:1208
UFSHostDevice::SCSIResumeInfo::finalAddress
Addr finalAddress
Definition: ufs_device.hh:478
UFSHostDevice::SCSIResumeInfo::done
uint32_t done
Definition: ufs_device.hh:481
UFSHostDevice::pendingDoorbells
uint8_t pendingDoorbells
Definition: ufs_device.hh:1030
UFSHostDevice::UFSSCSIDevice::SSDWriteStart
void SSDWriteStart()
SSD write start.
Definition: ufs_device.cc:2004
UFSHostDevice::UFSSCSIDevice::memWriteCallback
Callback memWriteCallback
Definition: ufs_device.hh:738
UFSHostDevice::regUTPTaskREQListRunStop
@ regUTPTaskREQListRunStop
Definition: ufs_device.hh:1207
UFSHostDevice::HCIMem::TRUTRLCLR
uint32_t TRUTRLCLR
Definition: ufs_device.hh:222
SectorSize
#define SectorSize
Definition: disk_image.hh:44
UFSHostDevice::UFSHostDeviceStats::transactionLatency
Stats::Histogram transactionLatency
Histogram of latencies.
Definition: ufs_device.hh:530
UFSHostDevice::writeToDiskBurst::SCSIDiskOffset
uint64_t SCSIDiskOffset
Definition: ufs_device.hh:490
ClockedObject::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: clocked_object.cc:56
UFSHostDevice::HCIMem::ORInterruptStatus
uint32_t ORInterruptStatus
Operation and runtime registers.
Definition: ufs_device.hh:200
UFSHostDevice::HCIMem::ORHostControllerStatus
uint32_t ORHostControllerStatus
Definition: ufs_device.hh:202
UFSHostDevice::transferStartInfo
std::deque< struct transferStart > transferStartInfo
Definition: ufs_device.hh:1101
UFSHostDevice::UFSSCSIDevice::SSDReadStart
void SSDReadStart(uint32_t total_read)
Start the transactions to (and from) the disk The host will queue all the transactions.
Definition: ufs_device.cc:2153
UFSHostDevice::UFSDevice
std::vector< UFSSCSIDevice * > UFSDevice
logic units connected to the UFS Host device Note again that the "device" as such is represented by o...
Definition: ufs_device.hh:1065
UFSHostDevice::regUTPTaskREQListBaseH
@ regUTPTaskREQListBaseH
Definition: ufs_device.hh:1204
UFSHostDevice::UFSSCSIDevice::signalDone
Callback signalDone
Callbacks between Host and Device.
Definition: ufs_device.hh:731
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:83
UFSHostDevice::HCIMem::ORUECPA
uint32_t ORUECPA
Definition: ufs_device.hh:204
UNIT_TICK
#define UNIT_TICK
Definition: units.hh:40
UFSHostDevice::HCIMem::ORUECDME
uint32_t ORUECDME
Definition: ufs_device.hh:208
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
UFSHostDevice::UTPTransferREQCOMPL
static const unsigned int UTPTransferREQCOMPL
Bits of interest within UFS data packages.
Definition: ufs_device.hh:1173
UFSHostDevice::HCIMem::CMDUCMDARG2
uint32_t CMDUCMDARG2
Definition: ufs_device.hh:239
UFSHostDevice::UFSHCIMem
HCIMem UFSHCIMem
Host controller memory.
Definition: ufs_device.hh:1012
UFSHostDevice::regUTPTaskREQDoorbell
@ regUTPTaskREQDoorbell
Definition: ufs_device.hh:1205
UFSHostDevice::HCIMem::ORUECT
uint32_t ORUECT
Definition: ufs_device.hh:207
UFSHostDevice::UFSSCSIDevice::SSDReadDone
void SSDReadDone()
SSD Read done; Determines if the final callback of the transaction should be made at the end of a rea...
Definition: ufs_device.cc:2174
UFSHostDevice::readCallback
void readCallback()
Read callback Call back function for the logic units to indicate the completion of a read action.
Definition: ufs_device.cc:2215
UFSHostDevice::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize; needed to restore from checkpoints.
Definition: ufs_device.cc:2282
UFSHostDevice::pioSize
const Addr pioSize
Definition: ufs_device.hh:1002
UFSHostDevice::UFSHostDevice
UFSHostDevice(const UFSHostDeviceParams &p)
Constructor for the UFS Host device.
Definition: ufs_device.cc:715
UFSHostDevice::UICCommandCOMPL
static const unsigned int UICCommandCOMPL
Definition: ufs_device.hh:1175
UFSHostDevice::HCIMem::ORHostControllerEnable
uint32_t ORHostControllerEnable
Definition: ufs_device.hh:203
UFSHostDevice::UFSHostDeviceStats::totalReadSSD
Stats::Scalar totalReadSSD
Amount of data read/written.
Definition: ufs_device.hh:508
UFSHostDevice::drain
DrainState drain() override
Drain; needed to enable checkpoints.
Definition: ufs_device.cc:2299
Packet::getSize
unsigned getSize() const
Definition: packet.hh:765
X86ISA::count
count
Definition: misc.hh:703
UFSHostDevice::writeToDiskBurst::LUN
uint32_t LUN
Definition: ufs_device.hh:492
UFSHostDevice::SSDWriteinfo
std::deque< struct transferInfo > SSDWriteinfo
Information from DMA transaction to disk.
Definition: ufs_device.hh:1111
UFSHostDevice::UFSHostDeviceStats::maxDoorbell
Stats::Scalar maxDoorbell
Definition: ufs_device.hh:526
UFSHostDevice::transferEventQueue
std::deque< EventFunctionWrapper > transferEventQueue
Definition: ufs_device.hh:1168
UFSHostDevice::regUICErrorCodeDME
@ regUICErrorCodeDME
Definition: ufs_device.hh:1196
UFSHostDevice::writeDevice
void writeDevice(Event *additional_action, bool toDisk, Addr start, int size, uint8_t *destination, uint64_t SCSIDiskOffset, uint32_t lun_id)
DMA transfer functions These allow the host to push/pull the data to the memory The provided event in...
Definition: ufs_device.cc:1847
UFSHostDevice::idlePhaseStart
Tick idlePhaseStart
Definition: ufs_device.hh:1058
UFSHostDevice::SCSIStart
void SCSIStart()
Transfer SCSI function.
Definition: ufs_device.cc:1444
UFSHostDevice::UFSSCSIDevice::~UFSSCSIDevice
~UFSSCSIDevice()
Definition: ufs_device.cc:143
UFSHostDevice::writePendingNum
int writePendingNum
Definition: ufs_device.hh:1018
Stats::none
const FlagsType none
Nothing extra to print.
Definition: info.hh:44
UFSHostDevice::readGarbage
void readGarbage()
Read garbage A read from disk data structure can vary in size and is therefor allocated on creation.
Definition: ufs_device.cc:2253
UFSHostDevice::HCIMem::TRUTRLBA
uint32_t TRUTRLBA
Transfer control registers.
Definition: ufs_device.hh:219
UFSHostDevice::UTPUPIUHeader::dWord2
uint32_t dWord2
Definition: ufs_device.hh:259
UFSHostDevice::UFSSCSIDevice::UFSSCSIDevice
UFSSCSIDevice(const UFSHostDeviceParams &p, uint32_t lun_id, const Callback &transfer_cb, const Callback &read_cb)
Constructor and destructor.
Definition: ufs_device.cc:75
UFSHostDevice::SCSIResumeInfo::RequestIn
struct UTPTransferReqDesc * RequestIn
Definition: ufs_device.hh:476
UFSHostDevice::writeDoneEvent
std::deque< EventFunctionWrapper > writeDoneEvent
Definition: ufs_device.hh:1138
UFSHostDevice::taskStart::address
Addr address
Definition: ufs_device.hh:466
UFSHostDevice::regControllerEnable
@ regControllerEnable
Definition: ufs_device.hh:1191
UFSHostDevice::readDoneEvent
std::deque< EventFunctionWrapper > readDoneEvent
Transfer flow events Basically these events form two queues, one from memory to UFS device (DMA) and ...
Definition: ufs_device.hh:1137
UFSHostDevice::SCSIReply::message
struct UPIUMessage message
Definition: ufs_device.hh:382
EventFunctionWrapper
Definition: eventq.hh:1112
UFSHostDevice::taskHandler
void taskHandler(struct UTPUPIUTaskReq *request_in, uint32_t req_pos, Addr finaladdress, uint32_t finalsize)
Task handler function.
Definition: ufs_device.cc:1365
UFSHostDevice::HCIMem::HCCAP
uint32_t HCCAP
Specify the host capabilities.
Definition: ufs_device.hh:192
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:339
DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
UFSHostDevice::regUICErrorCodePHYAdapterLayer
@ regUICErrorCodePHYAdapterLayer
Definition: ufs_device.hh:1192
DmaDevice::dmaPort
DmaPort dmaPort
Definition: dma_device.hh:203
UFSHostDevice::SCSIReply::expectMore
uint8_t expectMore
Definition: ufs_device.hh:384
UFSHostDevice::writeToDiskBurst::size
uint32_t size
Definition: ufs_device.hh:491
MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:86
UFSHostDevice::HCIMem::TMUTMRLDBR
uint32_t TMUTMRLDBR
Definition: ufs_device.hh:230
DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:71
UFSHostDevice::UFSHostDeviceStats::averageSCSIQueue
Stats::Average averageSCSIQueue
Average Queue lengths.
Definition: ufs_device.hh:520
UFSHostDevice::UTPUPIURSP
struct UTPUPIURSP - Response UPIU structure header: UPIU header DW-0 to DW-2 residualTransferCount: R...
Definition: ufs_device.hh:270
UFSHostDevice::UFSSCSIDevice::SSDWriteDone
void SSDWriteDone()
SSD Write Done; This is the callback function for the memory model.
Definition: ufs_device.cc:2023
cp
Definition: cprintf.cc:37
UFSHostDevice::countInt
uint32_t countInt
interrupt verification This keeps track of the number of interrupts generated.
Definition: ufs_device.hh:1039
UFSHostDevice::UTPUPIUTaskReq
struct UTPUPIUTaskReq - Task request UPIU structure header - UPIU header structure DW0 to DW-2 inputP...
Definition: ufs_device.hh:286
UFSHostDevice::UFSHostDeviceStats::idleTimes
Stats::Histogram idleTimes
Definition: ufs_device.hh:531
UFSHostDevice::transferStart::done
uint32_t done
Definition: ufs_device.hh:456
UFSHostDevice::serialize
void serialize(CheckpointOut &cp) const override
Serialize; needed to make checkpoints.
Definition: ufs_device.cc:2265
UFSHostDevice::SCSIReply::LUN
uint8_t LUN
Definition: ufs_device.hh:381
UFSHostDevice::HCIMem::TMUTMRLBAU
uint32_t TMUTMRLBAU
Definition: ufs_device.hh:229
UFSHostDevice::UFSHostDeviceStats::averageReadSSDQueue
Stats::Average averageReadSSDQueue
Definition: ufs_device.hh:521
UFSHostDevice::LUNInfo::product0
uint32_t product0
Definition: ufs_device.hh:399
UFSHostDevice::UFSHostDeviceStats::averageWriteSSDQueue
Stats::Average averageWriteSSDQueue
Definition: ufs_device.hh:522
UFSHostDevice::UFSSCSIDevice::deviceReadCallback
Callback deviceReadCallback
Definition: ufs_device.hh:732
UFSHostDevice::UFSHostDeviceStats::currentSCSIQueue
Stats::Scalar currentSCSIQueue
Queue lengths.
Definition: ufs_device.hh:503
Event
Definition: eventq.hh:248
UFSHostDevice::writeDone
void writeDone()
Write done After a DMA write with data intended for the disk, this function is called.
Definition: ufs_device.cc:1958
UFSHostDevice::UTPTransferReqDesc::responseUPIULength
uint16_t responseUPIULength
Definition: ufs_device.hh:362
Packet::getUintX
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:350
UFSHostDevice::taskStart
void taskStart()
Task Start function.
Definition: ufs_device.cc:1317
UFSHostDevice::requestHandler
void requestHandler()
Handler functions.
Definition: ufs_device.cc:1198
UFSHostDevice::request_out_datain
struct SCSIReply request_out_datain
SCSI reply structure, used for direct answering.
Definition: ufs_device.hh:1072
UFSHostDevice::checkDrain
void checkDrain()
Checkdrain; needed to enable checkpoints.
Definition: ufs_device.cc:2315
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
UFSHostDevice::UFSSCSIDevice::readCallback
void readCallback()
Functions to indicate that the action to the SSD has completed.
Definition: ufs_device.cc:2195
UFSHostDevice::HCIMem::CMDUCMDARG3
uint32_t CMDUCMDARG3
Definition: ufs_device.hh:240
UFSHostDevice::UTPTransferReqDesc::commandDescBaseAddrHi
uint32_t commandDescBaseAddrHi
Definition: ufs_device.hh:359
UFSHostDevice::UFSSCSIDevice::lunID
const uint32_t lunID
Definition: ufs_device.hh:706
UFSHostDevice::UFSSCSIDevice::memReadCallback
Callback memReadCallback
Callbacks between Device and Memory.
Definition: ufs_device.hh:737
UFSHostDevice::regUICErrorCodeDataLinkLayer
@ regUICErrorCodeDataLinkLayer
Definition: ufs_device.hh:1193
UFSHostDevice::UFSSCSIDevice::recoveryPage
static const unsigned int recoveryPage[3]
Definition: ufs_device.hh:755
UFSHostDevice::LUNInfo::product1
uint32_t product1
Definition: ufs_device.hh:400
UFSHostDevice::UFSSCSIDevice::diskSize
const uint64_t diskSize
Definition: ufs_device.hh:697
UFSHostDevice::SCSIReply
SCSI reply structure.
Definition: ufs_device.hh:374
UFSHostDevice::HCIMem::TRUTRLRSR
uint32_t TRUTRLRSR
Definition: ufs_device.hh:223
UFSHostDevice::activeDoorbells
uint8_t activeDoorbells
Statistics helper variables Active doorbells indicates how many doorbells are in teh process of being...
Definition: ufs_device.hh:1029
UFSHostDevice::SCSIReply::status
uint8_t status
Definition: ufs_device.hh:379
UFSHostDevice::UPIUMessage::header
struct UTPUPIUHeader header
Definition: ufs_device.hh:325
UFSHostDevice::HCIMem::ORInterruptEnable
uint32_t ORInterruptEnable
Definition: ufs_device.hh:201
UFSHostDevice::dmaWriteInfo
std::deque< struct writeToDiskBurst > dmaWriteInfo
Information to get a DMA transaction.
Definition: ufs_device.hh:1106
UFSHostDevice
UFS command flow state machine digraph CommandFlow{ node [fontsize=10]; IDLE -> transferHandler [ lab...
Definition: ufs_device.hh:169
UFSHostDevice::lunAvail
const uint32_t lunAvail
Definition: ufs_device.hh:1006
RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:651
UFSHostDevice::UFSHostDeviceStats::averageWriteSSDBW
Stats::Formula averageWriteSSDBW
Definition: ufs_device.hh:517
Stats::Group::stats
std::vector< Info * > stats
Definition: group.hh:215
UFSHostDevice::UTPTransferReqDesc::PRDTableOffset
uint16_t PRDTableOffset
Definition: ufs_device.hh:367
UFSHostDevice::UFSSCSIDevice::statusCheck
void statusCheck(uint8_t status, uint8_t *sensecodelist)
Status of SCSI.
Definition: ufs_device.cc:671
UFSHostDevice::regUTPTransferREQListRunStop
@ regUTPTransferREQListRunStop
Definition: ufs_device.hh:1202
UFSHostDevice::UTPTransferReqDesc::RequestDescHeader::dWord0
uint32_t dWord0
Definition: ufs_device.hh:351
Drainable::signalDrainDone
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:301
UFSHostDevice::transferTrack
uint32_t transferTrack
Track the transfer This is allows the driver to "group" certain transfers together by using a tag in ...
Definition: ufs_device.hh:1049
UFSHostDevice::UFSHostDeviceStats::totalReadUFSTransactions
Stats::Scalar totalReadUFSTransactions
Definition: ufs_device.hh:512
UFSHostDevice::HCIMem::TMUTMRLRSR
uint32_t TMUTMRLRSR
Definition: ufs_device.hh:232
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:626
UFSHostDevice::taskEventQueue
std::deque< EventFunctionWrapper > taskEventQueue
Multiple tasks transfers can be scheduled at once for the device, the only thing we know for sure abo...
Definition: ufs_device.hh:1167
UFSHostDevice::UFSHostDeviceStats::averageReadSSDBW
Stats::Formula averageReadSSDBW
Average bandwidth for reads and writes.
Definition: ufs_device.hh:516
UFSHostDevice::regInterruptEnable
@ regInterruptEnable
Definition: ufs_device.hh:1189
UFSHostDevice::SCSIReply::reset
void reset()
Definition: ufs_device.hh:375
UFSHostDevice::getAddrRanges
AddrRangeList getAddrRanges() const override
Address range functions.
Definition: ufs_device.cc:900
UFSHostDevice::taskInfo
std::deque< struct taskStart > taskInfo
When a task/transfer is started it needs information about the task/transfer it is about to perform.
Definition: ufs_device.hh:1100
UFSHostDevice::transferStart::address
Addr address
Definition: ufs_device.hh:454
UFSHostDevice::regUICCommandArg1
@ regUICCommandArg1
Definition: ufs_device.hh:1209
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
UFSHostDevice::transferStart
Transfer start information.
Definition: ufs_device.hh:451
UFSHostDevice::taskStart::done
bool done
Definition: ufs_device.hh:468
UFSHostDevice::taskStart::mask
uint32_t mask
Definition: ufs_device.hh:465
UFSHostDevice::taskStart::size
uint32_t size
Definition: ufs_device.hh:467
UFSHostDevice::readDone
void readDone()
Read done Started at the end of a transaction after the last read action.
Definition: ufs_device.cc:1758
UFSHostDevice::finalUTP
void finalUTP()
final UTP, sends the last acknowledge data structure to the system; prepares the clean up functions.
Definition: ufs_device.cc:1712
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
betoh
T betoh(T value)
Definition: byteswap.hh:144
UFSHostDevice::regUTPTaskREQListBaseL
@ regUTPTaskREQListBaseL
Definition: ufs_device.hh:1203
UFSHostDevice::UFSHostDeviceStats::UFSHostDeviceStats
UFSHostDeviceStats(UFSHostDevice *parent)
Amount of data read/written.
Definition: ufs_device.cc:757
UFSHostDevice::regUTPTransferREQDoorbell
@ regUTPTransferREQDoorbell
Definition: ufs_device.hh:1200
Packet::makeResponse
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1005
UFSHostDevice::transactionStart
Tick transactionStart[32]
Helper for latency stats These variables keep track of the latency for every doorbell.
Definition: ufs_device.hh:1057
simSeconds
Stats::Formula & simSeconds
Definition: stats.cc:42
UFSHostDevice::UFSHCDSGEntry::size
uint32_t size
Definition: ufs_device.hh:305
UFSHostDevice::HCIMem::HCversion
uint32_t HCversion
Definition: ufs_device.hh:193
UFSHostDevice::UFSSCSIDevice::lunInfo
struct LUNInfo lunInfo
Logic unit info; needed for SCSI Info messages and LU identification.
Definition: ufs_device.hh:705
UFSHostDevice::UFSHostDeviceStats::currentReadSSDQueue
Stats::Scalar currentReadSSDQueue
Definition: ufs_device.hh:504
name
const std::string & name()
Definition: trace.cc:48
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:584
UFSHostDevice::pioDelay
const Tick pioDelay
Definition: ufs_device.hh:1003
UFSHostDevice::UFSSCSIDevice::controlPage
static const unsigned int controlPage[3]
These pages are SCSI specific.
Definition: ufs_device.hh:754
UFSHostDevice::transferInfo::offset
uint64_t offset
Definition: ufs_device.hh:428
UFSHostDevice::UTPTransferReqDesc::PRDTableLength
uint16_t PRDTableLength
Definition: ufs_device.hh:366
UFSHostDevice::UTPEvent
EventFunctionWrapper UTPEvent
Wait for the moment where we can send the last frame.
Definition: ufs_device.hh:1155
LaneSize::Byte
@ Byte
UFSHostDevice::manageWriteTransfer
void manageWriteTransfer(uint8_t LUN, uint64_t offset, uint32_t sg_table_length, struct UFSHCDSGEntry *sglist)
Disk transfer management functions these set up the queues, and initiated them, leading to the data t...
Definition: ufs_device.cc:1899
UFSHostDevice::readPendingNum
int readPendingNum
Track number of DMA transactions in progress.
Definition: ufs_device.hh:1017
Stats::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:58
UFSHostDevice::UFSHostDeviceStats::curDoorbell
Stats::Formula curDoorbell
Number of doorbells rung.
Definition: ufs_device.hh:525
UFSHostDevice::transferInfo::size
uint32_t size
Definition: ufs_device.hh:427
BaseGic::sendInt
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
UFSHostDevice::regUICErrorCodeNetworkLayer
@ regUICErrorCodeNetworkLayer
Definition: ufs_device.hh:1194
UFSHostDevice::LUNInfo::product3
uint32_t product3
Definition: ufs_device.hh:402
UFSHostDevice::UFSSCSIDevice::lunAvail
const uint32_t lunAvail
Definition: ufs_device.hh:696
UFSHostDevice::regControllerPRODID
@ regControllerPRODID
Definition: ufs_device.hh:1187
UFSHostDevice::UFSSCSIDevice::flashDevice
AbstractNVM * flashDevice
Definition: ufs_device.hh:690
UFSHostDevice::regUICCommandArg2
@ regUICCommandArg2
Definition: ufs_device.hh:1210
UFSHostDevice::pioAddr
const Addr pioAddr
Host controller information.
Definition: ufs_device.hh:1001
Drainable::drainState
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:320
UFSHostDevice::LUNInfo::vendor1
uint32_t vendor1
Definition: ufs_device.hh:398
DmaPort::dmaAction
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
Definition: dma_device.cc:193
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
BaseGic::clearInt
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
AbstractNVM::initializeMemory
virtual void initializeMemory(uint64_t disk_size, uint32_t sector_size)=0
Initialize Memory.
UFSHostDevice::HCIMem::CMDUCMDARG1
uint32_t CMDUCMDARG1
Definition: ufs_device.hh:238
UFSHostDevice::UFSHCDSGEntry::upperAddr
uint32_t upperAddr
Definition: ufs_device.hh:303
UNIT_RATE
#define UNIT_RATE(T1, T2)
Definition: units.hh:47
UFSHostDevice::HCIMem::HCHCDDID
uint32_t HCHCDDID
Definition: ufs_device.hh:194
UFSHostDevice::regUTPTransferREQListBaseL
@ regUTPTransferREQListBaseL
Definition: ufs_device.hh:1198
UFSHostDevice::transferStart::lun_id
uint32_t lun_id
Definition: ufs_device.hh:457
UFSHostDevice::taskCommandTrack
uint32_t taskCommandTrack
Definition: ufs_device.hh:1050
UFSHostDevice::SCSIReply::senseSize
uint8_t senseSize
Definition: ufs_device.hh:383
UFSHostDevice::generateInterrupt
void generateInterrupt()
set interrupt and sort out the doorbell register.
Definition: ufs_device.cc:1786
UFSHostDevice::UTPTransferReqDesc::commandDescBaseAddrLo
uint32_t commandDescBaseAddrLo
Definition: ufs_device.hh:358
UFSHostDevice::SCSIResumeInfo::reqPos
int reqPos
Definition: ufs_device.hh:477
DmaDevice
Definition: dma_device.hh:200
inform
#define inform(...)
Definition: logging.hh:240
UFSHostDevice::UTPUPIUTaskReq::header
struct UTPUPIUHeader header
Definition: ufs_device.hh:287
UFSHostDevice::transferHandler
void transferHandler(struct UTPTransferReqDesc *request_in, int req_pos, Addr finaladdress, uint32_t finalsize, uint32_t done)
Transfer handler function.
Definition: ufs_device.cc:1401
UFSHostDevice::HCIMem::ORUECN
uint32_t ORUECN
Definition: ufs_device.hh:206
UFSHostDevice::regControllerStatus
@ regControllerStatus
Definition: ufs_device.hh:1190
UFSHostDevice::UTPTransferReqDesc::header
struct UFSHostDevice::UTPTransferReqDesc::RequestDescHeader header
UFSHostDevice::taskStart
Task start information.
Definition: ufs_device.hh:463
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:634
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:52
UFSHostDevice::transferInfo::lunID
uint32_t lunID
Definition: ufs_device.hh:430
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
UFSHostDevice::HCIMem::HCHCPMID
uint32_t HCHCPMID
Definition: ufs_device.hh:195
UFSHostDevice::HCIMem::CMDUICCMDR
uint32_t CMDUICCMDR
Command registers.
Definition: ufs_device.hh:237
UFSHostDevice::regUTPTransferREQListClear
@ regUTPTransferREQListClear
Definition: ufs_device.hh:1201
UFSHostDevice::clearInterrupt
void clearInterrupt()
Interrupt control functions.
Definition: ufs_device.cc:1809
UFSHostDevice::stats
struct UFSHostDeviceStats stats
RequestHandler stats.
Definition: ufs_device.hh:1126
UFSHostDevice::UFSSCSIDevice::cachingPage
static const unsigned int cachingPage[5]
Definition: ufs_device.hh:756
UFSHostDevice::read
Tick read(PacketPtr pkt) override
register access functions
Definition: ufs_device.cc:913
ClockedObject::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: clocked_object.cc:61
UFSHostDevice::UFSHostDeviceStats::totalReadDiskTransactions
Stats::Scalar totalReadDiskTransactions
Definition: ufs_device.hh:510
UFSHostDevice::write
Tick write(PacketPtr pkt) override
UFSHCD write function.
Definition: ufs_device.cc:1051
UFSHostDevice::transferInfo::filePointer
uint32_t filePointer
Definition: ufs_device.hh:429
UFSHostDevice::UFSHostDeviceStats::totalWrittenSSD
Stats::Scalar totalWrittenSSD
Definition: ufs_device.hh:509
UFSHostDevice::UPIUMessage::dataCount
uint32_t dataCount
Definition: ufs_device.hh:327
UFSHostDevice::HCIMem::TRUTRLBAU
uint32_t TRUTRLBAU
Definition: ufs_device.hh:220
UFSHostDevice::HCIMem::ORUECDL
uint32_t ORUECDL
Definition: ufs_device.hh:205
Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:105
UFSHostDevice::HCIMem::TMUTMRLCLR
uint32_t TMUTMRLCLR
Definition: ufs_device.hh:231
UFSHostDevice::SCSIResumeInfo::destination
std::vector< uint8_t > destination
Definition: ufs_device.hh:480
UFSHostDevice::SCSIReply::offset
uint64_t offset
Definition: ufs_device.hh:385
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
UFSHostDevice::UPIUMessage::dataMsg
std::vector< uint32_t > dataMsg
Definition: ufs_device.hh:328
findLsbSet
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
Definition: bitfield.hh:276
UFSHostDevice::transferDone
void transferDone(Addr responseStartAddr, uint32_t req_pos, struct UTPUPIURSP request_out, uint32_t size, Addr address, uint8_t *destination, bool finished, uint32_t lun_id)
transfer done, the beginning of the final stage of the transfer.
Definition: ufs_device.cc:1673
UFSHostDevice::LUNInfo::productRevision
uint32_t productRevision
Definition: ufs_device.hh:403
UFSHostDevice::garbage
std::deque< struct UTPTransferReqDesc * > garbage
garbage queue, ensure clearing of the allocated memory
Definition: ufs_device.hh:1121
Stats
Definition: statistics.cc:53
UFSHostDevice::regUTPTransferREQListBaseH
@ regUTPTransferREQListBaseH
Definition: ufs_device.hh:1199
UFSHostDevice::LUNInfo::product2
uint32_t product2
Definition: ufs_device.hh:401
UFSHostDevice::UICCommandReady
static const unsigned int UICCommandReady
Definition: ufs_device.hh:1176
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
UFSHostDevice::UFSHostDeviceStats::averageDoorbell
Stats::Average averageDoorbell
Definition: ufs_device.hh:527
UFSHostDevice::SCSIReply::senseCode
uint8_t senseCode[19]
Definition: ufs_device.hh:386
UFSHostDevice::HCIMem::TMUTMRLBA
uint32_t TMUTMRLBA
Task control registers.
Definition: ufs_device.hh:228
UFSHostDevice::readGarbageEventQueue
std::deque< EventFunctionWrapper > readGarbageEventQueue
Event after a read to clean up the UTP data structures.
Definition: ufs_device.hh:1160
UFSHostDevice::UTPTransferReqDesc::RequestDescHeader::dWord2
uint32_t dWord2
Definition: ufs_device.hh:353
Stats::Histogram::init
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2153
UFSHostDevice::regInterruptStatus
@ regInterruptStatus
Definition: ufs_device.hh:1188
UFSHostDevice::LUNSignal
void LUNSignal()
LU callback function to indicate that the action has completed.
Definition: ufs_device.cc:1641
UFSHostDevice::transferStart::mask
uint32_t mask
Definition: ufs_device.hh:453
UFSHostDevice::SCSIResume
void SCSIResume(uint32_t lun_id)
Starts the scsi handling function in the apropriate Logic unit, prepares the right data transfer sche...
Definition: ufs_device.cc:1489
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
std::list< AddrRange >
UFSHostDevice::UFSHostDeviceStats::totalWriteDiskTransactions
Stats::Scalar totalWriteDiskTransactions
Definition: ufs_device.hh:511
UFSHostDevice::UFSSCSIDevice::Callback
std::function< void()> Callback
Definition: ufs_device.hh:542
CheckpointIn
Definition: serialize.hh:68
X86ISA::destination
destination
Definition: intmessage.hh:43
UFSHostDevice::SCSIInfo
struct SCSIResumeInfo SCSIInfo
SCSI resume info information structure for SCSI resume.
Definition: ufs_device.hh:1080
ufs_device.hh
UFSHostDevice::regUFSVersion
@ regUFSVersion
Definition: ufs_device.hh:1185
UFSHostDevice::UTPTransferReqDesc
struct UTPTransferReqDesc - UTRD structure header: UTRD header DW-0 to DW-3 commandDescBaseAddrLo: UC...
Definition: ufs_device.hh:341
UFSHostDevice::regUTPTransferREQINTAGGControl
@ regUTPTransferREQINTAGGControl
Definition: ufs_device.hh:1197
UFSHostDevice::SCSIResumeEvent
EventFunctionWrapper SCSIResumeEvent
The events that control the functionality.
Definition: ufs_device.hh:1150
UFSHostDevice::regControllerDEVID
@ regControllerDEVID
Definition: ufs_device.hh:1186
UFSHostDevice::HCIMem::ORUTRIACR
uint32_t ORUTRIACR
Definition: ufs_device.hh:209
UFSHostDevice::regUICErrorCodeTransportLayer
@ regUICErrorCodeTransportLayer
Definition: ufs_device.hh:1195
UFSHostDevice::LUNInfo::dWord0
uint32_t dWord0
Definition: ufs_device.hh:395
UFSHostDevice::UTPUPIUHeader::dWord1
uint32_t dWord1
Definition: ufs_device.hh:258
UFSHostDevice::UTPTaskREQCOMPL
static const unsigned int UTPTaskREQCOMPL
Definition: ufs_device.hh:1174
UFSHostDevice::manageReadTransfer
void manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t offset, uint32_t sg_table_length, struct UFSHCDSGEntry *sglist)
Manage read transfer.
Definition: ufs_device.cc:2088
UFSHostDevice::UFSHostDeviceStats::currentWriteSSDQueue
Stats::Scalar currentWriteSSDQueue
Definition: ufs_device.hh:505
DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
UFSHostDevice::regUICCommandArg3
@ regUICCommandArg3
Definition: ufs_device.hh:1211
ArmISA::mask
Bitfield< 28, 24 > mask
Definition: miscregs_types.hh:711
UFSHostDevice::UFSSCSIDevice::writeFlash
void writeFlash(uint8_t *writeaddr, uint64_t offset, uint32_t size)
Write flash.
Definition: ufs_device.cc:702
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
UFSHostDevice::writeToDiskBurst::start
Addr start
Definition: ufs_device.hh:489
UFSHostDevice::SCSIReply::msgSize
uint32_t msgSize
Definition: ufs_device.hh:380
UFSHostDevice::transferEnd
std::deque< struct transferStart > transferEnd
To finish the transaction one needs information about the original message.
Definition: ufs_device.hh:1089
UFSHostDevice::UFSSlots
const uint8_t UFSSlots
Definition: ufs_device.hh:1007
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:141

Generated on Tue Jun 22 2021 15:28:27 for gem5 by doxygen 1.8.17