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,
182 switch (SCSI_msg[4] & 0xFF) {
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];
218 if ((read_offset + read_size) >
diskSize)
222 read_offset, read_size);
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);
250 if ((read_offset + read_size) >
diskSize)
254 read_offset, read_size);
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);
285 if ((read_offset + read_size) >
diskSize)
289 read_offset, read_size);
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)
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];
406 if ((write_offset + write_size) >
diskSize)
410 write_offset, write_size);
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);
436 if ((write_offset + write_size) >
diskSize)
440 write_offset, write_size);
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);
469 if ((write_offset + write_size) >
diskSize)
473 write_offset, write_size);
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) {
572 }
else inform(
"Wrong mode page requested\n");
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;
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;
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->
getLE<uint8_t>();
1078 data = pkt->
getLE<uint16_t>();
1082 data = pkt->
getLE<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");
1280 task_info.
size = size;
1286 reinterpret_cast<uint8_t*
> 1287 (&
taskInfo.back().destination), 0, 0);
1305 count, transferstart_info.
done);
1321 transferstart_info.
mask = mask <<
count;
1322 transferstart_info.
address = address;
1323 transferstart_info.
size = size;
1331 transferstart_info.
done);
1337 address, size,
reinterpret_cast<uint8_t*
> 1399 uint32_t req_pos,
Addr finaladdress, uint32_t
1417 readDevice(
true, finaladdress, finalsize, reinterpret_cast<uint8_t*>
1418 (request_in),
true, NULL);
1435 int req_pos,
Addr finaladdress, uint32_t
1436 finalsize, uint32_t done)
1439 Addr cmd_desc_addr = 0x00;
1458 cmd_desc_addr = (cmd_desc_addr << 32) |
1487 if (
UFSDevice[LUN]->SCSIInfoQueue.size() < 2)
1490 else if (
UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
1492 SCSIInfoQueue.size());
1525 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1526 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1531 SCSIInfoQueue.front().RequestIn;
1533 uint32_t req_pos =
UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;
1535 Addr finaladdress =
UFSDevice[lun_id]->SCSIInfoQueue.front().
1538 uint32_t finalsize =
UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;
1540 uint32_t* transfercommand =
reinterpret_cast<uint32_t*
> 1541 (&(
UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));
1546 SCSICMDHandle(transfercommand);
1556 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
1558 | (transfercommand[0] & 0xFF000000);
1560 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
1563 UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
1566 UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
1587 response_addr = (response_addr << 32) |
1592 UFSDevice[lun_id]->transferInfo.responseStartAddr = response_addr;
1593 UFSDevice[lun_id]->transferInfo.reqPos = req_pos;
1594 UFSDevice[lun_id]->transferInfo.size = finalsize;
1595 UFSDevice[lun_id]->transferInfo.address = finaladdress;
1596 UFSDevice[lun_id]->transferInfo.destination =
reinterpret_cast<uint8_t*
> 1597 (
UFSDevice[lun_id]->SCSIInfoQueue.front().RequestIn);
1598 UFSDevice[lun_id]->transferInfo.finished =
true;
1619 uint32_t size_accum = 0;
1624 while ((length > count) && size_accum
1628 SCSI_start = (SCSI_start << 32) |
1629 (sglist[count].baseAddr & 0xFFFFFFFF);
1632 (sglist[count].size + 1));
1640 uint32_t size_to_send = sglist[
count].
size + 1;
1646 reinterpret_cast<uint8_t*>
1650 size_accum += size_to_send;
1662 reinterpret_cast<uint8_t*>(request_in),
true, lun_id);
1676 uint8_t this_lun = 0;
1687 UFSDevice[this_lun]->transferInfo.reqPos,
1688 UFSDevice[this_lun]->transferInfo.requestOut,
1690 UFSDevice[this_lun]->transferInfo.address,
1691 UFSDevice[this_lun]->transferInfo.destination,
1692 UFSDevice[this_lun]->transferInfo.finished,
1693 UFSDevice[this_lun]->transferInfo.lunID);
1707 struct UTPUPIURSP request_out, uint32_t size,
1709 bool finished, uint32_t lun_id)
1712 if (
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1713 panic(
"No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
1717 responseStartAddr,
sizeof(request_out));
1720 lastinfo.
mask = req_pos;
1721 lastinfo.
done = finished;
1723 lastinfo.
size = size;
1726 lastinfo.
lun_id = lun_id;
1732 readDevice(
false, responseStartAddr,
sizeof(request_out),
1733 reinterpret_cast<uint8_t*>
1749 UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
1751 UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);
1764 transferEnd.front().size,
reinterpret_cast<uint8_t*
> 1783 if (!
UFSDevice[lun_id]->SCSIInfoQueue.empty())
1882 SCSIDiskOffset, uint32_t lun_id)
1902 new_transfer.
offset = SCSIDiskOffset;
1903 new_transfer.
size = size;
1904 new_transfer.
lunID = lun_id;
1919 assert(!additional_action->
scheduled());
1921 additional_action, destination, 0);
1940 UFSDevice[LUN]->setTotalWrite(sg_table_length);
1948 next_packet.
start = (next_packet.
start << 32) |
1949 (sglist[
count].baseAddr & 0xFFFFFFFF);
1950 next_packet.
LUN = LUN;
1954 (sglist[
count].size + 1));
1955 assert(sglist[
count].size > 0);
2001 UFSDevice[lun]->SSDWriteDoneInfo.size());
2039 assert(SSDWriteDoneInfo.size() > 0);
2040 flashDevice->writeMemory(
2041 SSDWriteDoneInfo.front().offset,
2042 SSDWriteDoneInfo.front().size, memWriteCallback);
2044 SSDWriteDoneInfo.pop_front();
2047 SSDWriteDoneInfo.size());
2059 totalWrite, amountOfWriteTransfers);
2062 ++amountOfWriteTransfers;
2065 assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);
2068 if (totalWrite == amountOfWriteTransfers) {
2071 amountOfWriteTransfers = 0;
2075 signalDone->process();
2091 start, size, (reinterpret_cast<uint32_t *>(destination))[0]);
2105 if (additional_action != NULL)
2106 assert(!additional_action->
scheduled());
2109 additional_action, destination, 0);
2122 offset, uint32_t sg_table_length,
2125 uint32_t size_accum = 0;
2137 (sglist[
count].baseAddr & 0xFFFFFFFF);
2140 new_transfer.
lunID = LUN;
2145 UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
2146 UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[
count].size
2155 SSDReadInfo.back().buffer[0],
2156 offset + size_accum,
2162 " 0x%8x\n", (
count + 1), (size-size_accum), size_accum);
2170 UFSDevice[LUN]->SSDReadStart(sg_table_length);
2188 totalRead = total_read;
2189 for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
2195 flashDevice->readMemory(SSDReadInfo.front().filePointer,
2210 " %d so far\n", lunID, totalRead, amountOfReadTransfers);
2212 if (totalRead == amountOfReadTransfers) {
2214 amountOfReadTransfers = 0;
2218 signalDone->process();
2230 ++amountOfReadTransfers;
2236 deviceReadCallback->process();
2251 uint8_t this_lun = 0;
2264 UFSDevice[this_lun]->SSDReadInfo.pop_front();
2302 const uint8_t* temp_HCI_mem =
reinterpret_cast<const uint8_t*
>(&
UFSHCIMem);
2318 uint8_t* temp_HCI_mem =
reinterpret_cast<uint8_t*
>(&
UFSHCIMem);
Stats::Average averageWriteSSDQueue
Stats::Scalar currentSCSIQueue
Queue lengths.
#define panic(...)
This implements a cprintf based panic() function.
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.
std::deque< EventFunctionWrapper > writeDoneEvent
Callback * transferDoneCallback
Callbacks for the logic units.
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...
#define fatal(...)
This implements a cprintf based fatal() function.
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.
EventFunctionWrapper UTPEvent
Wait for the moment where we can send the last frame.
void transferStart()
Transfer Start function.
std::deque< EventFunctionWrapper > readGarbageEventQueue
Event after a read to clean up the UTP data structures.
std::deque< EventFunctionWrapper > transferEventQueue
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.
DrainState drainState() const
Return the current drain state of an object.
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.
DiskImage * flashDisk
The objects this model links to.
void signalDrainDone() const
Signal that an object is drained.
struct UTPUPIUHeader header
virtual void regStats()
Callback to set stat parameters.
uint32_t ORInterruptEnable
Stats::Scalar totalReadDiskTransactions
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< EventFunctionWrapper > taskEventQueue
Multiple tasks transfers can be scheduled at once for the device, the only thing we know for sure abo...
std::deque< struct transferStart > transferEnd
To finish the transaction one needs information about the original message.
struct UFSHostDevice::UTPTransferReqDesc::RequestDescHeader header
uint32_t ORHostControllerEnable
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...
void setLE(T v)
Set the value in the data pointer to v as little endian.
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.
bool scheduled() const
Determine if the current event is scheduled.
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.
static const unsigned int UPIUHeaderDataIndWord0
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.
virtual std::streampos write(const uint8_t *data, std::streampos offset)=0
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.
const uint32_t capacityUpper
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
static const unsigned int UPIUHeaderDataIndWord2
static const unsigned int UPIUHeaderDataIndWord1
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.
virtual const std::string name() const
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.
EventFunctionWrapper SCSIResumeEvent
The events that control the functionality.
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)
std::deque< EventFunctionWrapper > readDoneEvent
Transfer flow events Basically these events form two queues, one from memory to UFS device (DMA) and ...
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
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.
virtual std::streampos read(uint8_t *data, std::streampos offset) const =0
uint16_t responseUPIULength
struct UPIUMessage message
uint32_t TRUTRLBA
Transfer control registers.
struct SCSIReply request_out_datain
SCSI reply structure, used for direct answering.
uint32_t taskCommandTrack
std::deque< struct transferInfo > SSDWriteinfo
Information from DMA transaction to disk.
const uint32_t capacityLower
Stats::Histogram transactionLatency
Histogram of latencies.
const uint32_t blkSize
Logic unit dimensions.
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
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
uint32_t countInt
interrupt verification This keeps track of the number of interrupts generated.
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.
void requestHandler()
Handler functions.
void checkDrain()
Checkdrain; needed to enable checkpoints.
Counter value() const
Return the current value of this stat as its base type.
void SCSIResume(uint32_t lun_id)
Starts the scsi handling function in the apropriate Logic unit, prepares the right data transfer sche...
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.
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