78 uint32_t lun_id,
Callback *transfer_cb,
81 flashDisk(p->image[lun_id]),
82 flashDevice(p->internalflash[lun_id]),
83 blkSize(p->img_blk_size),
84 lunAvail(p->image.
size()),
85 diskSize(flashDisk->
size()),
86 capacityLower((diskSize - 1) & 0xffffffff),
89 transferCompleted(false),
93 amountOfWriteTransfers(0),
94 amountOfReadTransfers(0)
112 uint32_t temp_id = ((lun_id | 0x30) << 24) | 0x3A4449;
137 {0x01400A0A, 0x00000000,
140 {0x03800A01, 0x00000000,
143 {0x00011208, 0x00000000,
144 0x00000000, 0x00000020,
164 memset(&scsi_out, 0,
sizeof(
struct SCSIReply));
174 statusCheck(SCSIGood, scsi_out.
senseCode);
176 scsi_out.
LUN = lunID;
177 scsi_out.
status = SCSIGood;
182 switch (SCSI_msg[4] & 0xFF) {
193 (reinterpret_cast<uint32_t*> (&lunInfo))[
count];
203 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
209 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(tempptr);
210 uint64_t read_offset =
betoh(tmp) & 0x1FFFFF;
212 uint32_t read_size = tempptr[4];
215 scsi_out.
msgSize = read_size * blkSize;
216 scsi_out.
offset = read_offset * blkSize;
218 if ((read_offset + read_size) > diskSize)
219 scsi_out.
status = SCSIIllegalRequest;
222 read_offset, read_size);
229 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
238 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
241 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
242 uint64_t read_offset =
betoh(tmp);
244 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
245 uint32_t read_size =
betoh(tmpsize);
247 scsi_out.
msgSize = read_size * blkSize;
248 scsi_out.
offset = read_offset * blkSize;
250 if ((read_offset + read_size) > diskSize)
251 scsi_out.
status = SCSIIllegalRequest;
254 read_offset, read_size);
261 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
270 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
273 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
274 uint64_t read_offset =
betoh(tmp);
276 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[6]);
277 read_offset = (read_offset << 32) |
betoh(tmp);
279 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[10]);
280 uint32_t read_size =
betoh(tmp);
282 scsi_out.
msgSize = read_size * blkSize;
283 scsi_out.
offset = read_offset * blkSize;
285 if ((read_offset + read_size) > diskSize)
286 scsi_out.
status = SCSIIllegalRequest;
289 read_offset, read_size);
296 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
301 case SCSIReadCapacity10: {
308 betoh(capacityLower);
312 case SCSIReadCapacity16: {
316 betoh(capacityUpper);
318 betoh(capacityLower);
328 case SCSIReportLUNs: {
345 case SCSIStartStop: {
351 case SCSITestUnitReady: {
364 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
367 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
368 uint64_t read_offset =
betoh(tmp);
370 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
371 uint32_t read_size =
betoh(tmpsize);
373 if ((read_offset + read_size) > diskSize)
374 scsi_out.
status = SCSIIllegalRequest;
381 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
391 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
397 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(tempptr);
398 uint64_t write_offset =
betoh(tmp) & 0x1FFFFF;
400 uint32_t write_size = tempptr[4];
402 scsi_out.
msgSize = write_size * blkSize;
403 scsi_out.
offset = write_offset * blkSize;
406 if ((write_offset + write_size) > diskSize)
407 scsi_out.
status = SCSIIllegalRequest;
410 write_offset, write_size);
417 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
423 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
426 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
427 uint64_t write_offset =
betoh(tmp);
429 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
430 uint32_t write_size =
betoh(tmpsize);
432 scsi_out.
msgSize = write_size * blkSize;
433 scsi_out.
offset = write_offset * blkSize;
436 if ((write_offset + write_size) > diskSize)
437 scsi_out.
status = SCSIIllegalRequest;
440 write_offset, write_size);
447 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
453 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
456 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
457 uint64_t write_offset =
betoh(tmp);
459 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[6]);
460 write_offset = (write_offset << 32) |
betoh(tmp);
462 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[10]);
463 uint32_t write_size =
betoh(tmp);
465 scsi_out.
msgSize = write_size * blkSize;
466 scsi_out.
offset = write_offset * blkSize;
469 if ((write_offset + write_size) > diskSize)
470 scsi_out.
status = SCSIIllegalRequest;
473 write_offset, write_size);
480 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
485 case SCSIFormatUnit: {
491 case SCSISendDiagnostic: {
496 case SCSISynchronizeCache: {
504 case SCSIModeSelect10:
510 case SCSIModeSense6:
case SCSIModeSense10: {
515 if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x0A) {
526 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x01) {
539 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x08) {
551 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x3F) {
554 sizeof(recoveryPage) +
555 sizeof(cachingPage)) >> 2)
572 }
else inform(
"Wrong mode page requested\n");
577 case SCSIRequestSense: {
582 case SCSIUnmap:
break;
584 case SCSIWriteBuffer: {
587 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
590 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
591 uint64_t write_offset =
betoh(tmp) & 0xFFFFFF;
593 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[5]);
594 uint32_t write_size =
betoh(tmp) & 0xFFFFFF;
597 scsi_out.
offset = write_offset;
601 case SCSIReadBuffer: {
609 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
612 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
613 uint64_t read_offset =
betoh(tmp) & 0xFFFFFF;
615 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[5]);
616 uint32_t read_size =
betoh(tmp) & 0xFFFFFF;
619 scsi_out.
offset = read_offset;
621 if ((read_offset + read_size) > capacityLower * blkSize)
622 scsi_out.
status = SCSIIllegalRequest;
630 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
635 case SCSIMaintenanceIn: {
643 statusCheck(SCSIIllegalRequest, scsi_out.
senseCode);
645 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
651 statusCheck(SCSIIllegalRequest, scsi_out.
senseCode);
653 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
656 inform(
"Unsupported scsi message type: %2x\n", SCSI_msg[4] & 0xFF);
657 inform(
"0x%8x\n", SCSI_msg[0]);
658 inform(
"0x%8x\n", SCSI_msg[1]);
659 inform(
"0x%8x\n", SCSI_msg[2]);
660 inform(
"0x%8x\n", SCSI_msg[3]);
661 inform(
"0x%8x\n", SCSI_msg[4]);
676 uint8_t* sensecodelist)
679 sensecodelist[
count] = 0;
681 sensecodelist[0] = 18;
682 sensecodelist[1] = 0x70;
683 sensecodelist[3] = status & 0xF;
684 sensecodelist[8] = 0x1F;
754 warn(
"UFSSlots = %d, this will results in %d command slots",
758 fatal(
"Number of UFS command slots should be between 1 and 32.");
768 UFSHostDeviceParams::create()
779 using namespace Stats;
781 std::string UFSHost_name =
name() +
".UFSDiskHost";
786 .
name(UFSHost_name +
".currentSCSIQueue")
787 .
desc(
"Most up to date length of the command queue")
790 .
name(UFSHost_name +
".currentReadSSDQueue")
791 .
desc(
"Most up to date length of the read SSD queue")
794 .
name(UFSHost_name +
".currentWriteSSDQueue")
795 .
desc(
"Most up to date length of the write SSD queue")
800 .
name(UFSHost_name +
".totalReadSSD")
801 .
desc(
"Number of bytes read from SSD")
805 .
name(UFSHost_name +
".totalWrittenSSD")
806 .
desc(
"Number of bytes written to SSD")
810 .
name(UFSHost_name +
".totalReadDiskTransactions")
811 .
desc(
"Number of transactions from disk")
814 .
name(UFSHost_name +
".totalWriteDiskTransactions")
815 .
desc(
"Number of transactions to disk")
818 .
name(UFSHost_name +
".totalReadUFSTransactions")
819 .
desc(
"Number of transactions from device")
822 .
name(UFSHost_name +
".totalWriteUFSTransactions")
823 .
desc(
"Number of transactions to device")
828 .
name(UFSHost_name +
".averageReadSSDBandwidth")
829 .
desc(
"Average read bandwidth (bytes/s)")
835 .
name(UFSHost_name +
".averageWriteSSDBandwidth")
836 .
desc(
"Average write bandwidth (bytes/s)")
842 .
name(UFSHost_name +
".averageSCSIQueueLength")
843 .
desc(
"Average command queue length")
846 .
name(UFSHost_name +
".averageReadSSDQueueLength")
847 .
desc(
"Average read queue length")
850 .
name(UFSHost_name +
".averageWriteSSDQueueLength")
851 .
desc(
"Average write queue length")
856 .
name(UFSHost_name +
".curDoorbell")
857 .
desc(
"Most up to date number of doorbells used")
863 .
name(UFSHost_name +
".maxDoorbell")
864 .
desc(
"Maximum number of doorbells utilized")
867 .
name(UFSHost_name +
".averageDoorbell")
868 .
desc(
"Average number of Doorbells used")
874 .
name(UFSHost_name +
".transactionLatency")
875 .
desc(
"Histogram of transaction times")
880 .
name(UFSHost_name +
".idlePeriods")
881 .
desc(
"Histogram of idle times")
1074 data = pkt->
get<uint8_t>();
1078 data = pkt->
get<uint16_t>();
1082 data = pkt->
get<uint32_t>();
1086 panic(
"Undefined UFSHCD controller write size!\n");
1090 switch (pkt->
getAddr() & 0xFF)
1233 Addr address = 0x00;
1239 transferstart_info.
done = 0;
1271 address = (count *
size) + (address << 32) +
1275 inform(
"UFSmodel received a task from the system; this might"
1276 " lead to untested behaviour.\n");
1285 reinterpret_cast<uint8_t*
>
1286 (&
taskInfo.back().destination), 0, 0);
1304 count, transferstart_info.
done);
1320 transferstart_info.
mask = mask <<
count;
1321 transferstart_info.
address = address;
1330 transferstart_info.
done);
1335 address,
size,
reinterpret_cast<uint8_t*
>
1397 uint32_t req_pos,
Addr finaladdress, uint32_t
1415 readDevice(
true, finaladdress, finalsize, reinterpret_cast<uint8_t*>
1416 (request_in),
true, NULL);
1433 int req_pos,
Addr finaladdress, uint32_t
1434 finalsize, uint32_t done)
1437 Addr cmd_desc_addr = 0x00;
1456 cmd_desc_addr = (cmd_desc_addr << 32) |
1485 if (
UFSDevice[LUN]->SCSIInfoQueue.size() < 2)
1488 else if (
UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
1490 SCSIInfoQueue.size());
1523 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1524 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1529 SCSIInfoQueue.front().RequestIn;
1531 uint32_t req_pos =
UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;
1533 Addr finaladdress =
UFSDevice[lun_id]->SCSIInfoQueue.front().
1536 uint32_t finalsize =
UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;
1538 uint32_t* transfercommand =
reinterpret_cast<uint32_t*
>
1539 (&(
UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));
1544 SCSICMDHandle(transfercommand);
1554 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
1556 | (transfercommand[0] & 0xFF000000);
1558 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
1561 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
1564 UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
1585 response_addr = (response_addr << 32) |
1590 UFSDevice[lun_id]->transferInfo.responseStartAddr = response_addr;
1591 UFSDevice[lun_id]->transferInfo.reqPos = req_pos;
1592 UFSDevice[lun_id]->transferInfo.size = finalsize;
1593 UFSDevice[lun_id]->transferInfo.address = finaladdress;
1594 UFSDevice[lun_id]->transferInfo.destination =
reinterpret_cast<uint8_t*
>
1595 (
UFSDevice[lun_id]->SCSIInfoQueue.front().RequestIn);
1596 UFSDevice[lun_id]->transferInfo.finished =
true;
1617 uint32_t size_accum = 0;
1622 while ((length > count) && size_accum
1626 SCSI_start = (SCSI_start << 32) |
1627 (sglist[count].baseAddr & 0xFFFFFFFF);
1630 (sglist[count].
size + 1));
1638 uint32_t size_to_send = sglist[
count].
size + 1;
1644 reinterpret_cast<uint8_t*>
1648 size_accum += size_to_send;
1660 reinterpret_cast<uint8_t*>(request_in),
true, lun_id);
1674 uint8_t this_lun = 0;
1685 UFSDevice[this_lun]->transferInfo.reqPos,
1686 UFSDevice[this_lun]->transferInfo.requestOut,
1688 UFSDevice[this_lun]->transferInfo.address,
1689 UFSDevice[this_lun]->transferInfo.destination,
1690 UFSDevice[this_lun]->transferInfo.finished,
1691 UFSDevice[this_lun]->transferInfo.lunID);
1707 bool finished, uint32_t lun_id)
1710 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1711 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1715 responseStartAddr,
sizeof(request_out));
1718 lastinfo.
mask = req_pos;
1719 lastinfo.
done = finished;
1724 lastinfo.
lun_id = lun_id;
1730 readDevice(
false, responseStartAddr,
sizeof(request_out),
1731 reinterpret_cast<uint8_t*>
1747 UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
1749 UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);
1762 transferEnd.front().size,
reinterpret_cast<uint8_t*
>
1781 if (!
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1880 SCSIDiskOffset, uint32_t lun_id)
1898 new_transfer.
offset = SCSIDiskOffset;
1900 new_transfer.
lunID = lun_id;
1915 assert(!additional_action->
scheduled());
1917 additional_action, destination, 0);
1936 UFSDevice[LUN]->setTotalWrite(sg_table_length);
1944 next_packet.
start = (next_packet.
start << 32) |
1945 (sglist[
count].baseAddr & 0xFFFFFFFF);
1946 next_packet.
LUN = LUN;
1997 UFSDevice[lun]->SSDWriteDoneInfo.size());
2035 assert(SSDWriteDoneInfo.size() > 0);
2036 flashDevice->writeMemory(
2037 SSDWriteDoneInfo.front().offset,
2038 SSDWriteDoneInfo.front().size, memWriteCallback);
2040 SSDWriteDoneInfo.pop_front();
2043 SSDWriteDoneInfo.size());
2055 totalWrite, amountOfWriteTransfers);
2058 ++amountOfWriteTransfers;
2061 assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);
2064 if (totalWrite == amountOfWriteTransfers) {
2067 amountOfWriteTransfers = 0;
2071 signalDone->process();
2087 start, size, (reinterpret_cast<uint32_t *>(destination))[0]);
2099 if (additional_action != NULL)
2100 assert(!additional_action->
scheduled());
2103 additional_action, destination, 0);
2116 offset, uint32_t sg_table_length,
2119 uint32_t size_accum = 0;
2131 (sglist[
count].baseAddr & 0xFFFFFFFF);
2134 new_transfer.
lunID = LUN;
2139 UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
2140 UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[
count].size
2149 SSDReadInfo.back().buffer[0],
2150 offset + size_accum,
2156 " 0x%8x\n", (
count + 1), (size-size_accum), size_accum);
2164 UFSDevice[LUN]->SSDReadStart(sg_table_length);
2182 totalRead = total_read;
2183 for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
2189 flashDevice->readMemory(SSDReadInfo.front().filePointer,
2204 " %d so far\n", lunID, totalRead, amountOfReadTransfers);
2206 if (totalRead == amountOfReadTransfers) {
2208 amountOfReadTransfers = 0;
2212 signalDone->process();
2224 ++amountOfReadTransfers;
2230 deviceReadCallback->process();
2245 uint8_t this_lun = 0;
2258 UFSDevice[this_lun]->SSDReadInfo.pop_front();
2295 const uint8_t* temp_HCI_mem =
reinterpret_cast<const uint8_t*
>(&
UFSHCIMem);
2311 uint8_t* temp_HCI_mem =
reinterpret_cast<uint8_t*
>(&
UFSHCIMem);
Stats::Average averageWriteSSDQueue
Stats::Scalar currentSCSIQueue
Queue lengths.
Counter value() const
Return the current value of this stat as its base type.
std::deque< struct transferInfo > SSDReadPending
Information from the Disk, waiting to be pushed to the DMA.
AddrRange RangeSize(Addr start, Addr size)
const FlagsType pdf
Print the percent of the total that this entry represents.
struct SCSIResumeInfo SCSIInfo
SCSI resume info information structure for SCSI resume.
void generateInterrupt()
set interrupt and sort out the doorbell register.
void SSDReadStart(uint32_t total_read)
Start the transactions to (and from) the disk The host will queue all the transactions.
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
Callback * transferDoneCallback
Callbacks for the logic units.
for(int i=0;i< p->texture_features.size();i++) idRegs[TEXTURE_FEATURES_REG(i)]
int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
std::deque< struct taskStart > taskInfo
When a task/transfer is started it needs information about the task/transfer it is about to perform...
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
AddrRangeList getAddrRanges() const override
Address range functions.
void unserialize(CheckpointIn &cp) override
Unserialize; needed to restore from checkpoints.
DrainState
Object drain/handover states.
void setValues()
Initialization function.
std::deque< struct transferStart > transferStartInfo
Tick transactionStart[32]
Helper for latency stats These variables keep track of the latency for every doorbell.
Stats::Scalar currentReadSSDQueue
uint32_t ORInterruptStatus
Operation and runtime registers.
void finalUTP()
final UTP, sends the last acknowledge data structure to the system; prepares the clean up functions...
Stats::Scalar totalReadSSD
Amount of data read/written.
void transferStart()
Transfer Start function.
struct UTPUPIURSP - Response UPIU structure header: UPIU header DW-0 to DW-2 residualTransferCount: R...
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...
void writeFlash(uint8_t *writeaddr, uint64_t offset, uint32_t size)
Write flash.
struct UTPTransferReqDesc - UTRD structure header: UTRD header DW-0 to DW-3 commandDescBaseAddrLo: UC...
void SSDWriteDone()
SSD Write Done; This is the callback function for the memory model.
bool scheduled() const
Determine if the current event is scheduled.
UFS command flow state machine digraph CommandFlow{ node [fontsize=10]; IDLE -> transferHandler [ lab...
Stats::Scalar totalReadUFSTransactions
UFSHostDevice(const UFSHostDeviceParams *p)
Constructor for the UFS Host device.
struct UTPUPIUHeader header
uint32_t ORInterruptEnable
Stats::Scalar totalReadDiskTransactions
std::deque< EventWrapper< UFSHostDevice,&UFSHostDevice::readGarbage > > readGarbageEventQueue
Event after a read to clean up the UTP data structures.
Histogram & init(size_type size)
Set the parameters of this histogram.
void regStats() override
register statistics
Stats::Scalar totalWriteDiskTransactions
struct UTPUPIUTaskReq - Task request UPIU structure header - UPIU header structure DW0 to DW-2 inputP...
Callback * memWriteCallback
Tick write(PacketPtr pkt) override
UFSHCD write function.
struct UFSHostDeviceStats stats
RequestHandler stats.
std::deque< struct transferStart > transferEnd
To finish the transaction one needs information about the original message.
struct UFSHostDevice::UTPTransferReqDesc::RequestDescHeader header
uint32_t ORHostControllerEnable
std::deque< EventWrapper< UFSHostDevice,&UFSHostDevice::writeDone > > writeDoneEvent
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Tick read(PacketPtr pkt) override
register access functions
void readFlash(uint8_t *readaddr, uint64_t offset, uint32_t size)
Disk access functions.
Stats::Formula simSeconds
void statusCheck(uint8_t status, uint8_t *sensecodelist)
Status of SCSI.
This is a base class for UFS devices The UFS interface consists out of one host controller which conn...
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
int readPendingNum
Track number of DMA transactions in progress.
const Addr pioAddr
Host controller information.
uint32_t commandDescBaseAddrLo
void readCallback()
Read callback Call back function for the logic units to indicate the completion of a read action...
std::deque< struct UTPTransferReqDesc * > garbage
garbage queue, ensure clearing of the allocated memory
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void commandHandler()
Command handler function.
#define UNSERIALIZE_SCALAR(scalar)
Tick curTick()
The current simulated tick.
uint32_t HCCAP
Specify the host capabilities.
uint8_t activeDoorbells
Statistics helper variables Active doorbells indicates how many doorbells are in teh process of being...
Callback * memReadCallback
Callbacks between Device and Memory.
Stats::Average averageSCSIQueue
Average Queue lengths.
uint32_t ORHostControllerStatus
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
uint64_t Tick
Tick count type.
Stats::Average averageDoorbell
void clearInterrupt()
Interrupt control functions.
Stats::Scalar currentWriteSSDQueue
void SSDReadDone()
SSD Read done; Determines if the final callback of the transaction should be made at the end of a rea...
Callback * deviceReadCallback
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::vector< uint8_t > destination
void taskStart()
Task Start function.
void readDevice(bool lastTransfer, Addr SCSIStart, uint32_t SCSISize, uint8_t *SCSIDestination, bool no_cache, Event *additional_action)
Dma transaction function: read device.
#define SERIALIZE_ARRAY(member, size)
void serialize(CheckpointOut &cp) const override
Serialize; needed to make checkpoints.
virtual void initializeMemory(uint64_t disk_size, uint32_t sector_size)=0
Initialize Memory.
Stats::Scalar totalWriteUFSTransactions
HCIMem UFSHCIMem
Host controller memory.
Stats::Formula curDoorbell
Number of doorbells rung.
void LUNSignal()
LU callback function to indicate that the action has completed.
DrainState drain() override
Drain; needed to enable checkpoints.
const FlagsType none
Nothing extra to print.
std::deque< struct writeToDiskBurst > dmaWriteInfo
Information to get a DMA transaction.
static const unsigned int cachingPage[5]
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint32_t TMUTMRLBA
Task control registers.
Stats::Scalar totalWrittenSSD
void transferHandler(struct UTPTransferReqDesc *request_in, int req_pos, Addr finaladdress, uint32_t finalsize, uint32_t done)
Transfer handler function.
Draining buffers pending serialization/handover.
void SCSIStart()
Transfer SCSI function.
UFSSCSIDevice(const UFSHostDeviceParams *p, uint32_t lun_id, Callback *transfer_cb, Callback *read_cb)
Constructor and destructor.
void readGarbage()
Read garbage A read from disk data structure can vary in size and is therefor allocated on creation...
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
uint32_t CMDUICCMDR
Command registers.
void readCallback()
Functions to indicate that the action to the SSD has completed.
Callback * signalDone
Callbacks between Host and Device.
static const unsigned int UTPTaskREQCOMPL
Stats::Average averageReadSSDQueue
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
void manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t offset, uint32_t sg_table_length, struct UFSHCDSGEntry *sglist)
Manage read transfer.
struct UTPTransferReqDesc * destination
#define SERIALIZE_SCALAR(scalar)
struct UTPUPIUHeader header
#define UNSERIALIZE_ARRAY(member, size)
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
static const unsigned int recoveryPage[3]
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Stats::Scalar maxDoorbell
device layer: This is your Logic unit This layer implements the SCSI functionality of the UFS Device ...
struct UTPTransferReqDesc * RequestIn
virtual const std::string name() const
std::deque< EventWrapper< UFSHostDevice,&UFSHostDevice::transferStart > > transferEventQueue
void readDone()
Read done Started at the end of a transaction after the last read action.
std::ostream CheckpointOut
static const unsigned int UTPTransferREQCOMPL
Bits of interest within UFS data packages.
uint32_t commandDescBaseAddrHi
Stats::Formula averageReadSSDBW
Average bandwidth for reads and writes.
Host Controller Interface This is a set of registers that allow the driver to control the transaction...
void writeDone()
Write done After a DMA write with data intended for the disk, this function is called.
Different events, and scenarios require different types of information.
uint16_t responseUPIULength
struct UPIUMessage message
uint32_t TRUTRLBA
Transfer control registers.
EventWrapper< UFSHostDevice,&UFSHostDevice::SCSIStart > SCSIResumeEvent
The events that control the functionality.
struct SCSIReply request_out_datain
SCSI reply structure, used for direct answering.
uint32_t taskCommandTrack
void signalDrainDone() const
Signal that an object is drained.
std::deque< struct transferInfo > SSDWriteinfo
Information from DMA transaction to disk.
Stats::Histogram transactionLatency
Histogram of latencies.
DrainState drainState() const
Return the current drain state of an object.
Transfer start information.
struct UFSHCDSGEntry - UFSHCI PRD Entry baseAddr: Lower 32bit physical address DW-0 upperAddr: Upper ...
static const unsigned int controlPage[3]
These pages are SCSI specific.
Callback * memReadCallback
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
void taskHandler(struct UTPUPIUTaskReq *request_in, uint32_t req_pos, Addr finaladdress, uint32_t finalsize)
Task handler function.
uint32_t transferTrack
Track the transfer This is allows the driver to "group" certain transfers together by using a tag in ...
std::vector< uint32_t > dataMsg
Disk transfer burst information.
AbstractNVM * flashDevice
Helper template class to turn a simple class member function into a callback.
std::vector< UFSSCSIDevice * > UFSDevice
logic units connected to the UFS Host device Note again that the "device" as such is represented by o...
struct LUNInfo lunInfo
Logic unit info; needed for SCSI Info messages and LU identification.
void SSDWriteStart()
SSD write start.
Stats::Histogram idleTimes
EventWrapper< UFSHostDevice,&UFSHostDevice::finalUTP > UTPEvent
Wait for the moment where we can send the last frame.
uint32_t countInt
interrupt verification This keeps track of the number of interrupts generated.
std::deque< EventWrapper< UFSHostDevice,&UFSHostDevice::taskStart > > taskEventQueue
Multiple tasks transfers can be scheduled at once for the device, the only thing we know for sure abo...
struct SCSIReply SCSICMDHandle(uint32_t *SCSI_msg)
SCSI command handle function; determines what the command is and returns a reply structure that allow...
const FlagsType nozero
Don't print if this is zero.
std::deque< EventWrapper< UFSHostDevice,&UFSHostDevice::readDone > > readDoneEvent
Transfer flow events Basically these events form two queues, one from memory to UFS device (DMA) and ...
void requestHandler()
Handler functions.
void checkDrain()
Checkdrain; needed to enable checkpoints.
void SCSIResume(uint32_t lun_id)
Starts the scsi handling function in the apropriate Logic unit, prepares the right data transfer sche...
void regStats() override
Register statistics for this object.
Abstract superclass for simulation objects.
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.
static const unsigned int UICCommandCOMPL
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
if(it_gpu==gpuTypeMap.end())
static const unsigned int UICCommandReady
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...
Stats::Formula averageWriteSSDBW