// 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/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) {
  base_printf("%c", cmd);
  simple_serial_print_hex(data, data_len);
  base_printf("\n");
}

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) {
  for (size_t i = 0; i < data_len; ++i) {
    base_printf("%2x", data[i]);
  }
}
