// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "dmidpi.h"

#include <assert.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "tcp_server.h"

// IDCODE register
// [31:28] 0x0,    - Version
// [27:12] 0x4F54, - Part Number: "OT"
// [11:1]  0x426,  - Manufacturer Identity: Google
// [0]     0x1     - fixed
const int IDCODEVAL = 0x04F5484D;

// DTMCS register
// [31:18]  0x0  - fixed
// [17]     0x0  - dmihardreset (unused)
// [16]     0x0  - dmireset (unused)
// [15]     0x0  - fixed
// [14:12]  0x0  - RunTestIdle cycles required (0)
// [11:10]  0x0  - DMI status (unused)
// [9:4]    0x7  - Number of address bits
// [3:0]    0x1  - Protocol version (0.13)
const int DTMCSRVAL = 0x00000071;

enum jtag_state_t {
  TestLogicReset,
  RunTestIdle,
  SelectDrScan,
  CaptureDr,
  ShiftDr,
  Exit1Dr,
  PauseDr,
  Exit2Dr,
  UpdateDr,
  SelectIrScan,
  CaptureIr,
  ShiftIr,
  Exit1Ir,
  PauseIr,
  Exit2Ir,
  UpdateIr
};

enum jtag_reg_t {
  Bypass0 = 0x0,
  IdCode = 0x1,
  DTMCSR = 0x10,
  DMIAccess = 0x11,
  Bypass1 = 0x1f
};

struct jtag_ctx {
  uint32_t ir_shift_reg;
  uint64_t dr_shift_reg;
  uint32_t ir_captured;
  uint64_t dr_captured;
  uint8_t dr_length;
  uint8_t jtag_tdo;
  enum jtag_state_t jtag_state;
  uint8_t dmi_outstanding;
};

struct dmi_sig_values {
  uint8_t dmi_req_valid;
  uint8_t dmi_req_ready;
  uint32_t dmi_req_addr;
  uint32_t dmi_req_op;
  uint32_t dmi_req_data;
  uint8_t dmi_rsp_valid;
  uint8_t dmi_rsp_ready;
  uint32_t dmi_rsp_data;
  uint32_t dmi_rsp_resp;
  uint8_t dmi_rst_n;
};

struct dmidpi_ctx {
  struct tcp_server_ctx *sock;
  struct jtag_ctx jtag;
  struct dmi_sig_values sig;
};

/**
 * Setup the correct shift register data
 *
 * @param ctx dmidpi context object
 */
static void set_dr_data(struct dmidpi_ctx *ctx) {
  switch (ctx->jtag.ir_captured) {
    case Bypass0:
    case Bypass1:
      ctx->jtag.dr_shift_reg = 0;
      ctx->jtag.dr_length = 1;
      break;
    case IdCode:
      ctx->jtag.dr_shift_reg = IDCODEVAL;
      ctx->jtag.dr_length = 32;
      break;
    case DTMCSR:
      ctx->jtag.dr_shift_reg = DTMCSRVAL;
      ctx->jtag.dr_length = 32;
      break;
    case DMIAccess:
      ctx->jtag.dr_shift_reg = ctx->jtag.dr_captured;
      ctx->jtag.dr_length = 32 + 7 + 2;
  }
}

/**
 * Drive a new DMI transaction to the DPI interface
 *
 * @param ctx dmidpi context object
 */
static void issue_dmi_req(struct dmidpi_ctx *ctx) {
  ctx->jtag.dmi_outstanding = 1;
  ctx->sig.dmi_req_valid = 1;
  ctx->sig.dmi_req_addr = (ctx->jtag.dr_captured >> 34) & 0x7F;
  ctx->sig.dmi_req_op = ctx->jtag.dr_captured & 0x3;
  ctx->sig.dmi_req_data = (ctx->jtag.dr_captured >> 2) & 0xFFFFFFFF;
}

/**
 * Advance internal JTAG state
 *
 * @param ctx dmidpi context object
 * @param tdi tms tck JTAG signal values
 * @return true when a command completes, false otherwise
 */
static bool process_jtag_cmd(struct dmidpi_ctx *ctx, bool tdi, bool tms,
                             bool tck) {
  // Return tdo values during tck low phase
  if (!tck) {
    if (ctx->jtag.jtag_state == ShiftDr) {
      ctx->jtag.jtag_tdo = ctx->jtag.dr_shift_reg & 0x1;
    } else {
      ctx->jtag.jtag_tdo = ctx->jtag.ir_shift_reg & 0x1;
    }
    return false;
  }

  // standard JTAG state machine
  switch (ctx->jtag.jtag_state) {
    case TestLogicReset:
      // reset design
      ctx->sig.dmi_rst_n = 0;
      ctx->jtag.ir_captured = 1;
      if (!tms) {
        ctx->jtag.jtag_state = RunTestIdle;
      }
      return true;
    case RunTestIdle:
      // release reset
      ctx->sig.dmi_rst_n = 1;
      if (tms) {
        ctx->jtag.jtag_state = SelectDrScan;
      }
      return false;
    case SelectDrScan:
      if (tms) {
        ctx->jtag.jtag_state = SelectIrScan;
      } else {
        ctx->jtag.jtag_state = CaptureDr;
      }
      return false;
    case CaptureDr:
      set_dr_data(ctx);
      if (tms) {
        ctx->jtag.jtag_state = Exit1Dr;
      } else {
        ctx->jtag.jtag_state = ShiftDr;
      }
      return false;
    case ShiftDr:
      ctx->jtag.dr_shift_reg |= ((uint64_t)tdi << ctx->jtag.dr_length);
      ctx->jtag.dr_shift_reg >>= 1;
      if (tms) {
        ctx->jtag.jtag_state = Exit1Dr;
      }
      return false;
    case Exit1Dr:
      if (tms) {
        ctx->jtag.jtag_state = UpdateDr;
      } else {
        ctx->jtag.jtag_state = PauseDr;
      }
      return false;
    case PauseDr:
      if (tms) {
        ctx->jtag.jtag_state = Exit2Dr;
      }
      return false;
    case Exit2Dr:
      if (tms) {
        ctx->jtag.jtag_state = UpdateDr;
      } else {
        ctx->jtag.jtag_state = ShiftDr;
      }
      return false;
    case UpdateDr:
      ctx->jtag.dr_captured = ctx->jtag.dr_shift_reg;
      if (tms) {
        ctx->jtag.jtag_state = SelectDrScan;
      } else {
        ctx->jtag.jtag_state = RunTestIdle;
      }
      // If a DMI read or write completes, write it out
      if ((ctx->jtag.ir_captured == DMIAccess) &&
          ((ctx->jtag.dr_captured & 0x3) != 0)) {
        issue_dmi_req(ctx);
        return true;
      }
      return false;
    case SelectIrScan:
      if (tms) {
        ctx->jtag.jtag_state = TestLogicReset;
      } else {
        ctx->jtag.jtag_state = CaptureIr;
      }
      return false;
    case CaptureIr:
      ctx->jtag.ir_shift_reg = 0x5;
      if (tms) {
        ctx->jtag.jtag_state = Exit1Ir;
      } else {
        ctx->jtag.jtag_state = ShiftIr;
      }
      return false;
    case ShiftIr:
      ctx->jtag.ir_shift_reg |= ((uint32_t)tdi << 5);
      ctx->jtag.ir_shift_reg >>= 1;
      if (tms) {
        ctx->jtag.jtag_state = Exit1Ir;
      }
      return false;
    case Exit1Ir:
      if (tms) {
        ctx->jtag.jtag_state = UpdateIr;
      } else {
        ctx->jtag.jtag_state = PauseIr;
      }
      return false;
    case PauseIr:
      if (tms) {
        ctx->jtag.jtag_state = Exit2Ir;
      }
      return false;
    case Exit2Ir:
      if (tms) {
        ctx->jtag.jtag_state = UpdateIr;
      } else {
        ctx->jtag.jtag_state = ShiftIr;
      }
      return false;
    case UpdateIr:
      ctx->jtag.ir_captured = ctx->jtag.ir_shift_reg;
      if (tms) {
        ctx->jtag.jtag_state = SelectDrScan;
      } else {
        ctx->jtag.jtag_state = RunTestIdle;
      }
      return false;
  }
  return false;
}

/**
 * Process a new command byte
 *
 * @param ctx a dmi context object
 * @param cmd a packaged OpenOCD cmd
 * @return true when a command completes, false otherwise
 */
static bool process_cmd_byte(struct dmidpi_ctx *ctx, char cmd) {
  /*
   * Documentation pointer:
   * The remote_bitbang protocol implemented below is documented in the OpenOCD
   * source tree at doc/manual/jtag/drivers/remote_bitbang.txt, or online at
   * https://repo.or.cz/openocd.git/blob/HEAD:/doc/manual/jtag/drivers/remote_bitbang.txt
   */

  // parse received command byte
  if (cmd >= '0' && cmd <= '7') {
    // JTAG write
    char cmd_bit = cmd - '0';
    char tdi = (cmd_bit >> 0) & 0x1;
    char tms = (cmd_bit >> 1) & 0x1;
    char tck = (cmd_bit >> 2) & 0x1;
    return (process_jtag_cmd(ctx, tdi, tms, tck));
  } else if (cmd >= 'r' && cmd <= 'u') {
    // JTAG reset (active high from OpenOCD)
    char cmd_bit = cmd - 'r';
    char trst = ((cmd_bit >> 1) & 0x1);
    if (trst) {
      ctx->sig.dmi_rst_n = 0;
      ctx->jtag.jtag_state = RunTestIdle;
    }
    return true;
  } else if (cmd == 'R') {
    // JTAG read, send tdo as response
    char tdo_ascii = ctx->jtag.jtag_tdo + '0';
    tcp_server_write(ctx->sock, tdo_ascii);
  } else if (cmd == 'B') {
    // printf("DMI DPI: BLINK ON!\n");
  } else if (cmd == 'b') {
    // printf("DMI DPI: BLINK OFF!\n");
  } else if (cmd == 'Q') {
    // quit (client disconnect)
    printf("DMI DPI: Remote disconnected.\n");
    tcp_server_client_close(ctx->sock);
  } else {
    fprintf(stderr,
            "DMI DPI: Protocol violation detected: unsupported command %c\n",
            cmd);
    exit(1);
  }

  return false;
}

/**
 * Process DPI inputs from the design
 *
 * @param ctx dmidpi context object
 */
static void process_dmi_inputs(struct dmidpi_ctx *ctx) {
  // Deassert dmi_req_valid when acked
  if (ctx->sig.dmi_req_ready) {
    ctx->sig.dmi_req_valid = 0;
  }
  // Always ready for a resp
  ctx->sig.dmi_rsp_ready = 1;
  if (ctx->sig.dmi_rsp_valid) {
    ctx->jtag.dr_captured = (uint64_t)ctx->sig.dmi_rsp_data << 2;
    ctx->jtag.dr_captured |= (uint64_t)ctx->sig.dmi_rsp_resp & 0x3;
    // Clear req outstanding flag
    ctx->jtag.dmi_outstanding = 0;
  }
}

/**
 * Advance DMI internal state
 *
 * @param ctx dmidpi context object
 */
static void update_dmi_state(struct dmidpi_ctx *ctx) {
  assert(ctx);

  // read input from design
  process_dmi_inputs(ctx);

  // If we are waiting for a previous transaction to complete, do not attempt
  // a new one
  if (ctx->jtag.dmi_outstanding) {
    return;
  }

  char done = 0;
  while (!done) {
    // read a command byte
    char cmd;
    if (!tcp_server_read(ctx->sock, &cmd)) {
      return;
    }
    // Process command bytes until a command completes
    done = process_cmd_byte(ctx, cmd);
  }
}

void *dmidpi_create(const char *display_name, int listen_port) {
  // Create context
  struct dmidpi_ctx *ctx =
      (struct dmidpi_ctx *)calloc(1, sizeof(struct dmidpi_ctx));
  assert(ctx);

  // Set up socket details
  ctx->sock = tcp_server_create(display_name, listen_port);

  printf(
      "\n"
      "JTAG: Virtual JTAG interface %s is listening on port %d. Use\n"
      "OpenOCD and the following configuration to connect:\n"
      "  interface remote_bitbang\n"
      "  remote_bitbang_host localhost\n"
      "  remote_bitbang_port %d\n",
      display_name, listen_port, listen_port);

  return (void *)ctx;
}

void dmidpi_close(void *ctx_void) {
  struct dmidpi_ctx *ctx = (struct dmidpi_ctx *)ctx_void;
  if (!ctx) {
    return;
  }

  // Shut down the server
  tcp_server_close(ctx->sock);

  free(ctx);
}

void dmidpi_tick(void *ctx_void, svBit *dmi_req_valid,
                 const svBit dmi_req_ready, svBitVecVal *dmi_req_addr,
                 svBitVecVal *dmi_req_op, svBitVecVal *dmi_req_data,
                 const svBit dmi_rsp_valid, svBit *dmi_rsp_ready,
                 const svBitVecVal *dmi_rsp_data,
                 const svBitVecVal *dmi_rsp_resp, svBit *dmi_rst_n) {
  struct dmidpi_ctx *ctx = (struct dmidpi_ctx *)ctx_void;

  if (!ctx) {
    return;
  }

  ctx->sig.dmi_req_ready = dmi_req_ready;
  ctx->sig.dmi_rsp_valid = dmi_rsp_valid;
  ctx->sig.dmi_rsp_data = *dmi_rsp_data;
  ctx->sig.dmi_rsp_resp = *dmi_rsp_resp;

  update_dmi_state(ctx);

  *dmi_req_valid = ctx->sig.dmi_req_valid;
  *dmi_req_addr = ctx->sig.dmi_req_addr;
  *dmi_req_op = ctx->sig.dmi_req_op;
  *dmi_req_data = ctx->sig.dmi_req_data;
  *dmi_rsp_ready = ctx->sig.dmi_rsp_ready;
  *dmi_rst_n = ctx->sig.dmi_rst_n;
}
