Merge remote-tracking branch 'origin/debug-0.13' into priv-1.10
authorPalmer Dabbelt <palmer@dabbelt.com>
Tue, 16 May 2017 16:33:40 +0000 (09:33 -0700)
committerPalmer Dabbelt <palmer@dabbelt.com>
Tue, 16 May 2017 19:35:49 +0000 (12:35 -0700)
1  2 
riscv/processor.cc
riscv/riscv.mk.in
riscv/sim.cc
riscv/sim.h
spike_main/spike.cc

diff --combined riscv/processor.cc
index 664b44d7df1fa5f0b7f8ff6e908e81c8edcf67c5,6f0d3a7b9008bef422a8769ec4b881e2edc81fb7..1e3573df903e56fc9982bc729baba3a9640f6df1
@@@ -7,7 -7,6 +7,6 @@@
  #include "sim.h"
  #include "mmu.h"
  #include "disasm.h"
- #include "gdbserver.h"
  #include <cinttypes>
  #include <cmath>
  #include <cstdlib>
@@@ -22,7 -21,8 +21,8 @@@
  
  processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
          bool halt_on_reset)
-   : debug(false), sim(sim), ext(NULL), id(id), halt_on_reset(halt_on_reset)
+   : debug(false), halt_request(false), sim(sim), ext(NULL), id(id),
+   halt_on_reset(halt_on_reset)
  {
    parse_isa_string(isa);
    register_base_instructions();
@@@ -178,15 -178,6 +178,15 @@@ void processor_t::take_interrupt(reg_t 
      throw trap_t(((reg_t)1 << (max_xlen-1)) | ctz(enabled_interrupts));
  }
  
 +static int xlen_to_uxl(int xlen)
 +{
 +  if (xlen == 32)
 +    return 1;
 +  if (xlen == 64)
 +    return 2;
 +  abort();
 +}
 +
  void processor_t::set_privilege(reg_t prv)
  {
    assert(prv <= PRV_M);
@@@ -202,7 -193,7 +202,7 @@@ void processor_t::enter_debug_mode(uint
    state.dcsr.prv = state.prv;
    set_privilege(PRV_M);
    state.dpc = state.pc;
-   state.pc = DEBUG_ROM_START;
+   state.pc = debug_rom_entry();
  }
  
  void processor_t::take_trap(trap_t& t, reg_t epc)
            t.get_badaddr());
    }
  
+   if (state.dcsr.cause) {
+     if (t.cause() == CAUSE_BREAKPOINT) {
+       state.pc = debug_rom_entry();
+     } else {
+       state.pc = DEBUG_ROM_TVEC;
+     }
+     return;
+   }
    if (t.cause() == CAUSE_BREAKPOINT && (
                (state.prv == PRV_M && state.dcsr.ebreakm) ||
                (state.prv == PRV_H && state.dcsr.ebreakh) ||
      return;
    }
  
-   if (state.dcsr.cause) {
-     state.pc = DEBUG_ROM_EXCEPTION;
-     return;
-   }
    // by default, trap to M-mode, unless delegated to S-mode
    reg_t bit = t.cause();
    reg_t deleg = state.medeleg;
  
  void processor_t::disasm(insn_t insn)
  {
+   static uint64_t last_pc = 1, last_bits;
+   static uint64_t executions = 1;
    uint64_t bits = insn.bits() & ((1ULL << (8 * insn_length(insn.bits()))) - 1);
-   fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx64 ") %s\n",
-           id, state.pc, bits, disassembler->disassemble(insn).c_str());
+   if (last_pc != state.pc || last_bits != bits) {
+     if (executions != 1) {
+       fprintf(stderr, "core %3d: Executed %" PRIx64 " times\n", id, executions);
+     }
+     fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx64 ") %s\n",
+             id, state.pc, bits, disassembler->disassemble(insn).c_str());
+     last_pc = state.pc;
+     last_bits = bits;
+     executions = 1;
+   } else {
+     executions++;
+   }
  }
  
  int processor_t::paddr_bits()
@@@ -309,8 -318,7 +327,8 @@@ void processor_t::set_csr(int which, re
        reg_t mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE
                   | MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM
                   | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TW | MSTATUS_TVM
 -                 | MSTATUS_TSR | (ext ? MSTATUS_XS : 0);
 +                 | MSTATUS_TSR | MSTATUS_UXL | MSTATUS_SXL |
 +                 (ext ? MSTATUS_XS : 0);
  
        state.mstatus = (state.mstatus & ~mask) | (val & mask);
  
        else
          state.mstatus = set_field(state.mstatus, MSTATUS64_SD, dirty);
  
 -      // spike supports the notion of xlen < max_xlen, but current priv spec
 -      // doesn't provide a mechanism to run RV32 software on an RV64 machine
 +      state.mstatus = set_field(state.mstatus, MSTATUS_UXL, xlen_to_uxl(max_xlen));
 +      state.mstatus = set_field(state.mstatus, MSTATUS_SXL, xlen_to_uxl(max_xlen));
 +      // U-XLEN == S-XLEN == M-XLEN
        xlen = max_xlen;
        break;
      }
@@@ -524,7 -531,7 +542,7 @@@ reg_t processor_t::get_csr(int which
      case CSR_MCOUNTEREN: return state.mcounteren;
      case CSR_SSTATUS: {
        reg_t mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_SPP | SSTATUS_FS
 -                 | SSTATUS_XS | SSTATUS_SUM;
 +                 | SSTATUS_XS | SSTATUS_SUM | SSTATUS_UXL;
        reg_t sstatus = state.mstatus & mask;
        if ((sstatus & SSTATUS_FS) == SSTATUS_FS ||
            (sstatus & SSTATUS_XS) == SSTATUS_XS)
        {
          uint32_t v = 0;
          v = set_field(v, DCSR_XDEBUGVER, 1);
-         v = set_field(v, DCSR_NDRESET, 0);
-         v = set_field(v, DCSR_FULLRESET, 0);
-         v = set_field(v, DCSR_PRV, state.dcsr.prv);
-         v = set_field(v, DCSR_STEP, state.dcsr.step);
-         v = set_field(v, DCSR_DEBUGINT, sim->debug_module.get_interrupt(id));
-         v = set_field(v, DCSR_STOPCYCLE, 0);
-         v = set_field(v, DCSR_STOPTIME, 0);
          v = set_field(v, DCSR_EBREAKM, state.dcsr.ebreakm);
          v = set_field(v, DCSR_EBREAKH, state.dcsr.ebreakh);
          v = set_field(v, DCSR_EBREAKS, state.dcsr.ebreaks);
          v = set_field(v, DCSR_EBREAKU, state.dcsr.ebreaku);
-         v = set_field(v, DCSR_HALT, state.dcsr.halt);
+         v = set_field(v, DCSR_STOPCYCLE, 0);
+         v = set_field(v, DCSR_STOPTIME, 0);
          v = set_field(v, DCSR_CAUSE, state.dcsr.cause);
+         v = set_field(v, DCSR_STEP, state.dcsr.step);
+         v = set_field(v, DCSR_PRV, state.dcsr.prv);
          return v;
        }
      case CSR_DPC:
diff --combined riscv/riscv.mk.in
index 5508a292785d2c62795d61ca989d0a4d457bcddf,40054cfbaa289793f4ca8051dc1edf0157be20e4..05e316a438ad4dd68e1e9f2646328afc1d5c1758
@@@ -23,8 -23,9 +23,9 @@@ riscv_hdrs = 
        rocc.h \
        insn_template.h \
        mulhi.h \
-       gdbserver.h \
        debug_module.h \
+       remote_bitbang.h \
+       jtag_dtm.h \
  
  riscv_precompiled_hdrs = \
        insn_template.h \
@@@ -45,8 -46,9 +46,9 @@@ riscv_srcs = 
        devices.cc \
        rom.cc \
        clint.cc \
-       gdbserver.cc \
        debug_module.cc \
+       remote_bitbang.cc \
+       jtag_dtm.cc \
        $(riscv_gen_srcs) \
  
  riscv_test_srcs =
@@@ -180,9 -182,9 +182,9 @@@ riscv_insn_list = 
        fmul_d \
        fmul_s \
        fmv_d_x \
 -      fmv_s_x \
 +      fmv_w_x \
        fmv_x_d \
 -      fmv_x_s \
 +      fmv_x_w \
        fnmadd_d \
        fnmadd_s \
        fnmsub_d \
diff --combined riscv/sim.cc
index edf0819369cc084fd63730fe373594cd28b96e5a,a44ced6a832a67950bd4d620b1b66cccde310c15..42d60a13266d6fcafa1503e952e54b4a1e641ecf
@@@ -2,7 -2,7 +2,7 @@@
  
  #include "sim.h"
  #include "mmu.h"
- #include "gdbserver.h"
+ #include "remote_bitbang.h"
  #include <map>
  #include <iostream>
  #include <sstream>
@@@ -23,19 -23,28 +23,19 @@@ static void handle_signal(int sig
    signal(sig, &handle_signal);
  }
  
 -sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted,
 +sim_t::sim_t(const char* isa, size_t nprocs, bool halted, reg_t start_pc,
 +             std::vector<std::pair<reg_t, mem_t*>> mems,
               const std::vector<std::string>& args)
-   : htif_t(args), mems(mems), procs(std::max(nprocs, size_t(1))),
 -  : htif_t(args), debug_module(this), procs(std::max(nprocs, size_t(1))),
++  : htif_t(args), debug_module(this), mems(mems), procs(std::max(nprocs, size_t(1))),
 +    start_pc(start_pc),
-     current_step(0), current_proc(0), debug(false), gdbserver(NULL)
+     current_step(0), current_proc(0), debug(false), remote_bitbang(NULL)
  {
    signal(SIGINT, &handle_signal);
 -  // allocate target machine's memory, shrinking it as necessary
 -  // until the allocation succeeds
 -  size_t memsz0 = (size_t)mem_mb << 20;
 -  size_t quantum = 1L << 20;
 -  if (memsz0 == 0)
 -    memsz0 = (size_t)2048 << 20;
  
 -  memsz = memsz0;
 -  while ((mem = (char*)calloc(1, memsz)) == NULL)
 -    memsz = (size_t)(memsz*0.9)/quantum*quantum;
 -
 -  if (memsz != memsz0)
 -    fprintf(stderr, "warning: only got %zu bytes of target mem (wanted %zu)\n",
 -            memsz, memsz0);
 +  for (auto& x : mems)
 +    bus.add_device(x.first, x.second);
  
-   bus.add_device(DEBUG_START, &debug_module);
+   debug_module.add_device(&bus);
  
    debug_mmu = new mmu_t(this, NULL);
  
@@@ -45,6 -54,8 +45,6 @@@
  
    clint.reset(new clint_t(procs));
    bus.add_device(CLINT_BASE, clint.get());
 -
 -  make_dtb();
  }
  
  sim_t::~sim_t()
@@@ -52,6 -63,7 +52,6 @@@
    for (size_t i = 0; i < procs.size(); i++)
      delete procs[i];
    delete debug_mmu;
 -  free(mem);
  }
  
  void sim_thread_main(void* arg)
@@@ -70,8 -82,8 +70,8 @@@ void sim_t::main(
        interactive();
      else
        step(INTERLEAVE);
-     if (gdbserver) {
-       gdbserver->handle();
+     if (remote_bitbang) {
+       remote_bitbang->tick();
      }
    }
  }
@@@ -226,24 -238,14 +226,24 @@@ static std::string dts_compile(const st
  
  void sim_t::make_dtb()
  {
 -  uint32_t reset_vec[] = {
 -    0x297 + DRAM_BASE - DEFAULT_RSTVEC, // auipc t0, DRAM_BASE
 -    0x597,                              // auipc a1, 0
 -    0x58593,                            // addi a1, a1, 0
 -    0xf1402573,                               // csrr a0,mhartid
 -    0x00028067                          // jalr zero, t0, 0 (jump straight to DRAM_BASE)
 +  const int reset_vec_size = 8;
 +
 +  start_pc = start_pc == reg_t(-1) ? get_entry_point() : start_pc;
 +  reg_t pc_delta = start_pc - DEFAULT_RSTVEC;
 +  reg_t pc_delta_hi = (pc_delta + 0x800U) & ~reg_t(0xfffU);
 +  reg_t pc_delta_lo = pc_delta - pc_delta_hi;
 +  if ((pc_delta_hi >> 31) != 0 && (pc_delta_hi >> 31) != reg_t(-1) >> 31) {
 +    fprintf(stderr, "initial pc %" PRIx64 " out of range\n", pc_delta);
 +    abort();
 +  }
 +
 +  uint32_t reset_vec[reset_vec_size] = {
 +    0x297 + uint32_t(pc_delta_hi),              // auipc t0, &pc
 +    0x597,                                      // auipc a1, &dtb
 +    0x58593 + ((reset_vec_size - 1) * 4 << 20), // addi a1, a1, &dtb
 +    0xf1402573,                                 // csrr a0, mhartid
 +    0x28067 + uint32_t(pc_delta_lo << 20)       // jalr zero, t0, &pc
    };
 -  reset_vec[2] += (sizeof(reset_vec) - 4) << 20; // addi a1, a1, sizeof(reset_vec) - 4 = DTB start
  
    std::vector<char> rom((char*)reset_vec, (char*)reset_vec + sizeof(reset_vec));
  
           "      };\n"
           "    };\n";
    }
 -  reg_t membs = DRAM_BASE;
 -  s << std::hex <<
 -         "  };\n"
 -         "  memory@" << DRAM_BASE << " {\n"
 +  s <<   "  };\n";
 +  for (auto& m : mems) {
 +    s << std::hex <<
 +         "  memory@" << m.first << " {\n"
           "    device_type = \"memory\";\n"
 -         "    reg = <0x" << (membs >> 32) << " 0x" << (membs & (uint32_t)-1) <<
 -                   " 0x" << (memsz >> 32) << " 0x" << (memsz & (uint32_t)-1) << ">;\n"
 -         "  };\n"
 -         "  soc {\n"
 +         "    reg = <0x" << (m.first >> 32) << " 0x" << (m.first & (uint32_t)-1) <<
 +                   " 0x" << (m.second->size() >> 32) << " 0x" << (m.second->size() & (uint32_t)-1) << ">;\n"
 +         "  };\n";
 +  }
 +  s <<   "  soc {\n"
           "    #address-cells = <2>;\n"
           "    #size-cells = <2>;\n"
           "    compatible = \"ucbbar,spike-bare-soc\", \"simple-bus\";\n"
    bus.add_device(DEFAULT_RSTVEC, boot_rom.get());
  }
  
 +char* sim_t::addr_to_mem(reg_t addr) {
 +  auto desc = bus.find_device(addr);
 +  if (auto mem = dynamic_cast<mem_t*>(desc.second))
 +    if (addr - desc.first < mem->size())
 +      return mem->contents() + (addr - desc.first);
 +  return NULL;
 +}
 +
  // htif
  
 +void sim_t::reset()
 +{
 +  make_dtb();
 +}
 +
  void sim_t::idle()
  {
    target.switch_to();
diff --combined riscv/sim.h
index 421f5c2bc3a279c8e6f99bce757b865546d5ecde,d3353a1bbcfd4cebb79abcfddadd11c552b14ea1..9372cc1e2d3207d3015e3c43059e8054a9f13acf
  #include <memory>
  
  class mmu_t;
- class gdbserver_t;
+ class remote_bitbang_t;
  
  // this class encapsulates the processors and memory in a RISC-V machine.
  class sim_t : public htif_t
  {
  public:
 -  sim_t(const char* isa, size_t _nprocs, size_t mem_mb, bool halted,
 +  sim_t(const char* isa, size_t _nprocs,  bool halted, reg_t start_pc,
 +        std::vector<std::pair<reg_t, mem_t*>> mems,
          const std::vector<std::string>& args);
    ~sim_t();
  
    void set_log(bool value);
    void set_histogram(bool value);
    void set_procs_debug(bool value);
-   void set_gdbserver(gdbserver_t* gdbserver) { this->gdbserver = gdbserver; }
+   void set_remote_bitbang(remote_bitbang_t* remote_bitbang) {
+     this->remote_bitbang = remote_bitbang;
+   }
 -  const char* get_dts() { return dts.c_str(); }
 +  const char* get_dts() { if (dts.empty()) reset(); return dts.c_str(); }
    processor_t* get_core(size_t i) { return procs.at(i); }
+   unsigned nprocs() const { return procs.size(); }
+   debug_module_t debug_module;
  
  private:
 -  char* mem; // main memory
 -  size_t memsz; // memory size in bytes
 +  std::vector<std::pair<reg_t, mem_t*>> mems;
    mmu_t* debug_mmu;  // debug port into main memory
    std::vector<processor_t*> procs;
 +  reg_t start_pc;
    std::string dts;
    std::unique_ptr<rom_device_t> boot_rom;
    std::unique_ptr<clint_t> clint;
    bus_t bus;
-   debug_module_t debug_module;
  
    processor_t* get_core(const std::string& i);
    void step(size_t n); // step through simulation
    bool debug;
    bool log;
    bool histogram_enabled; // provide a histogram of PCs
-   gdbserver_t* gdbserver;
+   remote_bitbang_t* remote_bitbang;
  
    // memory-mapped I/O routines
 -  bool addr_is_mem(reg_t addr) {
 -    return addr >= DRAM_BASE && addr < DRAM_BASE + memsz;
 -  }
 -  char* addr_to_mem(reg_t addr) { return mem + addr - DRAM_BASE; }
 -  reg_t mem_to_addr(char* x) { return x - mem + DRAM_BASE; }
 +  char* addr_to_mem(reg_t addr);
    bool mmio_load(reg_t addr, size_t len, uint8_t* bytes);
    bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes);
    void make_dtb();
@@@ -87,7 -94,6 +91,6 @@@
  
    friend class processor_t;
    friend class mmu_t;
-   friend class gdbserver_t;
  
    // htif
    friend void sim_thread_main(void*);
  
    context_t* host;
    context_t target;
 -  void reset() { }
 +  void reset();
    void idle();
    void read_chunk(addr_t taddr, size_t len, void* dst);
    void write_chunk(addr_t taddr, size_t len, const void* src);
diff --combined spike_main/spike.cc
index d69d4bc21b5999cc2c78349543aaeaabbae6b421,38529b2504e3297e2101e7594cd63ec9c6db305a..23f8e49c0deeca8bffe414cc341353912f244fd4
@@@ -2,7 -2,7 +2,7 @@@
  
  #include "sim.h"
  #include "mmu.h"
- #include "gdbserver.h"
+ #include "remote_bitbang.h"
  #include "cachesim.h"
  #include "extension.h"
  #include <dlfcn.h>
@@@ -18,55 -18,23 +18,55 @@@ static void help(
    fprintf(stderr, "usage: spike [host options] <target program> [target options]\n");
    fprintf(stderr, "Host Options:\n");
    fprintf(stderr, "  -p<n>                 Simulate <n> processors [default 1]\n");
 -  fprintf(stderr, "  -m<n>                 Provide <n> MiB of target memory [default 4096]\n");
 +  fprintf(stderr, "  -m<n>                 Provide <n> MiB of target memory [default 2048]\n");
 +  fprintf(stderr, "  -m<a:m,b:n,...>       Provide memory regions of size m and n bytes\n");
 +  fprintf(stderr, "                          at base addresses a and b (with 4 KiB alignment)\n");
    fprintf(stderr, "  -d                    Interactive debug mode\n");
    fprintf(stderr, "  -g                    Track histogram of PCs\n");
    fprintf(stderr, "  -l                    Generate a log of execution\n");
    fprintf(stderr, "  -h                    Print this help message\n");
    fprintf(stderr, "  -H                 Start halted, allowing a debugger to connect\n");
    fprintf(stderr, "  --isa=<name>          RISC-V ISA string [default %s]\n", DEFAULT_ISA);
 +  fprintf(stderr, "  --pc=<address>        Override ELF entry point\n");
    fprintf(stderr, "  --ic=<S>:<W>:<B>      Instantiate a cache model with S sets,\n");
    fprintf(stderr, "  --dc=<S>:<W>:<B>        W ways, and B-byte blocks (with S and\n");
    fprintf(stderr, "  --l2=<S>:<W>:<B>        B both powers of 2).\n");
    fprintf(stderr, "  --extension=<name>    Specify RoCC Extension\n");
    fprintf(stderr, "  --extlib=<name>       Shared library to load\n");
-   fprintf(stderr, "  --gdb-port=<port>  Listen on <port> for gdb to connect\n");
+   fprintf(stderr, "  --rbb-port=<port>     Listen on <port> for remote bitbang connection\n");
    fprintf(stderr, "  --dump-dts  Print device tree string and exit\n");
    exit(1);
  }
  
 +static std::vector<std::pair<reg_t, mem_t*>> make_mems(const char* arg)
 +{
 +  // handle legacy mem argument
 +  char* p;
 +  auto mb = strtoull(arg, &p, 0);
 +  if (*p == 0) {
 +    reg_t size = reg_t(mb) << 20;
 +    return std::vector<std::pair<reg_t, mem_t*>>(1, std::make_pair(reg_t(DRAM_BASE), new mem_t(size)));
 +  }
 +
 +  // handle base/size tuples
 +  std::vector<std::pair<reg_t, mem_t*>> res;
 +  while (true) {
 +    auto base = strtoull(arg, &p, 0);
 +    if (!*p || *p != ':')
 +      help();
 +    auto size = strtoull(p + 1, &p, 0);
 +    if ((size | base) % PGSIZE != 0)
 +      help();
 +    res.push_back(std::make_pair(reg_t(base), new mem_t(size)));
 +    if (!*p)
 +      break;
 +    if (*p != ',')
 +      help();
 +    arg = p + 1;
 +  }
 +  return res;
 +}
 +
  int main(int argc, char** argv)
  {
    bool debug = false;
    bool log = false;
    bool dump_dts = false;
    size_t nprocs = 1;
 -  size_t mem_mb = 0;
 +  reg_t start_pc = reg_t(-1);
 +  std::vector<std::pair<reg_t, mem_t*>> mems;
    std::unique_ptr<icache_sim_t> ic;
    std::unique_ptr<dcache_sim_t> dc;
    std::unique_ptr<cache_sim_t> l2;
    std::function<extension_t*()> extension;
    const char* isa = DEFAULT_ISA;
-   uint16_t gdb_port = 0;
+   uint16_t rbb_port = 0;
+   bool use_rbb = false;
  
    option_parser_t parser;
    parser.help(&help);
    parser.option('g', 0, 0, [&](const char* s){histogram = true;});
    parser.option('l', 0, 0, [&](const char* s){log = true;});
    parser.option('p', 0, 1, [&](const char* s){nprocs = atoi(s);});
 -  parser.option('m', 0, 1, [&](const char* s){mem_mb = atoi(s);});
 +  parser.option('m', 0, 1, [&](const char* s){mems = make_mems(s);});
    // I wanted to use --halted, but for some reason that doesn't work.
    parser.option('H', 0, 0, [&](const char* s){halted = true;});
-   parser.option(0, "gdb-port", 1, [&](const char* s){gdb_port = atoi(s);});
+   parser.option(0, "rbb-port", 1, [&](const char* s){use_rbb = true; rbb_port = atoi(s);});
 +  parser.option(0, "pc", 1, [&](const char* s){start_pc = strtoull(s, 0, 0);});
    parser.option(0, "ic", 1, [&](const char* s){ic.reset(new icache_sim_t(s));});
    parser.option(0, "dc", 1, [&](const char* s){dc.reset(new dcache_sim_t(s));});
    parser.option(0, "l2", 1, [&](const char* s){l2.reset(cache_sim_t::construct(s, "L2$"));});
  
    auto argv1 = parser.parse(argv);
    std::vector<std::string> htif_args(argv1, (const char*const*)argv + argc);
 -  sim_t s(isa, nprocs, mem_mb, halted, htif_args);
 -  std::unique_ptr<jtag_dtm_t> jtag_dtm(new jtag_dtm_t(&s.debug_module));
 +  if (mems.empty())
 +    mems = make_mems("2048");
 +
 +  sim_t s(isa, nprocs, halted, start_pc, mems, htif_args);
-   std::unique_ptr<gdbserver_t> gdbserver;
-   if (gdb_port) {
-     gdbserver = std::unique_ptr<gdbserver_t>(new gdbserver_t(gdb_port, &s));
-     s.set_gdbserver(&(*gdbserver));
+   std::unique_ptr<remote_bitbang_t> remote_bitbang((remote_bitbang_t *) NULL);
++  std::unique_ptr<jtag_dtm_t> jtag_dtm(new jtag_dtm_t(&s.debug_module));
+   if (use_rbb) {
+     remote_bitbang.reset(new remote_bitbang_t(rbb_port, &(*jtag_dtm)));
+     s.set_remote_bitbang(&(*remote_bitbang));
    }
  
    if (dump_dts) {