remote_gdb.cc revision 3536
15124Sgblack@eecs.umich.edu/*
25124Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
35124Sgblack@eecs.umich.edu * All rights reserved.
45124Sgblack@eecs.umich.edu *
55124Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
65124Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
75124Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
85124Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
95124Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
105124Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
115124Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
125124Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
135124Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
145124Sgblack@eecs.umich.edu * this software without specific prior written permission.
155124Sgblack@eecs.umich.edu *
165124Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175124Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185124Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195124Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205124Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215124Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225124Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235124Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245124Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255124Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265124Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275124Sgblack@eecs.umich.edu *
285124Sgblack@eecs.umich.edu * Authors: Nathan Binkert
295124Sgblack@eecs.umich.edu */
305124Sgblack@eecs.umich.edu
315124Sgblack@eecs.umich.edu/*
325124Sgblack@eecs.umich.edu * Copyright (c) 1990, 1993
335124Sgblack@eecs.umich.edu *	The Regents of the University of California.  All rights reserved.
345124Sgblack@eecs.umich.edu *
355124Sgblack@eecs.umich.edu * This software was developed by the Computer Systems Engineering group
365124Sgblack@eecs.umich.edu * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
375124Sgblack@eecs.umich.edu * contributed to Berkeley.
385124Sgblack@eecs.umich.edu *
395124Sgblack@eecs.umich.edu * All advertising materials mentioning features or use of this software
405124Sgblack@eecs.umich.edu * must display the following acknowledgement:
415124Sgblack@eecs.umich.edu *	This product includes software developed by the University of
425124Sgblack@eecs.umich.edu *	California, Lawrence Berkeley Laboratories.
435124Sgblack@eecs.umich.edu *
445124Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
455124Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions
465124Sgblack@eecs.umich.edu * are met:
475124Sgblack@eecs.umich.edu * 1. Redistributions of source code must retain the above copyright
485124Sgblack@eecs.umich.edu *    notice, this list of conditions and the following disclaimer.
495124Sgblack@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright
505124Sgblack@eecs.umich.edu *    notice, this list of conditions and the following disclaimer in the
515124Sgblack@eecs.umich.edu *    documentation and/or other materials provided with the distribution.
525124Sgblack@eecs.umich.edu * 3. All advertising materials mentioning features or use of this software
535124Sgblack@eecs.umich.edu *    must display the following acknowledgement:
545124Sgblack@eecs.umich.edu *	This product includes software developed by the University of
555124Sgblack@eecs.umich.edu *	California, Berkeley and its contributors.
565124Sgblack@eecs.umich.edu * 4. Neither the name of the University nor the names of its contributors
575124Sgblack@eecs.umich.edu *    may be used to endorse or promote products derived from this software
585124Sgblack@eecs.umich.edu *    without specific prior written permission.
595124Sgblack@eecs.umich.edu *
605124Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
615124Sgblack@eecs.umich.edu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
625124Sgblack@eecs.umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
635124Sgblack@eecs.umich.edu * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
645124Sgblack@eecs.umich.edu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
655124Sgblack@eecs.umich.edu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
665124Sgblack@eecs.umich.edu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
675124Sgblack@eecs.umich.edu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
685124Sgblack@eecs.umich.edu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
695124Sgblack@eecs.umich.edu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
705124Sgblack@eecs.umich.edu * SUCH DAMAGE.
715124Sgblack@eecs.umich.edu *
725124Sgblack@eecs.umich.edu *	@(#)kgdb_stub.c	8.4 (Berkeley) 1/12/94
735124Sgblack@eecs.umich.edu */
745124Sgblack@eecs.umich.edu
755124Sgblack@eecs.umich.edu/*-
765124Sgblack@eecs.umich.edu * Copyright (c) 2001 The NetBSD Foundation, Inc.
775124Sgblack@eecs.umich.edu * All rights reserved.
785124Sgblack@eecs.umich.edu *
795124Sgblack@eecs.umich.edu * This code is derived from software contributed to The NetBSD Foundation
805124Sgblack@eecs.umich.edu * by Jason R. Thorpe.
815124Sgblack@eecs.umich.edu *
825124Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
835124Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions
845124Sgblack@eecs.umich.edu * are met:
855124Sgblack@eecs.umich.edu * 1. Redistributions of source code must retain the above copyright
865124Sgblack@eecs.umich.edu *    notice, this list of conditions and the following disclaimer.
875124Sgblack@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright
885681Sgblack@eecs.umich.edu *    notice, this list of conditions and the following disclaimer in the
895124Sgblack@eecs.umich.edu *    documentation and/or other materials provided with the distribution.
905124Sgblack@eecs.umich.edu * 3. All advertising materials mentioning features or use of this software
915124Sgblack@eecs.umich.edu *    must display the following acknowledgement:
925124Sgblack@eecs.umich.edu *	This product includes software developed by the NetBSD
935124Sgblack@eecs.umich.edu *	Foundation, Inc. and its contributors.
945124Sgblack@eecs.umich.edu * 4. Neither the name of The NetBSD Foundation nor the names of its
955124Sgblack@eecs.umich.edu *    contributors may be used to endorse or promote products derived
965124Sgblack@eecs.umich.edu *    from this software without specific prior written permission.
975237Sgblack@eecs.umich.edu *
985237Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
995124Sgblack@eecs.umich.edu * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1005124Sgblack@eecs.umich.edu * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1015124Sgblack@eecs.umich.edu * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1025124Sgblack@eecs.umich.edu * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1035124Sgblack@eecs.umich.edu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1045858Sgblack@eecs.umich.edu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1055124Sgblack@eecs.umich.edu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1065909Sgblack@eecs.umich.edu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1075909Sgblack@eecs.umich.edu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1085681Sgblack@eecs.umich.edu * POSSIBILITY OF SUCH DAMAGE.
1095681Sgblack@eecs.umich.edu */
1105681Sgblack@eecs.umich.edu
1115681Sgblack@eecs.umich.edu/*
1125858Sgblack@eecs.umich.edu * $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
1135858Sgblack@eecs.umich.edu *
1145858Sgblack@eecs.umich.edu * Taken from NetBSD
1155858Sgblack@eecs.umich.edu *
1165858Sgblack@eecs.umich.edu * "Stub" to allow remote cpu to debug over a serial line using gdb.
1175681Sgblack@eecs.umich.edu */
1185681Sgblack@eecs.umich.edu
1195681Sgblack@eecs.umich.edu#include <sys/signal.h>
1205681Sgblack@eecs.umich.edu
1215909Sgblack@eecs.umich.edu#include <string>
1225857Sgblack@eecs.umich.edu#include <unistd.h>
1235858Sgblack@eecs.umich.edu
1245858Sgblack@eecs.umich.edu#include "arch/vtophys.hh"
1255858Sgblack@eecs.umich.edu#include "arch/alpha/remote_gdb.hh"
1265858Sgblack@eecs.umich.edu#include "base/intmath.hh"
1275858Sgblack@eecs.umich.edu#include "base/remote_gdb.hh"
1285858Sgblack@eecs.umich.edu#include "base/socket.hh"
1295858Sgblack@eecs.umich.edu#include "base/trace.hh"
1305858Sgblack@eecs.umich.edu#include "config/full_system.hh"
1315858Sgblack@eecs.umich.edu#include "cpu/thread_context.hh"
1325857Sgblack@eecs.umich.edu#include "cpu/static_inst.hh"
1335857Sgblack@eecs.umich.edu#include "mem/physical.hh"
1345681Sgblack@eecs.umich.edu#include "mem/port.hh"
1355681Sgblack@eecs.umich.edu#include "sim/system.hh"
1365124Sgblack@eecs.umich.edu
1375909Sgblack@eecs.umich.eduusing namespace std;
1385909Sgblack@eecs.umich.eduusing namespace AlphaISA;
1395909Sgblack@eecs.umich.edu
1405909Sgblack@eecs.umich.eduRemoteGDB::Event::Event(RemoteGDB *g, int fd, int e)
1415909Sgblack@eecs.umich.edu    : PollEvent(fd, e), gdb(g)
1425909Sgblack@eecs.umich.edu{}
1435909Sgblack@eecs.umich.edu
1445909Sgblack@eecs.umich.eduvoid
1455909Sgblack@eecs.umich.eduRemoteGDB::Event::process(int revent)
1465909Sgblack@eecs.umich.edu{
1475909Sgblack@eecs.umich.edu    if (revent & POLLIN)
1485909Sgblack@eecs.umich.edu        gdb->trap(ALPHA_KENTRY_IF);
1495858Sgblack@eecs.umich.edu    else if (revent & POLLNVAL)
1505858Sgblack@eecs.umich.edu        gdb->detach();
1515858Sgblack@eecs.umich.edu}
1525858Sgblack@eecs.umich.edu
1535858Sgblack@eecs.umich.eduRemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
1545858Sgblack@eecs.umich.edu    : BaseRemoteGDB(_system, c, KGDB_NUMREGS),
1555858Sgblack@eecs.umich.edu      event(NULL)
1565858Sgblack@eecs.umich.edu{}
1575858Sgblack@eecs.umich.edu
1585858Sgblack@eecs.umich.eduRemoteGDB::~RemoteGDB()
1595858Sgblack@eecs.umich.edu{
1605858Sgblack@eecs.umich.edu    if (event)
1615858Sgblack@eecs.umich.edu        delete event;
1625858Sgblack@eecs.umich.edu}
1635858Sgblack@eecs.umich.edu
1645858Sgblack@eecs.umich.edu///////////////////////////////////////////////////////////
1655858Sgblack@eecs.umich.edu// RemoteGDB::acc
1665858Sgblack@eecs.umich.edu//
1675858Sgblack@eecs.umich.edu//	Determine if the mapping at va..(va+len) is valid.
1685858Sgblack@eecs.umich.edu//
1695858Sgblack@eecs.umich.edubool
1705858Sgblack@eecs.umich.eduRemoteGDB::acc(Addr va, size_t len)
1715858Sgblack@eecs.umich.edu{
1725858Sgblack@eecs.umich.edu    Addr last_va;
1735858Sgblack@eecs.umich.edu
1745858Sgblack@eecs.umich.edu    va = TheISA::TruncPage(va);
1755858Sgblack@eecs.umich.edu    last_va = TheISA::RoundPage(va + len);
1765858Sgblack@eecs.umich.edu
1775858Sgblack@eecs.umich.edu    do  {
1785858Sgblack@eecs.umich.edu        if (TheISA::IsK0Seg(va)) {
1795237Sgblack@eecs.umich.edu            if (va < (TheISA::K0SegBase + pmem->size())) {
1805909Sgblack@eecs.umich.edu                DPRINTF(GDBAcc, "acc:   Mapping is valid  K0SEG <= "
1815909Sgblack@eecs.umich.edu                        "%#x < K0SEG + size\n", va);
1825909Sgblack@eecs.umich.edu                return true;
1835909Sgblack@eecs.umich.edu            } else {
1845909Sgblack@eecs.umich.edu                DPRINTF(GDBAcc, "acc:   Mapping invalid %#x > K0SEG + size\n",
1855909Sgblack@eecs.umich.edu                        va);
1865909Sgblack@eecs.umich.edu                return false;
1875909Sgblack@eecs.umich.edu            }
1886048Sgblack@eecs.umich.edu        }
1896048Sgblack@eecs.umich.edu
1906048Sgblack@eecs.umich.edu    /**
1916048Sgblack@eecs.umich.edu     * This code says that all accesses to palcode (instruction and data)
1926048Sgblack@eecs.umich.edu     * are valid since there isn't a va->pa mapping because palcode is
1936048Sgblack@eecs.umich.edu     * accessed physically. At some point this should probably be cleaned up
1946048Sgblack@eecs.umich.edu     * but there is no easy way to do it.
1956048Sgblack@eecs.umich.edu     */
1966048Sgblack@eecs.umich.edu
1976048Sgblack@eecs.umich.edu        if (AlphaISA::PcPAL(va) || va < 0x10000)
1986048Sgblack@eecs.umich.edu            return true;
1996048Sgblack@eecs.umich.edu
2006048Sgblack@eecs.umich.edu        Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
2016048Sgblack@eecs.umich.edu        TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
2026048Sgblack@eecs.umich.edu        if (!pte.valid()) {
2036048Sgblack@eecs.umich.edu            DPRINTF(GDBAcc, "acc:   %#x pte is invalid\n", va);
2046048Sgblack@eecs.umich.edu            return false;
2056048Sgblack@eecs.umich.edu        }
2066048Sgblack@eecs.umich.edu        va += TheISA::PageBytes;
2076048Sgblack@eecs.umich.edu    } while (va < last_va);
2086048Sgblack@eecs.umich.edu
2096048Sgblack@eecs.umich.edu    DPRINTF(GDBAcc, "acc:   %#x mapping is valid\n", va);
2106048Sgblack@eecs.umich.edu    return true;
2116048Sgblack@eecs.umich.edu}
2126048Sgblack@eecs.umich.edu
2136048Sgblack@eecs.umich.edu///////////////////////////////////////////////////////////
2146048Sgblack@eecs.umich.edu// RemoteGDB::getregs
2156048Sgblack@eecs.umich.edu//
2166048Sgblack@eecs.umich.edu//	Translate the kernel debugger register format into
2176048Sgblack@eecs.umich.edu//	the GDB register format.
2186048Sgblack@eecs.umich.eduvoid
2196048Sgblack@eecs.umich.eduRemoteGDB::getregs()
2206048Sgblack@eecs.umich.edu{
2216048Sgblack@eecs.umich.edu    memset(gdbregs.regs, 0, gdbregs.size);
2226048Sgblack@eecs.umich.edu
2236048Sgblack@eecs.umich.edu    gdbregs.regs[KGDB_REG_PC] = context->readPC();
2246048Sgblack@eecs.umich.edu
2256048Sgblack@eecs.umich.edu    // @todo: Currently this is very Alpha specific.
2266048Sgblack@eecs.umich.edu    if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
2276048Sgblack@eecs.umich.edu        for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
2286048Sgblack@eecs.umich.edu            gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
2296048Sgblack@eecs.umich.edu        }
2306048Sgblack@eecs.umich.edu    } else {
2316048Sgblack@eecs.umich.edu        for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
2326048Sgblack@eecs.umich.edu            gdbregs.regs[i] = context->readIntReg(i);
2336048Sgblack@eecs.umich.edu        }
2346048Sgblack@eecs.umich.edu    }
2356048Sgblack@eecs.umich.edu
2366048Sgblack@eecs.umich.edu#ifdef KGDB_FP_REGS
2376048Sgblack@eecs.umich.edu    for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
2386048Sgblack@eecs.umich.edu        gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
2396048Sgblack@eecs.umich.edu    }
2406048Sgblack@eecs.umich.edu#endif
2416048Sgblack@eecs.umich.edu}
2426048Sgblack@eecs.umich.edu
2436048Sgblack@eecs.umich.edu///////////////////////////////////////////////////////////
2446048Sgblack@eecs.umich.edu// RemoteGDB::setregs
2456048Sgblack@eecs.umich.edu//
2466048Sgblack@eecs.umich.edu//	Translate the GDB register format into the kernel
2476048Sgblack@eecs.umich.edu//	debugger register format.
2486048Sgblack@eecs.umich.edu//
2496048Sgblack@eecs.umich.eduvoid
2506048Sgblack@eecs.umich.eduRemoteGDB::setregs()
2516048Sgblack@eecs.umich.edu{
2526048Sgblack@eecs.umich.edu    // @todo: Currently this is very Alpha specific.
2536048Sgblack@eecs.umich.edu    if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) {
2546048Sgblack@eecs.umich.edu        for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
2556048Sgblack@eecs.umich.edu            context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]);
2566048Sgblack@eecs.umich.edu        }
2576048Sgblack@eecs.umich.edu    } else {
2586048Sgblack@eecs.umich.edu        for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
2596048Sgblack@eecs.umich.edu            context->setIntReg(i, gdbregs.regs[i]);
2606048Sgblack@eecs.umich.edu        }
2616048Sgblack@eecs.umich.edu    }
2626048Sgblack@eecs.umich.edu
2636048Sgblack@eecs.umich.edu#ifdef KGDB_FP_REGS
2646048Sgblack@eecs.umich.edu    for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
2656048Sgblack@eecs.umich.edu        context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
2666048Sgblack@eecs.umich.edu    }
2676048Sgblack@eecs.umich.edu#endif
2686048Sgblack@eecs.umich.edu    context->setPC(gdbregs.regs[KGDB_REG_PC]);
2696048Sgblack@eecs.umich.edu}
2706048Sgblack@eecs.umich.edu
2716048Sgblack@eecs.umich.eduvoid
2726048Sgblack@eecs.umich.eduRemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
2736048Sgblack@eecs.umich.edu{
2746048Sgblack@eecs.umich.edu    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr);
2756048Sgblack@eecs.umich.edu
2766048Sgblack@eecs.umich.edu    bkpt.address = addr;
2776048Sgblack@eecs.umich.edu    insertHardBreak(addr, 4);
2786048Sgblack@eecs.umich.edu}
2796048Sgblack@eecs.umich.edu
2806048Sgblack@eecs.umich.eduvoid
2816048Sgblack@eecs.umich.eduRemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
2826048Sgblack@eecs.umich.edu{
2836048Sgblack@eecs.umich.edu    DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n",
2846048Sgblack@eecs.umich.edu            bkpt.address);
2856049Sgblack@eecs.umich.edu
2866049Sgblack@eecs.umich.edu
2876049Sgblack@eecs.umich.edu    removeHardBreak(bkpt.address, 4);
2886049Sgblack@eecs.umich.edu    bkpt.address = 0;
2896049Sgblack@eecs.umich.edu}
2906049Sgblack@eecs.umich.edu
2916049Sgblack@eecs.umich.eduvoid
2926049Sgblack@eecs.umich.eduRemoteGDB::clearSingleStep()
2936049Sgblack@eecs.umich.edu{
2946049Sgblack@eecs.umich.edu    DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
2956049Sgblack@eecs.umich.edu            takenBkpt.address, notTakenBkpt.address);
2966049Sgblack@eecs.umich.edu
2976049Sgblack@eecs.umich.edu    if (takenBkpt.address != 0)
2986049Sgblack@eecs.umich.edu        clearTempBreakpoint(takenBkpt);
2996049Sgblack@eecs.umich.edu
3006049Sgblack@eecs.umich.edu    if (notTakenBkpt.address != 0)
3016049Sgblack@eecs.umich.edu        clearTempBreakpoint(notTakenBkpt);
3026049Sgblack@eecs.umich.edu}
3036049Sgblack@eecs.umich.edu
3046049Sgblack@eecs.umich.eduvoid
3055124Sgblack@eecs.umich.eduRemoteGDB::setSingleStep()
3065124Sgblack@eecs.umich.edu{
3075124Sgblack@eecs.umich.edu    Addr pc = context->readPC();
308    Addr npc, bpc;
309    bool set_bt = false;
310
311    npc = pc + sizeof(MachInst);
312
313    // User was stopped at pc, e.g. the instruction at pc was not
314    // executed.
315    MachInst inst = read<MachInst>(pc);
316    StaticInstPtr si(inst);
317    if (si->hasBranchTarget(pc, context, bpc)) {
318        // Don't bother setting a breakpoint on the taken branch if it
319        // is the same as the next pc
320        if (bpc != npc)
321            set_bt = true;
322    }
323
324    DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
325            takenBkpt.address, notTakenBkpt.address);
326
327    setTempBreakpoint(notTakenBkpt, npc);
328
329    if (set_bt)
330        setTempBreakpoint(takenBkpt, bpc);
331}
332
333// Write bytes to kernel address space for debugger.
334bool
335RemoteGDB::write(Addr vaddr, size_t size, const char *data)
336{
337    if (BaseRemoteGDB::write(vaddr, size, data)) {
338#ifdef IMB
339        alpha_pal_imb();
340#endif
341        return true;
342    } else {
343        return false;
344    }
345}
346
347
348PCEventQueue *RemoteGDB::getPcEventQueue()
349{
350    return &system->pcEventQueue;
351}
352
353
354RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
355    : PCEvent(_gdb->getPcEventQueue(), "HardBreakpoint Event", pc),
356      gdb(_gdb), refcount(0)
357{
358    DPRINTF(GDBMisc, "creating hardware breakpoint at %#x\n", evpc);
359}
360
361void
362RemoteGDB::HardBreakpoint::process(ThreadContext *tc)
363{
364    DPRINTF(GDBMisc, "handling hardware breakpoint at %#x\n", pc());
365
366    if (tc == gdb->context)
367        gdb->trap(ALPHA_KENTRY_INT);
368}
369
370bool
371RemoteGDB::insertSoftBreak(Addr addr, size_t len)
372{
373    if (len != sizeof(MachInst))
374        panic("invalid length\n");
375
376    return insertHardBreak(addr, len);
377}
378
379bool
380RemoteGDB::removeSoftBreak(Addr addr, size_t len)
381{
382    if (len != sizeof(MachInst))
383        panic("invalid length\n");
384
385    return removeHardBreak(addr, len);
386}
387
388bool
389RemoteGDB::insertHardBreak(Addr addr, size_t len)
390{
391    if (len != sizeof(MachInst))
392        panic("invalid length\n");
393
394    DPRINTF(GDBMisc, "inserting hardware breakpoint at %#x\n", addr);
395
396    HardBreakpoint *&bkpt = hardBreakMap[addr];
397    if (bkpt == 0)
398        bkpt = new HardBreakpoint(this, addr);
399
400    bkpt->refcount++;
401
402    return true;
403}
404
405bool
406RemoteGDB::removeHardBreak(Addr addr, size_t len)
407{
408    if (len != sizeof(MachInst))
409        panic("invalid length\n");
410
411    DPRINTF(GDBMisc, "removing hardware breakpoint at %#x\n", addr);
412
413    break_iter_t i = hardBreakMap.find(addr);
414    if (i == hardBreakMap.end())
415        return false;
416
417    HardBreakpoint *hbp = (*i).second;
418    if (--hbp->refcount == 0) {
419        delete hbp;
420        hardBreakMap.erase(i);
421    }
422
423    return true;
424}
425