gem5  v22.1.0.0
cfi_mem.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2013, 2015, 2021 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2001-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "mem/cfi_mem.hh"
42 
43 #include <cmath>
44 
45 #include "base/intmath.hh"
46 #include "base/random.hh"
47 #include "base/trace.hh"
48 #include "debug/CFI.hh"
49 #include "debug/Drain.hh"
50 
51 namespace gem5
52 {
53 
54 namespace memory
55 {
56 
57 bool
59 {
60  return locked[blockIdx(block_address)];
61 }
62 
63 void
65 {
66  locked[blockIdx(block_address)] = true;
67 }
68 
69 void
71 {
72  locked[blockIdx(block_address)] = false;
73 }
74 
75 void
77 {
78  SERIALIZE_CONTAINER(locked);
79 }
80 
81 void
83 {
84  UNSERIALIZE_CONTAINER(locked);
85 }
86 
87 uint32_t
89 {
90  return block_address / blockSize;
91 }
92 
93 void
94 CfiMemory::ProgramBuffer::setup(ssize_t buffer_size)
95 {
97  if (buffer_size > MAX_BUFFER_SIZE) {
98  buffer_size = MAX_BUFFER_SIZE;
99  }
100 
101  buffer.resize(buffer_size);
102  std::fill(buffer.begin(), buffer.end(), 0);
103  bytesWritten = 0;
104 }
105 
106 bool
108  void *data_ptr, ssize_t size)
109 {
110  if (bytesWritten >= buffer.size())
111  return true;
112 
113  if (bytesWritten == 0) {
114  blockPointer = flash_address;
115  }
116 
117  const Addr offset = flash_address - blockPointer;
118 
119  if (flash_address < blockPointer || offset >= MAX_BUFFER_SIZE)
120  return true;
121 
122  std::memcpy(buffer.data() + offset, data_ptr, size);
123  bytesWritten += size;
124 
125  return false;
126 }
127 
128 bool
130 {
131  if (parent.blocks.isLocked(blockPointer)) {
132  return false;
133  } else {
134  std::memcpy(parent.toHostAddr(parent.start() + blockPointer),
135  buffer.data(), bytesWritten);
136  return true;
137  }
138 }
139 
140 void
142 {
143  SERIALIZE_CONTAINER(buffer);
144  SERIALIZE_SCALAR(bytesWritten);
145  SERIALIZE_SCALAR(blockPointer);
146 }
147 
148 void
150 {
151  UNSERIALIZE_CONTAINER(buffer);
152  UNSERIALIZE_SCALAR(bytesWritten);
153  UNSERIALIZE_SCALAR(blockPointer);
154 }
155 
156 CfiMemory::CfiMemory(const CfiMemoryParams &p)
157  : AbstractMemory(p),
158  port(name() + ".port", *this), latency(p.latency),
160  retryReq(false), retryResp(false),
161  releaseEvent([this]{ release(); }, name()),
162  dequeueEvent([this]{ dequeue(); }, name()),
163  numberOfChips(2),
164  vendorID(p.vendor_id),
165  deviceID(p.device_id),
166  bankWidth(p.bank_width),
167  readState(CfiCommand::READ_ARRAY), writeState(CfiCommand::NO_CMD),
168  statusRegister(STATUS_READY),
169  blocks(*this, size() / p.blk_size, p.blk_size),
170  programBuffer(*this),
171  cfiQueryTable{
172  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174  /* Query-unique ASCII string */
175  'Q', 'R', 'Y',
176  /* Primary Algorithm Command Set and Control = Intel/Sharp */
177  0x01, 0x00,
178  /* Address for Primary Algorithm extended Query */
179  0x31, 0x00,
180  /* Alternative Algorithm Command Set and Control Interface */
181  0x00, 0x00,
182  /* Address for Alternative Algorithm extended Query */
183  0x00, 0x00,
184  /* Vcc Minimum Program/Erase or Write voltage ([7:4].[3-0]V) */
185  0x45,
186  /* Vcc Maximum Program/Erase or Write voltage ([7:4].[3-0]V) */
187  0x55,
188  /* Vpp Minimum Program/Erase voltage (0 = No Vpp pin) */
189  0x00,
190  /* Vpp Minimum Program/Erase voltage (0 = No Vpp pin) */
191  0x00,
192  /* Typical timeout per single byte/word/D-word program: (2^N us) */
193  0x01,
194  /* Typical timeout for maximum-size multi-byte program: (2^N us) */
195  0x01,
196  /* Typical timeout per individual block erase: (2^N ms) */
197  0x01,
198  /* Typical timeout for full chip erase: (2^N ms) */
199  0x00,
200  /* Maximum timeout for byte/word/D-word program (2^N typical) */
201  0x00,
202  /* Maximum timeout for multi-byte program (2^N typical) */
203  0x00,
204  /* Maximum timeout per individual block erase (2^N typical) */
205  0x00,
206  /* Maximum timeout for chip erase (2^N typical) */
207  0x00,
208  /* Device Size in number of bytes (2^N) */
209  static_cast<uint8_t>(log2(size())),
210  /* Flash Device Interface Code description */
211  0x05, 0x00,
212  /* Maximum number of bytes in multi-byte program (2^N) */
213  static_cast<uint8_t>(bits(log2i(ProgramBuffer::MAX_BUFFER_SIZE), 7, 0)),
214  static_cast<uint8_t>(bits(log2i(ProgramBuffer::MAX_BUFFER_SIZE), 15, 8)),
215  /* Number of Erase Block Regions within device */
216  0x01,
217  /* Erase Block Region Information */
218  static_cast<uint8_t>(bits(blocks.number(), 7, 0)),
219  static_cast<uint8_t>(bits(blocks.number(), 15, 8)),
220  static_cast<uint8_t>(bits(blocks.size(), 7, 0)),
221  static_cast<uint8_t>(bits(blocks.size(), 15, 8)),
222  0x00,0x00,0x00,0x00,//empty Block region 2 info
223  0x00,0x00,0x00,0x00,//empty Block region 3 info
224  0x00,0x00,0x00,0x00//empty Block region 4 info
225  }
226 {}
227 
228 void
230 {
232 
233  // allow unconnected memories as this is used in several ruby
234  // systems at the moment
235  if (port.isConnected()) {
237  }
238 }
239 
240 Tick
242 {
243  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
244  "is responding");
245 
246  cfiAccess(pkt);
247  return getLatency();
248 }
249 
250 Tick
252 {
253  Tick latency = recvAtomic(pkt);
254 
255  if (backdoor.ptr())
256  _backdoor = &backdoor;
257  return latency;
258 }
259 
260 void
262 {
263  pkt->pushLabel(name());
264 
265  functionalAccess(pkt);
266 
267  bool done = false;
268  auto p = packetQueue.begin();
269  // potentially update the packets in our packet queue as well
270  while (!done && p != packetQueue.end()) {
271  done = pkt->trySatisfyFunctional(p->pkt);
272  ++p;
273  }
274 
275  pkt->popLabel();
276 }
277 
278 bool
280 {
281  panic_if(pkt->cacheResponding(), "Should not see packets where cache "
282  "is responding");
283 
284  panic_if(!(pkt->isRead() || pkt->isWrite()),
285  "Should only see read and writes at memory controller, "
286  "saw %s to %#llx\n", pkt->cmdString(), pkt->getAddr());
287 
288  // we should not get a new request after committing to retry the
289  // current one, but unfortunately the CPU violates this rule, so
290  // simply ignore it for now
291  if (retryReq)
292  return false;
293 
294  // if we are busy with a read or write, remember that we have to
295  // retry
296  if (isBusy) {
297  retryReq = true;
298  return false;
299  }
300 
301  // technically the packet only reaches us after the header delay,
302  // and since this is a memory controller we also need to
303  // deserialise the payload before performing any write operation
304  Tick receive_delay = pkt->headerDelay + pkt->payloadDelay;
305  pkt->headerDelay = pkt->payloadDelay = 0;
306 
307  // update the release time according to the bandwidth limit, and
308  // do so with respect to the time it takes to finish this request
309  // rather than long term as it is the short term data rate that is
310  // limited for any real memory
311 
312  // calculate an appropriate tick to release to not exceed
313  // the bandwidth limit
314  Tick duration = pkt->getSize() * bandwidth;
315 
316  // only consider ourselves busy if there is any need to wait
317  // to avoid extra events being scheduled for (infinitely) fast
318  // memories
319  if (duration != 0) {
320  schedule(releaseEvent, curTick() + duration);
321  isBusy = true;
322  }
323 
324  // go ahead and deal with the packet and put the response in the
325  // queue if there is one
326  bool needs_response = pkt->needsResponse();
327  recvAtomic(pkt);
328  // turn packet around to go back to requester if response expected
329  if (needs_response) {
330  // recvAtomic() should already have turned packet into
331  // atomic response
332  assert(pkt->isResponse());
333 
334  Tick when_to_send = curTick() + receive_delay + getLatency();
335 
336  // typically this should be added at the end, so start the
337  // insertion sort with the last element, also make sure not to
338  // re-order in front of some existing packet with the same
339  // address, the latter is important as this memory effectively
340  // hands out exclusive copies (shared is not asserted)
341  auto i = packetQueue.end();
342  --i;
343  while (i != packetQueue.begin() && when_to_send < i->tick &&
344  !i->pkt->matchAddr(pkt)) {
345  --i;
346  }
347 
348  // emplace inserts the element before the position pointed to by
349  // the iterator, so advance it one step
350  packetQueue.emplace(++i, pkt, when_to_send);
351 
352  if (!retryResp && !dequeueEvent.scheduled())
353  schedule(dequeueEvent, packetQueue.back().tick);
354  } else {
355  pendingDelete.reset(pkt);
356  }
357 
358  return true;
359 }
360 
361 void
363 {
364  assert(isBusy);
365  isBusy = false;
366  if (retryReq) {
367  retryReq = false;
368  port.sendRetryReq();
369  }
370 }
371 
372 void
374 {
375  assert(!packetQueue.empty());
376  DeferredPacket deferred_pkt = packetQueue.front();
377 
378  retryResp = !port.sendTimingResp(deferred_pkt.pkt);
379 
380  if (!retryResp) {
381  packetQueue.pop_front();
382 
383  // if the queue is not empty, schedule the next dequeue event,
384  // otherwise signal that we are drained if we were asked to do so
385  if (!packetQueue.empty()) {
386  // if there were packets that got in-between then we
387  // already have an event scheduled, so use re-schedule
389  std::max(packetQueue.front().tick, curTick()), true);
390  } else if (drainState() == DrainState::Draining) {
391  DPRINTF(Drain, "Draining of CfiMemory complete\n");
392  signalDrainDone();
393  }
394  }
395 }
396 
397 Tick
399 {
400  return latency +
402 }
403 
404 void
406 {
407  assert(retryResp);
408 
409  dequeue();
410 }
411 
412 Port &
413 CfiMemory::getPort(const std::string &if_name, PortID idx)
414 {
415  if (if_name != "port") {
416  return AbstractMemory::getPort(if_name, idx);
417  } else {
418  return port;
419  }
420 }
421 
424 {
425  if (!packetQueue.empty()) {
426  DPRINTF(Drain, "CfiMemory Queue has requests, waiting to drain\n");
427  return DrainState::Draining;
428  } else {
429  return DrainState::Drained;
430  }
431 }
432 
433 void
435 {
438 
440 
443 }
444 
445 void
447 {
450 
452 
455 }
456 
457 CfiMemory::MemoryPort::MemoryPort(const std::string& _name,
458  CfiMemory& _memory)
459  : ResponsePort(_name, &_memory), mem(_memory)
460 { }
461 
464 {
465  AddrRangeList ranges;
466  ranges.push_back(mem.getAddrRange());
467  return ranges;
468 }
469 
470 Tick
472 {
473  return mem.recvAtomic(pkt);
474 }
475 
476 Tick
478  PacketPtr pkt, MemBackdoorPtr &_backdoor)
479 {
480  return mem.recvAtomicBackdoor(pkt, _backdoor);
481 }
482 
483 void
485 {
486  mem.recvFunctional(pkt);
487 }
488 
489 bool
491 {
492  return mem.recvTimingReq(pkt);
493 }
494 
495 void
497 {
498  mem.recvRespRetry();
499 }
500 
501 void
503 {
504  if (pkt->isWrite()) {
505  write(pkt);
506  } else {
507  read(pkt);
508  }
509 }
510 
511 void
513 {
514  DPRINTF(CFI, "write, address: %#x, val: %#x\n", pkt->getAddr(),
515  pkt->getUintX(ByteOrder::little));
516 
517  const Addr flash_address = pkt->getAddr() - start();
518 
519  const uint16_t value = pkt->getUintX(ByteOrder::little) & 0xffff;
520  const auto new_cmd = static_cast<CfiCommand>(value & 0xff);
521 
522  switch (writeState) {
523  case CfiCommand::NO_CMD:
524  handleCommand(new_cmd);
525  break;
526 
528  if (new_cmd == CfiCommand::BLOCK_ERASE_CONFIRM) {
529  // Erasing the block
530  // Check if block is locked
531  if (blocks.isLocked(flash_address)) {
533  } else {
534  blocks.erase(pkt);
535  }
536  } else {
538  }
541  break;
542 
544  if (new_cmd == CfiCommand::LOCK_BLOCK) {
545 
546  // Lock the addressed block
547  blocks.lock(flash_address);
549 
550  } else if (new_cmd == CfiCommand::UNLOCK_BLOCK) {
551 
552  // Unlock the addressed block
553  blocks.unlock(flash_address);
555 
556  } else {
558  }
559 
561  break;
562 
566 
567  if (blocks.isLocked(flash_address)) {
569  } else {
571  return;
572  }
573  break;
574 
576  // Buffer size in bytes
577  auto buffer_size = (value + 1) * sizeof(uint32_t);
578 
579  // Clearing the program buffer
580  programBuffer.setup(buffer_size);
581 
584  break;
585  }
586 
588  // Write to the buffer and check if a writeback is needed
589  // (if the buffer is full)
591  flash_address, pkt->getPtr<void>(), pkt->getSize());
592 
593  if (writeback) {
594  if (new_cmd == CfiCommand::BUFFERED_PROGRAM_CONFIRM) {
595  auto success = programBuffer.writeback();
596  if (!success)
598 
600  } else {
602  }
604  }
605  break;
606  }
607 
608  default:
609  panic("Invalid Write State\n");
610  return;
611  }
612 
613  pkt->makeResponse();
614 }
615 
616 void
618 {
619  const Addr flash_address = pkt->getAddr() - start();
620  uint64_t value = 0;
621 
622  switch (readState) {
624  value = statusRegister;
625  break;
627  value = readDeviceID(flash_address);
628  break;
630  value = cfiQuery(flash_address);
631  break;
634  return;
635  default:
636  panic("Invalid Read State\n");
637  return;
638  }
639 
640  if (numberOfChips == 2) {
641  value |= (value << 16);
642  }
643 
644  pkt->setUintX(value, ByteOrder::little);
645  pkt->makeResponse();
646 
647  DPRINTF(CFI, "read, address: %#x, val: %#x\n", pkt->getAddr(),
648  pkt->getUintX(ByteOrder::little));
649 
650 }
651 
652 uint64_t
653 CfiMemory::readDeviceID(Addr flash_address) const
654 {
655  switch ((flash_address & 0xff) / bankWidth) {
656  case 0x00: // vendor ID
657  return vendorID;
658  case 0x01: // device ID
659  return deviceID;
660  case 0x02: // lock bit
661  return blocks.isLocked(flash_address);
662  default:
663  // Unsupported entries
664  warn("Invalid Device Identifier code: %d\n", flash_address & 0xff);
665  return 0;
666  }
667 }
668 
669 void
671 {
672  switch (new_cmd) {
674  DPRINTF(CFI, "CFI Command: Read Array\n");
676  break;
678  DPRINTF(CFI, "CFI Command: Read Device Identifier\n");
680  break;
682  DPRINTF(CFI, "CFI Command: CFI Query\n");
684  break;
686  DPRINTF(CFI, "CFI Command: Read Status Register\n");
688  break;
690  DPRINTF(CFI, "CFI Command: Clear Status Register\n");
692  break;
694  DPRINTF(CFI, "CFI Command: Buffered Program Confirm\n");
695  break;
697  DPRINTF(CFI, "CFI Command: Erase Block Setup\n");
700  break;
702  DPRINTF(CFI, "CFI Command: Lock Block Setup\n");
704  break;
706  DPRINTF(CFI, "CFI Command: Word Program\n");
709  break;
711  DPRINTF(CFI, "CFI Command: Buffered Program Setup\n");
714  break;
716  //because of how u-boot works and reset the flash
717  //we have to ignore the AMD RESET explicitly
718  // (see the function __flash_cmd_reset in drivers/mtd/cfi_flash.c)
719  break;
720  default:
721  panic("Don't know what to do with %#x\n",
722  static_cast<uint16_t>(new_cmd));
723  }
724 
725 }
726 
727 uint64_t
728 CfiMemory::cfiQuery(Addr flash_address)
729 {
730  flash_address /= bankWidth;
731 
732  panic_if(flash_address >= sizeof(cfiQueryTable),
733  "Acessing invalid entry in CFI query table (addr=%#x)",
734  flash_address);
735 
736  return cfiQueryTable[flash_address];
737 }
738 
739 void
741 {
742  auto host_address = parent.toHostAddr(pkt->getAddr());
743  std::memset(host_address, 0xff, blockSize);
744 }
745 
746 } // namespace memory
747 } // namespace gem5
#define DPRINTF(x,...)
Definition: trace.hh:186
uint8_t * ptr() const
Definition: backdoor.hh:62
virtual std::string name() const
Definition: named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
bool isRead() const
Definition: packet.hh:592
T * getPtr()
get a pointer to the data ptr.
Definition: packet.hh:1212
Addr getAddr() const
Definition: packet.hh:805
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
Definition: packet.hh:1448
void setUintX(uint64_t w, ByteOrder endian)
Set the value in the word w after truncating it to the length of the packet and then byteswapping it ...
Definition: packet.cc:361
bool isResponse() const
Definition: packet.hh:597
bool needsResponse() const
Definition: packet.hh:607
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:448
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition: packet.hh:1059
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:430
bool isWrite() const
Definition: packet.hh:593
bool trySatisfyFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
Definition: packet.hh:1386
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:587
unsigned getSize() const
Definition: packet.hh:815
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:352
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
Definition: packet.hh:1458
bool cacheResponding() const
Definition: packet.hh:657
Ports are used to interface objects to each other.
Definition: port.hh:62
bool isConnected() const
Is this port currently connected to a peer?
Definition: port.hh:133
A ResponsePort is a specialization of a port.
Definition: port.hh:270
bool sendTimingResp(PacketPtr pkt)
Attempt to send a timing response to the request port by calling its corresponding receive function.
Definition: port.hh:370
void sendRangeChange() const
Called by the owner to send a range change.
Definition: port.hh:296
void sendRetryReq()
Send a retry to the request port that previously attempted a sendTimingReq to this response port and ...
Definition: port.hh:401
An abstract memory represents a contiguous block of physical memory, with an associated address range...
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
uint64_t size() const
Get the memory size.
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
Addr start() const
Get the start address.
A deferred packet stores a packet along with its scheduled transmission time.
Definition: cfi_mem.hh:227
MemoryPort(const std::string &_name, CfiMemory &_memory)
Definition: cfi_mem.cc:457
AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
Definition: cfi_mem.cc:463
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &_backdoor) override
Receive an atomic request packet from the peer, and optionally provide a backdoor to the data being a...
Definition: cfi_mem.cc:477
void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the peer.
Definition: cfi_mem.cc:484
bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the peer.
Definition: cfi_mem.cc:490
void recvRespRetry() override
Called by the peer if sendTimingResp was called on this protocol (causing recvTimingResp to be called...
Definition: cfi_mem.cc:496
Tick recvAtomic(PacketPtr pkt) override
Receive an atomic request packet from the peer.
Definition: cfi_mem.cc:471
CfiMemory: This is modelling a flash memory adhering to the Common Flash Interface (CFI):
Definition: cfi_mem.hh:72
EventFunctionWrapper releaseEvent
Definition: cfi_mem.hh:307
const uint16_t bankWidth
Definition: cfi_mem.hh:334
static const uint8_t STATUS_ERASE_ERROR
Possible in the status register.
Definition: cfi_mem.hh:98
void recvFunctional(PacketPtr pkt)
Definition: cfi_mem.cc:261
const uint16_t vendorID
Definition: cfi_mem.hh:332
CfiCommand readState
Previous command (issued in the previous write cycle)
Definition: cfi_mem.hh:337
Tick recvAtomic(PacketPtr pkt)
Definition: cfi_mem.cc:241
uint64_t readDeviceID(Addr flash_address) const
Helper function to read the device identifier after the read state machine is put in the CfiCommand::...
Definition: cfi_mem.cc:653
static const uint8_t STATUS_PROGRAM_LOCK_BIT
Definition: cfi_mem.hh:101
bool isBusy
Track the state of the memory as either idle or busy, no need for an enum with only two states.
Definition: cfi_mem.hh:287
EventFunctionWrapper dequeueEvent
Definition: cfi_mem.hh:315
static const uint8_t STATUS_LOCK_ERROR
Definition: cfi_mem.hh:99
static const uint8_t STATUS_READY
Definition: cfi_mem.hh:100
std::list< DeferredPacket > packetQueue
Internal (unbounded) storage to mimic the delay caused by the actual memory access.
Definition: cfi_mem.hh:274
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: cfi_mem.cc:413
CfiCommand writeState
Definition: cfi_mem.hh:338
ProgramBuffer programBuffer
Definition: cfi_mem.hh:344
bool recvTimingReq(PacketPtr pkt)
Definition: cfi_mem.cc:279
void write(PacketPtr pkt)
Write request to the CFI Memory.
Definition: cfi_mem.cc:512
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: cfi_mem.cc:229
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: cfi_mem.cc:423
CfiMemory(const CfiMemoryParams &p)
Definition: cfi_mem.cc:156
void handleCommand(CfiCommand command)
Service a new command issued to the flash device.
Definition: cfi_mem.cc:670
const uint8_t numberOfChips
Definition: cfi_mem.hh:330
Tick recvAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &_backdoor)
Definition: cfi_mem.cc:251
@ BUFFER_SIZE_READ
This is not a real command, but it is used by the internal model only to represent the 2nd write cycl...
Tick getLatency() const
Detemine the latency.
Definition: cfi_mem.cc:398
bool retryReq
Remember if we have to retry an outstanding request that arrived while we were busy.
Definition: cfi_mem.hh:293
uint64_t cfiQuery(Addr addr)
Return the selected entry in the CFI table.
Definition: cfi_mem.cc:728
void read(PacketPtr pkt)
Read request to the CFI Memory.
Definition: cfi_mem.cc:617
const uint16_t deviceID
Definition: cfi_mem.hh:333
uint8_t cfiQueryTable[61]
Definition: cfi_mem.hh:346
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: cfi_mem.cc:446
void release()
Release the memory after being busy and send a retry if a request was rejected in the meanwhile.
Definition: cfi_mem.cc:362
void cfiAccess(PacketPtr pkt)
Make a read/write access to the CFI Memory.
Definition: cfi_mem.cc:502
bool retryResp
Remember if we failed to send a response and are awaiting a retry.
Definition: cfi_mem.hh:299
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
Definition: cfi_mem.hh:328
const Tick latency_var
Fudge factor added to the latency.
Definition: cfi_mem.hh:267
void dequeue()
Dequeue a packet from our internal packet queue and move it to the port where it will be sent as soon...
Definition: cfi_mem.cc:373
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: cfi_mem.cc:434
const Tick latency
Latency from that a request is accepted until the response is ready to be sent.
Definition: cfi_mem.hh:262
const double bandwidth
Bandwidth in ticks per byte.
Definition: cfi_mem.hh:281
static constexpr int log2i(int value)
Calculate the log2 of a power of 2 integer.
Definition: intmath.hh:295
Random random_mt
Definition: random.cc:99
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:90
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:305
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:324
DrainState
Object drain/handover states.
Definition: drain.hh:75
@ Draining
Draining buffers pending serialization/handover.
@ Drained
Buffers drained, ready for serialization/handover.
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
void reschedule(Event &event, Tick when, bool always=false)
Definition: eventq.hh:1037
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:204
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:634
#define SERIALIZE_ENUM(scalar)
Definition: serialize.hh:591
#define UNSERIALIZE_OBJ(obj)
Definition: serialize.hh:655
#define SERIALIZE_OBJ(obj)
This macro serializes an object into its own section.
Definition: serialize.hh:648
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:626
#define UNSERIALIZE_ENUM(scalar)
Definition: serialize.hh:598
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:126
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: sim_object.cc:76
#define warn(...)
Definition: logging.hh:246
Bitfield< 21 > writeback
Definition: types.hh:126
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 23, 0 > offset
Definition: types.hh:144
Bitfield< 54 > p
Definition: pagetable.hh:70
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
std::ostream CheckpointOut
Definition: serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
uint64_t Tick
Tick count type.
Definition: types.hh:58
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
uint32_t blockIdx(Addr block_address) const
Definition: cfi_mem.cc:88
void lock(Addr block_address)
Lock the block pointed by the block_address parameter.
Definition: cfi_mem.cc:64
void erase(PacketPtr pkt)
Erase a single block.
Definition: cfi_mem.cc:740
void unlock(Addr block_address)
Unlock the block pointed by the block_address parameter.
Definition: cfi_mem.cc:70
bool isLocked(Addr block_address) const
Return true if the block pointed by the block_address parameter is locked.
Definition: cfi_mem.cc:58
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: cfi_mem.cc:82
std::vector< bool > locked
Definition: cfi_mem.hh:161
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: cfi_mem.cc:76
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: cfi_mem.cc:141
void setup(ssize_t buffer_size)
Start buffering.
Definition: cfi_mem.cc:94
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: cfi_mem.cc:149
bool write(Addr flash_address, void *data_ptr, ssize_t size)
Write data into the buffer.
Definition: cfi_mem.cc:107
Definition: mem.h:38
bool_vector8 mem[]
Definition: reset_stim.h:43
const std::string & name()
Definition: trace.cc:49

Generated on Wed Dec 21 2022 10:22:37 for gem5 by doxygen 1.9.1