Go to the documentation of this file.
76 uint32_t lun_id,
const Callback &transfer_cb,
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),
87 transferCompleted(false),
91 amountOfWriteTransfers(0),
92 amountOfReadTransfers(0)
108 uint32_t temp_id = ((lun_id | 0x30) << 24) | 0x3A4449;
133 {0x01400A0A, 0x00000000,
136 {0x03800A01, 0x00000000,
139 {0x00011208, 0x00000000,
140 0x00000000, 0x00000020,
170 statusCheck(SCSIGood, scsi_out.
senseCode);
172 scsi_out.
LUN = lunID;
173 scsi_out.
status = SCSIGood;
178 switch (SCSI_msg[4] & 0xFF) {
189 (
reinterpret_cast<uint32_t*
> (&lunInfo))[
count];
199 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
205 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(tempptr);
206 uint64_t read_offset =
betoh(tmp) & 0x1FFFFF;
208 uint32_t read_size = tempptr[4];
211 scsi_out.
msgSize = read_size * blkSize;
212 scsi_out.
offset = read_offset * blkSize;
214 if ((read_offset + read_size) > diskSize)
215 scsi_out.
status = SCSIIllegalRequest;
218 read_offset, read_size);
225 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
234 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
237 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
238 uint64_t read_offset =
betoh(tmp);
240 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
241 uint32_t read_size =
betoh(tmpsize);
243 scsi_out.
msgSize = read_size * blkSize;
244 scsi_out.
offset = read_offset * blkSize;
246 if ((read_offset + read_size) > diskSize)
247 scsi_out.
status = SCSIIllegalRequest;
250 read_offset, read_size);
257 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
266 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
269 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
270 uint64_t read_offset =
betoh(tmp);
272 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[6]);
273 read_offset = (read_offset << 32) |
betoh(tmp);
275 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[10]);
276 uint32_t read_size =
betoh(tmp);
278 scsi_out.
msgSize = read_size * blkSize;
279 scsi_out.
offset = read_offset * blkSize;
281 if ((read_offset + read_size) > diskSize)
282 scsi_out.
status = SCSIIllegalRequest;
285 read_offset, read_size);
292 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
297 case SCSIReadCapacity10: {
304 betoh(capacityLower);
308 case SCSIReadCapacity16: {
312 betoh(capacityUpper);
314 betoh(capacityLower);
324 case SCSIReportLUNs: {
341 case SCSIStartStop: {
347 case SCSITestUnitReady: {
360 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
363 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
364 uint64_t read_offset =
betoh(tmp);
366 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
367 uint32_t read_size =
betoh(tmpsize);
369 if ((read_offset + read_size) > diskSize)
370 scsi_out.
status = SCSIIllegalRequest;
377 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
387 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
393 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(tempptr);
394 uint64_t write_offset =
betoh(tmp) & 0x1FFFFF;
396 uint32_t write_size = tempptr[4];
398 scsi_out.
msgSize = write_size * blkSize;
399 scsi_out.
offset = write_offset * blkSize;
402 if ((write_offset + write_size) > diskSize)
403 scsi_out.
status = SCSIIllegalRequest;
406 write_offset, write_size);
413 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
419 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
422 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
423 uint64_t write_offset =
betoh(tmp);
425 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
426 uint32_t write_size =
betoh(tmpsize);
428 scsi_out.
msgSize = write_size * blkSize;
429 scsi_out.
offset = write_offset * blkSize;
432 if ((write_offset + write_size) > diskSize)
433 scsi_out.
status = SCSIIllegalRequest;
436 write_offset, write_size);
443 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
449 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
452 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
453 uint64_t write_offset =
betoh(tmp);
455 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[6]);
456 write_offset = (write_offset << 32) |
betoh(tmp);
458 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[10]);
459 uint32_t write_size =
betoh(tmp);
461 scsi_out.
msgSize = write_size * blkSize;
462 scsi_out.
offset = write_offset * blkSize;
465 if ((write_offset + write_size) > diskSize)
466 scsi_out.
status = SCSIIllegalRequest;
469 write_offset, write_size);
476 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
481 case SCSIFormatUnit: {
487 case SCSISendDiagnostic: {
492 case SCSISynchronizeCache: {
500 case SCSIModeSelect10:
506 case SCSIModeSense6:
case SCSIModeSense10: {
511 if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x0A) {
522 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x01) {
535 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x08) {
547 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x3F) {
550 sizeof(recoveryPage) +
551 sizeof(cachingPage)) >> 2)
568 }
else inform(
"Wrong mode page requested\n");
573 case SCSIRequestSense: {
578 case SCSIUnmap:
break;
580 case SCSIWriteBuffer: {
583 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
586 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
587 uint64_t write_offset =
betoh(tmp) & 0xFFFFFF;
589 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[5]);
590 uint32_t write_size =
betoh(tmp) & 0xFFFFFF;
593 scsi_out.
offset = write_offset;
597 case SCSIReadBuffer: {
605 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
608 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
609 uint64_t read_offset =
betoh(tmp) & 0xFFFFFF;
611 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[5]);
612 uint32_t read_size =
betoh(tmp) & 0xFFFFFF;
615 scsi_out.
offset = read_offset;
617 if ((read_offset + read_size) > capacityLower * blkSize)
618 scsi_out.
status = SCSIIllegalRequest;
626 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
631 case SCSIMaintenanceIn: {
639 statusCheck(SCSIIllegalRequest, scsi_out.
senseCode);
641 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
647 statusCheck(SCSIIllegalRequest, scsi_out.
senseCode);
649 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
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]);
672 uint8_t* sensecodelist)
675 sensecodelist[
count] = 0;
677 sensecodelist[0] = 18;
678 sensecodelist[1] = 0x70;
679 sensecodelist[3] =
status & 0xF;
680 sensecodelist[8] = 0x1F;
733 UTPEvent([
this]{ finalUTP(); },
name())
737 UFSDevice.resize(lunAvail);
741 [
this]() { LUNSignal(); },
742 [
this]() { readCallback(); });
746 warn(
"UFSSlots = %d, this will results in %d command slots",
747 UFSSlots, (UFSSlots & 0x1F));
749 if ((UFSSlots & 0x1F) == 0)
750 fatal(
"Number of UFS command slots should be between 1 and 32.");
760 UFSHostDeviceParams::create()
771 using namespace Stats;
773 std::string UFSHost_name =
name() +
".UFSDiskHost";
778 .
name(UFSHost_name +
".currentSCSIQueue")
779 .
desc(
"Most up to date length of the command queue")
782 .
name(UFSHost_name +
".currentReadSSDQueue")
783 .
desc(
"Most up to date length of the read SSD queue")
786 .
name(UFSHost_name +
".currentWriteSSDQueue")
787 .
desc(
"Most up to date length of the write SSD queue")
792 .
name(UFSHost_name +
".totalReadSSD")
793 .
desc(
"Number of bytes read from SSD")
797 .
name(UFSHost_name +
".totalWrittenSSD")
798 .
desc(
"Number of bytes written to SSD")
802 .
name(UFSHost_name +
".totalReadDiskTransactions")
803 .
desc(
"Number of transactions from disk")
806 .
name(UFSHost_name +
".totalWriteDiskTransactions")
807 .
desc(
"Number of transactions to disk")
810 .
name(UFSHost_name +
".totalReadUFSTransactions")
811 .
desc(
"Number of transactions from device")
814 .
name(UFSHost_name +
".totalWriteUFSTransactions")
815 .
desc(
"Number of transactions to device")
820 .
name(UFSHost_name +
".averageReadSSDBandwidth")
821 .
desc(
"Average read bandwidth (bytes/s)")
827 .
name(UFSHost_name +
".averageWriteSSDBandwidth")
828 .
desc(
"Average write bandwidth (bytes/s)")
834 .
name(UFSHost_name +
".averageSCSIQueueLength")
835 .
desc(
"Average command queue length")
838 .
name(UFSHost_name +
".averageReadSSDQueueLength")
839 .
desc(
"Average read queue length")
842 .
name(UFSHost_name +
".averageWriteSSDQueueLength")
843 .
desc(
"Average write queue length")
848 .
name(UFSHost_name +
".curDoorbell")
849 .
desc(
"Most up to date number of doorbells used")
855 .
name(UFSHost_name +
".maxDoorbell")
856 .
desc(
"Maximum number of doorbells utilized")
859 .
name(UFSHost_name +
".averageDoorbell")
860 .
desc(
"Average number of Doorbells used")
866 .
name(UFSHost_name +
".transactionLatency")
867 .
desc(
"Histogram of transaction times")
872 .
name(UFSHost_name +
".idlePeriods")
873 .
desc(
"Histogram of idle times")
1078 panic(
"Undefined UFSHCD controller write size!\n");
1082 switch (pkt->
getAddr() & 0xFF)
1225 Addr address = 0x00;
1231 transferstart_info.
done = 0;
1263 address = (
count * size) + (address << 32) +
1267 inform(
"UFSmodel received a task from the system; this might"
1268 " lead to untested behaviour.\n");
1272 task_info.
size = size;
1278 reinterpret_cast<uint8_t*
>
1279 (&
taskInfo.back().destination), 0, 0);
1314 transferstart_info.
address = address;
1315 transferstart_info.
size = size;
1323 transferstart_info.
done);
1329 address, size,
reinterpret_cast<uint8_t*
>
1391 uint32_t req_pos,
Addr finaladdress, uint32_t
1409 readDevice(
true, finaladdress, finalsize,
reinterpret_cast<uint8_t*
>
1410 (request_in),
true, NULL);
1427 int req_pos,
Addr finaladdress, uint32_t
1428 finalsize, uint32_t done)
1431 Addr cmd_desc_addr = 0x00;
1450 cmd_desc_addr = (cmd_desc_addr << 32) |
1479 if (
UFSDevice[LUN]->SCSIInfoQueue.size() < 2)
1482 else if (
UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
1484 SCSIInfoQueue.size());
1517 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1518 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1523 SCSIInfoQueue.front().RequestIn;
1525 uint32_t req_pos =
UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;
1527 Addr finaladdress =
UFSDevice[lun_id]->SCSIInfoQueue.front().
1530 uint32_t finalsize =
UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;
1532 uint32_t* transfercommand =
reinterpret_cast<uint32_t*
>
1533 (&(
UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));
1538 SCSICMDHandle(transfercommand);
1548 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
1550 | (transfercommand[0] & 0xFF000000);
1552 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
1555 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
1558 UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
1579 response_addr = (response_addr << 32) |
1584 UFSDevice[lun_id]->transferInfo.responseStartAddr = response_addr;
1585 UFSDevice[lun_id]->transferInfo.reqPos = req_pos;
1586 UFSDevice[lun_id]->transferInfo.size = finalsize;
1587 UFSDevice[lun_id]->transferInfo.address = finaladdress;
1588 UFSDevice[lun_id]->transferInfo.destination =
reinterpret_cast<uint8_t*
>
1589 (
UFSDevice[lun_id]->SCSIInfoQueue.front().RequestIn);
1590 UFSDevice[lun_id]->transferInfo.finished =
true;
1611 uint32_t size_accum = 0;
1620 SCSI_start = (SCSI_start << 32) |
1621 (sglist[
count].baseAddr & 0xFFFFFFFF);
1624 (sglist[
count].size + 1));
1632 uint32_t size_to_send = sglist[
count].
size + 1;
1638 reinterpret_cast<uint8_t*
>
1642 size_accum += size_to_send;
1654 reinterpret_cast<uint8_t*
>(request_in),
true, lun_id);
1668 uint8_t this_lun = 0;
1679 UFSDevice[this_lun]->transferInfo.reqPos,
1680 UFSDevice[this_lun]->transferInfo.requestOut,
1682 UFSDevice[this_lun]->transferInfo.address,
1683 UFSDevice[this_lun]->transferInfo.destination,
1684 UFSDevice[this_lun]->transferInfo.finished,
1685 UFSDevice[this_lun]->transferInfo.lunID);
1699 struct UTPUPIURSP request_out, uint32_t size,
1701 bool finished, uint32_t lun_id)
1704 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1705 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1709 responseStartAddr,
sizeof(request_out));
1712 lastinfo.
mask = req_pos;
1713 lastinfo.
done = finished;
1715 lastinfo.
size = size;
1718 lastinfo.
lun_id = lun_id;
1724 readDevice(
false, responseStartAddr,
sizeof(request_out),
1725 reinterpret_cast<uint8_t*
>
1741 UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
1743 UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);
1756 transferEnd.front().size,
reinterpret_cast<uint8_t*
>
1775 if (!
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1874 SCSIDiskOffset, uint32_t lun_id)
1894 new_transfer.
offset = SCSIDiskOffset;
1895 new_transfer.
size = size;
1896 new_transfer.
lunID = lun_id;
1911 assert(!additional_action->
scheduled());
1932 UFSDevice[LUN]->setTotalWrite(sg_table_length);
1940 next_packet.
start = (next_packet.
start << 32) |
1941 (sglist[
count].baseAddr & 0xFFFFFFFF);
1942 next_packet.
LUN = LUN;
1946 (sglist[
count].size + 1));
1947 assert(sglist[
count].size > 0);
1993 UFSDevice[lun]->SSDWriteDoneInfo.size());
2031 assert(SSDWriteDoneInfo.size() > 0);
2032 flashDevice->writeMemory(
2033 SSDWriteDoneInfo.front().offset,
2034 SSDWriteDoneInfo.front().size, memWriteCallback);
2036 SSDWriteDoneInfo.pop_front();
2039 SSDWriteDoneInfo.size());
2051 totalWrite, amountOfWriteTransfers);
2054 ++amountOfWriteTransfers;
2057 assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);
2060 if (totalWrite == amountOfWriteTransfers) {
2063 amountOfWriteTransfers = 0;
2083 start, size, (
reinterpret_cast<uint32_t *
>(
destination))[0]);
2097 if (additional_action != NULL)
2098 assert(!additional_action->
scheduled());
2114 offset, uint32_t sg_table_length,
2117 uint32_t size_accum = 0;
2129 (sglist[
count].baseAddr & 0xFFFFFFFF);
2132 new_transfer.
lunID = LUN;
2137 UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
2138 UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[
count].size
2147 SSDReadInfo.back().buffer[0],
2154 " 0x%8x\n", (
count + 1), (size-size_accum), size_accum);
2162 UFSDevice[LUN]->SSDReadStart(sg_table_length);
2180 totalRead = total_read;
2181 for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
2187 flashDevice->readMemory(SSDReadInfo.front().filePointer,
2188 SSDReadInfo.front().size, memReadCallback);
2202 " %d so far\n", lunID, totalRead, amountOfReadTransfers);
2204 if (totalRead == amountOfReadTransfers) {
2206 amountOfReadTransfers = 0;
2222 ++amountOfReadTransfers;
2228 deviceReadCallback();
2243 uint8_t this_lun = 0;
2256 UFSDevice[this_lun]->SSDReadInfo.pop_front();
2294 const uint8_t* temp_HCI_mem =
reinterpret_cast<const uint8_t*
>(&
UFSHCIMem);
2310 uint8_t* temp_HCI_mem =
reinterpret_cast<uint8_t*
>(&
UFSHCIMem);
void setValues()
Initialization function.
Stats::Scalar totalWriteUFSTransactions
#define fatal(...)
This implements a cprintf based fatal() function.
void readDevice(bool lastTransfer, Addr SCSIStart, uint32_t SCSISize, uint8_t *SCSIDestination, bool no_cache, Event *additional_action)
Dma transaction function: read device.
Host Controller Interface This is a set of registers that allow the driver to control the transaction...
struct SCSIReply SCSICMDHandle(uint32_t *SCSI_msg)
SCSI command handle function; determines what the command is and returns a reply structure that allow...
virtual void regStats()
Callback to set stat parameters.
bool scheduled() const
Determine if the current event is scheduled.
@ regControllerCapabilities
struct UTPTransferReqDesc * destination
Disk transfer burst information.
void commandHandler()
Command handler function.
std::deque< struct transferInfo > SSDReadPending
Information from the Disk, waiting to be pushed to the DMA.
Different events, and scenarios require different types of information.
void transferStart()
Transfer Start function.
UFSSCSIDevice(const UFSHostDeviceParams *p, uint32_t lun_id, const Callback &transfer_cb, const Callback &read_cb)
Constructor and destructor.
void readFlash(uint8_t *readaddr, uint64_t offset, uint32_t size)
Disk access functions.
#define UNSERIALIZE_SCALAR(scalar)
struct UFSHCDSGEntry - UFSHCI PRD Entry baseAddr: Lower 32bit physical address DW-0 upperAddr: Upper ...
void SSDWriteStart()
SSD write start.
Callback memWriteCallback
@ regUTPTaskREQListRunStop
Stats::Histogram transactionLatency
Histogram of latencies.
void serialize(CheckpointOut &cp) const override
Serialize an object.
uint32_t ORInterruptStatus
Operation and runtime registers.
uint32_t ORHostControllerStatus
std::deque< struct transferStart > transferStartInfo
void SSDReadStart(uint32_t total_read)
Start the transactions to (and from) the disk The host will queue all the transactions.
std::vector< UFSSCSIDevice * > UFSDevice
logic units connected to the UFS Host device Note again that the "device" as such is represented by o...
Callback signalDone
Callbacks between Host and Device.
uint64_t Tick
Tick count type.
static const unsigned int UTPTransferREQCOMPL
Bits of interest within UFS data packages.
HCIMem UFSHCIMem
Host controller memory.
void SSDReadDone()
SSD Read done; Determines if the final callback of the transaction should be made at the end of a rea...
void readCallback()
Read callback Call back function for the logic units to indicate the completion of a read action.
void unserialize(CheckpointIn &cp) override
Unserialize; needed to restore from checkpoints.
static const unsigned int UICCommandCOMPL
uint32_t ORHostControllerEnable
Stats::Scalar totalReadSSD
Amount of data read/written.
DrainState drain() override
Drain; needed to enable checkpoints.
std::deque< struct transferInfo > SSDWriteinfo
Information from DMA transaction to disk.
Stats::Scalar maxDoorbell
std::deque< EventFunctionWrapper > transferEventQueue
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...
void SCSIStart()
Transfer SCSI function.
const FlagsType none
Nothing extra to print.
void readGarbage()
Read garbage A read from disk data structure can vary in size and is therefor allocated on creation.
uint32_t TRUTRLBA
Transfer control registers.
struct UTPTransferReqDesc * RequestIn
std::deque< EventFunctionWrapper > writeDoneEvent
std::deque< EventFunctionWrapper > readDoneEvent
Transfer flow events Basically these events form two queues, one from memory to UFS device (DMA) and ...
struct UPIUMessage message
void taskHandler(struct UTPUPIUTaskReq *request_in, uint32_t req_pos, Addr finaladdress, uint32_t finalsize)
Task handler function.
uint32_t HCCAP
Specify the host capabilities.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
@ Drained
Buffers drained, ready for serialization/handover.
@ regUICErrorCodePHYAdapterLayer
DrainState
Object drain/handover states.
Stats::Average averageSCSIQueue
Average Queue lengths.
struct UTPUPIURSP - Response UPIU structure header: UPIU header DW-0 to DW-2 residualTransferCount: R...
void SSDWriteDone()
SSD Write Done; This is the callback function for the memory model.
uint32_t countInt
interrupt verification This keeps track of the number of interrupts generated.
struct UTPUPIUTaskReq - Task request UPIU structure header - UPIU header structure DW0 to DW-2 inputP...
Stats::Histogram idleTimes
void serialize(CheckpointOut &cp) const override
Serialize; needed to make checkpoints.
Stats::Average averageReadSSDQueue
Counter value() const
Return the current value of this stat as its base type.
Stats::Average averageWriteSSDQueue
Callback deviceReadCallback
Stats::Scalar currentSCSIQueue
Queue lengths.
void writeDone()
Write done After a DMA write with data intended for the disk, this function is called.
uint16_t responseUPIULength
void taskStart()
Task Start function.
void requestHandler()
Handler functions.
struct SCSIReply request_out_datain
SCSI reply structure, used for direct answering.
void checkDrain()
Checkdrain; needed to enable checkpoints.
void readCallback()
Functions to indicate that the action to the SSD has completed.
Stats::Formula simSeconds
uint32_t commandDescBaseAddrHi
Callback memReadCallback
Callbacks between Device and Memory.
@ regUICErrorCodeDataLinkLayer
static const unsigned int recoveryPage[3]
uint8_t activeDoorbells
Statistics helper variables Active doorbells indicates how many doorbells are in teh process of being...
struct UTPUPIUHeader header
uint32_t ORInterruptEnable
std::deque< struct writeToDiskBurst > dmaWriteInfo
Information to get a DMA transaction.
UFS command flow state machine digraph CommandFlow{ node [fontsize=10]; IDLE -> transferHandler [ lab...
AddrRange RangeSize(Addr start, Addr size)
Stats::Formula averageWriteSSDBW
void statusCheck(uint8_t status, uint8_t *sensecodelist)
Status of SCSI.
@ regUTPTransferREQListRunStop
void signalDrainDone() const
Signal that an object is drained.
uint32_t transferTrack
Track the transfer This is allows the driver to "group" certain transfers together by using a tag in ...
Stats::Scalar totalReadUFSTransactions
#define SERIALIZE_ARRAY(member, size)
std::deque< EventFunctionWrapper > taskEventQueue
Multiple tasks transfers can be scheduled at once for the device, the only thing we know for sure abo...
Stats::Formula averageReadSSDBW
Average bandwidth for reads and writes.
AddrRangeList getAddrRanges() const override
Address range functions.
std::deque< struct taskStart > taskInfo
When a task/transfer is started it needs information about the task/transfer it is about to perform.
Transfer start information.
void readDone()
Read done Started at the end of a transaction after the last read action.
void finalUTP()
final UTP, sends the last acknowledge data structure to the system; prepares the clean up functions.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
@ regUTPTransferREQDoorbell
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Tick transactionStart[32]
Helper for latency stats These variables keep track of the latency for every doorbell.
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
struct LUNInfo lunInfo
Logic unit info; needed for SCSI Info messages and LU identification.
Stats::Scalar currentReadSSDQueue
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
static const unsigned int controlPage[3]
These pages are SCSI specific.
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
EventFunctionWrapper UTPEvent
Wait for the moment where we can send the last frame.
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...
int readPendingNum
Track number of DMA transactions in progress.
const FlagsType nozero
Don't print if this is zero.
Stats::Formula curDoorbell
Number of doorbells rung.
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
@ regUICErrorCodeNetworkLayer
AbstractNVM * flashDevice
const Addr pioAddr
Host controller information.
DrainState drainState() const
Return the current drain state of an object.
virtual const std::string name() const
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
virtual void initializeMemory(uint64_t disk_size, uint32_t sector_size)=0
Initialize Memory.
@ regUTPTransferREQListBaseL
uint32_t taskCommandTrack
void generateInterrupt()
set interrupt and sort out the doorbell register.
uint32_t commandDescBaseAddrLo
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
struct UTPUPIUHeader header
void transferHandler(struct UTPTransferReqDesc *request_in, int req_pos, Addr finaladdress, uint32_t finalsize, uint32_t done)
Transfer handler function.
struct UFSHostDevice::UTPTransferReqDesc::RequestDescHeader header
#define UNSERIALIZE_ARRAY(member, size)
void regStats() override
register statistics
const FlagsType pdf
Print the percent of the total that this entry represents.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
uint32_t CMDUICCMDR
Command registers.
@ regUTPTransferREQListClear
void clearInterrupt()
Interrupt control functions.
struct UFSHostDeviceStats stats
RequestHandler stats.
static const unsigned int cachingPage[5]
Tick read(PacketPtr pkt) override
register access functions
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Stats::Scalar totalReadDiskTransactions
Tick write(PacketPtr pkt) override
UFSHCD write function.
Stats::Scalar totalWrittenSSD
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
void setLE(T v)
Set the value in the data pointer to v as little endian.
std::vector< uint8_t > destination
std::ostream CheckpointOut
std::vector< uint32_t > dataMsg
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.
std::deque< struct UTPTransferReqDesc * > garbage
garbage queue, ensure clearing of the allocated memory
@ regUTPTransferREQListBaseH
static const unsigned int UICCommandReady
Stats::Average averageDoorbell
int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
uint32_t TMUTMRLBA
Task control registers.
std::deque< EventFunctionWrapper > readGarbageEventQueue
Event after a read to clean up the UTP data structures.
Histogram & init(size_type size)
Set the parameters of this histogram.
void LUNSignal()
LU callback function to indicate that the action has completed.
void SCSIResume(uint32_t lun_id)
Starts the scsi handling function in the apropriate Logic unit, prepares the right data transfer sche...
Stats::Scalar totalWriteDiskTransactions
UFSHostDevice(const UFSHostDeviceParams *p)
Constructor for the UFS Host device.
std::function< void()> Callback
struct SCSIResumeInfo SCSIInfo
SCSI resume info information structure for SCSI resume.
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
struct UTPTransferReqDesc - UTRD structure header: UTRD header DW-0 to DW-3 commandDescBaseAddrLo: UC...
@ regUTPTransferREQINTAGGControl
EventFunctionWrapper SCSIResumeEvent
The events that control the functionality.
@ regUICErrorCodeTransportLayer
static const unsigned int UTPTaskREQCOMPL
void manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t offset, uint32_t sg_table_length, struct UFSHCDSGEntry *sglist)
Manage read transfer.
Stats::Scalar currentWriteSSDQueue
@ Draining
Draining buffers pending serialization/handover.
void writeFlash(uint8_t *writeaddr, uint64_t offset, uint32_t size)
Write flash.
#define panic(...)
This implements a cprintf based panic() function.
std::deque< struct transferStart > transferEnd
To finish the transaction one needs information about the original message.
Tick curTick()
The current simulated tick.
Abstract superclass for simulation objects.
Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17