79 uint32_t lun_id,
const Callback &transfer_cb,
82 flashDisk(
p.image[lun_id]),
83 flashDevice(
p.internalflash[lun_id]),
84 blkSize(
p.img_blk_size),
85 lunAvail(
p.image.size()),
86 diskSize(flashDisk->size()),
87 capacityLower((diskSize - 1) & 0xffffffff),
90 transferCompleted(false),
94 amountOfWriteTransfers(0),
95 amountOfReadTransfers(0)
111 uint32_t temp_id = ((lun_id | 0x30) << 24) | 0x3A4449;
136 {0x01400A0A, 0x00000000,
139 {0x03800A01, 0x00000000,
142 {0x00011208, 0x00000000,
143 0x00000000, 0x00000020,
173 statusCheck(SCSIGood, scsi_out.
senseCode);
175 scsi_out.
LUN = lunID;
176 scsi_out.
status = SCSIGood;
181 switch (SCSI_msg[4] & 0xFF) {
192 (
reinterpret_cast<uint32_t*
> (&lunInfo))[
count];
202 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
208 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(tempptr);
209 uint64_t read_offset =
betoh(tmp) & 0x1FFFFF;
211 uint32_t read_size = tempptr[4];
214 scsi_out.
msgSize = read_size * blkSize;
215 scsi_out.
offset = read_offset * blkSize;
217 if ((read_offset + read_size) > diskSize)
218 scsi_out.
status = SCSIIllegalRequest;
221 read_offset, read_size);
228 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
237 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
240 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
241 uint64_t read_offset =
betoh(tmp);
243 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
244 uint32_t read_size =
betoh(tmpsize);
246 scsi_out.
msgSize = read_size * blkSize;
247 scsi_out.
offset = read_offset * blkSize;
249 if ((read_offset + read_size) > diskSize)
250 scsi_out.
status = SCSIIllegalRequest;
253 read_offset, read_size);
260 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
269 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
272 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
273 uint64_t read_offset =
betoh(tmp);
275 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[6]);
276 read_offset = (read_offset << 32) |
betoh(tmp);
278 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[10]);
279 uint32_t read_size =
betoh(tmp);
281 scsi_out.
msgSize = read_size * blkSize;
282 scsi_out.
offset = read_offset * blkSize;
284 if ((read_offset + read_size) > diskSize)
285 scsi_out.
status = SCSIIllegalRequest;
288 read_offset, read_size);
295 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
300 case SCSIReadCapacity10: {
307 betoh(capacityLower);
311 case SCSIReadCapacity16: {
315 betoh(capacityUpper);
317 betoh(capacityLower);
327 case SCSIReportLUNs: {
331 scsi_out.
msgSize = (lunAvail * 8) + 8;
344 case SCSIStartStop: {
350 case SCSITestUnitReady: {
363 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
366 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
367 uint64_t read_offset =
betoh(tmp);
369 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
370 uint32_t read_size =
betoh(tmpsize);
372 if ((read_offset + read_size) > diskSize)
373 scsi_out.
status = SCSIIllegalRequest;
380 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
390 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
396 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(tempptr);
397 uint64_t write_offset =
betoh(tmp) & 0x1FFFFF;
399 uint32_t write_size = tempptr[4];
401 scsi_out.
msgSize = write_size * blkSize;
402 scsi_out.
offset = write_offset * blkSize;
405 if ((write_offset + write_size) > diskSize)
406 scsi_out.
status = SCSIIllegalRequest;
409 write_offset, write_size);
416 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
422 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
425 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
426 uint64_t write_offset =
betoh(tmp);
428 uint16_t tmpsize = *
reinterpret_cast<uint16_t*
>(&tempptr[7]);
429 uint32_t write_size =
betoh(tmpsize);
431 scsi_out.
msgSize = write_size * blkSize;
432 scsi_out.
offset = write_offset * blkSize;
435 if ((write_offset + write_size) > diskSize)
436 scsi_out.
status = SCSIIllegalRequest;
439 write_offset, write_size);
446 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
452 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
455 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
456 uint64_t write_offset =
betoh(tmp);
458 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[6]);
459 write_offset = (write_offset << 32) |
betoh(tmp);
461 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[10]);
462 uint32_t write_size =
betoh(tmp);
464 scsi_out.
msgSize = write_size * blkSize;
465 scsi_out.
offset = write_offset * blkSize;
468 if ((write_offset + write_size) > diskSize)
469 scsi_out.
status = SCSIIllegalRequest;
472 write_offset, write_size);
479 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
484 case SCSIFormatUnit: {
490 case SCSISendDiagnostic: {
495 case SCSISynchronizeCache: {
503 case SCSIModeSelect10:
509 case SCSIModeSense6:
case SCSIModeSense10: {
514 if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x0A) {
525 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x01) {
538 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x08) {
550 }
else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x3F) {
553 sizeof(recoveryPage) +
554 sizeof(cachingPage)) >> 2)
571 }
else inform(
"Wrong mode page requested\n");
576 case SCSIRequestSense: {
581 case SCSIUnmap:
break;
583 case SCSIWriteBuffer: {
586 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
589 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
590 uint64_t write_offset =
betoh(tmp) & 0xFFFFFF;
592 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[5]);
593 uint32_t write_size =
betoh(tmp) & 0xFFFFFF;
596 scsi_out.
offset = write_offset;
600 case SCSIReadBuffer: {
608 uint8_t* tempptr =
reinterpret_cast<uint8_t*
>(&SCSI_msg[4]);
611 uint32_t tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[2]);
612 uint64_t read_offset =
betoh(tmp) & 0xFFFFFF;
614 tmp = *
reinterpret_cast<uint32_t*
>(&tempptr[5]);
615 uint32_t read_size =
betoh(tmp) & 0xFFFFFF;
618 scsi_out.
offset = read_offset;
620 if ((read_offset + read_size) > capacityLower * blkSize)
621 scsi_out.
status = SCSIIllegalRequest;
629 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
634 case SCSIMaintenanceIn: {
642 statusCheck(SCSIIllegalRequest, scsi_out.
senseCode);
644 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
650 statusCheck(SCSIIllegalRequest, scsi_out.
senseCode);
652 scsi_out.
status = (scsi_out.
status == SCSIGood) ? SCSIGood :
655 inform(
"Unsupported scsi message type: %2x\n", SCSI_msg[4] & 0xFF);
656 inform(
"0x%8x\n", SCSI_msg[0]);
657 inform(
"0x%8x\n", SCSI_msg[1]);
658 inform(
"0x%8x\n", SCSI_msg[2]);
659 inform(
"0x%8x\n", SCSI_msg[3]);
660 inform(
"0x%8x\n", SCSI_msg[4]);
675 uint8_t* sensecodelist)
678 sensecodelist[
count] = 0;
680 sensecodelist[0] = 18;
681 sensecodelist[1] = 0x70;
682 sensecodelist[3] =
status & 0xF;
683 sensecodelist[8] = 0x1F;
737 UTPEvent([
this]{ finalUTP(); },
name())
739 DPRINTF(UFSHostDevice,
"The hostcontroller hosts %d Logic units\n",
741 UFSDevice.resize(lunAvail);
745 [
this]() { LUNSignal(); },
746 [
this]() { readCallback(); });
750 warn(
"UFSSlots = %d, this will results in %d command slots",
751 UFSSlots, (UFSSlots & 0x1F));
753 if ((UFSSlots & 0x1F) == 0)
754 fatal(
"Number of UFS command slots should be between 1 and 32.");
761 : statistics::
Group(parent,
"UFSDiskHost"),
762 ADD_STAT(currentSCSIQueue, statistics::units::Count::get(),
763 "Most up to date length of the command queue"),
764 ADD_STAT(currentReadSSDQueue, statistics::units::Count::get(),
765 "Most up to date length of the read SSD queue"),
766 ADD_STAT(currentWriteSSDQueue, statistics::units::Count::get(),
767 "Most up to date length of the write SSD queue"),
769 ADD_STAT(totalReadSSD, statistics::units::Byte::get(),
770 "Number of bytes read from SSD"),
771 ADD_STAT(totalWrittenSSD, statistics::units::Byte::get(),
772 "Number of bytes written to SSD"),
773 ADD_STAT(totalReadDiskTransactions, statistics::units::Count::get(),
774 "Number of transactions from disk"),
775 ADD_STAT(totalWriteDiskTransactions, statistics::units::Count::get(),
776 "Number of transactions to disk"),
777 ADD_STAT(totalReadUFSTransactions, statistics::units::Count::get(),
778 "Number of transactions from device"),
779 ADD_STAT(totalWriteUFSTransactions, statistics::units::Count::get(),
780 "Number of transactions to device"),
782 ADD_STAT(averageReadSSDBW, statistics::units::Rate<
783 statistics::units::Byte, statistics::units::Second>::get(),
784 "Average read bandwidth",
786 ADD_STAT(averageWriteSSDBW, statistics::units::Rate<
787 statistics::units::Byte, statistics::units::Second>::get(),
788 "Average write bandwidth",
790 ADD_STAT(averageSCSIQueue, statistics::units::Rate<
791 statistics::units::Count, statistics::units::
Tick>::get(),
792 "Average command queue length"),
793 ADD_STAT(averageReadSSDQueue, statistics::units::Rate<
794 statistics::units::Count, statistics::units::
Tick>::get(),
795 "Average read queue length"),
796 ADD_STAT(averageWriteSSDQueue, statistics::units::Rate<
797 statistics::units::Count, statistics::units::
Tick>::get(),
798 "Average write queue length"),
800 ADD_STAT(curDoorbell, statistics::units::Count::get(),
801 "Most up to date number of doorbells used",
802 parent->activeDoorbells),
803 ADD_STAT(maxDoorbell, statistics::units::Count::get(),
804 "Maximum number of doorbells utilized"),
805 ADD_STAT(averageDoorbell, statistics::units::Rate<
806 statistics::units::Count, statistics::units::
Tick>::get(),
807 "Average number of Doorbells used"),
809 ADD_STAT(transactionLatency, statistics::units::
Tick::get(),
810 "Histogram of transaction times"),
811 ADD_STAT(idleTimes, statistics::units::
Tick::get(),
"Histogram of idle times")
813 using namespace statistics;
1058 const uint32_t
data = pkt->
getUintX(ByteOrder::little);
1060 switch (pkt->
getAddr() & 0xFF)
1203 Addr address = 0x00;
1209 transferstart_info.
done = 0;
1241 address = (
count * size) + (address << 32) +
1245 inform(
"UFSmodel received a task from the system; this might"
1246 " lead to untested behaviour.\n");
1250 task_info.
size = size;
1256 reinterpret_cast<uint8_t*
>
1257 (&
taskInfo.back().destination), 0, 0);
1292 transferstart_info.
address = address;
1293 transferstart_info.
size = size;
1301 transferstart_info.
done);
1307 address, size,
reinterpret_cast<uint8_t*
>
1369 uint32_t req_pos,
Addr finaladdress, uint32_t
1387 readDevice(
true, finaladdress, finalsize,
reinterpret_cast<uint8_t*
>
1388 (request_in),
true, NULL);
1405 int req_pos,
Addr finaladdress, uint32_t
1406 finalsize, uint32_t done)
1409 Addr cmd_desc_addr = 0x00;
1428 cmd_desc_addr = (cmd_desc_addr << 32) |
1457 if (
UFSDevice[LUN]->SCSIInfoQueue.size() < 2)
1460 else if (
UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
1462 SCSIInfoQueue.size());
1495 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1496 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1501 SCSIInfoQueue.front().RequestIn;
1503 uint32_t req_pos =
UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;
1505 Addr finaladdress =
UFSDevice[lun_id]->SCSIInfoQueue.front().
1508 uint32_t finalsize =
UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;
1510 uint32_t* transfercommand =
reinterpret_cast<uint32_t*
>
1511 (&(
UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));
1516 SCSICMDHandle(transfercommand);
1526 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
1528 | (transfercommand[0] & 0xFF000000);
1530 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
1533 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
1536 UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
1557 response_addr = (response_addr << 32) |
1562 UFSDevice[lun_id]->transferInfo.responseStartAddr = response_addr;
1563 UFSDevice[lun_id]->transferInfo.reqPos = req_pos;
1564 UFSDevice[lun_id]->transferInfo.size = finalsize;
1565 UFSDevice[lun_id]->transferInfo.address = finaladdress;
1566 UFSDevice[lun_id]->transferInfo.destination =
reinterpret_cast<uint8_t*
>
1567 (
UFSDevice[lun_id]->SCSIInfoQueue.front().RequestIn);
1568 UFSDevice[lun_id]->transferInfo.finished =
true;
1589 uint32_t size_accum = 0;
1594 while ((length >
count) && size_accum
1598 SCSI_start = (SCSI_start << 32) |
1599 (sglist[
count].baseAddr & 0xFFFFFFFF);
1602 (sglist[
count].size + 1));
1610 uint32_t size_to_send = sglist[
count].
size + 1;
1616 reinterpret_cast<uint8_t*
>
1620 size_accum += size_to_send;
1632 reinterpret_cast<uint8_t*
>(request_in),
true, lun_id);
1646 uint8_t this_lun = 0;
1657 UFSDevice[this_lun]->transferInfo.reqPos,
1658 UFSDevice[this_lun]->transferInfo.requestOut,
1660 UFSDevice[this_lun]->transferInfo.address,
1661 UFSDevice[this_lun]->transferInfo.destination,
1662 UFSDevice[this_lun]->transferInfo.finished,
1663 UFSDevice[this_lun]->transferInfo.lunID);
1677 struct UTPUPIURSP request_out, uint32_t size,
1679 bool finished, uint32_t lun_id)
1682 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1683 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1687 responseStartAddr,
sizeof(request_out));
1690 lastinfo.
mask = req_pos;
1691 lastinfo.
done = finished;
1693 lastinfo.
size = size;
1696 lastinfo.
lun_id = lun_id;
1702 readDevice(
false, responseStartAddr,
sizeof(request_out),
1703 reinterpret_cast<uint8_t*
>
1719 UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
1721 UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);
1734 transferEnd.front().size,
reinterpret_cast<uint8_t*
>
1753 if (!
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1852 SCSIDiskOffset, uint32_t lun_id)
1872 new_transfer.
offset = SCSIDiskOffset;
1873 new_transfer.
size = size;
1874 new_transfer.
lunID = lun_id;
1889 assert(!additional_action->
scheduled());
1910 UFSDevice[LUN]->setTotalWrite(sg_table_length);
1918 next_packet.
start = (next_packet.
start << 32) |
1919 (sglist[
count].baseAddr & 0xFFFFFFFF);
1920 next_packet.
LUN = LUN;
1924 (sglist[
count].size + 1));
1925 assert(sglist[
count].size > 0);
1971 UFSDevice[lun]->SSDWriteDoneInfo.size());
2009 assert(SSDWriteDoneInfo.size() > 0);
2010 flashDevice->writeMemory(
2011 SSDWriteDoneInfo.front().offset,
2012 SSDWriteDoneInfo.front().size, memWriteCallback);
2014 SSDWriteDoneInfo.pop_front();
2017 SSDWriteDoneInfo.size());
2029 totalWrite, amountOfWriteTransfers);
2032 ++amountOfWriteTransfers;
2035 assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);
2038 if (totalWrite == amountOfWriteTransfers) {
2041 amountOfWriteTransfers = 0;
2061 start, size, (
reinterpret_cast<uint32_t *
>(
destination))[0]);
2075 if (additional_action != NULL)
2076 assert(!additional_action->
scheduled());
2092 offset, uint32_t sg_table_length,
2095 uint32_t size_accum = 0;
2107 (sglist[
count].baseAddr & 0xFFFFFFFF);
2110 new_transfer.
lunID = LUN;
2115 UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
2116 UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[
count].size
2125 SSDReadInfo.back().buffer[0],
2132 " 0x%8x\n", (
count + 1), (size-size_accum), size_accum);
2140 UFSDevice[LUN]->SSDReadStart(sg_table_length);
2158 totalRead = total_read;
2159 for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
2165 flashDevice->readMemory(SSDReadInfo.front().filePointer,
2166 SSDReadInfo.front().size, memReadCallback);
2180 " %d so far\n", lunID, totalRead, amountOfReadTransfers);
2182 if (totalRead == amountOfReadTransfers) {
2184 amountOfReadTransfers = 0;
2200 ++amountOfReadTransfers;
2206 deviceReadCallback();
2221 uint8_t this_lun = 0;
2234 UFSDevice[this_lun]->SSDReadInfo.pop_front();
2272 const uint8_t* temp_HCI_mem =
reinterpret_cast<const uint8_t*
>(&
UFSHCIMem);
2288 uint8_t* temp_HCI_mem =
reinterpret_cast<uint8_t*
>(&
UFSHCIMem);
virtual void initializeMemory(uint64_t disk_size, uint32_t sector_size)=0
Initialize Memory.
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Abstract superclass for simulation objects.
static const unsigned int cachingPage[5]
void SSDWriteStart()
SSD write start.
Callback memWriteCallback
void SSDReadDone()
SSD Read done; Determines if the final callback of the transaction should be made at the end of a rea...
static const unsigned int controlPage[3]
These pages are SCSI specific.
std::function< void()> Callback
UFSSCSIDevice(const UFSHostDeviceParams &p, uint32_t lun_id, const Callback &transfer_cb, const Callback &read_cb)
Constructor and destructor.
void writeFlash(uint8_t *writeaddr, uint64_t offset, uint32_t size)
Write flash.
void readFlash(uint8_t *readaddr, uint64_t offset, uint32_t size)
Disk access functions.
void statusCheck(uint8_t status, uint8_t *sensecodelist)
Status of SCSI.
Callback deviceReadCallback
Callback signalDone
Callbacks between Host and Device.
Callback memReadCallback
Callbacks between Device and Memory.
static const unsigned int recoveryPage[3]
struct SCSIReply SCSICMDHandle(uint32_t *SCSI_msg)
SCSI command handle function; determines what the command is and returns a reply structure that allow...
AbstractNVM * flashDevice
struct LUNInfo lunInfo
Logic unit info; needed for SCSI Info messages and LU identification.
void readCallback()
Functions to indicate that the action to the SSD has completed.
void SSDReadStart(uint32_t total_read)
Start the transactions to (and from) the disk The host will queue all the transactions.
void SSDWriteDone()
SSD Write Done; This is the callback function for the memory model.
Host controller layer: This is your Host controller This layer handles the UFS functionality.
int readPendingNum
Track number of DMA transactions in progress.
void taskHandler(struct UTPUPIUTaskReq *request_in, uint32_t req_pos, Addr finaladdress, uint32_t finalsize)
Task handler function.
std::deque< EventFunctionWrapper > taskEventQueue
Multiple tasks transfers can be scheduled at once for the device, the only thing we know for sure abo...
@ regUICErrorCodePHYAdapterLayer
@ regUTPTransferREQListBaseH
@ regUTPTaskREQListRunStop
@ regControllerCapabilities
@ regUICErrorCodeDataLinkLayer
@ regUICErrorCodeNetworkLayer
@ regUTPTransferREQListBaseL
@ regUTPTransferREQListClear
@ regUICErrorCodeTransportLayer
@ regUTPTransferREQListRunStop
@ regUTPTransferREQINTAGGControl
@ regUTPTransferREQDoorbell
void generateInterrupt()
set interrupt and sort out the doorbell register.
void writeDone()
Write done After a DMA write with data intended for the disk, this function is called.
std::deque< struct taskStart > taskInfo
When a task/transfer is started it needs information about the task/transfer it is about to perform.
std::deque< struct transferInfo > SSDWriteinfo
Information from DMA transaction to disk.
static const unsigned int UICCommandReady
std::deque< EventFunctionWrapper > transferEventQueue
EventFunctionWrapper SCSIResumeEvent
The events that control the functionality.
void serialize(CheckpointOut &cp) const override
Serialize; needed to make checkpoints.
void transferHandler(struct UTPTransferReqDesc *request_in, int req_pos, Addr finaladdress, uint32_t finalsize, uint32_t done)
Transfer handler function.
Tick transactionStart[32]
Helper for latency stats These variables keep track of the latency for every doorbell.
const Addr pioAddr
Host controller information.
void commandHandler()
Command handler function.
HCIMem UFSHCIMem
Host controller memory.
struct SCSIReply request_out_datain
SCSI reply structure, used for direct answering.
static const unsigned int UTPTaskREQCOMPL
void clearInterrupt()
Interrupt control functions.
static const unsigned int UTPTransferREQCOMPL
Bits of interest within UFS data packages.
static const unsigned int UICCommandCOMPL
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 finalUTP()
final UTP, sends the last acknowledge data structure to the system; prepares the clean up functions.
std::deque< struct writeToDiskBurst > dmaWriteInfo
Information to get a DMA transaction.
uint32_t transferTrack
Track the transfer This is allows the driver to "group" certain transfers together by using a tag in ...
DrainState drain() override
Drain; needed to enable checkpoints.
void setValues()
Initialization function.
void requestHandler()
Handler functions.
void unserialize(CheckpointIn &cp) override
Unserialize; needed to restore from checkpoints.
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...
struct SCSIResumeInfo SCSIInfo
SCSI resume info information structure for SCSI resume.
Tick read(PacketPtr pkt) override
register access functions
struct UFSHostDeviceStats stats
RequestHandler stats.
void readGarbage()
Read garbage A read from disk data structure can vary in size and is therefor allocated on creation.
std::deque< struct transferStart > transferEnd
To finish the transaction one needs information about the original message.
std::deque< EventFunctionWrapper > readDoneEvent
Transfer flow events Basically these events form two queues, one from memory to UFS device (DMA) and ...
uint32_t countInt
interrupt verification This keeps track of the number of interrupts generated.
std::deque< struct UTPTransferReqDesc * > garbage
garbage queue, ensure clearing of the allocated memory
uint8_t activeDoorbells
Statistics helper variables Active doorbells indicates how many doorbells are in teh process of being...
void manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t offset, uint32_t sg_table_length, struct UFSHCDSGEntry *sglist)
Manage read transfer.
std::vector< UFSSCSIDevice * > UFSDevice
logic units connected to the UFS Host device Note again that the "device" as such is represented by o...
std::deque< struct transferInfo > SSDReadPending
Information from the Disk, waiting to be pushed to the DMA.
void SCSIResume(uint32_t lun_id)
Starts the scsi handling function in the apropriate Logic unit, prepares the right data transfer sche...
std::deque< EventFunctionWrapper > writeDoneEvent
Tick write(PacketPtr pkt) override
UFSHCD write function.
std::deque< struct transferStart > transferStartInfo
AddrRangeList getAddrRanges() const override
Address range functions.
std::deque< EventFunctionWrapper > readGarbageEventQueue
Event after a read to clean up the UTP data structures.
EventFunctionWrapper UTPEvent
Wait for the moment where we can send the last frame.
void readCallback()
Read callback Call back function for the logic units to indicate the completion of a read action.
UFSHostDevice(const UFSHostDeviceParams &p)
Constructor for the UFS Host device.
void transferStart()
Transfer Start function.
void taskStart()
Task Start function.
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.
void LUNSignal()
LU callback function to indicate that the action has completed.
void readDone()
Read done Started at the end of a transaction after the last read action.
void readDevice(bool lastTransfer, Addr SCSIStart, uint32_t SCSISize, uint8_t *SCSIDestination, bool no_cache, Event *additional_action)
Dma transaction function: read device.
void checkDrain()
Checkdrain; needed to enable checkpoints.
void SCSIStart()
Transfer SCSI function.
uint32_t taskCommandTrack
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Histogram & init(size_type size)
Set the parameters of this histogram.
size_type size() const
Return the number of elements, always 1 for a scalar.
Counter value() const
Return the current value of this stat as its base type.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
AddrRange RangeSize(Addr start, Addr size)
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input That function will either use a builtin ...
void signalDrainDone() const
Signal that an object is drained.
DrainState drainState() const
Return the current drain state of an object.
DrainState
Object drain/handover states.
@ Draining
Draining buffers pending serialization/handover.
@ Drained
Buffers drained, ready for serialization/handover.
bool scheduled() const
Determine if the current event is scheduled.
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
#define UNSERIALIZE_ARRAY(member, size)
#define SERIALIZE_ARRAY(member, size)
const FlagsType pdf
Print the percent of the total that this entry represents.
const FlagsType nozero
Don't print if this is zero.
const FlagsType none
Nothing extra to print.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
statistics::Formula & simSeconds
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
Host Controller Interface This is a set of registers that allow the driver to control the transaction...
uint32_t TMUTMRLBA
Task control registers.
uint32_t ORHostControllerStatus
uint32_t TRUTRLBA
Transfer control registers.
uint32_t ORHostControllerEnable
uint32_t ORInterruptStatus
Operation and runtime registers.
uint32_t CMDUICCMDR
Command registers.
uint32_t HCCAP
Specify the host capabilities.
uint32_t ORInterruptEnable
struct UPIUMessage message
struct UTPTransferReqDesc * RequestIn
std::vector< uint8_t > destination
struct UFSHCDSGEntry - UFSHCI PRD Entry baseAddr: Lower 32bit physical address DW-0 upperAddr: Upper ...
statistics::Scalar maxDoorbell
statistics::Formula averageWriteSSDBW
statistics::Average averageSCSIQueue
Average Queue lengths.
statistics::Scalar currentReadSSDQueue
statistics::Scalar totalWriteUFSTransactions
statistics::Formula averageReadSSDBW
Average bandwidth for reads and writes.
statistics::Average averageReadSSDQueue
statistics::Scalar totalReadDiskTransactions
statistics::Scalar totalWriteDiskTransactions
UFSHostDeviceStats(UFSHostDevice *parent)
Amount of data read/written.
statistics::Average averageDoorbell
statistics::Average averageWriteSSDQueue
statistics::Histogram transactionLatency
Histogram of latencies.
statistics::Scalar totalWrittenSSD
statistics::Scalar totalReadSSD
Amount of data read/written.
statistics::Formula curDoorbell
Number of doorbells rung.
statistics::Scalar currentSCSIQueue
Queue lengths.
statistics::Scalar totalReadUFSTransactions
statistics::Scalar currentWriteSSDQueue
statistics::Histogram idleTimes
std::vector< uint32_t > dataMsg
struct UTPUPIUHeader header
struct UTPTransferReqDesc - UTRD structure header: UTRD header DW-0 to DW-3 commandDescBaseAddrLo: UC...
struct gem5::UFSHostDevice::UTPTransferReqDesc::RequestDescHeader header
uint32_t commandDescBaseAddrLo
uint32_t commandDescBaseAddrHi
uint16_t responseUPIULength
struct UTPUPIURSP - Response UPIU structure header: UPIU header DW-0 to DW-2 residualTransferCount: R...
struct UTPUPIUTaskReq - Task request UPIU structure header - UPIU header structure DW0 to DW-2 inputP...
struct UTPUPIUHeader header
Different events, and scenarios require different types of information.
Transfer start information.
struct UTPTransferReqDesc * destination
Disk transfer burst information.
const std::string & name()
This is a base class for UFS devices The UFS interface consists out of one host controller which conn...