1/* 2 * Copyright (c) 2012 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) 2002-2005 The Regents of The University of Michigan 15 * Copyright (c) 2011 Regents of the University of California 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution; 25 * neither the name of the copyright holders nor the names of its 26 * contributors may be used to endorse or promote products derived from 27 * this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Steve Reinhardt 42 * Lisa Hsu 43 * Nathan Binkert 44 * Rick Strong 45 */ 46 47#ifndef __SYSTEM_HH__ 48#define __SYSTEM_HH__ 49 50#include <string> 51#include <vector> 52 53#include "base/loader/symtab.hh" 54#include "base/misc.hh" 55#include "base/statistics.hh" 56#include "cpu/pc_event.hh" 57#include "enums/MemoryMode.hh" 58#include "kern/system_events.hh" 59#include "mem/fs_translating_port_proxy.hh" 60#include "mem/mem_object.hh" 61#include "mem/port.hh" 62#include "mem/physical.hh" 63#include "params/System.hh" 64 65class BaseCPU; 66class BaseRemoteGDB; 67class GDBListener; 68class ObjectFile; 69class Platform; 70class ThreadContext; 71 72class System : public MemObject 73{ 74 private: 75 76 /** 77 * Private class for the system port which is only used as a 78 * master for debug access and for non-structural entities that do 79 * not have a port of their own. 80 */ 81 class SystemPort : public MasterPort 82 { 83 public: 84 85 /** 86 * Create a system port with a name and an owner. 87 */ 88 SystemPort(const std::string &_name, MemObject *_owner) 89 : MasterPort(_name, _owner) 90 { } 91 bool recvTimingResp(PacketPtr pkt) 92 { panic("SystemPort does not receive timing!\n"); return false; } 93 void recvRetry() 94 { panic("SystemPort does not expect retry!\n"); } 95 }; 96 97 SystemPort _systemPort; 98 99 public: 100 101 /** 102 * After all objects have been created and all ports are 103 * connected, check that the system port is connected. 104 */ 105 virtual void init(); 106 107 /** 108 * Get a reference to the system port that can be used by 109 * non-structural simulation objects like processes or threads, or 110 * external entities like loaders and debuggers, etc, to access 111 * the memory system. 112 * 113 * @return a reference to the system port we own 114 */ 115 MasterPort& getSystemPort() { return _systemPort; } 116 117 /** 118 * Additional function to return the Port of a memory object. 119 */ 120 MasterPort& getMasterPort(const std::string &if_name, int idx = -1); 121 122 static const char *MemoryModeStrings[3]; 123 124 Enums::MemoryMode 125 getMemoryMode() 126 { 127 assert(memoryMode); 128 return memoryMode; 129 } 130 131 /** Change the memory mode of the system. This should only be called by the 132 * python!! 133 * @param mode Mode to change to (atomic/timing) 134 */ 135 void setMemoryMode(Enums::MemoryMode mode); 136 137 PCEventQueue pcEventQueue; 138 139 std::vector<ThreadContext *> threadContexts; 140 int _numContexts; 141 142 ThreadContext *getThreadContext(ThreadID tid) 143 { 144 return threadContexts[tid]; 145 } 146 147 int numContexts() 148 { 149 assert(_numContexts == (int)threadContexts.size()); 150 return _numContexts; 151 } 152 153 /** Return number of running (non-halted) thread contexts in 154 * system. These threads could be Active or Suspended. */ 155 int numRunningContexts(); 156 157 Addr pagePtr; 158 159 uint64_t init_param; 160 161 /** Port to physical memory used for writing object files into ram at 162 * boot.*/ 163 PortProxy physProxy; 164 FSTranslatingPortProxy virtProxy; 165 166 /** kernel symbol table */ 167 SymbolTable *kernelSymtab; 168 169 /** Object pointer for the kernel code */ 170 ObjectFile *kernel; 171 172 /** Begining of kernel code */ 173 Addr kernelStart; 174 175 /** End of kernel code */ 176 Addr kernelEnd; 177 178 /** Entry point in the kernel to start at */ 179 Addr kernelEntry; 180 181 /** Mask that should be anded for binary/symbol loading. 182 * This allows one two different OS requirements for the same ISA to be 183 * handled. Some OSes are compiled for a virtual address and need to be 184 * loaded into physical memory that starts at address 0, while other 185 * bare metal tools generate images that start at address 0. 186 */ 187 Addr loadAddrMask; 188 189 protected: 190 uint64_t nextPID; 191 192 public: 193 uint64_t allocatePID() 194 { 195 return nextPID++; 196 } 197 198 /** Get a pointer to access the physical memory of the system */ 199 PhysicalMemory& getPhysMem() { return physmem; } 200 201 /** Amount of physical memory that is still free */ 202 Addr freeMemSize() const; 203 204 /** Amount of physical memory that exists */ 205 Addr memSize() const; 206 207 /** 208 * Check if a physical address is within a range of a memory that 209 * is part of the global address map. 210 * 211 * @param addr A physical address 212 * @return Whether the address corresponds to a memory 213 */ 214 bool isMemAddr(Addr addr) const; 215 216 protected: 217 218 PhysicalMemory physmem; 219 220 Enums::MemoryMode memoryMode; 221 uint64_t workItemsBegin; 222 uint64_t workItemsEnd; 223 uint32_t numWorkIds; 224 std::vector<bool> activeCpus; 225 226 /** This array is a per-sytem list of all devices capable of issuing a 227 * memory system request and an associated string for each master id. 228 * It's used to uniquely id any master in the system by name for things 229 * like cache statistics. 230 */ 231 std::vector<std::string> masterIds; 232 233 public: 234 235 /** Request an id used to create a request object in the system. All objects 236 * that intend to issues requests into the memory system must request an id 237 * in the init() phase of startup. All master ids must be fixed by the 238 * regStats() phase that immediately preceeds it. This allows objects in the 239 * memory system to understand how many masters may exist and 240 * appropriately name the bins of their per-master stats before the stats 241 * are finalized 242 */ 243 MasterID getMasterId(std::string req_name); 244 245 /** Get the name of an object for a given request id. 246 */ 247 std::string getMasterName(MasterID master_id); 248 249 /** Get the number of masters registered in the system */ 250 MasterID maxMasters() 251 { 252 return masterIds.size(); 253 } 254 255 virtual void regStats(); 256 /** 257 * Called by pseudo_inst to track the number of work items started by this 258 * system. 259 */ 260 uint64_t 261 incWorkItemsBegin() 262 { 263 return ++workItemsBegin; 264 } 265 266 /** 267 * Called by pseudo_inst to track the number of work items completed by 268 * this system. 269 */ 270 uint64_t 271 incWorkItemsEnd() 272 { 273 return ++workItemsEnd; 274 } 275 276 /** 277 * Called by pseudo_inst to mark the cpus actively executing work items. 278 * Returns the total number of cpus that have executed work item begin or 279 * ends. 280 */ 281 int 282 markWorkItem(int index) 283 { 284 int count = 0; 285 assert(index < activeCpus.size()); 286 activeCpus[index] = true; 287 for (std::vector<bool>::iterator i = activeCpus.begin(); 288 i < activeCpus.end(); i++) { 289 if (*i) count++; 290 } 291 return count; 292 } 293 294 inline void workItemBegin(uint32_t tid, uint32_t workid) 295 { 296 std::pair<uint32_t,uint32_t> p(tid, workid); 297 lastWorkItemStarted[p] = curTick(); 298 } 299 300 void workItemEnd(uint32_t tid, uint32_t workid); 301 302 /** 303 * Fix up an address used to match PCs for hooking simulator 304 * events on to target function executions. See comment in 305 * system.cc for details. 306 */ 307 virtual Addr fixFuncEventAddr(Addr addr) 308 { 309 panic("Base fixFuncEventAddr not implemented.\n"); 310 } 311 312 /** 313 * Add a function-based event to the given function, to be looked 314 * up in the specified symbol table. 315 */ 316 template <class T> 317 T *addFuncEvent(SymbolTable *symtab, const char *lbl) 318 { 319 Addr addr = 0; // initialize only to avoid compiler warning 320 321 if (symtab->findAddress(lbl, addr)) { 322 T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr)); 323 return ev; 324 } 325 326 return NULL; 327 } 328 329 /** Add a function-based event to kernel code. */ 330 template <class T> 331 T *addKernelFuncEvent(const char *lbl) 332 { 333 return addFuncEvent<T>(kernelSymtab, lbl); 334 } 335 336 public: 337 std::vector<BaseRemoteGDB *> remoteGDB; 338 std::vector<GDBListener *> gdbListen; 339 bool breakpoint(); 340 341 public: 342 typedef SystemParams Params; 343 344 protected: 345 Params *_params; 346 347 public: 348 System(Params *p); 349 ~System(); 350 351 void initState(); 352 353 const Params *params() const { return (const Params *)_params; } 354 355 public: 356 357 /** 358 * Returns the addess the kernel starts at. 359 * @return address the kernel starts at 360 */ 361 Addr getKernelStart() const { return kernelStart; } 362 363 /** 364 * Returns the addess the kernel ends at. 365 * @return address the kernel ends at 366 */ 367 Addr getKernelEnd() const { return kernelEnd; } 368 369 /** 370 * Returns the addess the entry point to the kernel code. 371 * @return entry point of the kernel code 372 */ 373 Addr getKernelEntry() const { return kernelEntry; } 374 375 /// Allocate npages contiguous unused physical pages 376 /// @return Starting address of first page 377 Addr allocPhysPages(int npages); 378 379 int registerThreadContext(ThreadContext *tc, int assigned=-1); 380 void replaceThreadContext(ThreadContext *tc, int context_id); 381 382 void serialize(std::ostream &os); 383 void unserialize(Checkpoint *cp, const std::string §ion); 384 virtual void resume(); 385 386 public: 387 Counter totalNumInsts; 388 EventQueue instEventQueue; 389 std::map<std::pair<uint32_t,uint32_t>, Tick> lastWorkItemStarted; 390 std::map<uint32_t, Stats::Histogram*> workItemStats; 391 392 //////////////////////////////////////////// 393 // 394 // STATIC GLOBAL SYSTEM LIST 395 // 396 //////////////////////////////////////////// 397 398 static std::vector<System *> systemList; 399 static int numSystemsRunning; 400 401 static void printSystems(); 402 403 // For futex system call 404 std::map<uint64_t, std::list<ThreadContext *> * > futexMap; 405
|