// Copyright 2023 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include "physload.h"

#include <inttypes.h>
#include <lib/boot-options/boot-options.h>
#include <lib/elfldltl/diagnostics.h>
#include <lib/elfldltl/dynamic.h>
#include <lib/elfldltl/link.h>
#include <lib/elfldltl/memory.h>
#include <lib/elfldltl/relocation.h>
#include <lib/zbitl/error-stdio.h>
#include <lib/zbitl/view.h>

#include <ktl/array.h>
#include <ktl/byte.h>
#include <ktl/move.h>
#include <ktl/span.h>
#include <ktl/string_view.h>
#include <phys/address-space.h>
#include <phys/elf-image.h>
#include <phys/handoff.h>
#include <phys/kernel-package.h>
#include <phys/main.h>
#include <phys/stdio.h>
#include <phys/symbolize.h>

#include "log.h"

#include <ktl/enforce.h>

namespace {

// physload, physboot, EL2, kernel
constexpr size_t kMaxPhysloadModules = 4;

void LogSerial(FILE* out = stdout) {
  fprintf(out, "%s: Console configured as ", ProgramName());
  gBootOptions->Show("kernel.serial"sv, false, out);
}

}  // namespace

[[noreturn]] void ZbiMain(void* zbi_ptr, arch::EarlyTicks ticks) {
  PhysBootTimes times;
  times.Set(PhysBootTimes::kZbiEntry, ticks);

  MainSymbolize symbolize("physload");
  if (gBootOptions->phys_verbose) {
    symbolize.Context();
    LogSerial();
  }

  AddressSpace aspace;
  InitMemory(zbi_ptr, &aspace);

  // This marks the interval between handoff from the boot loader (kZbiEntry)
  // and phys environment setup with identity-mapped memory management et al.
  times.SampleNow(PhysBootTimes::kPhysSetup);

  // Start collecting the log in memory as well as logging to the console.
  Log log;

  {
    // Prime the log with what would already have been written to the console
    // under kernel.phys.verbose=true (even if it wasn't), but don't send that
    // to the console.
    FILE log_file{&log};
    symbolize.ContextAlways(&log_file);
    LogSerial(&log_file);
    Allocation::GetPool().PrintMemoryRanges(symbolize.name(), &log_file);
  }

  // Now mirror all stdout to the log, and write debugf there even if verbose
  // logging to stdout is disabled.
  gLog = &log;
  log.SetStdout();

  auto zbi_header = static_cast<zbi_header_t*>(zbi_ptr);
  auto zbi = zbitl::StorageFromRawHeader<ktl::span<ktl::byte>>(zbi_header);

  // Unpack the compressed KERNEL_STORAGE payload.
  KernelStorage kernel_storage;
  kernel_storage.Init(zbitl::View{zbi});
  kernel_storage.GetTimes(times);

  // TODO: add some time samples around bootfs decoding, loading, etc.
  KernelStorage::Bootfs bootfs = kernel_storage.root();

  // Provide space for loading modules.
  ktl::array<const ElfImage*, kMaxPhysloadModules> modules_storage;
  symbolize.ReplaceModulesStorage(Symbolize::ModuleList(modules_storage));

  ktl::string_view next_file_name = gBootOptions->phys_next.data();

  // Load up the next module.
  ElfImage next_elf;
  if (auto result = next_elf.Init(bootfs, next_file_name, true); result.is_error()) {
    zbitl::PrintBootfsError(result.error_value());
    abort();
  }

  // We don't support any code-patching for physboot - or any physload module
  // at the moment - though we could if there were any worth doing.
  ZX_ASSERT_MSG(!next_elf.has_patches(),
                "kernel.phys.next ELF image with code-patches not supported");

  // Load the image, in place if space or copied elsewhere if not.
  Allocation loaded = next_elf.Load();

  // Relocate the image.
  next_elf.Relocate();

  next_elf.AssertInterpMatchesBuildId(symbolize.name(), symbolize.build_id());

  if (gBootOptions->phys_verbose) {
    symbolize.LogHandoff(next_elf.name(), next_elf.entry());
  }

  // Call into the entry point.  It must not return, but it will keep using the
  // same stack so it can safely take references to our stack objects.
  next_elf.Handoff<PhysLoadHandoffFunction>(next_elf, &log, gArchPhysInfo, GetUartDriver(),
                                            &symbolize, gBootOptions, Allocation::GetPool(),
                                            gAddressSpace, times, ktl::move(kernel_storage));
}
