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;
734 UTPEvent([
this]{ finalUTP(); },
name())
738 UFSDevice.resize(lunAvail);
742 [
this]() { LUNSignal(); },
743 [
this]() { readCallback(); });
747 warn(
"UFSSlots = %d, this will results in %d command slots",
748 UFSSlots, (UFSSlots & 0x1F));
750 if ((UFSSlots & 0x1F) == 0)
751 fatal(
"Number of UFS command slots should be between 1 and 32.");
758 :
Stats::Group(parent,
"UFSDiskHost"),
760 "Most up to date length of the command queue"),
762 "Most up to date length of the read SSD queue"),
764 "Most up to date length of the write SSD queue"),
767 "Number of bytes read from SSD"),
769 "Number of bytes written to SSD"),
771 "Number of transactions from disk"),
773 "Number of transactions to disk"),
775 "Number of transactions from device"),
777 "Number of transactions to device"),
781 "Average read bandwidth",
785 "Average write bandwidth",
789 "Average command queue length"),
792 "Average read queue length"),
795 "Average write queue length"),
798 "Most up to date number of doorbells used",
799 parent->activeDoorbells),
801 "Maximum number of doorbells utilized"),
804 "Average number of Doorbells used"),
807 "Histogram of transaction times"),
810 using namespace Stats;
1055 const uint32_t
data = pkt->
getUintX(ByteOrder::little);
1057 switch (pkt->
getAddr() & 0xFF)
1200 Addr address = 0x00;
1206 transferstart_info.
done = 0;
1238 address = (
count * size) + (address << 32) +
1242 inform(
"UFSmodel received a task from the system; this might"
1243 " lead to untested behaviour.\n");
1247 task_info.
size = size;
1253 reinterpret_cast<uint8_t*
>
1254 (&
taskInfo.back().destination), 0, 0);
1281 stats.averageDoorbell =
stats.maxDoorbell.value();
1289 transferstart_info.
address = address;
1290 transferstart_info.
size = size;
1298 transferstart_info.
done);
1304 address, size,
reinterpret_cast<uint8_t*
>
1366 uint32_t req_pos,
Addr finaladdress, uint32_t
1384 readDevice(
true, finaladdress, finalsize,
reinterpret_cast<uint8_t*
>
1385 (request_in),
true, NULL);
1402 int req_pos,
Addr finaladdress, uint32_t
1403 finalsize, uint32_t done)
1406 Addr cmd_desc_addr = 0x00;
1425 cmd_desc_addr = (cmd_desc_addr << 32) |
1454 if (
UFSDevice[LUN]->SCSIInfoQueue.size() < 2)
1457 else if (
UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
1459 SCSIInfoQueue.size());
1492 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1493 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1498 SCSIInfoQueue.front().RequestIn;
1500 uint32_t req_pos =
UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;
1502 Addr finaladdress =
UFSDevice[lun_id]->SCSIInfoQueue.front().
1505 uint32_t finalsize =
UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;
1507 uint32_t* transfercommand =
reinterpret_cast<uint32_t*
>
1508 (&(
UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));
1513 SCSICMDHandle(transfercommand);
1523 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
1525 | (transfercommand[0] & 0xFF000000);
1527 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
1530 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
1533 UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
1554 response_addr = (response_addr << 32) |
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;
1586 uint32_t size_accum = 0;
1591 while ((length >
count) && size_accum
1595 SCSI_start = (SCSI_start << 32) |
1596 (sglist[
count].baseAddr & 0xFFFFFFFF);
1599 (sglist[
count].size + 1));
1607 uint32_t size_to_send = sglist[
count].
size + 1;
1613 reinterpret_cast<uint8_t*
>
1617 size_accum += size_to_send;
1629 reinterpret_cast<uint8_t*
>(request_in),
true, lun_id);
1643 uint8_t this_lun = 0;
1654 UFSDevice[this_lun]->transferInfo.reqPos,
1655 UFSDevice[this_lun]->transferInfo.requestOut,
1657 UFSDevice[this_lun]->transferInfo.address,
1658 UFSDevice[this_lun]->transferInfo.destination,
1659 UFSDevice[this_lun]->transferInfo.finished,
1660 UFSDevice[this_lun]->transferInfo.lunID);
1674 struct UTPUPIURSP request_out, uint32_t size,
1676 bool finished, uint32_t lun_id)
1679 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1680 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1684 responseStartAddr,
sizeof(request_out));
1687 lastinfo.
mask = req_pos;
1688 lastinfo.
done = finished;
1690 lastinfo.
size = size;
1693 lastinfo.
lun_id = lun_id;
1699 readDevice(
false, responseStartAddr,
sizeof(request_out),
1700 reinterpret_cast<uint8_t*
>
1716 UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
1718 UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);
1731 transferEnd.front().size,
reinterpret_cast<uint8_t*
>
1743 stats.averageDoorbell =
stats.maxDoorbell.value();
1750 if (!
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1849 SCSIDiskOffset, uint32_t lun_id)
1869 new_transfer.
offset = SCSIDiskOffset;
1870 new_transfer.
size = size;
1871 new_transfer.
lunID = lun_id;
1886 assert(!additional_action->
scheduled());
1907 UFSDevice[LUN]->setTotalWrite(sg_table_length);
1915 next_packet.
start = (next_packet.
start << 32) |
1916 (sglist[
count].baseAddr & 0xFFFFFFFF);
1917 next_packet.
LUN = LUN;
1921 (sglist[
count].size + 1));
1922 assert(sglist[
count].size > 0);
1949 ++
stats.totalWriteUFSTransactions;
1968 UFSDevice[lun]->SSDWriteDoneInfo.size());
1987 stats.currentWriteSSDQueue =
UFSDevice[lun]->SSDWriteDoneInfo.size();
1988 stats.averageWriteSSDQueue =
UFSDevice[lun]->SSDWriteDoneInfo.size();
1989 ++
stats.totalWriteDiskTransactions;
2006 assert(SSDWriteDoneInfo.size() > 0);
2007 flashDevice->writeMemory(
2008 SSDWriteDoneInfo.front().offset,
2009 SSDWriteDoneInfo.front().size, memWriteCallback);
2011 SSDWriteDoneInfo.pop_front();
2014 SSDWriteDoneInfo.size());
2026 totalWrite, amountOfWriteTransfers);
2029 ++amountOfWriteTransfers;
2032 assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);
2035 if (totalWrite == amountOfWriteTransfers) {
2038 amountOfWriteTransfers = 0;
2058 start, size, (
reinterpret_cast<uint32_t *
>(
destination))[0]);
2072 if (additional_action != NULL)
2073 assert(!additional_action->
scheduled());
2089 offset, uint32_t sg_table_length,
2092 uint32_t size_accum = 0;
2104 (sglist[
count].baseAddr & 0xFFFFFFFF);
2107 new_transfer.
lunID = LUN;
2112 UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
2113 UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[
count].size
2122 SSDReadInfo.back().buffer[0],
2129 " 0x%8x\n", (
count + 1), (size-size_accum), size_accum);
2137 UFSDevice[LUN]->SSDReadStart(sg_table_length);
2140 ++
stats.totalReadUFSTransactions;
2155 totalRead = total_read;
2156 for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
2162 flashDevice->readMemory(SSDReadInfo.front().filePointer,
2163 SSDReadInfo.front().size, memReadCallback);
2177 " %d so far\n", lunID, totalRead, amountOfReadTransfers);
2179 if (totalRead == amountOfReadTransfers) {
2181 amountOfReadTransfers = 0;
2197 ++amountOfReadTransfers;
2203 deviceReadCallback();
2218 uint8_t this_lun = 0;
2231 UFSDevice[this_lun]->SSDReadInfo.pop_front();
2242 ++
stats.totalReadDiskTransactions;
2269 const uint8_t* temp_HCI_mem =
reinterpret_cast<const uint8_t*
>(&
UFSHCIMem);
2285 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...
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.
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.
UFSHostDevice(const UFSHostDeviceParams &p)
Constructor for the UFS Host device.
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.
UFSSCSIDevice(const UFSHostDeviceParams &p, uint32_t lun_id, const Callback &transfer_cb, const Callback &read_cb)
Constructor and destructor.
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
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
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
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.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
void readCallback()
Functions to indicate that the action to the SSD has completed.
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
std::vector< Info * > stats
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.
UFSHostDeviceStats(UFSHostDevice *parent)
Amount of data read/written.
@ 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.
Stats::Formula & simSeconds
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.
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.
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
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.
#define UNIT_RATE(T1, T2)
@ regUTPTransferREQListBaseL
uint32_t taskCommandTrack
void generateInterrupt()
set interrupt and sort out the doorbell register.
uint32_t commandDescBaseAddrLo
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)
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 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
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
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
Tick curTick()
The universal simulation clock.
Stats::Average averageDoorbell
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
std::function< void()> Callback
struct SCSIResumeInfo SCSIInfo
SCSI resume info information structure for SCSI resume.
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.
Abstract superclass for simulation objects.
Generated on Tue Jun 22 2021 15:28:27 for gem5 by doxygen 1.8.17