From 52b31ea0a6a15b4a88530cfe411224d750e37899 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 10 Oct 2003 09:57:26 -0700 Subject: File moves for the reorg. Tree is in broken state until I commit the makefile and #include changes. --HG-- rename : sim/cache/lzss_compression.cc => base/compression/lzss_compression.cc rename : sim/cache/lzss_compression.hh => base/compression/lzss_compression.hh rename : sim/cache/null_compression.hh => base/compression/null_compression.hh rename : sim/hybrid_pred.cc => base/hybrid_pred.cc rename : sim/hybrid_pred.hh => base/hybrid_pred.hh rename : base/aout_object.cc => base/loader/aout_object.cc rename : base/aout_object.hh => base/loader/aout_object.hh rename : base/coff_sym.h => base/loader/coff_sym.h rename : base/coff_symconst.h => base/loader/coff_symconst.h rename : base/ecoff_object.cc => base/loader/ecoff_object.cc rename : base/ecoff_object.hh => base/loader/ecoff_object.hh rename : base/elf_object.cc => base/loader/elf_object.cc rename : base/elf_object.hh => base/loader/elf_object.hh rename : base/exec_aout.h => base/loader/exec_aout.h rename : base/exec_ecoff.h => base/loader/exec_ecoff.h rename : base/object_file.cc => base/loader/object_file.cc rename : base/object_file.hh => base/loader/object_file.hh rename : base/symtab.cc => base/loader/symtab.cc rename : base/symtab.hh => base/loader/symtab.hh rename : sim/predictor.hh => base/predictor.hh rename : sim/sat_counter.cc => base/sat_counter.cc rename : sim/sat_counter.hh => base/sat_counter.hh rename : sim/base_cpu.cc => cpu/base_cpu.cc rename : sim/base_cpu.hh => cpu/base_cpu.hh rename : sim/exec_context.cc => cpu/exec_context.cc rename : sim/exec_context.hh => cpu/exec_context.hh rename : sim/exetrace.cc => cpu/exetrace.cc rename : sim/exetrace.hh => cpu/exetrace.hh rename : sim/op_class.hh => cpu/full_cpu/op_class.hh rename : sim/smt.hh => cpu/full_cpu/smt.hh rename : sim/inst_seq.hh => cpu/inst_seq.hh rename : sim/intr_control.cc => cpu/intr_control.cc rename : sim/intr_control.hh => cpu/intr_control.hh rename : sim/memtest.cc => cpu/memtest/memtest.cc rename : sim/memtest.hh => cpu/memtest/memtest.hh rename : sim/pc_event.cc => cpu/pc_event.cc rename : sim/pc_event.hh => cpu/pc_event.hh rename : sim/simple_cpu.cc => cpu/simple_cpu/simple_cpu.cc rename : sim/simple_cpu.hh => cpu/simple_cpu/simple_cpu.hh rename : sim/static_inst.cc => cpu/static_inst.cc rename : sim/static_inst.hh => cpu/static_inst.hh extra : convert_revision : 05bd41acb2a424f1a38609fd4ac6df681bb479d6 --- cpu/pc_event.cc | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 cpu/pc_event.cc (limited to 'cpu/pc_event.cc') diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc new file mode 100644 index 000000000..4de425199 --- /dev/null +++ b/cpu/pc_event.cc @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2003 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. + */ + +#include +#include +#include +#include + +#include "debug.hh" +#include "exec_context.hh" +#include "pc_event.hh" +#include "trace.hh" +#include "universe.hh" + +#ifdef FULL_SYSTEM +#include "arguments.hh" +#include "pmap.h" +#include "kernel.hh" +#include "memory_control.hh" +#include "cpu.hh" +#include "system.hh" +#include "bpred.hh" +#endif + +using namespace std; + +PCEventQueue::PCEventQueue() +{} + +PCEventQueue::~PCEventQueue() +{} + +bool +PCEventQueue::remove(PCEvent *event) +{ + int removed = 0; + range_t range = equal_range(event); + for (iterator i = range.first; i != range.second; ++i) { + if (*i == event) { + DPRINTF(PCEvent, "PC based event removed at %#x: %s\n", + event->pc(), event->descr()); + pc_map.erase(i); + ++removed; + } + } + + return removed > 0; +} + +bool +PCEventQueue::schedule(PCEvent *event) +{ + pc_map.push_back(event); + sort(pc_map.begin(), pc_map.end(), MapCompare()); + + DPRINTF(PCEvent, "PC based event scheduled for %#x: %s\n", + event->pc(), event->descr()); + + return true; +} + +bool +PCEventQueue::service(ExecContext *xc) +{ + Addr pc = xc->regs.pc; + int serviced = 0; + range_t range = equal_range(pc); + for (iterator i = range.first; i != range.second; ++i) { + // Make sure that the pc wasn't changed as the side effect of + // another event. This for example, prevents two invocations + // of the SkipFuncEvent. Maybe we should have separate PC + // event queues for each processor? + if (pc != xc->regs.pc) + continue; + + DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n", + (*i)->pc(), (*i)->descr()); + + (*i)->process(xc); + ++serviced; + } + + return serviced > 0; +} + +void +PCEventQueue::dump() const +{ + const_iterator i = pc_map.begin(); + const_iterator e = pc_map.end(); + + for (; i != e; ++i) + cprintf("%d: event at %#x: %s\n", curTick, (*i)->pc(), + (*i)->descr()); +} + +PCEventQueue::range_t +PCEventQueue::equal_range(Addr pc) +{ + return std::equal_range(pc_map.begin(), pc_map.end(), pc, MapCompare()); +} + +#ifdef FULL_SYSTEM +void +SkipFuncEvent::process(ExecContext *xc) +{ + Addr newpc = xc->regs.intRegFile[ReturnAddressReg]; + + DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description, + xc->regs.pc, newpc); + + xc->regs.pc = newpc; + xc->regs.npc = xc->regs.pc + sizeof(MachInst); + + BranchPred *bp = xc->cpu->getBranchPred(); + if (bp != NULL) { + bp->popRAS(xc->thread_num); + } +} + +void +BadAddrEvent::process(ExecContext *xc) +{ + // The following gross hack is the equivalent function to the + // annotation for vmunix::badaddr in: + // simos/simulation/apps/tcl/osf/tlaser.tcl + + uint64_t a0 = xc->regs.intRegFile[ArgumentReg0]; + + if (a0 < ALPHA_K0SEG_BASE || a0 >= ALPHA_K1SEG_BASE || + xc->memCtrl->badaddr(ALPHA_K0SEG_TO_PHYS(a0) & PA_IMPL_MASK)) { + + DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); + xc->regs.intRegFile[ReturnValueReg] = 0x1; + SkipFuncEvent::process(xc); + } + else + DPRINTF(BADADDR, "badaddr arg=%#x good\n", a0); +} + +void +PrintfEvent::process(ExecContext *xc) +{ + if (DTRACE(Printf)) { + DebugOut() << curTick << ": " << xc->cpu->name() << ": "; + + AlphaArguments args(xc); + Kernel::Printf(args); + } +} + +void +DebugPrintfEvent::process(ExecContext *xc) +{ + if (DTRACE(DebugPrintf)) { + if (!raw) + DebugOut() << curTick << ": " << xc->cpu->name() << ": "; + + AlphaArguments args(xc); + Kernel::Printf(args); + } +} + +void +DumpMbufEvent::process(ExecContext *xc) +{ + if (DTRACE(DebugPrintf)) { + AlphaArguments args(xc); + Kernel::DumpMbuf(args); + } +} +#endif + +BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, bool del) + : PCEvent(q, desc), remove(del) +{ +} + +void +BreakPCEvent::process(ExecContext *xc) +{ + debug_break(); + if (remove) + delete this; +} + +#ifdef FULL_SYSTEM +extern "C" +void +sched_break_pc_sys(System *sys, Addr addr) +{ + PCEvent *event = new BreakPCEvent(&sys->pcEventQueue, "debug break", true); + event->schedule(addr); +} + +extern "C" +void +sched_break_pc(Addr addr) +{ + for (vector::iterator sysi = System::systemList.begin(); + sysi != System::systemList.end(); ++sysi) { + sched_break_pc_sys(*sysi, addr); + } + +} +#endif -- cgit v1.2.3