Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_BreakPoint.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_BreakPoint.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
#include "SS_BreakPoint.h"
#include "SS_Signal.h"
#include "SS_Strand.h"
BL_Mutex SS_BreakPoint::id_mutex;
SS_BreakPoint::Ident SS_BreakPoint::id_count = 0;
SS_BreakPoint::SS_BreakPoint( Break _type, SS_BreakPoint* _next )/*{{{*/
:
type(_type),
enabled(true),
triggered(false),
next(_next),
link(0)
{
id_mutex.lock();
id = id_count;
id_count++;
id_mutex.unlock();
}
/*}}}*/
bool SS_BreakPoint::trigger( SS_Strand* s )/*{{{*/
{
if (triggered)
{
triggered = false;
}
else
{
triggered = true;
SS_Signal* sgn = s->msg.make_signal(SS_Signal::BREAKPOINT);
sgn->breakpoint = this;
s->post_signal(sgn);
// In case of trc_step(1) we should get out of the loop
// signaling a breakpoint. Breaks are reported to the
// UI though a non zero return of step. See SS_Strand::trc_step()
// for why we set break_hit prematurely.
s->break_hit = this;
}
return triggered;
}
/*}}}*/
void SS_BreakPoint::unlink( SS_BreakPoint** root )/*{{{*/
{
SS_BreakPoint* prev = 0;
SS_BreakPoint* help = *root;
while (help != this)
{
prev = help;
help = help->link;
}
(prev ? prev->link : *root) = this->link;
}
/*}}}*/
extern "C" SS_Vaddr run_exe_breakpoint( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i )/*{{{*/
{
SS_BreakPoint* bp = i->bp;
if (bp->enabled)
{
if (bp->triggered)
{
bp->triggered = false;
}
else
{
bp->triggered = true;
SS_Signal* sgn = s->msg.make_signal(SS_Signal::BREAKPOINT);
sgn->breakpoint = bp;
s->post_signal(sgn);
return pc;
}
}
return (bp->inst.exe)(pc,npc,s,&bp->inst);
}
/*}}}*/
void SS_BreakPoint::remove()/*{{{*/
{
orig->exe = inst.exe;
orig->rs1 = inst.rs1;
orig->rs2 = inst.rs2;
orig->rs3 = inst.rs3;
orig->rd = inst.rd;
orig->bp = inst.bp;
orig->opc = inst.opc;
orig->flg = inst.flg;
}
/*}}}*/