1/* 2 * Copyright (c) 2012-2014 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 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Andrew Bardsley 38 */ 39 40/** 41 * @file 42 * 43 * Top level definition of the Minor in-order CPU model 44 */ 45 46#ifndef __CPU_MINOR_CPU_HH__ 47#define __CPU_MINOR_CPU_HH__ 48 49#include "cpu/minor/activity.hh" 50#include "cpu/minor/stats.hh" 51#include "cpu/base.hh" 52#include "cpu/simple_thread.hh" 53#include "enums/ThreadPolicy.hh" 54#include "params/MinorCPU.hh" 55 56namespace Minor 57{ 58/** Forward declared to break the cyclic inclusion dependencies between 59 * pipeline and cpu */ 60class Pipeline; 61 62/** Minor will use the SimpleThread state for now */ 63typedef SimpleThread MinorThread; 64}; 65 66/** 67 * MinorCPU is an in-order CPU model with four fixed pipeline stages: 68 * 69 * Fetch1 - fetches lines from memory 70 * Fetch2 - decomposes lines into macro-op instructions 71 * Decode - decomposes macro-ops into micro-ops 72 * Execute - executes those micro-ops 73 * 74 * This pipeline is carried in the MinorCPU::pipeline object. 75 * The exec_context interface is not carried by MinorCPU but by 76 * Minor::ExecContext objects 77 * created by Minor::Execute. 78 */ 79class MinorCPU : public BaseCPU 80{ 81 protected: 82 /** pipeline is a container for the clockable pipeline stage objects. 83 * Elements of pipeline call TheISA to implement the model. */ 84 Minor::Pipeline *pipeline; 85 86 public: 87 /** Activity recording for pipeline. This belongs to Pipeline but 88 * stages will access it through the CPU as the MinorCPU object 89 * actually mediates idling behaviour */ 90 Minor::MinorActivityRecorder *activityRecorder; 91 92 /** These are thread state-representing objects for this CPU. If 93 * you need a ThreadContext for *any* reason, use 94 * threads[threadId]->getTC() */ 95 std::vector<Minor::MinorThread *> threads; 96 97 public: 98 /** Provide a non-protected base class for Minor's Ports as derived 99 * classes are created by Fetch1 and Execute */ 100 class MinorCPUPort : public MasterPort 101 { 102 public: 103 /** The enclosing cpu */ 104 MinorCPU &cpu; 105 106 public: 107 MinorCPUPort(const std::string& name_, MinorCPU &cpu_) 108 : MasterPort(name_, &cpu_), cpu(cpu_) 109 { } 110 111 }; 112 113 /** Thread Scheduling Policy (RoundRobin, Random, etc) */ 114 Enums::ThreadPolicy threadPolicy; 115 protected: 116 /** Return a reference to the data port. */ 117 Port &getDataPort() override; 118 119 /** Return a reference to the instruction port. */ 120 Port &getInstPort() override; 121 122 public: 123 MinorCPU(MinorCPUParams *params); 124 125 ~MinorCPU(); 126 127 public: 128 /** Starting, waking and initialisation */ 129 void init() override; 130 void startup() override; 131 void wakeup(ThreadID tid) override; 132 133 Addr dbg_vtophys(Addr addr); 134 135 /** Processor-specific statistics */ 136 Minor::MinorStats stats; 137 138 /** Stats interface from SimObject (by way of BaseCPU) */ 139 void regStats() override; 140 141 /** Simple inst count interface from BaseCPU */ 142 Counter totalInsts() const override; 143 Counter totalOps() const override; 144 145 void serializeThread(CheckpointOut &cp, ThreadID tid) const override; 146 void unserializeThread(CheckpointIn &cp, ThreadID tid) override; 147 148 /** Serialize pipeline data */ 149 void serialize(CheckpointOut &cp) const override; 150 void unserialize(CheckpointIn &cp) override; 151 152 /** Drain interface */ 153 DrainState drain() override; 154 void drainResume() override; 155 /** Signal from Pipeline that MinorCPU should signal that a drain 156 * is complete and set its drainState */ 157 void signalDrainDone(); 158 void memWriteback() override; 159 160 /** Switching interface from BaseCPU */ 161 void switchOut() override; 162 void takeOverFrom(BaseCPU *old_cpu) override; 163 164 /** Thread activation interface from BaseCPU. */ 165 void activateContext(ThreadID thread_id) override; 166 void suspendContext(ThreadID thread_id) override; 167 168 /** Thread scheduling utility functions */ 169 std::vector<ThreadID> roundRobinPriority(ThreadID priority) 170 { 171 std::vector<ThreadID> prio_list; 172 for (ThreadID i = 1; i <= numThreads; i++) { 173 prio_list.push_back((priority + i) % numThreads); 174 } 175 return prio_list; 176 } 177 178 std::vector<ThreadID> randomPriority() 179 { 180 std::vector<ThreadID> prio_list; 181 for (ThreadID i = 0; i < numThreads; i++) { 182 prio_list.push_back(i); 183 } 184 std::random_shuffle(prio_list.begin(), prio_list.end()); 185 return prio_list; 186 } 187 188 /** Interface for stages to signal that they have become active after 189 * a callback or eventq event where the pipeline itself may have 190 * already been idled. The stage argument should be from the 191 * enumeration Pipeline::StageId */ 192 void wakeupOnEvent(unsigned int stage_id); 193}; 194 195#endif /* __CPU_MINOR_CPU_HH__ */ 196