Go to the documentation of this file.
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: {
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"),
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"),
801 "Most up to date number of doorbells used",
802 parent->activeDoorbells),
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);
1284 stats.averageDoorbell =
stats.maxDoorbell.value();
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) |
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*
>
1746 stats.averageDoorbell =
stats.maxDoorbell.value();
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) |
1920 next_packet.
LUN = LUN;
1924 (sglist[
count].size + 1));
1925 assert(sglist[
count].size > 0);
1952 ++
stats.totalWriteUFSTransactions;
1971 UFSDevice[lun]->SSDWriteDoneInfo.size());
1990 stats.currentWriteSSDQueue =
UFSDevice[lun]->SSDWriteDoneInfo.size();
1991 stats.averageWriteSSDQueue =
UFSDevice[lun]->SSDWriteDoneInfo.size();
1992 ++
stats.totalWriteDiskTransactions;
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;
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);
2143 ++
stats.totalReadUFSTransactions;
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();
2245 ++
stats.totalReadDiskTransactions;
2272 const uint8_t* temp_HCI_mem =
reinterpret_cast<const uint8_t*
>(&
UFSHCIMem);
2288 uint8_t* temp_HCI_mem =
reinterpret_cast<uint8_t*
>(&
UFSHCIMem);
Disk transfer burst information.
struct SCSIReply request_out_datain
SCSI reply structure, used for direct answering.
Tick curTick()
The universal simulation clock.
#define fatal(...)
This implements a cprintf based fatal() function.
statistics::Formula averageWriteSSDBW
void requestHandler()
Handler functions.
void setValues()
Initialization function.
void transferStart()
Transfer Start function.
struct UTPUPIUTaskReq - Task request UPIU structure header - UPIU header structure DW0 to DW-2 inputP...
statistics::Scalar totalReadDiskTransactions
uint32_t taskCommandTrack
void commandHandler()
Command handler function.
Callback signalDone
Callbacks between Host and Device.
void SCSIResume(uint32_t lun_id)
Starts the scsi handling function in the apropriate Logic unit, prepares the right data transfer sche...
uint32_t countInt
interrupt verification This keeps track of the number of interrupts generated.
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
uint32_t commandDescBaseAddrLo
void generateInterrupt()
set interrupt and sort out the doorbell register.
void clearInterrupt()
Interrupt control functions.
std::deque< struct UTPTransferReqDesc * > garbage
garbage queue, ensure clearing of the allocated memory
@ regUICErrorCodeTransportLayer
#define UNSERIALIZE_SCALAR(scalar)
DrainState drainState() const
Return the current drain state of an object.
statistics::Scalar totalWriteDiskTransactions
static const unsigned int cachingPage[5]
AddrRange RangeSize(Addr start, Addr size)
std::deque< struct taskStart > taskInfo
When a task/transfer is started it needs information about the task/transfer it is about to perform.
DrainState drain() override
Drain; needed to enable checkpoints.
statistics::Scalar totalReadUFSTransactions
Tick read(PacketPtr pkt) override
register access functions
statistics::Formula averageReadSSDBW
Average bandwidth for reads and writes.
std::deque< struct writeToDiskBurst > dmaWriteInfo
Information to get a DMA transaction.
std::deque< struct transferInfo > SSDWriteinfo
Information from DMA transaction to disk.
struct gem5::UFSHostDevice::UTPTransferReqDesc::RequestDescHeader header
std::vector< uint8_t > destination
uint32_t ORHostControllerEnable
const FlagsType nozero
Don't print if this is zero.
@ regUICErrorCodeNetworkLayer
void SSDReadDone()
SSD Read done; Determines if the final callback of the transaction should be made at the end of a rea...
AddrRangeList getAddrRanges() const override
Address range functions.
statistics::Histogram transactionLatency
Histogram of latencies.
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
static const unsigned int UICCommandReady
@ regUTPTransferREQListRunStop
statistics::Scalar totalReadSSD
Amount of data read/written.
uint32_t HCCAP
Specify the host capabilities.
Callback deviceReadCallback
int readPendingNum
Track number of DMA transactions in progress.
virtual void initializeMemory(uint64_t disk_size, uint32_t sector_size)=0
Initialize Memory.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Bitfield< 47, 6 > baseAddr
HCIMem UFSHCIMem
Host controller memory.
const FlagsType none
Nothing extra to print.
@ regUICErrorCodePHYAdapterLayer
std::deque< struct transferInfo > SSDReadPending
Information from the Disk, waiting to be pushed to the DMA.
struct UFSHCDSGEntry - UFSHCI PRD Entry baseAddr: Lower 32bit physical address DW-0 upperAddr: Upper ...
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
@ regUTPTransferREQListBaseH
struct UFSHostDeviceStats stats
RequestHandler stats.
const FlagsType pdf
Print the percent of the total that this entry represents.
std::deque< EventFunctionWrapper > readDoneEvent
Transfer flow events Basically these events form two queues, one from memory to UFS device (DMA) and ...
UFSSCSIDevice(const UFSHostDeviceParams &p, uint32_t lun_id, const Callback &transfer_cb, const Callback &read_cb)
Constructor and destructor.
void finalUTP()
final UTP, sends the last acknowledge data structure to the system; prepares the clean up functions.
UFSHostDeviceStats(UFSHostDevice *parent)
Amount of data read/written.
uint32_t transferTrack
Track the transfer This is allows the driver to "group" certain transfers together by using a tag in ...
void SSDReadStart(uint32_t total_read)
Start the transactions to (and from) the disk The host will queue all the transactions.
statistics::Scalar currentWriteSSDQueue
DrainState
Object drain/handover states.
static const unsigned int UTPTaskREQCOMPL
const Addr pioAddr
Host controller information.
AbstractNVM * flashDevice
void taskStart()
Task Start function.
virtual std::string name() const
constexpr int findLsbSet(uint64_t val)
Returns the bit position of the LSB that is set in the input.
statistics::Average averageDoorbell
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
statistics::Formula curDoorbell
Number of doorbells rung.
void readDone()
Read done Started at the end of a transaction after the last read action.
struct UPIUMessage message
uint8_t activeDoorbells
Statistics helper variables Active doorbells indicates how many doorbells are in teh process of being...
uint64_t Tick
Tick count type.
std::deque< EventFunctionWrapper > taskEventQueue
Multiple tasks transfers can be scheduled at once for the device, the only thing we know for sure abo...
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 readGarbage()
Read garbage A read from disk data structure can vary in size and is therefor allocated on creation.
static const unsigned int UICCommandCOMPL
std::deque< EventFunctionWrapper > readGarbageEventQueue
Event after a read to clean up the UTP data structures.
static const unsigned int UTPTransferREQCOMPL
Bits of interest within UFS data packages.
uint16_t responseUPIULength
Host controller layer: This is your Host controller This layer handles the UFS functionality.
uint32_t TMUTMRLBA
Task control registers.
struct UTPUPIURSP - Response UPIU structure header: UPIU header DW-0 to DW-2 residualTransferCount: R...
void writeDone()
Write done After a DMA write with data intended for the disk, this function is called.
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::deque< struct transferStart > transferStartInfo
void taskHandler(struct UTPUPIUTaskReq *request_in, uint32_t req_pos, Addr finaladdress, uint32_t finalsize)
Task handler function.
#define SERIALIZE_ARRAY(member, size)
Abstract superclass for simulation objects.
@ Drained
Buffers drained, ready for serialization/handover.
statistics::Scalar maxDoorbell
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
void SCSIStart()
Transfer SCSI function.
void unserialize(CheckpointIn &cp) override
Unserialize; needed to restore from checkpoints.
statistics::Average averageReadSSDQueue
static const unsigned int controlPage[3]
These pages are SCSI specific.
Callback memWriteCallback
void readFlash(uint8_t *readaddr, uint64_t offset, uint32_t size)
Disk access functions.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
statistics::Average averageSCSIQueue
Average Queue lengths.
Histogram & init(size_type size)
Set the parameters of this histogram.
void statusCheck(uint8_t status, uint8_t *sensecodelist)
Status of SCSI.
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
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...
statistics::Average averageWriteSSDQueue
struct SCSIResumeInfo SCSIInfo
SCSI resume info information structure for SCSI resume.
uint32_t TRUTRLBA
Transfer control registers.
void checkDrain()
Checkdrain; needed to enable checkpoints.
void signalDrainDone() const
Signal that an object is drained.
struct UTPUPIUHeader header
void readCallback()
Functions to indicate that the action to the SSD has completed.
std::deque< EventFunctionWrapper > transferEventQueue
UFSHostDevice(const UFSHostDeviceParams &p)
Constructor for the UFS Host device.
statistics::Histogram idleTimes
uint32_t ORInterruptStatus
Operation and runtime registers.
struct UTPTransferReqDesc * RequestIn
void writeFlash(uint8_t *writeaddr, uint64_t offset, uint32_t size)
Write flash.
@ regUTPTransferREQListClear
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
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...
std::function< void()> Callback
Host Controller Interface This is a set of registers that allow the driver to control the transaction...
#define UNSERIALIZE_ARRAY(member, size)
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 makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
@ regUTPTransferREQINTAGGControl
uint32_t ORInterruptEnable
statistics::Formula & simSeconds
EventFunctionWrapper UTPEvent
Wait for the moment where we can send the last frame.
void serialize(CheckpointOut &cp) const override
Serialize; needed to make checkpoints.
@ regUICErrorCodeDataLinkLayer
Different events, and scenarios require different types of information.
@ regUTPTransferREQListBaseL
std::vector< Info * > stats
void transferHandler(struct UTPTransferReqDesc *request_in, int req_pos, Addr finaladdress, uint32_t finalsize, uint32_t done)
Transfer handler function.
Tick write(PacketPtr pkt) override
UFSHCD write function.
void LUNSignal()
LU callback function to indicate that the action has completed.
std::ostream CheckpointOut
statistics::Scalar currentReadSSDQueue
void setLE(T v)
Set the value in the data pointer to v as little endian.
struct UTPUPIUHeader header
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
struct UTPTransferReqDesc * destination
uint32_t CMDUICCMDR
Command registers.
Tick transactionStart[32]
Helper for latency stats These variables keep track of the latency for every doorbell.
EventFunctionWrapper SCSIResumeEvent
The events that control the functionality.
std::deque< EventFunctionWrapper > writeDoneEvent
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
void readDevice(bool lastTransfer, Addr SCSIStart, uint32_t SCSISize, uint8_t *SCSIDestination, bool no_cache, Event *additional_action)
Dma transaction function: read device.
@ regControllerCapabilities
uint32_t commandDescBaseAddrHi
void SSDWriteDone()
SSD Write Done; This is the callback function for the memory model.
statistics::Scalar totalWriteUFSTransactions
@ regUTPTransferREQDoorbell
Callback memReadCallback
Callbacks between Device and Memory.
std::deque< struct transferStart > transferEnd
To finish the transaction one needs information about the original message.
uint32_t ORHostControllerStatus
static const unsigned int recoveryPage[3]
void readCallback()
Read callback Call back function for the logic units to indicate the completion of a read action.
std::vector< uint32_t > dataMsg
@ Draining
Draining buffers pending serialization/handover.
bool scheduled() const
Determine if the current event is scheduled.
@ regUTPTaskREQListRunStop
void manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t offset, uint32_t sg_table_length, struct UFSHCDSGEntry *sglist)
Manage read transfer.
statistics::Scalar totalWrittenSSD
#define panic(...)
This implements a cprintf based panic() function.
Transfer start information.
struct UTPTransferReqDesc - UTRD structure header: UTRD header DW-0 to DW-3 commandDescBaseAddrLo: UC...
void SSDWriteStart()
SSD write start.
statistics::Scalar currentSCSIQueue
Queue lengths.
struct SCSIReply SCSICMDHandle(uint32_t *SCSI_msg)
SCSI command handle function; determines what the command is and returns a reply structure that allow...
Generated on Sun Jul 30 2023 01:56:55 for gem5 by doxygen 1.8.17