base.cc revision 2
12SN/A/* 21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292SN/A#include <string> 302SN/A#include <sstream> 312439SN/A#include <iostream> 322984Sgblack@eecs.umich.edu 33146SN/A#include "base_cpu.hh" 34146SN/A#include "cprintf.hh" 35146SN/A#include "stats.hh" 36146SN/A#include "exec_context.hh" 37146SN/A#include "misc.hh" 38146SN/A#include "sim_events.hh" 391717SN/A 40146SN/Ausing namespace std; 411717SN/A 42146SN/Avector<BaseCPU *> BaseCPU::cpuList; 431977SN/A 442623SN/A// This variable reflects the max number of threads in any CPU. Be 452683Sktlim@umich.edu// careful to only use it once all the CPUs that you care about have 461717SN/A// been initialized 47146SN/Aint maxThreadsPerCPU = 1; 482683Sktlim@umich.edu 493348Sbinkertn@umich.edu#ifdef FULL_SYSTEM 502683Sktlim@umich.eduBaseCPU::BaseCPU(const string &_name, int _number_of_threads, 512036SN/A Counter max_insts_any_thread, 52146SN/A Counter max_insts_all_threads, 5356SN/A System *_system, int num, Tick freq) 5456SN/A : SimObject(_name), number(num), frequency(freq), 5556SN/A number_of_threads(_number_of_threads), system(_system) 56695SN/A#else 572901Ssaidi@eecs.umich.eduBaseCPU::BaseCPU(const string &_name, int _number_of_threads, 582SN/A Counter max_insts_any_thread, 591858SN/A Counter max_insts_all_threads) 603565Sgblack@eecs.umich.edu : SimObject(_name), number_of_threads(_number_of_threads) 613565Sgblack@eecs.umich.edu#endif 622171SN/A{ 632170SN/A // add self to global list of CPUs 643562Sgblack@eecs.umich.edu cpuList.push_back(this); 65146SN/A 662462SN/A if (number_of_threads > maxThreadsPerCPU) 67146SN/A maxThreadsPerCPU = number_of_threads; 682SN/A 692SN/A // allocate per-thread instruction-based event queues 702449SN/A comInsnEventQueue = new (EventQueue *)[number_of_threads]; 711355SN/A for (int i = 0; i < number_of_threads; ++i) 722623SN/A comInsnEventQueue[i] = new EventQueue("instruction-based event queue"); 733402Sktlim@umich.edu 74224SN/A // 751858SN/A // set up instruction-count-based termination events, if any 762683Sktlim@umich.edu // 772420SN/A if (max_insts_any_thread != 0) 782683Sktlim@umich.edu for (int i = 0; i < number_of_threads; ++i) 793402Sktlim@umich.edu new SimExitEvent(comInsnEventQueue[i], max_insts_any_thread, 802420SN/A "a thread reached the max instruction count"); 812SN/A 822683Sktlim@umich.edu if (max_insts_all_threads != 0) { 832672Sktlim@umich.edu // allocate & initialize shared downcounter: each event will 842683Sktlim@umich.edu // decrement this when triggered; simulation will terminate 852SN/A // when counter reaches 0 862SN/A int *counter = new int; 87334SN/A *counter = number_of_threads; 88140SN/A for (int i = 0; i < number_of_threads; ++i) 89334SN/A new CountedExitEvent(comInsnEventQueue[i], 902SN/A "all threads reached the max instruction count", 912SN/A max_insts_all_threads, *counter); 922SN/A } 932680Sktlim@umich.edu 942SN/A#ifdef FULL_SYSTEM 952SN/A memset(interrupts, 0, sizeof(interrupts)); 962623SN/A intstatus = 0; 972SN/A#endif 982SN/A} 992SN/A 100180SN/Avoid 1012623SN/ABaseCPU::regStats() 102393SN/A{ 103393SN/A int size = contexts.size(); 104393SN/A if (size > 1) { 105393SN/A for (int i = 0; i < size; ++i) { 106384SN/A stringstream namestr; 107384SN/A ccprintf(namestr, "%s.ctx%d", name(), i); 108393SN/A contexts[i]->regStats(namestr.str()); 1092623SN/A } 110393SN/A } else if (size == 1) 111393SN/A contexts[0]->regStats(name()); 112393SN/A} 113393SN/A 114384SN/A#ifdef FULL_SYSTEM 115189SN/Avoid 116189SN/ABaseCPU::post_interrupt(int int_num, int index) 1172623SN/A{ 1182SN/A DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 119729SN/A 120334SN/A if (int_num < 0 || int_num >= NumInterruptLevels) 1212SN/A panic("int_num out of bounds\n"); 1222SN/A 1232SN/A if (index < 0 || index >= sizeof(uint8_t) * 8) 1242SN/A panic("int_num out of bounds\n"); 1252SN/A 1262SN/A AlphaISA::check_interrupts = 1; 1272SN/A interrupts[int_num] |= 1 << index; 1282SN/A intstatus |= (ULL(1) << int_num); 1292SN/A} 1302SN/A 1312SN/Avoid 1322SN/ABaseCPU::clear_interrupt(int int_num, int index) 1331001SN/A{ 1341001SN/A DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 1351001SN/A 1361001SN/A if (int_num < 0 || int_num >= NumInterruptLevels) 1371001SN/A panic("int_num out of bounds\n"); 1382SN/A 1392SN/A if (index < 0 || index >= sizeof(uint8_t) * 8) 1402SN/A panic("int_num out of bounds\n"); 1412SN/A 1422SN/A interrupts[int_num] &= ~(1 << index); 1432SN/A if (interrupts[int_num] == 0) 1442SN/A intstatus &= ~(ULL(1) << int_num); 1452SN/A} 1462SN/A 1472SN/Avoid 1482SN/ABaseCPU::clear_interrupts() 1492SN/A{ 1502SN/A DPRINTF(Interrupt, "Interrupts all cleared\n"); 1512SN/A 1522SN/A memset(interrupts, 0, sizeof(interrupts)); 1532SN/A intstatus = 0; 1542SN/A} 1552390SN/A 1562390SN/A#endif // FULL_SYSTEM 1572390SN/A 1582390SN/ADEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU) 1592390SN/A