base.cc revision 2
14997Sgblack@eecs.umich.edu/*
25268Sksewell@umich.edu * Copyright (c) 2003 The Regents of The University of Michigan
35254Sksewell@umich.edu * All rights reserved.
45254Sksewell@umich.edu *
54997Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145254Sksewell@umich.edu * this software without specific prior written permission.
155254Sksewell@umich.edu *
164997Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275254Sksewell@umich.edu */
284997Sgblack@eecs.umich.edu
295268Sksewell@umich.edu#include <string>
305268Sksewell@umich.edu#include <sstream>
315268Sksewell@umich.edu#include <iostream>
324997Sgblack@eecs.umich.edu
334997Sgblack@eecs.umich.edu#include "base_cpu.hh"
345222Sksewell@umich.edu#include "cprintf.hh"
355222Sksewell@umich.edu#include "stats.hh"
364997Sgblack@eecs.umich.edu#include "exec_context.hh"
375222Sksewell@umich.edu#include "misc.hh"
385222Sksewell@umich.edu#include "sim_events.hh"
394997Sgblack@eecs.umich.edu
405222Sksewell@umich.eduusing namespace std;
415222Sksewell@umich.edu
425222Sksewell@umich.eduvector<BaseCPU *> BaseCPU::cpuList;
435222Sksewell@umich.edu
445222Sksewell@umich.edu// This variable reflects the max number of threads in any CPU.  Be
455222Sksewell@umich.edu// careful to only use it once all the CPUs that you care about have
465224Sksewell@umich.edu// been initialized
475224Sksewell@umich.eduint maxThreadsPerCPU = 1;
485222Sksewell@umich.edu
494997Sgblack@eecs.umich.edu#ifdef FULL_SYSTEM
505019Sgblack@eecs.umich.eduBaseCPU::BaseCPU(const string &_name, int _number_of_threads,
515222Sksewell@umich.edu                 Counter max_insts_any_thread,
525222Sksewell@umich.edu                 Counter max_insts_all_threads,
535019Sgblack@eecs.umich.edu                 System *_system, int num, Tick freq)
545222Sksewell@umich.edu    : SimObject(_name), number(num), frequency(freq),
555222Sksewell@umich.edu      number_of_threads(_number_of_threads), system(_system)
565222Sksewell@umich.edu#else
575222Sksewell@umich.eduBaseCPU::BaseCPU(const string &_name, int _number_of_threads,
585019Sgblack@eecs.umich.edu                 Counter max_insts_any_thread,
596329Sgblack@eecs.umich.edu                 Counter max_insts_all_threads)
606329Sgblack@eecs.umich.edu    : SimObject(_name), number_of_threads(_number_of_threads)
616329Sgblack@eecs.umich.edu#endif
626378Sgblack@eecs.umich.edu{
636329Sgblack@eecs.umich.edu    // add self to global list of CPUs
646378Sgblack@eecs.umich.edu    cpuList.push_back(this);
656329Sgblack@eecs.umich.edu
666378Sgblack@eecs.umich.edu    if (number_of_threads > maxThreadsPerCPU)
676329Sgblack@eecs.umich.edu        maxThreadsPerCPU = number_of_threads;
686329Sgblack@eecs.umich.edu
696329Sgblack@eecs.umich.edu    // allocate per-thread instruction-based event queues
706329Sgblack@eecs.umich.edu    comInsnEventQueue = new (EventQueue *)[number_of_threads];
716329Sgblack@eecs.umich.edu    for (int i = 0; i < number_of_threads; ++i)
726329Sgblack@eecs.umich.edu        comInsnEventQueue[i] = new EventQueue("instruction-based event queue");
736329Sgblack@eecs.umich.edu
745222Sksewell@umich.edu    //
755358Sgblack@eecs.umich.edu    // set up instruction-count-based termination events, if any
765222Sksewell@umich.edu    //
776378Sgblack@eecs.umich.edu    if (max_insts_any_thread != 0)
786378Sgblack@eecs.umich.edu        for (int i = 0; i < number_of_threads; ++i)
796378Sgblack@eecs.umich.edu            new SimExitEvent(comInsnEventQueue[i], max_insts_any_thread,
805222Sksewell@umich.edu                "a thread reached the max instruction count");
815222Sksewell@umich.edu
825222Sksewell@umich.edu    if (max_insts_all_threads != 0) {
835222Sksewell@umich.edu        // allocate & initialize shared downcounter: each event will
845222Sksewell@umich.edu        // decrement this when triggered; simulation will terminate
855222Sksewell@umich.edu        // when counter reaches 0
865222Sksewell@umich.edu        int *counter = new int;
875222Sksewell@umich.edu        *counter = number_of_threads;
885222Sksewell@umich.edu        for (int i = 0; i < number_of_threads; ++i)
895222Sksewell@umich.edu            new CountedExitEvent(comInsnEventQueue[i],
905222Sksewell@umich.edu                "all threads reached the max instruction count",
915222Sksewell@umich.edu                max_insts_all_threads, *counter);
925222Sksewell@umich.edu    }
936378Sgblack@eecs.umich.edu
945222Sksewell@umich.edu#ifdef FULL_SYSTEM
955222Sksewell@umich.edu    memset(interrupts, 0, sizeof(interrupts));
965222Sksewell@umich.edu    intstatus = 0;
975222Sksewell@umich.edu#endif
986378Sgblack@eecs.umich.edu}
995222Sksewell@umich.edu
1005222Sksewell@umich.eduvoid
1015222Sksewell@umich.eduBaseCPU::regStats()
1025222Sksewell@umich.edu{
1035222Sksewell@umich.edu    int size = contexts.size();
1046378Sgblack@eecs.umich.edu    if (size > 1) {
1056378Sgblack@eecs.umich.edu        for (int i = 0; i < size; ++i) {
1066378Sgblack@eecs.umich.edu            stringstream namestr;
1075222Sksewell@umich.edu            ccprintf(namestr, "%s.ctx%d", name(), i);
1085222Sksewell@umich.edu            contexts[i]->regStats(namestr.str());
1096378Sgblack@eecs.umich.edu        }
1105222Sksewell@umich.edu    } else if (size == 1)
1115222Sksewell@umich.edu        contexts[0]->regStats(name());
1125019Sgblack@eecs.umich.edu}
1135019Sgblack@eecs.umich.edu
1145222Sksewell@umich.edu#ifdef FULL_SYSTEM
1155222Sksewell@umich.eduvoid
1165222Sksewell@umich.eduBaseCPU::post_interrupt(int int_num, int index)
1175222Sksewell@umich.edu{
1185222Sksewell@umich.edu    DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
1196378Sgblack@eecs.umich.edu
1206378Sgblack@eecs.umich.edu    if (int_num < 0 || int_num >= NumInterruptLevels)
1215222Sksewell@umich.edu        panic("int_num out of bounds\n");
1225222Sksewell@umich.edu
1235222Sksewell@umich.edu    if (index < 0 || index >= sizeof(uint8_t) * 8)
1245222Sksewell@umich.edu        panic("int_num out of bounds\n");
1255222Sksewell@umich.edu
1265222Sksewell@umich.edu    AlphaISA::check_interrupts = 1;
1276378Sgblack@eecs.umich.edu    interrupts[int_num] |= 1 << index;
1286378Sgblack@eecs.umich.edu    intstatus |= (ULL(1) << int_num);
1295222Sksewell@umich.edu}
1305222Sksewell@umich.edu
1316378Sgblack@eecs.umich.eduvoid
1326378Sgblack@eecs.umich.eduBaseCPU::clear_interrupt(int int_num, int index)
1335222Sksewell@umich.edu{
1345222Sksewell@umich.edu    DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
1355222Sksewell@umich.edu
1365222Sksewell@umich.edu    if (int_num < 0 || int_num >= NumInterruptLevels)
1376378Sgblack@eecs.umich.edu        panic("int_num out of bounds\n");
1385222Sksewell@umich.edu
1395222Sksewell@umich.edu    if (index < 0 || index >= sizeof(uint8_t) * 8)
1405222Sksewell@umich.edu        panic("int_num out of bounds\n");
1415222Sksewell@umich.edu
1426378Sgblack@eecs.umich.edu    interrupts[int_num] &= ~(1 << index);
1436378Sgblack@eecs.umich.edu    if (interrupts[int_num] == 0)
1446378Sgblack@eecs.umich.edu        intstatus &= ~(ULL(1) << int_num);
1456378Sgblack@eecs.umich.edu}
1465222Sksewell@umich.edu
1475222Sksewell@umich.eduvoid
1485222Sksewell@umich.eduBaseCPU::clear_interrupts()
1496378Sgblack@eecs.umich.edu{
1505222Sksewell@umich.edu    DPRINTF(Interrupt, "Interrupts all cleared\n");
1515222Sksewell@umich.edu
1525222Sksewell@umich.edu    memset(interrupts, 0, sizeof(interrupts));
1535222Sksewell@umich.edu    intstatus = 0;
1545222Sksewell@umich.edu}
1555222Sksewell@umich.edu
1566378Sgblack@eecs.umich.edu#endif // FULL_SYSTEM
1576378Sgblack@eecs.umich.edu
1585222Sksewell@umich.eduDEFINE_SIM_OBJECT_CLASS_NAME("BaseCPU", BaseCPU)
1595222Sksewell@umich.edu