/*
 * 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.
 */

#ifndef __REMOTE_GDB_HH__
#define __REMOTE_GDB_HH__

#include <map>

#include "base/kgdb.h"
#include "cpu/pc_event.hh"
#include "base/pollevent.hh"
#include "base/socket.hh"

class System;
class ExecContext;
class PhysicalMemory;

class RemoteGDB
{
  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:
    int fd;
    uint64_t gdbregs[KGDB_NUMREGS];

  protected:
#ifdef notyet
    label_t recover;
#endif
    bool active;
    bool attached;

    System *system;
    PhysicalMemory *pmem;
    ExecContext *context;

  protected:
    uint8_t getbyte();
    void putbyte(uint8_t b);

    int recv(char *data, int len);
    void send(const char *data);

  protected:
    // Machine memory
    bool read(Addr addr, size_t size, char *data);
    bool write(Addr addr, size_t size, const char *data);

    template <class T> T read(Addr addr);
    template <class T> void write(Addr addr, T data);

  public:
    RemoteGDB(System *system, ExecContext *context);
    ~RemoteGDB();

    void attach(int fd);
    void detach();
    bool isattached();

    bool acc(Addr addr, size_t len);
    static int signal(int type);
    bool trap(int type);

  protected:
    void getregs();
    void setregs();

    void clearSingleStep();
    void setSingleStep();

    PCEventQueue *getPcEventQueue();

  protected:
    class HardBreakpoint : public PCEvent
    {
      private:
        RemoteGDB *gdb;

      public:
        HardBreakpoint(RemoteGDB *_gdb, Addr addr);

        int refcount;
        virtual void process(ExecContext *xc);
    };
    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);
};

template <class T>
inline T
RemoteGDB::read(Addr addr)
{
    T temp;
    read(addr, sizeof(T), (char *)&temp);
    return temp;
}

template <class T>
inline void
RemoteGDB::write(Addr addr, T data)
{ write(addr, sizeof(T), (const char *)&data); }

class GDBListener
{
  protected:
    class Event : public PollEvent
    {
      protected:
        GDBListener *listener;

      public:
        Event(GDBListener *l, int fd, int e);
        void process(int revent);
    };

    friend class Event;
    Event *event;

  protected:
    ListenSocket listener;
    RemoteGDB *gdb;
    int port;

  public:
    GDBListener(RemoteGDB *g, int p);
    ~GDBListener();

    void accept();
    void listen();
};

#endif /* __REMOTE_GDB_H__ */
