| /* |
| * Copyright (c) 2012-2013 ARM Limited |
| * All rights reserved. |
| * |
| * The license below extends only to copyright in the software and shall |
| * not be construed as granting a license to any other intellectual |
| * property including but not limited to intellectual property relating |
| * to a hardware implementation of the functionality of the software |
| * licensed hereunder. You may use the software subject to the license |
| * terms below provided that you ensure that this notice is replicated |
| * unmodified and in its entirety in all distributions of the software, |
| * modified or unmodified, in source code or in binary form. |
| * |
| * Copyright (c) 2002-2005 The Regents of The University of Michigan |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer; |
| * redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution; |
| * neither the name of the copyright holders nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * Authors: Steve Reinhardt |
| */ |
| |
| #ifndef __CPU_SIMPLE_ATOMIC_HH__ |
| #define __CPU_SIMPLE_ATOMIC_HH__ |
| |
| #include "cpu/simple/base.hh" |
| #include "params/AtomicSimpleCPU.hh" |
| #include "sim/probe/probe.hh" |
| |
| class AtomicSimpleCPU : public BaseSimpleCPU |
| { |
| public: |
| |
| AtomicSimpleCPU(AtomicSimpleCPUParams *params); |
| virtual ~AtomicSimpleCPU(); |
| |
| virtual void init(); |
| |
| private: |
| |
| struct TickEvent : public Event |
| { |
| AtomicSimpleCPU *cpu; |
| |
| TickEvent(AtomicSimpleCPU *c); |
| void process(); |
| const char *description() const; |
| }; |
| |
| TickEvent tickEvent; |
| |
| const int width; |
| bool locked; |
| const bool simulate_data_stalls; |
| const bool simulate_inst_stalls; |
| |
| /** |
| * Drain manager to use when signaling drain completion |
| * |
| * This pointer is non-NULL when draining and NULL otherwise. |
| */ |
| DrainManager *drain_manager; |
| |
| // main simulation loop (one cycle) |
| void tick(); |
| |
| /** |
| * Check if a system is in a drained state. |
| * |
| * We need to drain if: |
| * <ul> |
| * <li>We are in the middle of a microcode sequence as some CPUs |
| * (e.g., HW accelerated CPUs) can't be started in the middle |
| * of a gem5 microcode sequence. |
| * |
| * <li>The CPU is in a LLSC region. This shouldn't normally happen |
| * as these are executed atomically within a single tick() |
| * call. The only way this can happen at the moment is if |
| * there is an event in the PC event queue that affects the |
| * CPU state while it is in an LLSC region. |
| * |
| * <li>Stay at PC is true. |
| * </ul> |
| */ |
| bool isDrained() { |
| return microPC() == 0 && |
| !locked && |
| !stayAtPC; |
| } |
| |
| /** |
| * Try to complete a drain request. |
| * |
| * @returns true if the CPU is drained, false otherwise. |
| */ |
| bool tryCompleteDrain(); |
| |
| /** |
| * An AtomicCPUPort overrides the default behaviour of the |
| * recvAtomicSnoop and ignores the packet instead of panicking. It |
| * also provides an implementation for the purely virtual timing |
| * functions and panics on either of these. |
| */ |
| class AtomicCPUPort : public MasterPort |
| { |
| |
| public: |
| |
| AtomicCPUPort(const std::string &_name, BaseSimpleCPU* _cpu) |
| : MasterPort(_name, _cpu) |
| { } |
| |
| protected: |
| virtual Tick recvAtomicSnoop(PacketPtr pkt) { return 0; } |
| |
| bool recvTimingResp(PacketPtr pkt) |
| { |
| panic("Atomic CPU doesn't expect recvTimingResp!\n"); |
| return true; |
| } |
| |
| void recvRetry() |
| { |
| panic("Atomic CPU doesn't expect recvRetry!\n"); |
| } |
| |
| }; |
| |
| class AtomicCPUDPort : public AtomicCPUPort |
| { |
| |
| public: |
| |
| AtomicCPUDPort(const std::string &_name, BaseSimpleCPU* _cpu) |
| : AtomicCPUPort(_name, _cpu), cpu(_cpu) |
| { |
| cacheBlockMask = ~(cpu->cacheLineSize() - 1); |
| } |
| |
| bool isSnooping() const { return true; } |
| |
| Addr cacheBlockMask; |
| protected: |
| BaseSimpleCPU *cpu; |
| |
| virtual Tick recvAtomicSnoop(PacketPtr pkt); |
| virtual void recvFunctionalSnoop(PacketPtr pkt); |
| }; |
| |
| |
| AtomicCPUPort icachePort; |
| AtomicCPUDPort dcachePort; |
| |
| bool fastmem; |
| Request ifetch_req; |
| Request data_read_req; |
| Request data_write_req; |
| |
| bool dcache_access; |
| Tick dcache_latency; |
| |
| /** Probe Points. */ |
| ProbePointArg<std::pair<SimpleThread*, const StaticInstPtr>> *ppCommit; |
| |
| protected: |
| |
| /** Return a reference to the data port. */ |
| virtual MasterPort &getDataPort() { return dcachePort; } |
| |
| /** Return a reference to the instruction port. */ |
| virtual MasterPort &getInstPort() { return icachePort; } |
| |
| public: |
| |
| unsigned int drain(DrainManager *drain_manager); |
| void drainResume(); |
| |
| void switchOut(); |
| void takeOverFrom(BaseCPU *oldCPU); |
| |
| void verifyMemoryMode() const; |
| |
| virtual void activateContext(ThreadID thread_num); |
| virtual void suspendContext(ThreadID thread_num); |
| |
| Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags); |
| |
| Fault writeMem(uint8_t *data, unsigned size, |
| Addr addr, unsigned flags, uint64_t *res); |
| |
| virtual void regProbePoints(); |
| |
| /** |
| * Print state of address in memory system via PrintReq (for |
| * debugging). |
| */ |
| void printAddr(Addr a); |
| }; |
| |
| #endif // __CPU_SIMPLE_ATOMIC_HH__ |