gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
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
51namespace gem5
52{
53
54namespace memory
55{
56
57bool
59{
60 return locked[blockIdx(block_address)];
61}
62
63void
65{
66 locked[blockIdx(block_address)] = true;
67}
68
69void
71{
72 locked[blockIdx(block_address)] = false;
73}
74
75void
80
81void
86
87uint32_t
89{
90 return block_address / blockSize;
91}
92
93void
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
106bool
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);
124
125 return false;
126}
127
128bool
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
140void
147
148void
155
156CfiMemory::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
228void
230{
232
233 // allow unconnected memories as this is used in several ruby
234 // systems at the moment
235 if (port.isConnected()) {
236 port.sendRangeChange();
237 }
238}
239
240Tick
242{
243 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
244 "is responding");
245
246 cfiAccess(pkt);
247 return getLatency();
248}
249
250Tick
252{
253 Tick latency = recvAtomic(pkt);
254
255 if (backdoor.ptr())
256 _backdoor = &backdoor;
257 return latency;
258}
259
260void
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
278void
280 MemBackdoorPtr &_backdoor)
281{
282 if (backdoor.ptr())
283 _backdoor = &backdoor;
284}
285
286bool
288{
289 panic_if(pkt->cacheResponding(), "Should not see packets where cache "
290 "is responding");
291
292 panic_if(!(pkt->isRead() || pkt->isWrite()),
293 "Should only see read and writes at memory controller, "
294 "saw %s to %#llx\n", pkt->cmdString(), pkt->getAddr());
295
296 // we should not get a new request after committing to retry the
297 // current one, but unfortunately the CPU violates this rule, so
298 // simply ignore it for now
299 if (retryReq)
300 return false;
301
302 // if we are busy with a read or write, remember that we have to
303 // retry
304 if (isBusy) {
305 retryReq = true;
306 return false;
307 }
308
309 // technically the packet only reaches us after the header delay,
310 // and since this is a memory controller we also need to
311 // deserialise the payload before performing any write operation
312 Tick receive_delay = pkt->headerDelay + pkt->payloadDelay;
313 pkt->headerDelay = pkt->payloadDelay = 0;
314
315 // update the release time according to the bandwidth limit, and
316 // do so with respect to the time it takes to finish this request
317 // rather than long term as it is the short term data rate that is
318 // limited for any real memory
319
320 // calculate an appropriate tick to release to not exceed
321 // the bandwidth limit
322 Tick duration = pkt->getSize() * bandwidth;
323
324 // only consider ourselves busy if there is any need to wait
325 // to avoid extra events being scheduled for (infinitely) fast
326 // memories
327 if (duration != 0) {
328 schedule(releaseEvent, curTick() + duration);
329 isBusy = true;
330 }
331
332 // go ahead and deal with the packet and put the response in the
333 // queue if there is one
334 bool needs_response = pkt->needsResponse();
335 recvAtomic(pkt);
336 // turn packet around to go back to requester if response expected
337 if (needs_response) {
338 // recvAtomic() should already have turned packet into
339 // atomic response
340 assert(pkt->isResponse());
341
342 Tick when_to_send = curTick() + receive_delay + getLatency();
343
344 // typically this should be added at the end, so start the
345 // insertion sort with the last element, also make sure not to
346 // re-order in front of some existing packet with the same
347 // address, the latter is important as this memory effectively
348 // hands out exclusive copies (shared is not asserted)
349 auto i = packetQueue.end();
350 --i;
351 while (i != packetQueue.begin() && when_to_send < i->tick &&
352 !i->pkt->matchAddr(pkt)) {
353 --i;
354 }
355
356 // emplace inserts the element before the position pointed to by
357 // the iterator, so advance it one step
358 packetQueue.emplace(++i, pkt, when_to_send);
359
360 if (!retryResp && !dequeueEvent.scheduled())
361 schedule(dequeueEvent, packetQueue.back().tick);
362 } else {
363 pendingDelete.reset(pkt);
364 }
365
366 return true;
367}
368
369void
371{
372 assert(isBusy);
373 isBusy = false;
374 if (retryReq) {
375 retryReq = false;
376 port.sendRetryReq();
377 }
378}
379
380void
382{
383 assert(!packetQueue.empty());
384 DeferredPacket deferred_pkt = packetQueue.front();
385
386 retryResp = !port.sendTimingResp(deferred_pkt.pkt);
387
388 if (!retryResp) {
389 packetQueue.pop_front();
390
391 // if the queue is not empty, schedule the next dequeue event,
392 // otherwise signal that we are drained if we were asked to do so
393 if (!packetQueue.empty()) {
394 // if there were packets that got in-between then we
395 // already have an event scheduled, so use re-schedule
397 std::max(packetQueue.front().tick, curTick()), true);
398 } else if (drainState() == DrainState::Draining) {
399 DPRINTF(Drain, "Draining of CfiMemory complete\n");
401 }
402 }
403}
404
405Tick
407{
408 return latency +
409 (latency_var ? rng->random<Tick>(0, latency_var) : 0);
410}
411
412void
414{
415 assert(retryResp);
416
417 dequeue();
418}
419
420Port &
421CfiMemory::getPort(const std::string &if_name, PortID idx)
422{
423 if (if_name != "port") {
424 return AbstractMemory::getPort(if_name, idx);
425 } else {
426 return port;
427 }
428}
429
432{
433 if (!packetQueue.empty()) {
434 DPRINTF(Drain, "CfiMemory Queue has requests, waiting to drain\n");
436 } else {
437 return DrainState::Drained;
438 }
439}
440
441void
452
453void
464
466 CfiMemory& _memory)
467 : ResponsePort(_name), mem(_memory)
468{ }
469
472{
473 AddrRangeList ranges;
474 ranges.push_back(mem.getAddrRange());
475 return ranges;
476}
477
478Tick
480{
481 return mem.recvAtomic(pkt);
482}
483
484Tick
486 PacketPtr pkt, MemBackdoorPtr &_backdoor)
487{
488 return mem.recvAtomicBackdoor(pkt, _backdoor);
489}
490
491void
493{
494 mem.recvFunctional(pkt);
495}
496
497void
499 MemBackdoorPtr &_backdoor)
500{
501 mem.recvMemBackdoorReq(req, _backdoor);
502}
503
504bool
506{
507 return mem.recvTimingReq(pkt);
508}
509
510void
512{
513 mem.recvRespRetry();
514}
515
516void
518{
519 if (pkt->isWrite()) {
520 write(pkt);
521 } else {
522 read(pkt);
523 }
524}
525
526void
528{
529 DPRINTF(CFI, "write, address: %#x, val: %#x\n", pkt->getAddr(),
530 pkt->getUintX(ByteOrder::little));
531
532 const Addr flash_address = pkt->getAddr() - start();
533
534 const uint16_t value = pkt->getUintX(ByteOrder::little) & 0xffff;
535 const auto new_cmd = static_cast<CfiCommand>(value & 0xff);
536
537 switch (writeState) {
539 handleCommand(new_cmd);
540 break;
541
543 if (new_cmd == CfiCommand::BLOCK_ERASE_CONFIRM) {
544 // Erasing the block
545 // Check if block is locked
546 if (blocks.isLocked(flash_address)) {
548 } else {
549 blocks.erase(pkt);
550 }
551 } else {
553 }
556 break;
557
559 if (new_cmd == CfiCommand::LOCK_BLOCK) {
560
561 // Lock the addressed block
562 blocks.lock(flash_address);
564
565 } else if (new_cmd == CfiCommand::UNLOCK_BLOCK) {
566
567 // Unlock the addressed block
568 blocks.unlock(flash_address);
570
571 } else {
573 }
574
576 break;
577
581
582 if (blocks.isLocked(flash_address)) {
584 } else {
586 return;
587 }
588 break;
589
591 // Buffer size in bytes
592 auto buffer_size = (value + 1) * sizeof(uint32_t);
593
594 // Clearing the program buffer
595 programBuffer.setup(buffer_size);
596
599 break;
600 }
601
603 // Write to the buffer and check if a writeback is needed
604 // (if the buffer is full)
605 auto writeback = programBuffer.write(
606 flash_address, pkt->getPtr<void>(), pkt->getSize());
607
608 if (writeback) {
610 auto success = programBuffer.writeback();
611 if (!success)
613
615 } else {
617 }
619 }
620 break;
621 }
622
623 default:
624 panic("Invalid Write State\n");
625 return;
626 }
627
628 pkt->makeResponse();
629}
630
631void
633{
634 const Addr flash_address = pkt->getAddr() - start();
635 uint64_t value = 0;
636
637 switch (readState) {
639 value = statusRegister;
640 break;
642 value = readDeviceID(flash_address);
643 break;
645 value = cfiQuery(flash_address);
646 break;
649 return;
650 default:
651 panic("Invalid Read State\n");
652 return;
653 }
654
655 if (numberOfChips == 2) {
656 value |= (value << 16);
657 }
658
659 pkt->setUintX(value, ByteOrder::little);
660 pkt->makeResponse();
661
662 DPRINTF(CFI, "read, address: %#x, val: %#x\n", pkt->getAddr(),
663 pkt->getUintX(ByteOrder::little));
664
665}
666
667uint64_t
668CfiMemory::readDeviceID(Addr flash_address) const
669{
670 switch ((flash_address & 0xff) / bankWidth) {
671 case 0x00: // vendor ID
672 return vendorID;
673 case 0x01: // device ID
674 return deviceID;
675 case 0x02: // lock bit
676 return blocks.isLocked(flash_address);
677 default:
678 // Unsupported entries
679 warn("Invalid Device Identifier code: %d\n", flash_address & 0xff);
680 return 0;
681 }
682}
683
684void
686{
687 switch (new_cmd) {
689 DPRINTF(CFI, "CFI Command: Read Array\n");
691 break;
693 DPRINTF(CFI, "CFI Command: Read Device Identifier\n");
695 break;
697 DPRINTF(CFI, "CFI Command: CFI Query\n");
699 break;
701 DPRINTF(CFI, "CFI Command: Read Status Register\n");
703 break;
705 DPRINTF(CFI, "CFI Command: Clear Status Register\n");
707 break;
709 DPRINTF(CFI, "CFI Command: Buffered Program Confirm\n");
710 break;
712 DPRINTF(CFI, "CFI Command: Erase Block Setup\n");
715 break;
717 DPRINTF(CFI, "CFI Command: Lock Block Setup\n");
719 break;
721 DPRINTF(CFI, "CFI Command: Word Program\n");
724 break;
726 DPRINTF(CFI, "CFI Command: Buffered Program Setup\n");
729 break;
731 //because of how u-boot works and reset the flash
732 //we have to ignore the AMD RESET explicitly
733 // (see the function __flash_cmd_reset in drivers/mtd/cfi_flash.c)
734 break;
735 default:
736 panic("Don't know what to do with %#x\n",
737 static_cast<uint16_t>(new_cmd));
738 }
739
740}
741
742uint64_t
744{
745 flash_address /= bankWidth;
746
747 panic_if(flash_address >= sizeof(cfiQueryTable),
748 "Acessing invalid entry in CFI query table (addr=%#x)",
749 flash_address);
750
751 return cfiQueryTable[flash_address];
752}
753
754void
756{
757 auto host_address = parent.toHostAddr(pkt->getAddr());
758 std::memset(host_address, 0xff, blockSize);
759}
760
761} // namespace memory
762} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
const std::string _name
Definition named.hh:54
virtual std::string name() const
Definition named.hh:60
bool isRead() const
Definition packet.hh:593
Addr getAddr() const
Definition packet.hh:807
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
Definition packet.hh:1470
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
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition packet.hh:588
bool isResponse() const
Definition packet.hh:598
bool needsResponse() const
Definition packet.hh:608
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition packet.hh:449
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:1062
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition packet.hh:431
T * getPtr()
get a pointer to the data ptr.
Definition packet.hh:1225
bool isWrite() const
Definition packet.hh:594
bool trySatisfyFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
Definition packet.hh:1399
unsigned getSize() const
Definition packet.hh:817
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:1480
bool cacheResponding() const
Definition packet.hh:659
Ports are used to interface objects to each other.
Definition port.hh:62
ResponsePort(const std::string &name, SimObject *_owner, PortID id=InvalidPortID)
Response port.
Definition port.cc:218
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
uint64_t size() const
Get the memory size.
AbstractMemory(const AbstractMemory &)
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:228
MemoryPort(const std::string &_name, CfiMemory &_memory)
Definition cfi_mem.cc:465
AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
Definition cfi_mem.cc:471
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:485
void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the peer.
Definition cfi_mem.cc:492
bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the peer.
Definition cfi_mem.cc:505
void recvMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &_backdoor) override
Receive a request for a back door to a range of memory.
Definition cfi_mem.cc:498
void recvRespRetry() override
Called by the peer if sendTimingResp was called on this protocol (causing recvTimingResp to be called...
Definition cfi_mem.cc:511
Tick recvAtomic(PacketPtr pkt) override
Receive an atomic request packet from the peer.
Definition cfi_mem.cc:479
EventFunctionWrapper releaseEvent
Definition cfi_mem.hh:310
const uint16_t bankWidth
Definition cfi_mem.hh:337
static const uint8_t STATUS_ERASE_ERROR
Possible in the status register.
Definition cfi_mem.hh:99
void recvFunctional(PacketPtr pkt)
Definition cfi_mem.cc:261
const uint16_t vendorID
Definition cfi_mem.hh:335
CfiCommand readState
Previous command (issued in the previous write cycle)
Definition cfi_mem.hh:340
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:668
static const uint8_t STATUS_PROGRAM_LOCK_BIT
Definition cfi_mem.hh:102
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:290
EventFunctionWrapper dequeueEvent
Definition cfi_mem.hh:318
static const uint8_t STATUS_LOCK_ERROR
Definition cfi_mem.hh:100
static const uint8_t STATUS_READY
Definition cfi_mem.hh:101
std::list< DeferredPacket > packetQueue
Internal (unbounded) storage to mimic the delay caused by the actual memory access.
Definition cfi_mem.hh:277
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition cfi_mem.cc:421
void recvMemBackdoorReq(const MemBackdoorReq &req, MemBackdoorPtr &_backdoor)
Definition cfi_mem.cc:279
ProgramBuffer programBuffer
Definition cfi_mem.hh:347
bool recvTimingReq(PacketPtr pkt)
Definition cfi_mem.cc:287
void write(PacketPtr pkt)
Write request to the CFI Memory.
Definition cfi_mem.cc:527
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:431
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:685
const uint8_t numberOfChips
Definition cfi_mem.hh:333
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...
Definition cfi_mem.hh:95
Tick getLatency() const
Detemine the latency.
Definition cfi_mem.cc:406
bool retryReq
Remember if we have to retry an outstanding request that arrived while we were busy.
Definition cfi_mem.hh:296
uint64_t cfiQuery(Addr addr)
Return the selected entry in the CFI table.
Definition cfi_mem.cc:743
void read(PacketPtr pkt)
Read request to the CFI Memory.
Definition cfi_mem.cc:632
const uint16_t deviceID
Definition cfi_mem.hh:336
uint8_t cfiQueryTable[61]
Definition cfi_mem.hh:349
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition cfi_mem.cc:454
void release()
Release the memory after being busy and send a retry if a request was rejected in the meanwhile.
Definition cfi_mem.cc:370
void cfiAccess(PacketPtr pkt)
Make a read/write access to the CFI Memory.
Definition cfi_mem.cc:517
bool retryResp
Remember if we failed to send a response and are awaiting a retry.
Definition cfi_mem.hh:302
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:331
const Tick latency_var
Fudge factor added to the latency.
Definition cfi_mem.hh:270
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:381
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition cfi_mem.cc:442
const Tick latency
Latency from that a request is accepted until the response is ready to be sent.
Definition cfi_mem.hh:265
const double bandwidth
Bandwidth in ticks per byte.
Definition cfi_mem.hh:284
Random::RandomPtr rng
Definition cfi_mem.hh:351
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition addr_range.hh:64
static constexpr int log2i(int value)
Calculate the log2 of a power of 2 integer.
Definition intmath.hh:295
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:79
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.
Definition drain.hh:77
@ Drained
Buffers drained, ready for serialization/handover.
Definition drain.hh:78
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
void reschedule(Event &event, Tick when, bool always=false)
Definition eventq.hh:1030
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
#define UNSERIALIZE_CONTAINER(member)
Definition serialize.hh:651
#define SERIALIZE_ENUM(scalar)
Definition serialize.hh:591
#define UNSERIALIZE_OBJ(obj)
Definition serialize.hh:672
#define SERIALIZE_OBJ(obj)
This macro serializes an object into its own section.
Definition serialize.hh:665
#define SERIALIZE_CONTAINER(member)
Definition serialize.hh:643
#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.
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition sim_object.cc:73
#define warn(...)
Definition logging.hh:288
Bitfield< 21 > writeback
Definition types.hh:126
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 0 > p
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
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
MemBackdoor * MemBackdoorPtr
Definition backdoor.hh:127
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
Packet * PacketPtr
#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:755
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
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
static const ssize_t MAX_BUFFER_SIZE
Definition cfi_mem.hh:178
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition cfi_mem.cc:149
std::vector< uint8_t > buffer
Definition cfi_mem.hh:212
bool write(Addr flash_address, void *data_ptr, ssize_t size)
Write data into the buffer.
Definition cfi_mem.cc:107
const std::string & name()
Definition trace.cc:48

Generated on Mon May 26 2025 09:19:11 for gem5 by doxygen 1.13.2