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

#include "sw/device/sca/lib/simple_serial.h"

#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/dif/dif_uart.h"
#include "sw/device/lib/runtime/print.h"
#include "sw/device/sca/lib/prng.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"

/**
 * Macro for ignoring return values.
 *
 * This is needed because ‘(void)expr;` does not work for gcc.
 */
#define IGNORE_RESULT(expr) \
  if (expr) {               \
  }

enum {
  /**
   * Simple serial protocol version 1.1.
   */
  kSimpleSerialProtocolVersion = 1,
  kUartMaxRxPacketSize = 64,
};

/**
 * Command handlers.
 *
 * Clients can register handlers for commands 'a'-'z' using
 * `simple_serial_register_handler()` except for 'v' (version) and 's' (seed
 * PRNG), which are handled by this library. This array has an extra element
 * (27) that is initialized in `simple_serial_init()` to point to
 * `simple_serial_unknown_command()` in order to simplify handling of invalid
 * commands in `simple_serial_process_packet()`.
 */
static simple_serial_command_handler handlers[27];
static const dif_uart_t *uart;

static bool simple_serial_is_valid_command(uint8_t cmd) {
  return cmd >= 'a' && cmd <= 'z';
}

/**
 * Converts a hex encoded nibble to binary.
 *
 * @param hex A hex encoded nibble.
 * @param[out] val Value of the nibble.
 *
 * @return Result of the operation.
 */
static simple_serial_result_t simple_serial_hex_to_bin(uint8_t hex,
                                                       uint8_t *val) {
  if (hex >= '0' && hex <= '9') {
    *val = hex - '0';
  } else if (hex >= 'A' && hex <= 'F') {
    *val = hex - 'A' + 10;
  } else if (hex >= 'a' && hex <= 'f') {
    *val = hex - 'a' + 10;
  } else {
    return kSimpleSerialError;
  }
  return kSimpleSerialOk;
}

/**
 * Receives a simple serial packet over UART.
 *
 * Simple serial packets are composed of:
 * - Command: A single byte character,
 * - Payload: A variable length hex encoded string,
 * - Terminator: '\n'.
 *
 * @param[out] cmd Simple serial command.
 * @param[out] data Buffer for received packet payload.
 * @param data_buf_len Length of the packet payload buffer.
 * @param[out] data_len Received packet payload length.
 */
static void simple_serial_receive_packet(uint8_t *cmd, uint8_t *data,
                                         size_t data_buf_len,
                                         size_t *data_len) {
  while (true) {
    // Read command byte - a single character.
    IGNORE_RESULT(dif_uart_byte_receive_polled(uart, cmd));
    if (*cmd == '\n') {
      continue;
    }
    *data_len = 0;
    // Read payload - a variable length hex encoded string terminated with '\n'.
    do {
      uint8_t hex_byte[2];
      IGNORE_RESULT(dif_uart_byte_receive_polled(uart, &hex_byte[0]));
      if (hex_byte[0] == '\n') {
        return;
      }
      if (simple_serial_hex_to_bin(hex_byte[0], &hex_byte[0]) !=
          kSimpleSerialOk) {
        break;
      }
      IGNORE_RESULT(dif_uart_byte_receive_polled(uart, &hex_byte[1]));
      if (simple_serial_hex_to_bin(hex_byte[1], &hex_byte[1]) !=
          kSimpleSerialOk) {
        break;
      }
      if (*data_len == data_buf_len) {
        break;
      }
      data[*data_len] = hex_byte[0] << 4 | hex_byte[1];
      ++*data_len;
    } while (true);
  }
}

/**
 * Returns the index of a command's handler in `handlers`.
 *
 * This function returns the index of the last element, which points to
 * `simple_serial_unknown_command(), if the given command is not valid.
 *
 * @param cmd A simple serial command.
 * @return Command handler's index in `handlers`.
 */
static size_t simple_serial_get_handler_index(uint8_t cmd) {
  if (simple_serial_is_valid_command(cmd)) {
    return cmd - 'a';
  } else {
    return ARRAYSIZE(handlers) - 1;
  }
}

/**
 * Simple serial 'v' (version) command handler.
 *
 * Returns the simple serial version that this file implements. This command is
 * useful for checking that the host and the device can communicate properly
 * before starting capturing traces.
 *
 * @param data Received packet payload.
 * @param data_len Payload length.
 */
static void simple_serial_version(const uint8_t *data, size_t data_len) {
  simple_serial_send_status(kSimpleSerialProtocolVersion);
}

/**
 * Simple serial 's' (seed PRNG) command handler.
 *
 * This function only supports 4-byte seeds.
 *
 * @param seed A buffer holding the seed.
 * @param seed_len Seed length.
 */
static void simple_serial_seed_prng(const uint8_t *seed, size_t seed_len) {
  SS_CHECK(seed_len == sizeof(uint32_t));
  prng_seed(read_32(seed));
}

/**
 * Handler for uninmplemented simple serial commands.
 *
 * Sends an error packet over UART.
 *
 * @param data Received packet payload
 * @param data_len Payload length.
 */
static void simple_serial_unknown_command(const uint8_t *data,
                                          size_t data_len) {
  simple_serial_send_status(kSimpleSerialError);
}

void simple_serial_init(const dif_uart_t *uart_) {
  uart = uart_;

  for (size_t i = 0; i < ARRAYSIZE(handlers); ++i) {
    handlers[i] = simple_serial_unknown_command;
  }
  handlers[simple_serial_get_handler_index('s')] = simple_serial_seed_prng;
  handlers[simple_serial_get_handler_index('v')] = simple_serial_version;
}

simple_serial_result_t simple_serial_register_handler(
    uint8_t cmd, simple_serial_command_handler handler) {
  if (!simple_serial_is_valid_command(cmd)) {
    return kSimpleSerialError;
  } else if (cmd == 's' || cmd == 'v') {
    // Cannot register handlers for built-in commands.
    return kSimpleSerialError;
  } else {
    handlers[simple_serial_get_handler_index(cmd)] = handler;
    return kSimpleSerialOk;
  }
}

void simple_serial_process_packet(void) {
  uint8_t cmd;
  uint8_t data[kUartMaxRxPacketSize];
  size_t data_len;
  simple_serial_receive_packet(&cmd, data, ARRAYSIZE(data), &data_len);
  handlers[simple_serial_get_handler_index(cmd)](data, data_len);
}

void simple_serial_send_packet(const uint8_t cmd, const uint8_t *data,
                               size_t data_len) {
  char buf;
  base_snprintf(&buf, 1, "%c", cmd);
  IGNORE_RESULT(dif_uart_byte_send_polled(uart, buf));
  simple_serial_print_hex(data, data_len);
  base_snprintf(&buf, 1, "\n");
  IGNORE_RESULT(dif_uart_byte_send_polled(uart, buf));
}

void simple_serial_send_status(uint8_t res) {
  simple_serial_send_packet('z', (uint8_t[1]){res}, 1);
}

void simple_serial_print_hex(const uint8_t *data, size_t data_len) {
  char buf[2];
  for (size_t i = 0; i < data_len; ++i) {
    base_snprintf(&buf[0], 2, "%02x", data[i]);
    IGNORE_RESULT(dif_uart_byte_send_polled(uart, buf[0]));
    IGNORE_RESULT(dif_uart_byte_send_polled(uart, buf[1]));
  }
}
