summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/SConscript2
-rw-r--r--src/arch/sparc/asi.hh2
-rw-r--r--src/arch/sparc/faults.cc41
-rw-r--r--src/arch/sparc/faults.hh8
-rw-r--r--src/arch/sparc/interrupts.hh92
-rw-r--r--src/arch/sparc/miscregfile.cc147
-rw-r--r--src/arch/sparc/miscregfile.hh6
-rw-r--r--src/arch/sparc/remote_gdb.cc456
-rw-r--r--src/arch/sparc/remote_gdb.hh129
-rw-r--r--src/arch/sparc/system.cc13
-rw-r--r--src/arch/sparc/system.hh2
-rw-r--r--src/arch/sparc/utility.hh7
-rw-r--r--src/arch/sparc/vtophys.cc132
13 files changed, 857 insertions, 180 deletions
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index e317502e0..5843058a4 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -54,8 +54,8 @@ base_sources = Split('''
# Full-system sources
full_system_sources = Split('''
- ua2005.cc
vtophys.cc
+ system.cc
''')
# Syscall emulation (non-full-system) sources
diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh
index 876567225..6677b23df 100644
--- a/src/arch/sparc/asi.hh
+++ b/src/arch/sparc/asi.hh
@@ -219,4 +219,4 @@ namespace SparcISA
};
-#endif // __ARCH_SPARC_TLB_HH__
+#endif // __ARCH_SPARC_ASI_HH__
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 567ca5f5c..da7fc730d 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -33,12 +33,13 @@
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
-#include "arch/sparc/process.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
+#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
+#include "arch/sparc/process.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#endif
@@ -361,15 +362,43 @@ void SparcFault::invoke(ThreadContext * tc)
//Use the SPARC trap state machine
}
+void PowerOnReset::invoke(ThreadContext * tc)
+{
+ //For SPARC, when a system is first started, there is a power
+ //on reset Trap which sets the processor into the following state.
+ //Bits that aren't set aren't defined on startup.
+ /*
+ tl = MaxTL;
+ gl = MaxGL;
+
+ tickFields.counter = 0; //The TICK register is unreadable bya
+ tickFields.npt = 1; //The TICK register is unreadable by by !priv
+
+ softint = 0; // Clear all the soft interrupt bits
+ tick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ stickFields.npt = 1; //The TICK register is unreadable by by !priv
+ stick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+
+ tt[tl] = _trapType;
+ pstate = 0; // fields 0 but pef
+ pstateFields.pef = 1;
+
+ hpstate = 0;
+ hpstateFields.red = 1;
+ hpstateFields.hpriv = 1;
+ hpstateFields.tlz = 0; // this is a guess
+ hintp = 0; // no interrupts pending
+ hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ */
+}
+
#endif
#if !FULL_SYSTEM
-void TrapInstruction::invoke(ThreadContext * tc)
-{
- // Should be handled in ISA.
-}
-
void SpillNNormal::invoke(ThreadContext *tc)
{
doNormalFault(tc, trapType());
diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh
index 394a06294..0c7106707 100644
--- a/src/arch/sparc/faults.hh
+++ b/src/arch/sparc/faults.hh
@@ -130,6 +130,7 @@ class PowerOnReset : public SparcFault
TrapType trapType() {return _trapType;}
FaultPriority priority() {return _priority;}
FaultStat & countStat() {return _count;}
+ void invoke(ThreadContext * tc);
};
class WatchDogReset : public SparcFault
@@ -603,17 +604,12 @@ class TrapInstruction : public EnumeratedFault
static TrapType _baseTrapType;
static FaultPriority _priority;
static FaultStat _count;
- uint64_t syscall_num;
TrapType baseTrapType() {return _baseTrapType;}
public:
- TrapInstruction(uint32_t n, uint64_t syscall) :
- EnumeratedFault(n), syscall_num(syscall) {;}
+ TrapInstruction(int32_t n) : EnumeratedFault(n) {;}
FaultName name() {return _name;}
FaultPriority priority() {return _priority;}
FaultStat & countStat() {return _count;}
-#if !FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
};
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh
new file mode 100644
index 000000000..0072f4184
--- /dev/null
+++ b/src/arch/sparc/interrupts.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006 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.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_SPARC_INTERRUPT_HH__
+#define __ARCH_SPARC_INTERRUPT_HH__
+
+#include "arch/sparc/faults.hh"
+
+namespace SparcISA
+{
+ class Interrupts
+ {
+ protected:
+ Fault interrupts[NumInterruptLevels];
+ bool requested[NumInterruptLevels];
+
+ public:
+ Interrupts()
+ {
+ for(int x = 0; x < NumInterruptLevels; x++)
+ {
+ interrupts[x] = new InterruptLevelN(x);
+ requested[x] = false;
+ }
+ }
+ void post(int int_num, int index)
+ {
+ if(int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds\n");
+
+ requested[int_num] = true;
+ }
+
+ void clear(int int_num, int index)
+ {
+ requested[int_num] = false;
+ }
+
+ void clear_all()
+ {
+ for(int x = 0; x < NumInterruptLevels; x++)
+ requested[x] = false;
+ }
+
+ bool check_interrupts(ThreadContext * tc) const
+ {
+ return true;
+ }
+
+ Fault getInterrupt(ThreadContext * tc)
+ {
+ return NoFault;
+ }
+
+ void serialize(std::ostream &os)
+ {
+ }
+
+ void unserialize(Checkpoint *cp, const std::string &section)
+ {
+ }
+ };
+}
+
+#endif // __ARCH_SPARC_INTERRUPT_HH__
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 2f3cfb417..217fba0bd 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -31,9 +31,14 @@
#include "arch/sparc/miscregfile.hh"
#include "base/trace.hh"
+#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
+#if FULL_SYSTEM
+#include "arch/sparc/system.hh"
+#endif
+
using namespace SparcISA;
using namespace std;
@@ -55,51 +60,8 @@ string SparcISA::getMiscRegName(RegIndex index)
return miscRegName[index];
}
-#if FULL_SYSTEM
-
-//XXX These need an implementation someplace
-/** Fullsystem only register version of ReadRegWithEffect() */
-MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, ThreadContext *tc);
-/** Fullsystem only register version of SetRegWithEffect() */
-void MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc);
-#endif
-
void MiscRegFile::reset()
{
- //pstateFields.pef = 0; //No FPU
- //pstateFields.pef = 1; //FPU
-#if FULL_SYSTEM
- //For SPARC, when a system is first started, there is a power
- //on reset Trap which sets the processor into the following state.
- //Bits that aren't set aren't defined on startup.
- //XXX this code should be moved into the POR fault.
- tl = MaxTL;
- gl = MaxGL;
-
- tickFields.counter = 0; //The TICK register is unreadable bya
- tickFields.npt = 1; //The TICK register is unreadable by by !priv
-
- softint = 0; // Clear all the soft interrupt bits
- tick_cmprFields.int_dis = 1; // disable timer compare interrupts
- tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
- stickFields.npt = 1; //The TICK register is unreadable by by !priv
- stick_cmprFields.int_dis = 1; // disable timer compare interrupts
- stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-
- tt[tl] = power_on_reset;
- pstate = 0; // fields 0 but pef
- pstateFields.pef = 1;
-
- hpstate = 0;
- hpstateFields.red = 1;
- hpstateFields.hpriv = 1;
- hpstateFields.tlz = 0; // this is a guess
- hintp = 0; // no interrupts pending
- hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
- hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-#endif
}
MiscReg MiscRegFile::readReg(int miscReg)
@@ -199,10 +161,20 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
case MISCREG_PCR:
case MISCREG_PIC:
panic("Performance Instrumentation not impl\n");
-
/** Floating Point Status Register */
case MISCREG_FSR:
panic("Floating Point not implemented\n");
+//We'll include this only in FS so we don't need the SparcSystem type around
+//in SE.
+#if FULL_SYSTEM
+ case MISCREG_STICK:
+ SparcSystem *sys;
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63;
+#endif
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
}
return readReg(miscReg);
}
@@ -350,6 +322,10 @@ void MiscRegFile::setRegWithEffect(int miscReg,
const MiscReg &val, ThreadContext * tc)
{
const uint64_t Bit64 = (1ULL << 63);
+#if FULL_SYSTEM
+ uint64_t time;
+ SparcSystem *sys;
+#endif
switch (miscReg) {
case MISCREG_TICK:
tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
@@ -375,6 +351,70 @@ void MiscRegFile::setRegWithEffect(int miscReg,
case MISCREG_GL:
tc->changeRegFileContext(CONTEXT_GLOBALS, val);
break;
+ case MISCREG_SOFTINT:
+ //We need to inject interrupts, and or notify the interrupt
+ //object that it needs to use a different interrupt level.
+ //Any newly appropriate interrupts will happen when the cpu gets
+ //around to checking for them. This might not be quite what we
+ //want.
+ break;
+ case MISCREG_SOFTINT_CLR:
+ //Do whatever this is supposed to do...
+ break;
+ case MISCREG_SOFTINT_SET:
+ //Do whatever this is supposed to do...
+ break;
+#if FULL_SYSTEM
+ case MISCREG_TICK_CMPR:
+ if (tickCompare == NULL)
+ tickCompare = new TickCompareEvent(this, tc);
+ setReg(miscReg, val);
+ if (tick_cmprFields.int_dis && tickCompare->scheduled())
+ tickCompare->deschedule();
+ time = tick_cmprFields.tick_cmpr - tickFields.counter;
+ if (!tick_cmprFields.int_dis && time > 0)
+ tickCompare->schedule(time * tc->getCpuPtr()->cycles(1));
+ break;
+#endif
+ case MISCREG_PIL:
+ //We need to inject interrupts, and or notify the interrupt
+ //object that it needs to use a different interrupt level.
+ //Any newly appropriate interrupts will happen when the cpu gets
+ //around to checking for them. This might not be quite what we
+ //want.
+ break;
+//We'll include this only in FS so we don't need the SparcSystem type around
+//in SE.
+#if FULL_SYSTEM
+ case MISCREG_STICK:
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
+ stickFields.npt = val & Bit64 ? 1 : 0;
+ break;
+ case MISCREG_STICK_CMPR:
+ if (sTickCompare == NULL)
+ sTickCompare = new STickCompareEvent(this, tc);
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ if (stick_cmprFields.int_dis && sTickCompare->scheduled())
+ sTickCompare->deschedule();
+ time = stick_cmprFields.tick_cmpr - sys->sysTick;
+ if (!stick_cmprFields.int_dis && time > 0)
+ sTickCompare->schedule(time * Clock::Int::ns);
+ break;
+ case MISCREG_HSTICK_CMPR:
+ if (hSTickCompare == NULL)
+ hSTickCompare = new HSTickCompareEvent(this, tc);
+ sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
+ assert(sys != NULL);
+ if (hstick_cmprFields.int_dis && hSTickCompare->scheduled())
+ hSTickCompare->deschedule();
+ int64_t time = hstick_cmprFields.tick_cmpr - sys->sysTick;
+ if (!hstick_cmprFields.int_dis && time > 0)
+ hSTickCompare->schedule(time * Clock::Int::ns);
+ break;
+#endif
}
setReg(miscReg, val);
}
@@ -444,3 +484,22 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
implicitDataAsi = (ASI)temp;
}
+#if FULL_SYSTEM
+void
+MiscRegFile::processTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+
+void
+MiscRegFile::processSTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+
+void
+MiscRegFile::processHSTickCompare(ThreadContext *tc)
+{
+ panic("tick compare not implemented\n");
+}
+#endif
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index ac1ad90b9..0e424dbd2 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -354,12 +354,6 @@ namespace SparcISA
typedef CpuEventWrapper<MiscRegFile,
&MiscRegFile::processHSTickCompare> HSTickCompareEvent;
HSTickCompareEvent *hSTickCompare;
-
- /** Fullsystem only register version of ReadRegWithEffect() */
- MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
- /** Fullsystem only register version of SetRegWithEffect() */
- Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc);
#endif
public:
diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc
new file mode 100644
index 000000000..2e662af7f
--- /dev/null
+++ b/src/arch/sparc/remote_gdb.cc
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ *
+ * Authors: Nathan Binkert
+ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratories.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
+ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
+ *
+ * Taken from NetBSD
+ *
+ * "Stub" to allow remote cpu to debug over a serial line using gdb.
+ */
+
+#include <sys/signal.h>
+
+#include <string>
+#include <unistd.h>
+
+#include "arch/vtophys.hh"
+#include "arch/sparc/remote_gdb.hh"
+#include "base/intmath.hh"
+#include "base/kgdb.h"
+#include "base/remote_gdb.hh"
+#include "base/socket.hh"
+#include "base/trace.hh"
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/static_inst.hh"
+#include "mem/physical.hh"
+#include "mem/port.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace TheISA;
+
+RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e)
+ : PollEvent(fd, e), gdb(g)
+{}
+
+void
+RemoteGDB::Event::process(int revent)
+{
+ if (revent & POLLIN)
+ gdb->trap(ALPHA_KENTRY_IF);
+ else if (revent & POLLNVAL)
+ gdb->detach();
+}
+
+RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
+ : BaseRemoteGDB(_system, c, KGDB_NUMREGS),
+ event(NULL)
+{}
+
+RemoteGDB::~RemoteGDB()
+{
+ if (event)
+ delete event;
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::acc
+//
+// Determine if the mapping at va..(va+len) is valid.
+//
+bool
+RemoteGDB::acc(Addr va, size_t len)
+{
+ Addr last_va;
+
+ va = TheISA::TruncPage(va);
+ last_va = TheISA::RoundPage(va + len);
+
+ do {
+ if (TheISA::IsK0Seg(va)) {
+ if (va < (TheISA::K0SegBase + pmem->size())) {
+ DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
+ "%#x < K0SEG + size\n", va);
+ return true;
+ } else {
+ DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n",
+ va);
+ return false;
+ }
+ }
+
+ /**
+ * This code says that all accesses to palcode (instruction and data)
+ * are valid since there isn't a va->pa mapping because palcode is
+ * accessed physically. At some point this should probably be cleaned up
+ * but there is no easy way to do it.
+ */
+
+ if (AlphaISA::PcPAL(va) || va < 0x10000)
+ return true;
+
+ Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
+ TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
+ if (!pte.valid()) {
+ DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
+ return false;
+ }
+ va += TheISA::PageBytes;
+ } while (va < last_va);
+
+ DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
+ return true;
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::signal
+//
+// Translate a trap number into a Unix-compatible signal number.
+// (GDB only understands Unix signal numbers.)
+//
+int
+RemoteGDB::signal(int type)
+{
+ switch (type) {
+ case ALPHA_KENTRY_INT:
+ return (SIGTRAP);
+
+ case ALPHA_KENTRY_UNA:
+ return (SIGBUS);
+
+ case ALPHA_KENTRY_ARITH:
+ return (SIGFPE);
+
+ case ALPHA_KENTRY_IF:
+ return (SIGILL);
+
+ case ALPHA_KENTRY_MM:
+ return (SIGSEGV);
+
+ default:
+ panic("unknown signal type");
+ return 0;
+ }
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::getregs
+//
+// Translate the kernel debugger register format into
+// the GDB register format.
+void
+RemoteGDB::getregs()
+{
+ memset(gdbregs.regs, 0, gdbregs.size);
+
+ gdbregs.regs[KGDB_REG_PC] = context->readPC();
+
+ // @todo: Currently this is very Alpha specific.
+ if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
+ }
+ } else {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ gdbregs.regs[i] = context->readIntReg(i);
+ }
+ }
+
+#ifdef KGDB_FP_REGS
+ for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
+ gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
+ }
+#endif
+}
+
+///////////////////////////////////////////////////////////
+// RemoteGDB::setregs
+//
+// Translate the GDB register format into the kernel
+// debugger register format.
+//
+void
+RemoteGDB::setregs()
+{
+ // @todo: Currently this is very Alpha specific.
+ if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]);
+ }
+ } else {
+ for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
+ context->setIntReg(i, gdbregs.regs[i]);
+ }
+ }
+
+#ifdef KGDB_FP_REGS
+ for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
+ context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
+ }
+#endif
+ context->setPC(gdbregs.regs[KGDB_REG_PC]);
+}
+
+void
+RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
+{
+ DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr);
+
+ bkpt.address = addr;
+ insertHardBreak(addr, 4);
+}
+
+void
+RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
+{
+ DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n",
+ bkpt.address);
+
+
+ removeHardBreak(bkpt.address, 4);
+ bkpt.address = 0;
+}
+
+void
+RemoteGDB::clearSingleStep()
+{
+ DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
+ takenBkpt.address, notTakenBkpt.address);
+
+ if (takenBkpt.address != 0)
+ clearTempBreakpoint(takenBkpt);
+
+ if (notTakenBkpt.address != 0)
+ clearTempBreakpoint(notTakenBkpt);
+}
+
+void
+RemoteGDB::setSingleStep()
+{
+ Addr pc = context->readPC();
+ Addr npc, bpc;
+ bool set_bt = false;
+
+ npc = pc + sizeof(MachInst);
+
+ // User was stopped at pc, e.g. the instruction at pc was not
+ // executed.
+ MachInst inst = read<MachInst>(pc);
+ StaticInstPtr si(inst);
+ if (si->hasBranchTarget(pc, context, bpc)) {
+ // Don't bother setting a breakpoint on the taken branch if it
+ // is the same as the next pc
+ if (bpc != npc)
+ set_bt = true;
+ }
+
+ DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
+ takenBkpt.address, notTakenBkpt.address);
+
+ setTempBreakpoint(notTakenBkpt, npc);
+
+ if (set_bt)
+ setTempBreakpoint(takenBkpt, bpc);
+}
+
+// Write bytes to kernel address space for debugger.
+bool
+RemoteGDB::write(Addr vaddr, size_t size, const char *data)
+{
+ if (BaseRemoteGDB::write(vaddr, size, data)) {
+#ifdef IMB
+ alpha_pal_imb();
+#endif
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+PCEventQueue *RemoteGDB::getPcEventQueue()
+{
+ return &system->pcEventQueue;
+}
+
+
+RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
+ : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
+ gdb(_gdb), refcount(0)
+{
+ DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
+}
+
+void
+RemoteGDB::HardBreakpoint::process(ThreadContext *tc)
+{
+ DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
+
+ if (tc == gdb->context)
+ gdb->trap(ALPHA_KENTRY_INT);
+}
+
+bool
+RemoteGDB::insertSoftBreak(Addr addr, size_t len)
+{
+ if (len != sizeof(MachInst))
+ panic("invalid length\n");
+
+ return insertHardBreak(addr, len);
+}
+
+bool
+RemoteGDB::removeSoftBreak(Addr addr, size_t len)
+{
+ if (len != sizeof(MachInst))
+ panic("invalid length\n");
+
+ return removeHardBreak(addr, len);
+}
+
+bool
+RemoteGDB::insertHardBreak(Addr addr, size_t len)
+{
+ if (len != sizeof(MachInst))
+ panic("invalid length\n");
+
+ DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr);
+
+ HardBreakpoint *&bkpt = hardBreakMap[addr];
+ if (bkpt == 0)
+ bkpt = new HardBreakpoint(this, addr);
+
+ bkpt->refcount++;
+
+ return true;
+}
+
+bool
+RemoteGDB::removeHardBreak(Addr addr, size_t len)
+{
+ if (len != sizeof(MachInst))
+ panic("invalid length\n");
+
+ DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr);
+
+ break_iter_t i = hardBreakMap.find(addr);
+ if (i == hardBreakMap.end())
+ return false;
+
+ HardBreakpoint *hbp = (*i).second;
+ if (--hbp->refcount == 0) {
+ delete hbp;
+ hardBreakMap.erase(i);
+ }
+
+ return true;
+}
diff --git a/src/arch/sparc/remote_gdb.hh b/src/arch/sparc/remote_gdb.hh
new file mode 100644
index 000000000..6ac4f296f
--- /dev/null
+++ b/src/arch/sparc/remote_gdb.hh
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2002-2005 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.
+ *
+ * Authors: Nathan Binkert
+ */
+
+#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__
+#define __ARCH_ALPHA_REMOTE_GDB_HH__
+
+#include <map>
+
+#include "arch/types.hh"
+#include "base/remote_gdb.hh"
+#include "cpu/pc_event.hh"
+#include "base/pollevent.hh"
+
+class System;
+class ThreadContext;
+class PhysicalMemory;
+
+namespace SparcISA
+{
+ class RemoteGDB : public BaseRemoteGDB
+ {
+ private:
+ friend void debugger();
+ friend class GDBListener;
+
+ protected:
+ class Event : public PollEvent
+ {
+ protected:
+ RemoteGDB *gdb;
+
+ public:
+ Event(RemoteGDB *g, int fd, int e);
+ void process(int revent);
+ };
+
+ friend class Event;
+ Event *event;
+
+ protected:
+ // Machine memory
+ bool write(Addr addr, size_t size, const char *data);
+
+ public:
+ RemoteGDB(System *system, ThreadContext *context);
+ ~RemoteGDB();
+
+ bool acc(Addr addr, size_t len);
+ int signal(int type);
+
+ protected:
+ void getregs();
+ void setregs();
+
+ void clearSingleStep();
+ void setSingleStep();
+
+ PCEventQueue *getPcEventQueue();
+
+ protected:
+ class HardBreakpoint : public PCEvent
+ {
+ private:
+ RemoteGDB *gdb;
+
+ public:
+ int refcount;
+
+ public:
+ HardBreakpoint(RemoteGDB *_gdb, Addr addr);
+ std::string name() { return gdb->name() + ".hwbkpt"; }
+
+ virtual void process(ThreadContext *tc);
+ };
+ friend class HardBreakpoint;
+
+ typedef std::map<Addr, HardBreakpoint *> break_map_t;
+ typedef break_map_t::iterator break_iter_t;
+ break_map_t hardBreakMap;
+
+ bool insertSoftBreak(Addr addr, size_t len);
+ bool removeSoftBreak(Addr addr, size_t len);
+ bool insertHardBreak(Addr addr, size_t len);
+ bool removeHardBreak(Addr addr, size_t len);
+
+ protected:
+ struct TempBreakpoint {
+ Addr address; // set here
+ MachInst bkpt_inst; // saved instruction at bkpt
+ int init_count; // number of times to skip bkpt
+ int count; // current count
+ };
+
+ TempBreakpoint notTakenBkpt;
+ TempBreakpoint takenBkpt;
+
+ void clearTempBreakpoint(TempBreakpoint &bkpt);
+ void setTempBreakpoint(TempBreakpoint &bkpt, Addr addr);
+ };
+}
+
+#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index ef6443d17..952ac2deb 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -77,7 +77,7 @@ SparcSystem::SparcSystem(Params *p)
hypervisor->loadSections(&functionalPort, SparcISA::LoadAddrMask);
// load symbols
- if (!reset->loadGlobalSymbols(reset))
+ if (!reset->loadGlobalSymbols(resetSymtab))
panic("could not load reset symbols\n");
if (!openboot->loadGlobalSymbols(openbootSymtab))
@@ -148,7 +148,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
Param<std::string> hypervisor_bin;
Param<std::string> openboot_bin;
+ Param<Tick> boot_cpu_frequency;
Param<std::string> boot_osflags;
+ Param<uint64_t> system_type;
+ Param<uint64_t> system_rev;
Param<std::string> readfile;
Param<unsigned int> init_param;
@@ -156,7 +159,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
- INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
System::MemoryModeStrings),
@@ -164,12 +166,13 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
INIT_PARAM(reset_bin, "file that contains the reset code"),
INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
INIT_PARAM(openboot_bin, "file that contains the openboot code"),
+ INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
- INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
- INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
- INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
+ INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
+ INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0)
END_INIT_SIM_OBJECT_PARAMS(SparcSystem)
diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh
index 614707f6c..3c8c6327e 100644
--- a/src/arch/sparc/system.hh
+++ b/src/arch/sparc/system.hh
@@ -46,7 +46,7 @@ class SparcSystem : public System
struct Params : public System::Params
{
std::string reset_bin;
- std::string hypervison_bin;
+ std::string hypervisor_bin;
std::string openboot_bin;
std::string boot_osflags;
uint64_t system_type;
diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh
index 23fddf0e9..e2b0b2307 100644
--- a/src/arch/sparc/utility.hh
+++ b/src/arch/sparc/utility.hh
@@ -31,6 +31,7 @@
#ifndef __ARCH_SPARC_UTILITY_HH__
#define __ARCH_SPARC_UTILITY_HH__
+#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
@@ -99,6 +100,12 @@ namespace SparcISA
template <class TC>
void zeroRegisters(TC *tc);
+ inline void initCPU(ThreadContext *tc, int cpuId)
+ {
+ static Fault por = new PowerOnReset();
+ por->invoke(tc);
+ }
+
} // namespace SparcISA
#endif
diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc
index f7fd92c15..429126b70 100644
--- a/src/arch/sparc/vtophys.cc
+++ b/src/arch/sparc/vtophys.cc
@@ -32,135 +32,47 @@
#include <string>
-#include "arch/alpha/ev5.hh"
-#include "arch/alpha/vtophys.hh"
+#include "arch/sparc/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
using namespace std;
-using namespace AlphaISA;
-AlphaISA::PageTableEntry
-AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
+namespace SparcISA
{
- Addr level1_pte = ptbr + vaddr.level1();
- AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
- if (!level1.valid()) {
- DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
- return 0;
+ PageTableEntry kernel_pte_lookup(FunctionalPort *mem,
+ Addr ptbr, VAddr vaddr)
+ {
+ PageTableEntry pte(4);
+ return pte;
}
- Addr level2_pte = level1.paddr() + vaddr.level2();
- AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte);
- if (!level2.valid()) {
- DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
- return 0;
+ Addr vtophys(Addr vaddr)
+ {
+ return vaddr;
}
- Addr level3_pte = level2.paddr() + vaddr.level3();
- AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
- if (!level3.valid()) {
- DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
- return 0;
+ Addr vtophys(ThreadContext *tc, Addr addr)
+ {
+ return addr;
}
- return level3;
-}
-Addr
-AlphaISA::vtophys(Addr vaddr)
-{
- Addr paddr = 0;
- if (AlphaISA::IsUSeg(vaddr))
- DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
- else if (AlphaISA::IsK0Seg(vaddr))
- paddr = AlphaISA::K0Seg2Phys(vaddr);
- else
- panic("vtophys: ptbr is not set on virtual lookup");
- DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
-
- return paddr;
-}
-
-Addr
-AlphaISA::vtophys(ThreadContext *tc, Addr addr)
-{
- AlphaISA::VAddr vaddr = addr;
- Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20);
- Addr paddr = 0;
- //@todo Andrew couldn't remember why he commented some of this code
- //so I put it back in. Perhaps something to do with gdb debugging?
- if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) {
- paddr = vaddr & ~ULL(1);
- } else {
- if (AlphaISA::IsK0Seg(vaddr)) {
- paddr = AlphaISA::K0Seg2Phys(vaddr);
- } else if (!ptbr) {
- paddr = vaddr;
- } else {
- AlphaISA::PageTableEntry pte =
- kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
- if (pte.valid())
- paddr = pte.paddr() | vaddr.offset();
- }
+ void CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
+ {
}
+ void CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
+ {
+ }
- DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
-
- return paddr;
-}
-
-
-void
-AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
-{
- uint8_t *dst = (uint8_t *)dest;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- vp->readBlob(src, dst, cplen);
-
- tc->delVirtPort(vp);
-
-}
-
-void
-AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
-{
- uint8_t *src = (uint8_t *)source;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- vp->writeBlob(dest, src, cplen);
-
- tc->delVirtPort(vp);
-}
-
-void
-AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
-{
- int len = 0;
- VirtualPort *vp = tc->getVirtPort(tc);
-
- do {
- vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
- len++;
- } while (len < maxlen && dst[len] != 0 );
-
- tc->delVirtPort(vp);
- dst[len] = 0;
-}
+ void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
+ {
+ }
-void
-AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
-{
- VirtualPort *vp = tc->getVirtPort(tc);
- for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
- gen.next())
+ void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
- vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
- src += gen.size();
}
- tc->delVirtPort(vp);
}