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

#include <stddef.h>
#include <stdint.h>

#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/base/log.h"
#include "sw/device/lib/base/print.h"
#include "sw/device/lib/base/stdasm.h"
#include "sw/device/lib/runtime/check.h"
#include "sw/device/lib/testing/test_status.h"
#include "sw/device/lib/uart.h"

// Symbols defined in sw/device/exts/common/flash_link.ld, which we use to
// check that the CRT did what it was supposed to.
extern char _bss_start;
extern char _bss_end;
extern char _data_start;
extern char _data_end;
extern char _data_init_start;

// The addresses of the values above.
static const uintptr_t bss_start_addr = (uintptr_t)&_bss_start;
static const uintptr_t bss_end_addr = (uintptr_t)&_bss_end;
static const uintptr_t data_start_addr = (uintptr_t)&_data_start;
static const uintptr_t data_end_addr = (uintptr_t)&_data_end;
static const uintptr_t data_init_start_addr = (uintptr_t)&_data_init_start;

// Ensure that both .bss and .data are non-empty. The compiler will always keep
// these symbols, since they're volatile.
volatile char ensure_data_exists = 42;
volatile char ensure_bss_exists;

int main(int argc, char **argv) {
  // NOTE: we cannot call any external functions until all checks of post-CRT
  // state are complete; this is to ensure that our checks are not tainted by
  // external functions.
  //
  // Among other things, this means we can't CHECK, since we can't initialize
  // UART. Thus, any critical failures are handled by returning from main.
  // To minimize the chance of things going wrong, we don't even bother placing
  // the checks in their own function.

  // Test core assumptions above the five addresses above. The test code
  // must be able to assume these all hold.
  //
  // Note that performing these comparisons on their addresses is UB, and will
  // cause this entire function to get deleted by the compiler.
  if (&_bss_start > &_bss_end || &_data_start > &_data_end) {
    // Something has gone terribly wrong and we have no hope of continuing the
    // test, so we're going to return and let the test time out.
    //
    // The best method for debugging a failure like this is to stare at an
    // instruction trace.
    return 1;
  }

  // Ensure that .bss was *actually* zeroed at the start of execution. If it
  // wasn't, we note the offset from _bss_start at which it wasn't.
  char *bss = &_bss_start;
  ptrdiff_t bss_len = &_bss_end - &_bss_start;
  int bad_bss_index = -1;
  for (int i = 0; i < bss_len; ++i) {
    if (bss[i] != 0) {
      bad_bss_index = i;
      break;
    }
  }

  // Similarly, ensure that .data has the values in the init section.
  char *data = &_data_start;
  char *data_init = &_data_init_start;
  ptrdiff_t data_len = &_data_end - &_data_start;
  int bad_data_index = -1;
  for (int i = 0; i < data_len; ++i) {
    if (data[i] != data_init[i]) {
      bad_data_index = i;
      break;
    }
  }

  // End of post-CRT checks; begin actual assertions..
  test_status_set(kTestStatusInTest);
  // Initialize the UART to enable logging for non-DV simulation platforms.
  if (kDeviceType != kDeviceSimDV) {
    uart_init(kUartBaudrate);
    base_set_stdout(uart_stdout);
  }

  CHECK(bss_start_addr % sizeof(uint32_t) == 0,
        "_bss_start not word-aligned: 0x%08x", bss_start_addr);
  CHECK(bss_end_addr % sizeof(uint32_t) == 0,
        "_bss_end not word-aligned: 0x%08x", bss_end_addr);
  CHECK(data_start_addr % sizeof(uint32_t) == 0,
        "_data_start not word-aligned: 0x%08x", data_start_addr);
  CHECK(data_end_addr % sizeof(uint32_t) == 0,
        "_data_end not word-aligned: 0x%08x", data_end_addr);
  CHECK(data_init_start_addr % sizeof(uint32_t) == 0,
        "_data_init_start not word-aligned: 0x%08x", data_init_start_addr);

  CHECK(bad_bss_index == -1, "found non-zero .bss byte at *0x%08x == 0x%02x",
        bss_start_addr + bad_bss_index, (uint32_t)bss[bad_bss_index]);
  CHECK(bad_data_index == -1,
        "found bad .data byte at *0x%08x == 0x%02x, expected 0x%02x",
        data_start_addr + bad_data_index, (uint32_t)data_init[bad_data_index]);

  test_status_set(kTestStatusPassed);

  // Unreachable code.
  return 1;
}
